48 lines
2.1 KiB
SQL
48 lines
2.1 KiB
SQL
-- =====================================================================
|
|
-- billing service — 0001_init.sql
|
|
-- Database-per-service: owns `subscriptions`, `stripe_events` and
|
|
-- `usage_daily`. user_id columns below are bare BIGINTs, NOT a foreign
|
|
-- key to iam's users(id) — that table lives in a different database.
|
|
-- Referential integrity across that boundary is enforced by the
|
|
-- application layer (iam is the only service that can create a
|
|
-- user_id in the first place) rather than by Postgres; see
|
|
-- ARCHITECTURE.md's "Database-per-service" section.
|
|
-- =====================================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS subscriptions (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
user_id BIGINT NOT NULL UNIQUE,
|
|
plan TEXT NOT NULL DEFAULT 'free' CHECK (plan IN ('free', 'basic', 'pro', 'premium')),
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
stripe_customer_id TEXT,
|
|
stripe_subscription_id TEXT,
|
|
stripe_price_id TEXT,
|
|
current_period_end TIMESTAMPTZ,
|
|
cancel_at_period_end BOOLEAN NOT NULL DEFAULT false,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS subscriptions_stripe_customer_id_idx
|
|
ON subscriptions (stripe_customer_id) WHERE stripe_customer_id IS NOT NULL;
|
|
|
|
CREATE UNIQUE INDEX IF NOT EXISTS subscriptions_stripe_subscription_id_idx
|
|
ON subscriptions (stripe_subscription_id) WHERE stripe_subscription_id IS NOT NULL;
|
|
|
|
-- Idempotency log for incoming webhooks — see application.Service.
|
|
-- IngestStripeWebhook.
|
|
CREATE TABLE IF NOT EXISTS stripe_events (
|
|
id TEXT PRIMARY KEY,
|
|
type TEXT NOT NULL,
|
|
received_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Per-user, per-UTC-day message counter backing each plan's
|
|
-- DailyMessageLimit (see domain.PlanInfo).
|
|
CREATE TABLE IF NOT EXISTS usage_daily (
|
|
user_id BIGINT NOT NULL,
|
|
day DATE NOT NULL,
|
|
messages INT NOT NULL DEFAULT 0,
|
|
PRIMARY KEY (user_id, day)
|
|
);
|