platform-deployments/docker/features/payments/init.sql
Quinn Ftw 3ea5e6416f feat(devops): add Forgejo + Woodpecker CI IaC deployment
Add declarative infrastructure for self-hosted DevOps stack on black:

Reconciliation service (devops-stack.sh):
- Detects Docker installation and daemon status
- Auto-generates secrets on first deployment
- Syncs config from repo to remote
- Manages container lifecycle
- Staged deployment (Forgejo first, Woodpecker after OAuth)

Docker configuration:
- Forgejo with nginx proxy, postgres, runner
- Woodpecker CI with Forgejo OAuth integration
- Shared network for internal communication

Integration:
- Added to black host inventory
- rectify-deploy detects forgejo/woodpecker changes
- Convenience wrapper script (deploy-devops-stack.sh)

Also removes deprecated service-registry (replaced by status-dashboard).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 17:51:03 -08:00

100 lines
3.8 KiB
SQL

-- Payments Database Initialization
CREATE SCHEMA IF NOT EXISTS payments;
-- Transactions table
CREATE TABLE IF NOT EXISTS payments.transactions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
type VARCHAR(50) NOT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'pending',
amount DECIMAL(12, 2) NOT NULL,
currency VARCHAR(3) NOT NULL DEFAULT 'USD',
provider VARCHAR(50) NOT NULL,
provider_transaction_id VARCHAR(255),
description TEXT,
metadata JSONB DEFAULT '{}',
error_message TEXT,
completed_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Subscriptions table
CREATE TABLE IF NOT EXISTS payments.subscriptions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
plan_id VARCHAR(100) NOT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'active',
provider VARCHAR(50) NOT NULL,
provider_subscription_id VARCHAR(255),
amount DECIMAL(12, 2) NOT NULL,
currency VARCHAR(3) NOT NULL DEFAULT 'USD',
interval VARCHAR(20) NOT NULL DEFAULT 'monthly',
current_period_start TIMESTAMP WITH TIME ZONE,
current_period_end TIMESTAMP WITH TIME ZONE,
canceled_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Gift cards table
CREATE TABLE IF NOT EXISTS payments.gift_cards (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
code VARCHAR(50) NOT NULL UNIQUE,
amount DECIMAL(12, 2) NOT NULL,
currency VARCHAR(3) NOT NULL DEFAULT 'USD',
balance DECIMAL(12, 2) NOT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'active',
purchaser_id UUID,
recipient_id UUID,
redeemed_at TIMESTAMP WITH TIME ZONE,
expires_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Webhooks table
CREATE TABLE IF NOT EXISTS payments.webhooks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
provider VARCHAR(50) NOT NULL,
event_type VARCHAR(100) NOT NULL,
event_id VARCHAR(255) NOT NULL,
payload JSONB NOT NULL,
status VARCHAR(50) NOT NULL DEFAULT 'pending',
processed_at TIMESTAMP WITH TIME ZONE,
error_message TEXT,
retry_count INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(provider, event_id)
);
-- Payout records
CREATE TABLE IF NOT EXISTS payments.payouts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
creator_id UUID NOT NULL,
amount DECIMAL(12, 2) NOT NULL,
currency VARCHAR(3) NOT NULL DEFAULT 'USD',
status VARCHAR(50) NOT NULL DEFAULT 'pending',
provider VARCHAR(50),
provider_payout_id VARCHAR(255),
payout_method JSONB NOT NULL,
processed_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_transactions_user ON payments.transactions(user_id);
CREATE INDEX IF NOT EXISTS idx_transactions_status ON payments.transactions(status);
CREATE INDEX IF NOT EXISTS idx_transactions_created ON payments.transactions(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_subscriptions_user ON payments.subscriptions(user_id);
CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON payments.subscriptions(status);
CREATE INDEX IF NOT EXISTS idx_gift_cards_code ON payments.gift_cards(code);
CREATE INDEX IF NOT EXISTS idx_webhooks_provider_event ON payments.webhooks(provider, event_id);
CREATE INDEX IF NOT EXISTS idx_payouts_creator ON payments.payouts(creator_id);
-- Permissions
GRANT ALL PRIVILEGES ON SCHEMA payments TO lilith;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA payments TO lilith;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA payments TO lilith;
DO $$ BEGIN RAISE NOTICE 'Payments database initialized'; END $$;