-- 065: Crypto payment orchestrator jobs + Relay deposit source tagging
--
-- `crypto_payment_jobs` is the worker's mutable state machine (one row
-- per crypto-paid order). `crypto_payment_ledger` is immutable audit;
-- `crypto_payment_jobs` is where the worker records state transitions.
--
-- Also adds `source_kind` to `relay_deposits` so the matcher can tell
-- "this $X deposit was our Coinbase Prime offramp" vs "this was a
-- Stripe ACH batch" vs "something else — operator review".

CREATE TABLE IF NOT EXISTS crypto_payment_jobs (
    order_id                TEXT PRIMARY KEY,
    order_type              TEXT NOT NULL,
    state                   TEXT NOT NULL DEFAULT 'received'
                            CHECK (state IN (
                              'received',         -- SHKeeper webhook in, job enqueued
                              'sizing',           -- computing vendor_obligations
                              'offramping',       -- Coinbase Prime sell + wire initiated
                              'funds_at_relay',   -- USD landed in RelayFi account
                              'ready',            -- Playwright filing flow can now charge the card
                              'settled',          -- reservation spent, order complete
                              'failed',           -- attempt_count exhausted
                              'manual'            -- admin intervention required
                            )),
    coin                    TEXT NOT NULL,
    amount_coin             NUMERIC(36,18) NOT NULL,
    amount_usd_cents        BIGINT NOT NULL,               -- SHKeeper balance_fiat at receipt
    needed_usd_cents        BIGINT,                        -- sizer output: filing + 10% + commission
    offramp_provider        TEXT DEFAULT 'coinbase_prime',
    offramp_ref             TEXT,                          -- Coinbase Prime order id / transfer id
    relay_deposit_id        INT REFERENCES relay_deposits(id),
    target_card_id          TEXT DEFAULT 'RELAY_FILING_CARD_ID',
    last_error              TEXT,
    attempt_count           INT NOT NULL DEFAULT 0,
    next_retry_at           TIMESTAMPTZ,
    idempotency_key         TEXT UNIQUE,                   -- "shkeeper-settle:<order>:<first-txid>"
    received_at             TIMESTAMPTZ,
    sized_at                TIMESTAMPTZ,
    offramping_at           TIMESTAMPTZ,
    funds_at_relay_at       TIMESTAMPTZ,
    settled_at              TIMESTAMPTZ,
    created_at              TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at              TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_cpj_active
    ON crypto_payment_jobs (state)
    WHERE state NOT IN ('settled','failed');

CREATE INDEX IF NOT EXISTS idx_cpj_retry
    ON crypto_payment_jobs (next_retry_at)
    WHERE state NOT IN ('settled','failed','manual') AND next_retry_at IS NOT NULL;

-- ── Extend relay_deposits for source tagging ──────────────────────────
-- Parsed from the Relay deposit notification email body/sender. Values:
--   'stripe_ach'             — Stripe customer payments batched to Relay
--   'offramp_coinbase_prime' — our own Coinbase Prime → Relay wire/RTP
--   'internal_transfer'      — between our own accounts
--   'unknown'                — operator review required
ALTER TABLE relay_deposits ADD COLUMN IF NOT EXISTS source_kind TEXT;
ALTER TABLE relay_deposits ADD COLUMN IF NOT EXISTS memo TEXT;
-- memo captures the beneficiary memo field (e.g., 'PW-ORDER-FO-2026-0042')
-- so the matcher can find the corresponding crypto_payment_jobs row.

CREATE INDEX IF NOT EXISTS idx_relay_deposits_unmatched_offramp
    ON relay_deposits (detected_at DESC)
    WHERE source_kind = 'offramp_coinbase_prime' AND processed = FALSE;
