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" ) // SessionRepository provides PostgreSQL-backed CRUD for sessions. type SessionRepository struct { pool *pgxpool.Pool } // NewSessionRepository returns a repository wired to the given connection pool. func NewSessionRepository(pool *pgxpool.Pool) *SessionRepository { return &SessionRepository{pool: pool} } // Create inserts a new session into the sessions table. // Because the existing sessions table only has id, agent_id, started_at, // ended_at, and status, we map what we can and store additional metadata // as a fallback. AgentID is required by FK — if the session AgentID can't // be cast to a valid UUID we store a sentinel. func (r *SessionRepository) Create(ctx context.Context, s models.Session) (models.Session, error) { if s.StartedAt.IsZero() { s.StartedAt = time.Now().UTC() } if s.LastActivityAt.IsZero() { s.LastActivityAt = s.StartedAt } err := r.pool.QueryRow(ctx, ` INSERT INTO sessions (agent_id, started_at, status) VALUES ($1, $2, $3) RETURNING id, agent_id, started_at, ended_at, status `, s.AgentID, s.StartedAt, s.Status).Scan( &s.ID, &s.AgentID, &s.StartedAt, nil, &s.Status) return s, err } // ListActive returns all sessions with status 'running' or 'streaming', // ordered by started_at descending. func (r *SessionRepository) ListActive(ctx context.Context) ([]models.Session, error) { rows, err := r.pool.Query(ctx, ` SELECT id, agent_id, started_at, ended_at, status FROM sessions WHERE status IN ('running', 'streaming') ORDER BY started_at DESC `) if err != nil { return nil, err } defer rows.Close() return pgx.CollectRows(rows, func(row pgx.CollectableRow) (models.Session, error) { var s models.Session var endedAt *time.Time if err := row.Scan(&s.ID, &s.AgentID, &s.StartedAt, &endedAt, &s.Status); err != nil { return s, err } s.LastActivityAt = s.StartedAt if endedAt != nil { s.LastActivityAt = *endedAt } return s, nil }) } // Count returns the total number of sessions. func (r *SessionRepository) Count(ctx context.Context) (int, error) { var n int err := r.pool.QueryRow(ctx, `SELECT COUNT(*) FROM sessions`).Scan(&n) return n, err }