Files
WHOOSH/internal/tasks/models.go
Claude Code 69e812826e Implement comprehensive task management system with GITEA integration
Replace mock endpoints with real database-backed task management:
- Add tasks table with full relationships and indexes
- Create generic task management service supporting multiple sources
- Implement GITEA integration service for issue synchronization
- Add task creation, retrieval, assignment, and status updates

Database schema changes:
- New tasks table with external_id mapping for GITEA/GitHub/Jira
- Foreign key relationships to teams and agents
- Task workflow tracking (claimed_at, started_at, completed_at)
- JSONB fields for labels, tech_stack, requirements

Task management features:
- Generic TaskFilter with pagination and multi-field filtering
- Automatic tech stack inference from labels and descriptions
- Complexity scoring based on multiple factors
- Real task assignment to teams and agents
- GITEA webhook integration for automated task sync

API endpoints now use real database operations:
- GET /api/v1/tasks (real filtering and pagination)
- GET /api/v1/tasks/{id} (database lookup)
- POST /api/v1/tasks/ingest (creates actual task records)
- POST /api/v1/tasks/{id}/claim (real assignment operations)

GITEA integration includes:
- Issue-to-task synchronization with configurable task labels
- Priority mapping from issue labels
- Estimated hours extraction from issue descriptions
- Webhook processing for real-time updates

This removes the major mocked components and provides
a foundation for genuine E2E testing with real data.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-08 12:21:33 +10:00

142 lines
5.7 KiB
Go

package tasks
import (
"time"
"github.com/google/uuid"
)
// TaskStatus represents the current status of a task
type TaskStatus string
const (
TaskStatusOpen TaskStatus = "open"
TaskStatusClaimed TaskStatus = "claimed"
TaskStatusInProgress TaskStatus = "in_progress"
TaskStatusCompleted TaskStatus = "completed"
TaskStatusClosed TaskStatus = "closed"
TaskStatusBlocked TaskStatus = "blocked"
)
// TaskPriority represents task priority levels
type TaskPriority string
const (
TaskPriorityLow TaskPriority = "low"
TaskPriorityMedium TaskPriority = "medium"
TaskPriorityHigh TaskPriority = "high"
TaskPriorityCritical TaskPriority = "critical"
)
// SourceType represents different task management systems
type SourceType string
const (
SourceTypeGitea SourceType = "gitea"
SourceTypeGitHub SourceType = "github"
SourceTypeJira SourceType = "jira"
SourceTypeManual SourceType = "manual"
)
// Task represents a development task from any source system
type Task struct {
ID uuid.UUID `json:"id" db:"id"`
ExternalID string `json:"external_id" db:"external_id"`
ExternalURL string `json:"external_url" db:"external_url"`
SourceType SourceType `json:"source_type" db:"source_type"`
SourceConfig map[string]interface{} `json:"source_config" db:"source_config"`
// Core task data
Title string `json:"title" db:"title"`
Description string `json:"description" db:"description"`
Status TaskStatus `json:"status" db:"status"`
Priority TaskPriority `json:"priority" db:"priority"`
// Assignment data
AssignedTeamID *uuid.UUID `json:"assigned_team_id,omitempty" db:"assigned_team_id"`
AssignedAgentID *uuid.UUID `json:"assigned_agent_id,omitempty" db:"assigned_agent_id"`
// Context data
Repository string `json:"repository,omitempty" db:"repository"`
ProjectID string `json:"project_id,omitempty" db:"project_id"`
Labels []string `json:"labels" db:"labels"`
TechStack []string `json:"tech_stack" db:"tech_stack"`
Requirements []string `json:"requirements" db:"requirements"`
EstimatedHours int `json:"estimated_hours,omitempty" db:"estimated_hours"`
ComplexityScore float64 `json:"complexity_score,omitempty" db:"complexity_score"`
// Workflow timestamps
ClaimedAt *time.Time `json:"claimed_at,omitempty" db:"claimed_at"`
StartedAt *time.Time `json:"started_at,omitempty" db:"started_at"`
CompletedAt *time.Time `json:"completed_at,omitempty" db:"completed_at"`
// Timestamps
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
ExternalCreatedAt *time.Time `json:"external_created_at,omitempty" db:"external_created_at"`
ExternalUpdatedAt *time.Time `json:"external_updated_at,omitempty" db:"external_updated_at"`
}
// CreateTaskInput represents input for creating a new task
type CreateTaskInput struct {
ExternalID string `json:"external_id"`
ExternalURL string `json:"external_url"`
SourceType SourceType `json:"source_type"`
SourceConfig map[string]interface{} `json:"source_config,omitempty"`
Title string `json:"title"`
Description string `json:"description"`
Priority TaskPriority `json:"priority,omitempty"`
Repository string `json:"repository,omitempty"`
ProjectID string `json:"project_id,omitempty"`
Labels []string `json:"labels,omitempty"`
EstimatedHours int `json:"estimated_hours,omitempty"`
ExternalCreatedAt *time.Time `json:"external_created_at,omitempty"`
ExternalUpdatedAt *time.Time `json:"external_updated_at,omitempty"`
}
// TaskFilter represents filtering options for task queries
type TaskFilter struct {
Status []TaskStatus `json:"status,omitempty"`
Priority []TaskPriority `json:"priority,omitempty"`
SourceType []SourceType `json:"source_type,omitempty"`
Repository string `json:"repository,omitempty"`
ProjectID string `json:"project_id,omitempty"`
AssignedTeam *uuid.UUID `json:"assigned_team,omitempty"`
AssignedAgent *uuid.UUID `json:"assigned_agent,omitempty"`
TechStack []string `json:"tech_stack,omitempty"`
Limit int `json:"limit,omitempty"`
Offset int `json:"offset,omitempty"`
}
// TaskAssignment represents assigning a task to a team or agent
type TaskAssignment struct {
TaskID uuid.UUID `json:"task_id"`
TeamID *uuid.UUID `json:"team_id,omitempty"`
AgentID *uuid.UUID `json:"agent_id,omitempty"`
Reason string `json:"reason,omitempty"`
}
// TaskStatusUpdate represents updating a task's status
type TaskStatusUpdate struct {
TaskID uuid.UUID `json:"task_id"`
Status TaskStatus `json:"status"`
Reason string `json:"reason,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
}
// ExternalTask represents a task from an external system (GITEA, GitHub, etc.)
type ExternalTask struct {
ID string `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
State string `json:"state"` // open, closed, etc.
URL string `json:"url"`
Repository string `json:"repository"`
Labels []string `json:"labels"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Metadata map[string]interface{} `json:"metadata"`
}