86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
|
|
package repository
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"code.cubecraftcreations.com/CubeCraft-Creations/Control-Center/go-backend/internal/models"
|
||
|
|
"github.com/jackc/pgx/v5"
|
||
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
||
|
|
)
|
||
|
|
|
||
|
|
// TaskRepository provides PostgreSQL-backed CRUD for task_logs.
|
||
|
|
type TaskRepository struct {
|
||
|
|
pool *pgxpool.Pool
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewTaskRepository returns a repository wired to the given connection pool.
|
||
|
|
func NewTaskRepository(pool *pgxpool.Pool) *TaskRepository {
|
||
|
|
return &TaskRepository{pool: pool}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Create inserts a new task into the task_logs table.
|
||
|
|
func (r *TaskRepository) Create(ctx context.Context, t models.Task) (models.Task, error) {
|
||
|
|
now := time.Now().UTC()
|
||
|
|
if t.CreatedAt.IsZero() {
|
||
|
|
t.CreatedAt = now
|
||
|
|
}
|
||
|
|
if t.UpdatedAt.IsZero() {
|
||
|
|
t.UpdatedAt = now
|
||
|
|
}
|
||
|
|
|
||
|
|
err := r.pool.QueryRow(ctx, `
|
||
|
|
INSERT INTO task_logs (agent_id, task, status, started_at)
|
||
|
|
VALUES ($1, $2, $3, $4)
|
||
|
|
RETURNING id, agent_id, task, status, started_at, completed_at, error_message
|
||
|
|
`, t.AgentID, t.Title, string(t.Status), t.CreatedAt).Scan(
|
||
|
|
&t.ID, &t.AgentID, &t.Title, &t.Status, &t.CreatedAt,
|
||
|
|
nil, nil,
|
||
|
|
)
|
||
|
|
if err != nil {
|
||
|
|
return t, err
|
||
|
|
}
|
||
|
|
|
||
|
|
// Rebuild the Description since task_logs only stores the title as "task".
|
||
|
|
t.Description = t.Title
|
||
|
|
return t, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListRecent returns the most recent tasks, newest first.
|
||
|
|
func (r *TaskRepository) ListRecent(ctx context.Context) ([]models.Task, error) {
|
||
|
|
rows, err := r.pool.Query(ctx, `
|
||
|
|
SELECT id, agent_id, task, status, started_at, completed_at, error_message
|
||
|
|
FROM task_logs
|
||
|
|
ORDER BY started_at DESC
|
||
|
|
`)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer rows.Close()
|
||
|
|
|
||
|
|
return pgx.CollectRows(rows, func(row pgx.CollectableRow) (models.Task, error) {
|
||
|
|
var t models.Task
|
||
|
|
var completedAt *time.Time
|
||
|
|
var errMsg *string
|
||
|
|
|
||
|
|
if err := row.Scan(&t.ID, &t.AgentID, &t.Title, &t.Status,
|
||
|
|
&t.CreatedAt, &completedAt, &errMsg); err != nil {
|
||
|
|
return t, err
|
||
|
|
}
|
||
|
|
|
||
|
|
t.Description = t.Title
|
||
|
|
t.UpdatedAt = t.CreatedAt
|
||
|
|
if completedAt != nil {
|
||
|
|
t.UpdatedAt = *completedAt
|
||
|
|
}
|
||
|
|
return t, nil
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// Count returns the total number of tasks.
|
||
|
|
func (r *TaskRepository) Count(ctx context.Context) (int, error) {
|
||
|
|
var n int
|
||
|
|
err := r.pool.QueryRow(ctx, `SELECT COUNT(*) FROM task_logs`).Scan(&n)
|
||
|
|
return n, err
|
||
|
|
}
|