Refactor billing to manage subscriptions/invoices internally

This commit is contained in:
Jon Staab
2026-05-26 14:25:21 -07:00
parent 28cd7b0a9a
commit 7a2baf6f82
23 changed files with 1464 additions and 1694 deletions
+55 -20
View File
@@ -4,7 +4,8 @@ CREATE TABLE IF NOT EXISTS activity (
created_at INTEGER NOT NULL,
activity_type TEXT NOT NULL,
resource_type TEXT NOT NULL,
resource_id TEXT NOT NULL
resource_id TEXT NOT NULL,
billed_at INTEGER
);
CREATE TABLE IF NOT EXISTS tenant (
@@ -12,9 +13,8 @@ CREATE TABLE IF NOT EXISTS tenant (
nwc_url TEXT NOT NULL DEFAULT '',
nwc_error TEXT,
created_at INTEGER NOT NULL,
stripe_customer_id TEXT NOT NULL,
stripe_subscription_id TEXT,
past_due_at INTEGER
billing_anchor INTEGER,
stripe_customer_id TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS relay (
@@ -38,29 +38,64 @@ CREATE TABLE IF NOT EXISTS relay (
FOREIGN KEY (tenant) REFERENCES tenant(pubkey)
);
CREATE TABLE IF NOT EXISTS lightning_invoice (
stripe_invoice_id TEXT PRIMARY KEY,
CREATE TABLE IF NOT EXISTS invoice (
id TEXT PRIMARY KEY,
tenant_pubkey TEXT NOT NULL,
bolt11 TEXT NOT NULL,
status TEXT NOT NULL CHECK (status IN ('pending', 'paid')),
paid_method TEXT CHECK (paid_method IN ('nwc', 'manual')),
expires_at INTEGER NOT NULL,
status TEXT NOT NULL CHECK (status IN ('open','paid','void','churn')),
method TEXT CHECK (method IS NULL OR method IN ('nwc','stripe','oob')),
period_start INTEGER NOT NULL,
period_end INTEGER NOT NULL,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
FOREIGN KEY (tenant_pubkey) REFERENCES tenant(pubkey)
);
CREATE INDEX IF NOT EXISTS idx_tenant_stripe_customer_id
ON tenant (stripe_customer_id);
CREATE TABLE IF NOT EXISTS invoice_item (
id TEXT PRIMARY KEY,
invoice_id TEXT NOT NULL,
activity_id TEXT NOT NULL,
tenant_pubkey TEXT NOT NULL,
relay_id TEXT NOT NULL,
plan TEXT NOT NULL,
amount INTEGER NOT NULL,
description TEXT NOT NULL DEFAULT '',
created_at INTEGER NOT NULL,
FOREIGN KEY (invoice_id) REFERENCES invoice(id),
FOREIGN KEY (tenant_pubkey) REFERENCES tenant(pubkey)
);
CREATE INDEX IF NOT EXISTS idx_relay_tenant_id
ON relay (tenant, id);
CREATE TABLE IF NOT EXISTS bolt11 (
id TEXT PRIMARY KEY,
invoice_id TEXT NOT NULL,
lnbc TEXT NOT NULL,
msats INTEGER NOT NULL,
created_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL,
settled_at INTEGER,
FOREIGN KEY (invoice_id) REFERENCES invoice(id)
);
CREATE INDEX IF NOT EXISTS idx_relay_tenant_status_plan
ON relay (tenant, status, plan);
CREATE TABLE IF NOT EXISTS intent (
id TEXT PRIMARY KEY,
invoice_id TEXT NOT NULL,
created_at INTEGER NOT NULL,
FOREIGN KEY (invoice_id) REFERENCES invoice(id)
);
CREATE INDEX IF NOT EXISTS idx_activity_resource_type_resource_id_created_at_id
ON activity (resource_type, resource_id, created_at DESC, id DESC);
CREATE INDEX IF NOT EXISTS idx_relay_tenant ON relay (tenant);
CREATE INDEX IF NOT EXISTS idx_lightning_invoice_tenant_pubkey
ON lightning_invoice (tenant_pubkey);
CREATE INDEX IF NOT EXISTS idx_activity_tenant_created ON activity (tenant, created_at);
CREATE INDEX IF NOT EXISTS idx_activity_resource_created ON activity (resource_id, created_at);
CREATE INDEX IF NOT EXISTS idx_activity_unbilled ON activity (tenant, created_at) WHERE billed_at IS NULL;
CREATE UNIQUE INDEX IF NOT EXISTS uniq_invoice_tenant_period ON invoice (tenant_pubkey, period_start);
CREATE INDEX IF NOT EXISTS idx_invoice_tenant_created ON invoice (tenant_pubkey, created_at);
CREATE INDEX IF NOT EXISTS idx_invoice_item_invoice ON invoice_item (invoice_id);
CREATE INDEX IF NOT EXISTS idx_bolt11_invoice_created ON bolt11 (invoice_id, created_at);
CREATE INDEX IF NOT EXISTS idx_intent_invoice ON intent (invoice_id);