mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 07:41:16 +00:00
refactor(db): replace sqlc with handwritten pgx repos
- Finish Paddle-to-Stripe billing migration; drop paddle/stripe libs - Renumber migrations; add 00012 memberships+manage_token, 00013 location_type_capacity - Add tests: admin, auth, bookings customer service - Remove graphify-out artifacts and stale env files Authored By: TDvorak <[email protected]> Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
2039669e2c
commit
f2f7439050
93 files changed
+6987
-69060
No files matched your search
+20
@@ -8,6 +8,7 @@ ALTER TABLE billing_snapshots
|
||||
ALTER TABLE subscription_events
|
||||
ADD COLUMN IF NOT EXISTS billing_provider text NOT NULL DEFAULT 'paddle';
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -18,7 +19,9 @@ BEGIN
|
||||
ALTER TABLE tenants RENAME COLUMN stripe_customer_id TO billing_customer_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -29,7 +32,9 @@ BEGIN
|
||||
ALTER TABLE tenants RENAME COLUMN stripe_subscription_id TO billing_subscription_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -40,7 +45,9 @@ BEGIN
|
||||
ALTER TABLE billing_snapshots RENAME COLUMN stripe_customer_id TO billing_customer_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -51,7 +58,9 @@ BEGIN
|
||||
ALTER TABLE billing_snapshots RENAME COLUMN stripe_subscription_id TO billing_subscription_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -62,6 +71,7 @@ BEGIN
|
||||
ALTER TABLE subscription_events RENAME COLUMN stripe_event_id TO billing_provider_event_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
ALTER TABLE subscription_events DROP CONSTRAINT IF EXISTS subscription_events_stripe_event_id_key;
|
||||
ALTER TABLE subscription_events
|
||||
@@ -70,6 +80,7 @@ ALTER TABLE subscription_events
|
||||
-- +goose Down
|
||||
ALTER TABLE subscription_events DROP CONSTRAINT IF EXISTS subscription_events_provider_event_key;
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -80,7 +91,9 @@ BEGIN
|
||||
ALTER TABLE subscription_events RENAME COLUMN billing_provider_event_id TO stripe_event_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -91,7 +104,9 @@ BEGIN
|
||||
ALTER TABLE billing_snapshots RENAME COLUMN billing_subscription_id TO stripe_subscription_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -102,7 +117,9 @@ BEGIN
|
||||
ALTER TABLE billing_snapshots RENAME COLUMN billing_customer_id TO stripe_customer_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -113,7 +130,9 @@ BEGIN
|
||||
ALTER TABLE tenants RENAME COLUMN billing_subscription_id TO stripe_subscription_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose StatementBegin
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
@@ -124,6 +143,7 @@ BEGIN
|
||||
ALTER TABLE tenants RENAME COLUMN billing_customer_id TO stripe_customer_id;
|
||||
END IF;
|
||||
END $$;
|
||||
-- +goose StatementEnd
|
||||
|
||||
ALTER TABLE subscription_events DROP COLUMN IF EXISTS billing_provider;
|
||||
ALTER TABLE billing_snapshots DROP COLUMN IF EXISTS billing_provider;
|
||||
File renamed without changes.
+27
-16
@@ -1,22 +1,21 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
|
||||
-- Users table for authentication (migrated from auth-service)
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
name VARCHAR(255),
|
||||
password_hash VARCHAR(255),
|
||||
email_verified BOOLEAN DEFAULT FALSE,
|
||||
provider VARCHAR(50) NOT NULL DEFAULT 'email',
|
||||
provider_id VARCHAR(255),
|
||||
role VARCHAR(50) NOT NULL DEFAULT 'user',
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
last_login_at TIMESTAMP WITH TIME ZONE
|
||||
);
|
||||
-- Authentication columns for the users table (migrated from auth-service).
|
||||
-- The users table itself is created in 00001_init; this migration adds the
|
||||
-- columns the auth and admin code paths require.
|
||||
ALTER TABLE users
|
||||
ADD COLUMN IF NOT EXISTS name VARCHAR(255),
|
||||
ADD COLUMN IF NOT EXISTS password_hash VARCHAR(255),
|
||||
ADD COLUMN IF NOT EXISTS email_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
ADD COLUMN IF NOT EXISTS provider VARCHAR(50) NOT NULL DEFAULT 'email',
|
||||
ADD COLUMN IF NOT EXISTS provider_id VARCHAR(255),
|
||||
ADD COLUMN IF NOT EXISTS role VARCHAR(50) NOT NULL DEFAULT 'user',
|
||||
ADD COLUMN IF NOT EXISTS last_login_at TIMESTAMP WITH TIME ZONE;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
|
||||
ALTER TABLE users ALTER COLUMN id SET DEFAULT gen_random_uuid();
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email_unique ON users(email);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_provider ON users(provider, provider_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_role ON users(role);
|
||||
|
||||
@@ -92,6 +91,18 @@ DROP TABLE IF EXISTS admin_audit_log;
|
||||
DROP TABLE IF EXISTS oauth_states;
|
||||
DROP TABLE IF EXISTS password_resets;
|
||||
DROP TABLE IF EXISTS magic_links;
|
||||
DROP TABLE IF EXISTS users;
|
||||
|
||||
DROP INDEX IF EXISTS idx_users_role;
|
||||
DROP INDEX IF EXISTS idx_users_provider;
|
||||
DROP INDEX IF EXISTS idx_users_email_unique;
|
||||
|
||||
ALTER TABLE users
|
||||
DROP COLUMN IF EXISTS last_login_at,
|
||||
DROP COLUMN IF EXISTS role,
|
||||
DROP COLUMN IF EXISTS provider_id,
|
||||
DROP COLUMN IF EXISTS provider,
|
||||
DROP COLUMN IF EXISTS email_verified,
|
||||
DROP COLUMN IF EXISTS password_hash,
|
||||
DROP COLUMN IF EXISTS name;
|
||||
|
||||
-- +goose StatementEnd
|
||||
+4
@@ -27,11 +27,15 @@ CREATE TABLE IF NOT EXISTS team_invites (
|
||||
email text NOT NULL,
|
||||
role text NOT NULL DEFAULT 'staff',
|
||||
status text NOT NULL DEFAULT 'pending',
|
||||
expires_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, email)
|
||||
);
|
||||
|
||||
ALTER TABLE team_invites
|
||||
ADD COLUMN IF NOT EXISTS expires_at timestamptz;
|
||||
|
||||
UPDATE tenants SET plan_code = 'pro' WHERE plan_code = 'growth';
|
||||
UPDATE tenants SET plan_code = 'business' WHERE plan_code = 'multi-location';
|
||||
UPDATE billing_snapshots SET plan_code = 'pro' WHERE plan_code = 'growth';
|
||||
File renamed without changes.
@@ -34,14 +34,12 @@ CREATE TABLE IF NOT EXISTS sms_monthly_reports (
|
||||
UNIQUE (tenant_id, year_month)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_sms_usage_tenant_month ON sms_usage_logs (tenant_id, date_trunc('month', created_at));
|
||||
CREATE INDEX IF NOT EXISTS idx_sms_usage_tenant_created ON sms_usage_logs (tenant_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_sms_reports_tenant ON sms_monthly_reports (tenant_id, year_month DESC);
|
||||
|
||||
-- +goose Down
|
||||
DROP INDEX IF EXISTS idx_sms_reports_tenant;
|
||||
DROP INDEX IF EXISTS idx_sms_usage_tenant_created;
|
||||
DROP INDEX IF EXISTS idx_sms_usage_tenant_month;
|
||||
DROP TABLE IF EXISTS sms_monthly_reports;
|
||||
DROP TABLE IF EXISTS sms_usage_logs;
|
||||
DROP TABLE IF EXISTS tenant_sms_settings;
|
||||
File renamed without changes.
@@ -0,0 +1,50 @@
|
||||
-- +goose Up
|
||||
|
||||
-- Tenant memberships keyed by the auth subject (Neon Auth `sub`).
|
||||
-- The auth middleware resolves JWT subjects to memberships through users.neon_subject.
|
||||
CREATE TABLE IF NOT EXISTS tenant_memberships (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
user_neon_subject text NOT NULL,
|
||||
role text NOT NULL DEFAULT 'staff',
|
||||
joined_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, user_neon_subject)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_tenant_memberships_subject ON tenant_memberships (user_neon_subject);
|
||||
|
||||
-- Unguessable per-booking management token used by /v1/public/bookings/:reference endpoints.
|
||||
ALTER TABLE bookings
|
||||
ADD COLUMN IF NOT EXISTS manage_token text;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_bookings_manage_token
|
||||
ON bookings (manage_token)
|
||||
WHERE manage_token IS NOT NULL;
|
||||
|
||||
-- Backfill tokens for pre-existing bookings.
|
||||
UPDATE bookings
|
||||
SET manage_token = replace(gen_random_uuid()::text, '-', '') || replace(gen_random_uuid()::text, '-', '')
|
||||
WHERE manage_token IS NULL;
|
||||
|
||||
-- locations.updated_at is written by the repository update path.
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN IF NOT EXISTS updated_at timestamptz NOT NULL DEFAULT now();
|
||||
|
||||
-- Demo tenant membership so demo-owner resolves to Studio Atelier.
|
||||
INSERT INTO tenant_memberships (tenant_id, user_neon_subject, role)
|
||||
SELECT t.id, u.neon_subject, 'owner'
|
||||
FROM tenants t
|
||||
JOIN users u ON u.neon_subject = 'demo-owner'
|
||||
WHERE t.slug = 'studio-atelier'
|
||||
ON CONFLICT (tenant_id, user_neon_subject) DO NOTHING;
|
||||
|
||||
-- +goose Down
|
||||
|
||||
ALTER TABLE locations
|
||||
DROP COLUMN IF EXISTS updated_at;
|
||||
|
||||
DROP INDEX IF EXISTS idx_bookings_manage_token;
|
||||
ALTER TABLE bookings
|
||||
DROP COLUMN IF EXISTS manage_token;
|
||||
|
||||
DROP TABLE IF EXISTS tenant_memberships;
|
||||
@@ -0,0 +1,25 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE locations
|
||||
ADD COLUMN IF NOT EXISTS type text NOT NULL DEFAULT 'room',
|
||||
ADD COLUMN IF NOT EXISTS capacity integer NOT NULL DEFAULT 1;
|
||||
|
||||
-- Per-tenant custom email templates (overrides for built-in subjects/bodies).
|
||||
CREATE TABLE IF NOT EXISTS email_templates (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
type text NOT NULL,
|
||||
subject text NOT NULL DEFAULT '',
|
||||
body_html text NOT NULL DEFAULT '',
|
||||
body_text text NOT NULL DEFAULT '',
|
||||
is_enabled boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, type)
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS email_templates;
|
||||
|
||||
ALTER TABLE locations
|
||||
DROP COLUMN IF EXISTS type,
|
||||
DROP COLUMN IF EXISTS capacity;
|
||||
Reference in new issue
Block a user