Slice 1: scaffolding + propose-to-super-draft vertical
Brings the §1 bot wrapper, the §4 cache (webhook + reconciler), the §5 schema (six numbered migrations), Gitea OAuth + §6 user provisioning, the §7 catalog left pane, and the propose-to-merge vertical: propose modal opens an idea PR against the meta repo, an owner merges from the pending-idea view, the cache picks it up via webhook or reconciler sweep, and the catalog renders the new super-draft. Per §1 the bot is the only Git writer; every commit, branch creation, and PR merge carries the §6.5 On-behalf-of: trailer and an `actions` audit row. Per §4 the cache is never written from a user action — it's webhook+reconciler only. Covered by `backend/tests/test_propose_vertical.py` against an in-process Gitea simulator. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
-- §4: the metadata cache. Reconstructible from Gitea at any time by the
|
||||
-- §4.1 reconciler; never written from user actions, only from webhook
|
||||
-- handlers and reconciler sweeps. Body content is cached for main-branch
|
||||
-- reads (§4 #3); branch bodies are not.
|
||||
--
|
||||
-- These tables are not in §5's "canonical app tables" list because they
|
||||
-- are cache, not truth — but they are required for the left-pane render
|
||||
-- path and for serving super-draft and main-branch bodies without a
|
||||
-- Gitea round-trip on every navigation.
|
||||
|
||||
-- One row per meta-repo rfcs/<slug>.md entry. Mirrors §2.1 frontmatter
|
||||
-- plus the cached body for super-draft preview (graduated entries have
|
||||
-- frontmatter-only bodies per §13.3 step 3, but the field is reused).
|
||||
CREATE TABLE cached_rfcs (
|
||||
slug TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
state TEXT NOT NULL CHECK (state IN ('super-draft', 'active', 'withdrawn')),
|
||||
rfc_id TEXT, -- 'RFC-NNNN' or NULL until graduated
|
||||
repo TEXT, -- 'org/repo' or NULL until graduated
|
||||
proposed_by TEXT, -- gitea login or email
|
||||
proposed_at TEXT,
|
||||
graduated_at TEXT,
|
||||
graduated_by TEXT,
|
||||
owners_json TEXT NOT NULL DEFAULT '[]',
|
||||
arbiters_json TEXT NOT NULL DEFAULT '[]',
|
||||
tags_json TEXT NOT NULL DEFAULT '[]',
|
||||
body TEXT, -- super-draft body or main RFC.md body
|
||||
body_sha TEXT, -- the commit sha the body was fetched at
|
||||
last_main_commit_at TEXT, -- §7.1's "Recently active" sort
|
||||
last_entry_commit_at TEXT, -- last meta-repo commit touching this entry
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cached_rfcs_state ON cached_rfcs (state);
|
||||
CREATE INDEX idx_cached_rfcs_last_active ON cached_rfcs (
|
||||
COALESCE(last_main_commit_at, last_entry_commit_at) DESC
|
||||
);
|
||||
|
||||
-- One row per branch the bot knows about on either a per-RFC repo
|
||||
-- (rfc_slug, state='active'') or on the meta repo as a super-draft edit
|
||||
-- branch (rfc_slug, state='super-draft', branch_name like 'edit/<slug>/...').
|
||||
-- §11.5: closed branches stay; deleted branches keep their metadata row
|
||||
-- per §12 ("branch removed from Gitea, row remains").
|
||||
CREATE TABLE cached_branches (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
rfc_slug TEXT NOT NULL,
|
||||
branch_name TEXT NOT NULL,
|
||||
head_sha TEXT,
|
||||
state TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('open', 'closed', 'deleted')),
|
||||
pinned INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
last_commit_at TEXT,
|
||||
closed_at TEXT,
|
||||
UNIQUE (rfc_slug, branch_name)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cached_branches_rfc ON cached_branches (rfc_slug, state);
|
||||
|
||||
-- One row per PR the bot knows about. Includes meta-repo idea PRs (rfc_slug
|
||||
-- carries the proposed slug, see §5 super-draft scoping note) and meta-repo
|
||||
-- body-edit PRs and per-RFC-repo PRs. The pr_kind disambiguates.
|
||||
CREATE TABLE cached_prs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
rfc_slug TEXT NOT NULL,
|
||||
pr_kind TEXT NOT NULL CHECK (pr_kind IN ('idea', 'meta_body_edit', 'meta_metadata', 'meta_claim', 'rfc_branch')),
|
||||
repo TEXT NOT NULL, -- 'org/repo' the PR lives on
|
||||
pr_number INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
state TEXT NOT NULL CHECK (state IN ('open', 'merged', 'closed', 'withdrawn')),
|
||||
opened_by TEXT, -- gitea login (resolved from On-behalf-of trailer where present)
|
||||
opened_at TEXT,
|
||||
merged_at TEXT,
|
||||
closed_at TEXT,
|
||||
head_branch TEXT,
|
||||
base_branch TEXT NOT NULL DEFAULT 'main',
|
||||
head_sha TEXT,
|
||||
UNIQUE (repo, pr_number)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cached_prs_rfc ON cached_prs (rfc_slug, state);
|
||||
CREATE INDEX idx_cached_prs_kind ON cached_prs (pr_kind, state);
|
||||
Reference in New Issue
Block a user