-- ===================================================== -- 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';