Includes: API (Express/TypeScript), Astro site, Python workers, document generators, FCC compliance tools, Canada CRTC formation, Ansible infrastructure, and deployment scripts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
67 lines
3.7 KiB
SQL
67 lines
3.7 KiB
SQL
-- 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;
|