trading-platform-database-v2/ddl/schemas/financial/tables/01-wallets.sql
rckrdmrd 45e77e9a9c feat: Initial commit - Database schemas and scripts
DDL schemas for Trading Platform:
- User management
- Authentication
- Payments
- Education
- ML predictions
- Trading data

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 04:30:23 -06:00

86 lines
3.8 KiB
SQL

-- =====================================================
-- ORBIQUANT IA - WALLETS TABLE (UNIFIED)
-- =====================================================
-- Description: Single source of truth for all wallet types
-- Schema: financial
-- =====================================================
-- UNIFICACIÓN: Esta tabla reemplaza definiciones previas en:
-- - OQI-004 (trading schema)
-- - OQI-005 (investment schema)
-- - OQI-008 (financial schema - legacy)
-- =====================================================
CREATE TABLE financial.wallets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE RESTRICT,
-- Tipo y estado
wallet_type financial.wallet_type NOT NULL,
status financial.wallet_status NOT NULL DEFAULT 'active',
-- Balance (precisión de 8 decimales para soportar crypto)
balance DECIMAL(20,8) NOT NULL DEFAULT 0.00,
available_balance DECIMAL(20,8) NOT NULL DEFAULT 0.00,
pending_balance DECIMAL(20,8) NOT NULL DEFAULT 0.00,
-- Moneda
currency financial.currency_code NOT NULL DEFAULT 'USD',
-- Stripe integration (si aplica)
stripe_account_id VARCHAR(255),
stripe_customer_id VARCHAR(255),
-- Límites operacionales
daily_withdrawal_limit DECIMAL(15,2),
monthly_withdrawal_limit DECIMAL(15,2),
min_balance DECIMAL(15,2) DEFAULT 0.00,
-- Tracking de uso
last_transaction_at TIMESTAMPTZ,
total_deposits DECIMAL(20,8) DEFAULT 0.00,
total_withdrawals DECIMAL(20,8) DEFAULT 0.00,
-- Metadata extensible
metadata JSONB DEFAULT '{}',
-- Timestamps
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
closed_at TIMESTAMPTZ,
-- Constraints
CONSTRAINT positive_balance CHECK (balance >= 0),
CONSTRAINT positive_available CHECK (available_balance >= 0),
CONSTRAINT positive_pending CHECK (pending_balance >= 0),
CONSTRAINT available_lte_balance CHECK (available_balance <= balance),
CONSTRAINT balance_equation CHECK (balance = available_balance + pending_balance),
CONSTRAINT positive_limits CHECK (
(daily_withdrawal_limit IS NULL OR daily_withdrawal_limit > 0) AND
(monthly_withdrawal_limit IS NULL OR monthly_withdrawal_limit > 0)
),
CONSTRAINT unique_user_wallet_type UNIQUE(user_id, wallet_type, currency),
CONSTRAINT closed_status_has_date CHECK (
(status = 'closed' AND closed_at IS NOT NULL) OR
(status != 'closed' AND closed_at IS NULL)
)
);
-- Indexes para performance
CREATE INDEX idx_wallets_user_id ON financial.wallets(user_id);
CREATE INDEX idx_wallets_wallet_type ON financial.wallets(wallet_type);
CREATE INDEX idx_wallets_status ON financial.wallets(status) WHERE status = 'active';
CREATE INDEX idx_wallets_currency ON financial.wallets(currency);
CREATE INDEX idx_wallets_user_type_currency ON financial.wallets(user_id, wallet_type, currency);
CREATE INDEX idx_wallets_stripe_account ON financial.wallets(stripe_account_id) WHERE stripe_account_id IS NOT NULL;
CREATE INDEX idx_wallets_last_transaction ON financial.wallets(last_transaction_at DESC NULLS LAST);
-- Comments
COMMENT ON TABLE financial.wallets IS 'Unified wallet table - single source of truth for all wallet types';
COMMENT ON COLUMN financial.wallets.wallet_type IS 'Type of wallet: trading, investment, earnings, referral';
COMMENT ON COLUMN financial.wallets.balance IS 'Total balance = available + pending';
COMMENT ON COLUMN financial.wallets.available_balance IS 'Balance available for immediate use';
COMMENT ON COLUMN financial.wallets.pending_balance IS 'Balance in pending transactions';
COMMENT ON COLUMN financial.wallets.stripe_account_id IS 'Stripe Connect account ID for payouts';
COMMENT ON COLUMN financial.wallets.stripe_customer_id IS 'Stripe Customer ID for payments';
COMMENT ON COLUMN financial.wallets.metadata IS 'Extensible JSON field for additional data';