Add migrations 072-076: sandbox accounts, pending uniqueness, promo tracking, content removal, termination 072: sandbox account columns (is_sandbox, sandbox_expires_at) with partial index 073: partial unique indexes preventing duplicate pending checkouts per buyer 074: promo_code_id on transactions for stale reservation cleanup 075: per-item admin content removal fields (removed_by_admin, removal_reason, removed_at) 076: terminated_at column for 30-day export window before account deletion
- Co-Authored-By
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> - 2026-04-26 19:39 UTC
Commit:
69240f66ec2e78e65287ea441e696694192e04c9Parent:
5 files changed,
+35 insertions,
-0 deletions
OldNewLine
@@ -1,0 +1,8 @@
1
-- Sandbox accounts: ephemeral creator accounts for exploring the dashboard.2
-- Sandbox users are real rows with is_sandbox = TRUE, auto-deleted after expiry.3
4
ALTER TABLE users ADD COLUMN is_sandbox BOOLEAN NOT NULL DEFAULT FALSE;5
ALTER TABLE users ADD COLUMN sandbox_expires_at TIMESTAMPTZ;6
7
-- Partial index for the cleanup query (only sandbox rows).8
CREATE INDEX idx_users_sandbox_expires ON users (sandbox_expires_at) WHERE is_sandbox = TRUE;OldNewLine
@@ -1,0 +1,11 @@
1
-- Prevent duplicate pending transactions for the same buyer+item or buyer+project.2
-- This closes a TOCTOU race where two concurrent checkout requests both pass3
-- the has_purchased_item check and create separate pending transactions.4
5
CREATE UNIQUE INDEX idx_transactions_buyer_item_pending6
ON transactions (buyer_id, item_id)7
WHERE status = 'pending' AND item_id IS NOT NULL;8
9
CREATE UNIQUE INDEX idx_transactions_buyer_project_pending10
ON transactions (buyer_id, project_id)11
WHERE status = 'pending' AND project_id IS NOT NULL;OldNewLine
@@ -1,0 +1,3 @@
1
-- Track which promo code was used for a transaction so the scheduler can2
-- release reserved use_count slots when stale pending transactions are cleaned up.3
ALTER TABLE transactions ADD COLUMN promo_code_id UUID REFERENCES promo_codes(id) ON DELETE SET NULL;OldNewLine
@@ -1,0 +1,7 @@
1
-- Per-item content removal by admin, separate from user unpublish.2
-- Fulfills the enforcement ladder's "content removal" step (item hidden,3
-- account stays active, creator notified with reason).4
5
ALTER TABLE items ADD COLUMN removed_by_admin BOOLEAN NOT NULL DEFAULT false;6
ALTER TABLE items ADD COLUMN removal_reason TEXT;7
ALTER TABLE items ADD COLUMN removed_at TIMESTAMPTZ;OldNewLine
@@ -1,0 +1,6 @@
1
-- Account termination with 30-day export window.2
-- terminated_at marks when the admin permanently terminated the account.3
-- The user can still log in and use export endpoints for 30 days.4
-- After 30 days, the scheduler deletes the account.5
6
ALTER TABLE users ADD COLUMN terminated_at TIMESTAMPTZ;