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>
142 lines
5.7 KiB
Go
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"`
|
|
} |