// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: dashboard.sql package acpsqlc import ( "context" "github.com/jackc/pgx/v5/pgtype" ) const sessionRollup = `-- name: SessionRollup :one SELECT COUNT(*)::bigint AS total, COUNT(*) FILTER (WHERE status = 'exited')::bigint AS succeeded, COUNT(*) FILTER (WHERE status = 'crashed')::bigint AS crashed, COUNT(*) FILTER (WHERE status IN ('starting','running'))::bigint AS active, COALESCE(SUM(cost_usd), 0)::numeric AS total_cost_usd, COALESCE(SUM(tokens_total), 0)::bigint AS total_tokens, COALESCE( AVG(EXTRACT(EPOCH FROM (ended_at - started_at))) FILTER (WHERE ended_at IS NOT NULL), 0)::float8 AS avg_duration_seconds FROM acp_sessions WHERE ($1::uuid IS NULL OR user_id = $1) AND ($2::uuid IS NULL OR project_id = $2) AND ($3::uuid IS NULL OR requirement_id = $3) AND started_at >= $4 AND started_at < $5 ` type SessionRollupParams struct { Column1 pgtype.UUID `json:"column_1"` Column2 pgtype.UUID `json:"column_2"` Column3 pgtype.UUID `json:"column_3"` StartedAt pgtype.Timestamptz `json:"started_at"` StartedAt_2 pgtype.Timestamptz `json:"started_at_2"` } type SessionRollupRow struct { Total int64 `json:"total"` Succeeded int64 `json:"succeeded"` Crashed int64 `json:"crashed"` Active int64 `json:"active"` TotalCostUsd pgtype.Numeric `json:"total_cost_usd"` TotalTokens int64 `json:"total_tokens"` AvgDurationSeconds float64 `json:"avg_duration_seconds"` } // owner/admin scope + 可选 project/requirement + 时间窗内的会话汇总。 // success = status='exited';avg_duration_seconds 仅统计已结束(ended_at 非空)会话。 func (q *Queries) SessionRollup(ctx context.Context, arg SessionRollupParams) (SessionRollupRow, error) { row := q.db.QueryRow(ctx, sessionRollup, arg.Column1, arg.Column2, arg.Column3, arg.StartedAt, arg.StartedAt_2, ) var i SessionRollupRow err := row.Scan( &i.Total, &i.Succeeded, &i.Crashed, &i.Active, &i.TotalCostUsd, &i.TotalTokens, &i.AvgDurationSeconds, ) return i, err } const sessionTimeline = `-- name: SessionTimeline :many SELECT direction, rpc_kind, COALESCE(method, '') AS method, COUNT(*)::bigint AS event_count, MIN(created_at)::timestamptz AS first_at, MAX(created_at)::timestamptz AS last_at FROM acp_events WHERE session_id = $1 GROUP BY direction, rpc_kind, COALESCE(method, '') ORDER BY first_at ASC ` type SessionTimelineRow struct { Direction string `json:"direction"` RpcKind string `json:"rpc_kind"` Method string `json:"method"` EventCount int64 `json:"event_count"` FirstAt pgtype.Timestamptz `json:"first_at"` LastAt pgtype.Timestamptz `json:"last_at"` } // dashboard.sql: run-history dashboard 读模型(只读聚合)。 // - SessionTimeline: 单会话的 RPC 事件按 (direction, rpc_kind, method) 分桶, // 给出条数 + 首/末时间戳,用于会话时间线概览。 // - SessionRollup: 在 owner/admin scope + 可选 project/requirement 过滤下, // 统计会话总数、成功率(exited 视为成功)、总成本、平均时长。 // - SessionsByDay: 按天的 总数 / 成功 / 失败 / 成本 时间序列。 // // scope 约定(与 ListSessionsByUser/ListAllSessions 一致): // // $1 user_id 为 NULL 时不按用户过滤(admin 全量),非 NULL 时仅该用户。 // // 单会话事件时间线:按 method/kind 分桶聚合(条数 + 首末时间)。 func (q *Queries) SessionTimeline(ctx context.Context, sessionID pgtype.UUID) ([]SessionTimelineRow, error) { rows, err := q.db.Query(ctx, sessionTimeline, sessionID) if err != nil { return nil, err } defer rows.Close() var items []SessionTimelineRow for rows.Next() { var i SessionTimelineRow if err := rows.Scan( &i.Direction, &i.RpcKind, &i.Method, &i.EventCount, &i.FirstAt, &i.LastAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const sessionsByDay = `-- name: SessionsByDay :many SELECT date_trunc('day', started_at)::timestamptz AS day, COUNT(*)::bigint AS total, COUNT(*) FILTER (WHERE status = 'exited')::bigint AS succeeded, COUNT(*) FILTER (WHERE status = 'crashed')::bigint AS crashed, COALESCE(SUM(cost_usd), 0)::numeric AS total_cost_usd FROM acp_sessions WHERE ($1::uuid IS NULL OR user_id = $1) AND ($2::uuid IS NULL OR project_id = $2) AND ($3::uuid IS NULL OR requirement_id = $3) AND started_at >= $4 AND started_at < $5 GROUP BY day ORDER BY day ASC ` type SessionsByDayParams struct { Column1 pgtype.UUID `json:"column_1"` Column2 pgtype.UUID `json:"column_2"` Column3 pgtype.UUID `json:"column_3"` StartedAt pgtype.Timestamptz `json:"started_at"` StartedAt_2 pgtype.Timestamptz `json:"started_at_2"` } type SessionsByDayRow struct { Day pgtype.Timestamptz `json:"day"` Total int64 `json:"total"` Succeeded int64 `json:"succeeded"` Crashed int64 `json:"crashed"` TotalCostUsd pgtype.Numeric `json:"total_cost_usd"` } // 按天的会话时间序列(总数 / 成功 / 失败 / 成本),同 SessionRollup 的 scope。 func (q *Queries) SessionsByDay(ctx context.Context, arg SessionsByDayParams) ([]SessionsByDayRow, error) { rows, err := q.db.Query(ctx, sessionsByDay, arg.Column1, arg.Column2, arg.Column3, arg.StartedAt, arg.StartedAt_2, ) if err != nil { return nil, err } defer rows.Close() var items []SessionsByDayRow for rows.Next() { var i SessionsByDayRow if err := rows.Scan( &i.Day, &i.Total, &i.Succeeded, &i.Crashed, &i.TotalCostUsd, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil }