-- v0.29.0 / roadmap #28 Part 3 — offer-to-contribute-to-a-pending-RFC.
--
-- When the #28 scanner matches a term in submitted PR/comment text to a
-- *pending* RFC (a super-draft: accepted-as-an-idea but not yet graduated
-- to an active RFC), the reader is offered a "ask to contribute" popover.
-- Submitting it lands a row here AND a notification in each owner's §15
-- inbox; the owner can accept (which fires #12's owner-invite flow with
-- the requester as the invitee) or decline (the requester is notified and
-- the request closes).
--
-- A "pending RFC" is scoped to a super-draft (cached_rfcs.state =
-- 'super-draft'): it is in cached_rfcs (so the rfc_invitations FK that the
-- accept path reuses resolves), it carries owners (owners_json) to route
-- the request to, and it already has a discussion/contribution surface to
-- open. Pre-merge idea PRs (not yet in cached_rfcs, no contribution
-- surface) are deliberately out of scope — see backend/app/rfc_links.py.
--
-- The request row is the persistent record; the inbox notification is the
-- owner-facing actionable surface keyed back to it via `notification_id`.

CREATE TABLE IF NOT EXISTS contribution_requests (
    id                  INTEGER PRIMARY KEY AUTOINCREMENT,
    rfc_slug            TEXT NOT NULL
                            REFERENCES cached_rfcs(slug) ON DELETE CASCADE,
    requester_user_id   INTEGER NOT NULL
                            REFERENCES users(id) ON DELETE CASCADE,
    -- The term in the PR/comment text that surfaced the offer (e.g. the
    -- super-draft's title). Carried for the owner's context line and the
    -- requester's "what RFC" anchor; not a foreign key.
    matched_term        TEXT NOT NULL,
    -- The three contribute-request fields (§15 / #26 vocabulary).
    -- `who_i_am` and `why` are required; `use_case` mirrors #26's
    -- optional ground-truth field.
    who_i_am            TEXT NOT NULL,
    why                 TEXT NOT NULL,
    use_case            TEXT,
    status              TEXT NOT NULL DEFAULT 'pending'
                            CHECK (status IN ('pending', 'accepted', 'declined')),
    created_at          TEXT NOT NULL DEFAULT (datetime('now')),
    decided_at          TEXT,
    decided_by_user_id  INTEGER REFERENCES users(id) ON DELETE SET NULL,
    -- The rfc_invitations row minted on accept (the #12 reuse), and the
    -- owner-facing notification row that carries the Accept/Decline action.
    invitation_id       INTEGER REFERENCES rfc_invitations(id) ON DELETE SET NULL,
    notification_id     INTEGER REFERENCES notifications(id) ON DELETE SET NULL
);

CREATE INDEX IF NOT EXISTS idx_contribution_requests_rfc
    ON contribution_requests(rfc_slug, status);

CREATE INDEX IF NOT EXISTS idx_contribution_requests_requester
    ON contribution_requests(requester_user_id, status);

-- At most one open (pending) request per (RFC, requester): a second ask
-- while one is still pending is a 409, not a duplicate row. A decided
-- request (accepted/declined) does not block a fresh ask later.
CREATE UNIQUE INDEX IF NOT EXISTS idx_contribution_requests_one_open
    ON contribution_requests(rfc_slug, requester_user_id)
    WHERE status = 'pending';
