mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-02 01:45:52 +02:00
Address Elon's third-round review on the MUL-5265 PR snapshot pipeline. Must-fix — migration built a non-concurrent index. The github_pull_request_check_run table declared PRIMARY KEY (pr_id, ordinal) inside CREATE TABLE, which builds a unique index synchronously and violates the repo rule that every migration-created index (including on a new table) use CREATE UNIQUE INDEX CONCURRENTLY in its own single-statement file. Split: 222 now creates the table without a primary key; new 223 adds the (pr_id, ordinal) unique index CONCURRENTLY. The atomic delete-all/insert write path already guarantees ordinal uniqueness, so a plain unique index is sufficient; the index also serves the pr_id-prefix list aggregation and the workspace/PR cleanup deletes. Nit — token mint now singleflights per installation. installationToken released the lock before minting, so the N workers of one installation could mint N tokens on a cold cache or a simultaneous renew. Concurrent callers for the same installation are now collapsed via singleflight into one HTTP mint; added a -race concurrent-mint test asserting a single mint under 16 callers. Verified: fresh DB migrates through 223 (table has no PK, concurrent unique index present); ghsnapshot suite + new test pass under -race; migration lint and handler github/workspace-delete tests pass; sqlc produced no diff; go build / vet / gofmt / git diff --check clean. Co-authored-by: multica-agent <github@multica.ai>
59 lines
3.2 KiB
SQL
59 lines
3.2 KiB
SQL
-- MUL-5265: GitHub API snapshot for PR cards (Plan C).
|
|
--
|
|
-- The PR card's CI status and mergeability are now sourced from an
|
|
-- authenticated GitHub API snapshot (GraphQL pullRequest query) rather than
|
|
-- inferred from webhook check_suite events. Webhooks and page visits only
|
|
-- trigger a refresh; the API response is the single source of truth and is
|
|
-- written as one atomic batch replace per PR.
|
|
--
|
|
-- All new columns are nullable / defaulted so rows that pre-date the snapshot
|
|
-- (or deployments without a GitHub App private key, where the feature degrades
|
|
-- off) keep working: the card simply hides the CI / merge region until a
|
|
-- snapshot lands.
|
|
|
|
ALTER TABLE github_pull_request
|
|
-- GraphQL `mergeable`: MERGEABLE / CONFLICTING / UNKNOWN. Answers only
|
|
-- "is there a merge conflict". NULL until first snapshot.
|
|
ADD COLUMN api_mergeable TEXT,
|
|
-- GraphQL `mergeStateStatus`: CLEAN / DIRTY / BLOCKED / BEHIND / UNSTABLE /
|
|
-- DRAFT / HAS_HOOKS / UNKNOWN. "Ready to merge" is derived ONLY from CLEAN.
|
|
ADD COLUMN api_merge_state_status TEXT,
|
|
-- GraphQL statusCheckRollup.state: SUCCESS / FAILURE / PENDING / ERROR /
|
|
-- EXPECTED. NULL means statusCheckRollup was null → "no checks yet", which
|
|
-- must never be rendered as passed.
|
|
ADD COLUMN checks_rollup_state TEXT,
|
|
-- The head SHA the snapshot was fetched for. Pinned so a slow response for
|
|
-- an old head cannot overwrite a newer head's snapshot (head-SHA anti-stale
|
|
-- write). Empty until first snapshot.
|
|
ADD COLUMN snapshot_head_sha TEXT NOT NULL DEFAULT '',
|
|
-- When the snapshot was fetched. Drives the TTL / page-visit refresh and the
|
|
-- stale visual marker. NULL until first snapshot.
|
|
ADD COLUMN snapshot_fetched_at TIMESTAMPTZ;
|
|
|
|
-- Per-check snapshot rows for a PR's current head. Replaced atomically (delete
|
|
-- all + insert) on every successful API fetch — no incremental inference. Both
|
|
-- GraphQL CheckRun and StatusContext contexts are normalized into this shape at
|
|
-- write time (see ghsnapshot.normalizeContext). Rows are addressed by
|
|
-- (pr_id, ordinal): two checks can share a name (matrix jobs, re-runs), so name
|
|
-- is not unique. The (pr_id, ordinal) UNIQUE index is created CONCURRENTLY in
|
|
-- the next migration (223) — no index (including a PRIMARY KEY's) may be built
|
|
-- non-concurrently in a migration, even on a new table (see CLAUDE.md), so the
|
|
-- table is created without a primary key and the unique index is added in its
|
|
-- own single-statement migration.
|
|
CREATE TABLE github_pull_request_check_run (
|
|
pr_id UUID NOT NULL,
|
|
head_sha TEXT NOT NULL,
|
|
ordinal INTEGER NOT NULL,
|
|
name TEXT NOT NULL,
|
|
-- Normalized lifecycle: 'queued' / 'in_progress' / 'completed'.
|
|
status TEXT NOT NULL,
|
|
-- Normalized conclusion: 'success' / 'failure' / 'neutral' / 'cancelled' /
|
|
-- 'skipped' / 'timed_out' / 'action_required' / 'error' / ... ; NULL while
|
|
-- the check is still running.
|
|
conclusion TEXT,
|
|
details_url TEXT,
|
|
-- TRUE for legacy commit-status contexts (GraphQL StatusContext), FALSE for
|
|
-- Checks API runs (GraphQL CheckRun). Kept for display / debugging.
|
|
is_status_context BOOLEAN NOT NULL DEFAULT FALSE
|
|
);
|