trading-platform-database-v2/ddl/schemas/financial/tables/11-refunds.sql
Adrian Flores Cortes c651fe5a30 [TASK-2026-02-03-ANALISIS-DDL-MODELADO] feat(ddl): FASE-1 Gaps Críticos P0
ST-1.1: financial.refunds - Already exists with approval flow
ST-1.2: education.instructors - Created with GIN indexes
ST-1.3: trading.price_alerts - FK exists, idempotent migration added
ST-1.4: ml.prediction_overlays - New table + overlay columns

New files:
- ddl/schemas/education/tables/17-instructors.sql
- ddl/schemas/ml/tables/12-prediction_overlays.sql
- migrations/2026-02-03_add_predictions_overlay.sql
- migrations/2026-02-03_add_price_alerts_symbol_fk.sql

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 23:45:39 -06:00

75 lines
2.6 KiB
SQL

-- =====================================================
-- ORBIQUANT IA - REFUNDS TABLE
-- =====================================================
-- Description: Registro de reembolsos para compliance
-- Schema: financial
-- Gap: GAP-DDL-004
-- Created: 2026-02-03
-- =====================================================
CREATE TABLE financial.refunds (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Relacion con pago original
payment_id UUID NOT NULL REFERENCES financial.payments(id) ON DELETE RESTRICT,
-- Monto y moneda
amount DECIMAL(20,8) NOT NULL CHECK (amount > 0),
currency financial.currency_code NOT NULL,
-- Razon y metadata
reason VARCHAR(255) NOT NULL,
reason_code VARCHAR(50), -- e.g., 'duplicate', 'fraudulent', 'requested_by_customer'
notes TEXT,
-- Estado
status financial.payment_status NOT NULL DEFAULT 'pending',
-- Stripe integration
stripe_refund_id VARCHAR(255) UNIQUE,
stripe_failure_reason TEXT,
-- Aprobacion
requested_by UUID REFERENCES auth.users(id),
approved_by UUID REFERENCES auth.users(id),
approved_at TIMESTAMPTZ,
rejected_at TIMESTAMPTZ,
rejection_reason TEXT,
-- Metadata
metadata JSONB DEFAULT '{}',
-- Timestamps
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
processed_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
failed_at TIMESTAMPTZ,
-- Constraints
CONSTRAINT refund_approval_valid CHECK (
(status = 'succeeded' AND approved_by IS NOT NULL AND approved_at IS NOT NULL) OR
(status != 'succeeded')
),
CONSTRAINT refund_failure_valid CHECK (
(status = 'failed' AND failed_at IS NOT NULL) OR
(status != 'failed')
)
);
-- Indices
CREATE INDEX idx_refunds_payment ON financial.refunds(payment_id);
CREATE INDEX idx_refunds_status ON financial.refunds(status);
CREATE INDEX idx_refunds_stripe ON financial.refunds(stripe_refund_id)
WHERE stripe_refund_id IS NOT NULL;
CREATE INDEX idx_refunds_created ON financial.refunds(created_at DESC);
CREATE INDEX idx_refunds_requested_by ON financial.refunds(requested_by)
WHERE requested_by IS NOT NULL;
-- Comentarios
COMMENT ON TABLE financial.refunds IS 'Registro de reembolsos para compliance y tracking';
COMMENT ON COLUMN financial.refunds.payment_id IS 'Pago original que se esta reembolsando';
COMMENT ON COLUMN financial.refunds.reason_code IS 'Codigo de razon: duplicate, fraudulent, requested_by_customer, etc.';
COMMENT ON COLUMN financial.refunds.stripe_refund_id IS 'ID del refund en Stripe';
COMMENT ON COLUMN financial.refunds.requested_by IS 'Usuario que solicito el reembolso';
COMMENT ON COLUMN financial.refunds.approved_by IS 'Admin que aprobo el reembolso';