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>
75 lines
2.6 KiB
SQL
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';
|