internal/storage: SQLite-БД для задач и трассировок (таски + статус-машина, трассы с группировкой по task_id)
All checks were successful
build-test / build (push) Successful in 30s
All checks were successful
build-test / build (push) Successful in 30s
This commit is contained in:
104
internal/storage/models.go
Normal file
104
internal/storage/models.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package storage
|
||||
|
||||
// Status — статус задачи (state machine).
|
||||
type Status string
|
||||
|
||||
const (
|
||||
StatusDraft Status = "draft" // только что создана
|
||||
StatusCollecting Status = "collecting" // аналитик собирает детали
|
||||
StatusReady Status = "ready" // черновик готов, ждёт запуска
|
||||
StatusRunning Status = "running" // opencode работает
|
||||
StatusSuccess Status = "success" // задача выполнена
|
||||
StatusFailed Status = "failed" // ошибка выполнения
|
||||
StatusTimeout Status = "timeout" // таймаут opencode
|
||||
StatusCancelled Status = "cancelled" // отменена пользователем
|
||||
StatusAborted Status = "aborted" // сбой сбора, черновик выброшен
|
||||
StatusClosed Status = "closed" // закрыта вручную
|
||||
)
|
||||
|
||||
// AllStatuses — все возможные статусы для валидации.
|
||||
var AllStatuses = []Status{
|
||||
StatusDraft, StatusCollecting, StatusReady,
|
||||
StatusRunning, StatusSuccess, StatusFailed, StatusTimeout,
|
||||
StatusCancelled, StatusAborted, StatusClosed,
|
||||
}
|
||||
|
||||
// validTransitions задаёт разрешённые переходы статусов.
|
||||
var validTransitions = map[Status][]Status{
|
||||
StatusDraft: {StatusCollecting, StatusCancelled, StatusAborted},
|
||||
StatusCollecting: {StatusReady, StatusDraft, StatusCancelled, StatusAborted},
|
||||
StatusReady: {StatusRunning, StatusCancelled, StatusAborted, StatusClosed},
|
||||
StatusRunning: {StatusSuccess, StatusFailed, StatusTimeout, StatusCancelled},
|
||||
StatusSuccess: {StatusClosed},
|
||||
StatusFailed: {StatusReady, StatusClosed, StatusCancelled}, // retry
|
||||
StatusTimeout: {StatusReady, StatusClosed, StatusCancelled}, // retry
|
||||
StatusCancelled: {StatusClosed},
|
||||
StatusAborted: {StatusClosed},
|
||||
StatusClosed: {}, // терминальный
|
||||
}
|
||||
|
||||
// IsValidTransition проверяет, допустим ли переход from → to.
|
||||
func IsValidTransition(from, to Status) bool {
|
||||
allowed, ok := validTransitions[from]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for _, s := range allowed {
|
||||
if s == to {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsTerminal возвращает true, если статус терминальный.
|
||||
func IsTerminal(s Status) bool {
|
||||
return s == StatusSuccess || s == StatusCancelled ||
|
||||
s == StatusAborted || s == StatusClosed
|
||||
}
|
||||
|
||||
// Task — запись задачи в БД.
|
||||
type Task struct {
|
||||
ID int64 `json:"id"`
|
||||
ChatID string `json:"chat_id"` // tg://<id>
|
||||
Title string `json:"title"`
|
||||
Goal string `json:"goal"`
|
||||
Repo string `json:"repo"`
|
||||
Why string `json:"why"`
|
||||
AC string `json:"ac"` // acceptance criteria
|
||||
TaskTag string `json:"task_tag"` // UUID, стабильный на всю жизнь
|
||||
Status Status `json:"status"`
|
||||
CreatedAt SQLiteTime `json:"created_at"`
|
||||
UpdatedAt SQLiteTime `json:"updated_at"`
|
||||
}
|
||||
|
||||
// Trace — запись трассировки выполнения.
|
||||
type TraceStatus string
|
||||
|
||||
const (
|
||||
TraceRunning TraceStatus = "running"
|
||||
TraceSuccess TraceStatus = "success"
|
||||
TraceFailed TraceStatus = "failed"
|
||||
TraceTimeout TraceStatus = "timeout"
|
||||
)
|
||||
|
||||
// Trace — лог одного субагента.
|
||||
type Trace struct {
|
||||
ID int64 `json:"id"`
|
||||
TaskID int64 `json:"task_id"`
|
||||
Agent string `json:"agent"` // analyst | researcher | dev | reviewer
|
||||
SessionID string `json:"session_id"` // opencode session_id
|
||||
Prompt string `json:"prompt"`
|
||||
Output string `json:"output"` // полный NDJSON или summary
|
||||
Status TraceStatus `json:"status"`
|
||||
StartedAt SQLiteTime `json:"started_at"`
|
||||
FinishedAt NullSQLiteTime `json:"finished_at,omitempty"`
|
||||
}
|
||||
|
||||
// TaskFilter — параметры фильтрации списка задач.
|
||||
type TaskFilter struct {
|
||||
ChatID string
|
||||
Status Status
|
||||
Limit int
|
||||
Offset int
|
||||
}
|
||||
Reference in New Issue
Block a user