--- id: "ET-INV-001" title: "Modelo de Datos Investment" type: "Technical Specification" status: "Done" priority: "Alta" epic: "OQI-004" project: "trading-platform" version: "1.0.0" created_date: "2025-12-05" updated_date: "2026-01-04" --- # ET-INV-001: Modelo de Datos Investment **Epic:** OQI-004 Cuentas de Inversión **Versión:** 1.0 **Fecha:** 2025-12-05 **Responsable:** Requirements-Analyst --- ## 1. Descripción Define el modelo de datos completo para el schema `investment` en PostgreSQL 15+, incluyendo: - Productos de inversión (agentes ML) - Cuentas de inversión de usuarios - Transacciones (depósitos, retiros, distribuciones) - Solicitudes de retiro - Performance diaria de cuentas - Distribuciones mensuales de utilidades --- ## 2. Arquitectura de Base de Datos ``` ┌─────────────────────────────────────────────────────────────────┐ │ SCHEMA: investment │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ ┌─────────────────┐ │ │ │ products │◄────────│ accounts │ │ │ └──────────────┘ └─────────────────┘ │ │ │ │ │ │ │ ▼ │ │ │ ┌─────────────────┐ │ │ │ │ transactions │ │ │ │ └─────────────────┘ │ │ │ │ │ │ │ ▼ │ │ │ ┌─────────────────┐ │ │ └─────────────────►│ daily_performance│ │ │ └─────────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ distributions │ │ │ └─────────────────┘ │ │ │ │ ┌──────────────────┐ │ │ │withdrawal_requests│ │ │ └──────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 3. Especificación de Tablas ### 3.1 Tabla: `products` Productos de inversión basados en agentes ML. ```sql CREATE TABLE investment.products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Información básica name VARCHAR(100) NOT NULL, description TEXT, agent_type VARCHAR(50) NOT NULL, -- 'swing', 'day', 'scalping', 'arbitrage' -- Configuración financiera min_investment DECIMAL(15, 2) NOT NULL DEFAULT 100.00, max_investment DECIMAL(15, 2), -- NULL = sin límite performance_fee_percentage DECIMAL(5, 2) NOT NULL DEFAULT 20.00, -- 20% target_annual_return DECIMAL(5, 2), -- Estimado, opcional risk_level VARCHAR(20) NOT NULL, -- 'low', 'medium', 'high', 'very_high' -- ML Engine ml_agent_id VARCHAR(100) NOT NULL UNIQUE, -- ID del agente en ML Engine ml_config JSONB, -- Configuración específica del agente -- Estado status VARCHAR(20) NOT NULL DEFAULT 'active', -- 'active', 'paused', 'closed' is_accepting_new_investors BOOLEAN NOT NULL DEFAULT true, total_aum DECIMAL(15, 2) NOT NULL DEFAULT 0.00, -- Assets Under Management total_investors INTEGER NOT NULL DEFAULT 0, -- Metadata created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), -- Constraints CONSTRAINT chk_min_investment_positive CHECK (min_investment > 0), CONSTRAINT chk_max_investment_valid CHECK (max_investment IS NULL OR max_investment >= min_investment), CONSTRAINT chk_performance_fee_range CHECK (performance_fee_percentage >= 0 AND performance_fee_percentage <= 100), CONSTRAINT chk_risk_level CHECK (risk_level IN ('low', 'medium', 'high', 'very_high')), CONSTRAINT chk_status CHECK (status IN ('active', 'paused', 'closed')) ); -- Índices CREATE INDEX idx_products_agent_type ON investment.products(agent_type); CREATE INDEX idx_products_status ON investment.products(status); CREATE INDEX idx_products_ml_agent_id ON investment.products(ml_agent_id); -- Trigger para updated_at CREATE TRIGGER update_products_updated_at BEFORE UPDATE ON investment.products FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); ``` ### 3.2 Tabla: `accounts` Cuentas de inversión de usuarios en productos específicos. ```sql CREATE TABLE investment.accounts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Relaciones user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, product_id UUID NOT NULL REFERENCES investment.products(id) ON DELETE RESTRICT, -- Balance y performance current_balance DECIMAL(15, 2) NOT NULL DEFAULT 0.00, initial_investment DECIMAL(15, 2) NOT NULL DEFAULT 0.00, total_deposited DECIMAL(15, 2) NOT NULL DEFAULT 0.00, total_withdrawn DECIMAL(15, 2) NOT NULL DEFAULT 0.00, total_profit_distributed DECIMAL(15, 2) NOT NULL DEFAULT 0.00, -- Performance total_return_percentage DECIMAL(10, 4), -- Retorno total % annualized_return_percentage DECIMAL(10, 4), -- Retorno anualizado % -- Estado status VARCHAR(20) NOT NULL DEFAULT 'active', -- 'active', 'paused', 'closed' opened_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), closed_at TIMESTAMP WITH TIME ZONE, -- Metadata created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), -- Constraints CONSTRAINT uq_user_product UNIQUE (user_id, product_id), CONSTRAINT chk_current_balance_positive CHECK (current_balance >= 0), CONSTRAINT chk_account_status CHECK (status IN ('active', 'paused', 'closed')) ); -- Índices CREATE INDEX idx_accounts_user_id ON investment.accounts(user_id); CREATE INDEX idx_accounts_product_id ON investment.accounts(product_id); CREATE INDEX idx_accounts_status ON investment.accounts(status); CREATE INDEX idx_accounts_opened_at ON investment.accounts(opened_at DESC); -- Trigger para updated_at CREATE TRIGGER update_accounts_updated_at BEFORE UPDATE ON investment.accounts FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); ``` ### 3.3 Tabla: `transactions` Registro de todas las transacciones de cuentas de inversión. ```sql CREATE TABLE investment.transactions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Relaciones account_id UUID NOT NULL REFERENCES investment.accounts(id) ON DELETE CASCADE, user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, -- Tipo y estado type VARCHAR(30) NOT NULL, -- 'deposit', 'withdrawal', 'profit_distribution', 'fee' status VARCHAR(20) NOT NULL DEFAULT 'pending', -- 'pending', 'completed', 'failed', 'cancelled' -- Montos amount DECIMAL(15, 2) NOT NULL, balance_before DECIMAL(15, 2) NOT NULL, balance_after DECIMAL(15, 2), -- Integración con payments payment_id UUID, -- Referencia a financial.payments para depósitos stripe_payment_intent_id VARCHAR(255), -- Retiros withdrawal_request_id UUID, -- Referencia a withdrawal_requests withdrawal_method VARCHAR(50), -- 'bank_transfer', 'stripe_payout' withdrawal_destination_id VARCHAR(255), -- bank_account_id o stripe_payout_id -- Distribuciones distribution_id UUID, -- Referencia a distributions distribution_period VARCHAR(20), -- '2025-01', '2025-02' -- Metadata notes TEXT, processed_at TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), -- Constraints CONSTRAINT chk_amount_positive CHECK (amount > 0), CONSTRAINT chk_transaction_type CHECK (type IN ('deposit', 'withdrawal', 'profit_distribution', 'fee')), CONSTRAINT chk_transaction_status CHECK (status IN ('pending', 'completed', 'failed', 'cancelled')) ); -- Índices CREATE INDEX idx_transactions_account_id ON investment.transactions(account_id); CREATE INDEX idx_transactions_user_id ON investment.transactions(user_id); CREATE INDEX idx_transactions_type ON investment.transactions(type); CREATE INDEX idx_transactions_status ON investment.transactions(status); CREATE INDEX idx_transactions_created_at ON investment.transactions(created_at DESC); CREATE INDEX idx_transactions_payment_id ON investment.transactions(payment_id); ``` ### 3.4 Tabla: `withdrawal_requests` Solicitudes de retiro pendientes de aprobación. ```sql CREATE TABLE investment.withdrawal_requests ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Relaciones account_id UUID NOT NULL REFERENCES investment.accounts(id) ON DELETE CASCADE, user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, -- Monto y método amount DECIMAL(15, 2) NOT NULL, withdrawal_method VARCHAR(50) NOT NULL, -- 'bank_transfer', 'stripe_payout' destination_details JSONB NOT NULL, -- { "bank_account": "...", "routing": "..." } -- Estado y procesamiento status VARCHAR(20) NOT NULL DEFAULT 'pending', -- 'pending', 'approved', 'rejected', 'completed', 'cancelled' requested_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), reviewed_at TIMESTAMP WITH TIME ZONE, reviewed_by UUID REFERENCES auth.users(id), processed_at TIMESTAMP WITH TIME ZONE, -- Razones rejection_reason TEXT, admin_notes TEXT, -- Referencia a transacción transaction_id UUID REFERENCES investment.transactions(id), -- Metadata created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), -- Constraints CONSTRAINT chk_withdrawal_amount_positive CHECK (amount > 0), CONSTRAINT chk_withdrawal_status CHECK (status IN ('pending', 'approved', 'rejected', 'completed', 'cancelled')), CONSTRAINT chk_withdrawal_method CHECK (withdrawal_method IN ('bank_transfer', 'stripe_payout')) ); -- Índices CREATE INDEX idx_withdrawal_requests_account_id ON investment.withdrawal_requests(account_id); CREATE INDEX idx_withdrawal_requests_user_id ON investment.withdrawal_requests(user_id); CREATE INDEX idx_withdrawal_requests_status ON investment.withdrawal_requests(status); CREATE INDEX idx_withdrawal_requests_requested_at ON investment.withdrawal_requests(requested_at DESC); ``` ### 3.5 Tabla: `daily_performance` Registro diario del rendimiento de cada cuenta. ```sql CREATE TABLE investment.daily_performance ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Relaciones account_id UUID NOT NULL REFERENCES investment.accounts(id) ON DELETE CASCADE, product_id UUID NOT NULL REFERENCES investment.products(id) ON DELETE CASCADE, -- Fecha date DATE NOT NULL, -- Valores del día opening_balance DECIMAL(15, 2) NOT NULL, closing_balance DECIMAL(15, 2) NOT NULL, daily_return DECIMAL(15, 2) NOT NULL, -- Ganancia/pérdida del día daily_return_percentage DECIMAL(10, 4), -- Métricas acumuladas cumulative_return DECIMAL(15, 2), cumulative_return_percentage DECIMAL(10, 4), -- Datos del agente ML trades_executed INTEGER DEFAULT 0, winning_trades INTEGER DEFAULT 0, losing_trades INTEGER DEFAULT 0, ml_agent_data JSONB, -- Datos adicionales del agente -- Metadata calculated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), -- Constraints CONSTRAINT uq_account_date UNIQUE (account_id, date) ); -- Índices CREATE INDEX idx_daily_performance_account_id ON investment.daily_performance(account_id); CREATE INDEX idx_daily_performance_product_id ON investment.daily_performance(product_id); CREATE INDEX idx_daily_performance_date ON investment.daily_performance(date DESC); CREATE INDEX idx_daily_performance_account_date ON investment.daily_performance(account_id, date DESC); ``` ### 3.6 Tabla: `distributions` Distribuciones mensuales de utilidades (performance fee). ```sql CREATE TABLE investment.distributions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Relaciones account_id UUID NOT NULL REFERENCES investment.accounts(id) ON DELETE CASCADE, product_id UUID NOT NULL REFERENCES investment.products(id) ON DELETE CASCADE, user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, -- Período period VARCHAR(20) NOT NULL, -- '2025-01', '2025-02' period_start DATE NOT NULL, period_end DATE NOT NULL, -- Cálculos opening_balance DECIMAL(15, 2) NOT NULL, closing_balance DECIMAL(15, 2) NOT NULL, gross_profit DECIMAL(15, 2) NOT NULL, performance_fee_percentage DECIMAL(5, 2) NOT NULL, performance_fee_amount DECIMAL(15, 2) NOT NULL, net_profit DECIMAL(15, 2) NOT NULL, -- gross_profit - performance_fee_amount -- Estado status VARCHAR(20) NOT NULL DEFAULT 'pending', -- 'pending', 'distributed', 'failed' distributed_at TIMESTAMP WITH TIME ZONE, -- Referencia a transacción transaction_id UUID REFERENCES investment.transactions(id), -- Metadata created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), -- Constraints CONSTRAINT uq_account_period UNIQUE (account_id, period), CONSTRAINT chk_distribution_status CHECK (status IN ('pending', 'distributed', 'failed')), CONSTRAINT chk_net_profit CHECK (net_profit >= 0) ); -- Índices CREATE INDEX idx_distributions_account_id ON investment.distributions(account_id); CREATE INDEX idx_distributions_product_id ON investment.distributions(product_id); CREATE INDEX idx_distributions_user_id ON investment.distributions(user_id); CREATE INDEX idx_distributions_period ON investment.distributions(period); CREATE INDEX idx_distributions_status ON investment.distributions(status); ``` --- ## 4. Interfaces TypeScript ### 4.1 Types del Modelo ```typescript // src/types/investment.types.ts export type AgentType = 'swing' | 'day' | 'scalping' | 'arbitrage'; export type RiskLevel = 'low' | 'medium' | 'high' | 'very_high'; export type ProductStatus = 'active' | 'paused' | 'closed'; export type AccountStatus = 'active' | 'paused' | 'closed'; export type TransactionType = 'deposit' | 'withdrawal' | 'profit_distribution' | 'fee'; export type TransactionStatus = 'pending' | 'completed' | 'failed' | 'cancelled'; export type WithdrawalStatus = 'pending' | 'approved' | 'rejected' | 'completed' | 'cancelled'; export type WithdrawalMethod = 'bank_transfer' | 'stripe_payout'; export type DistributionStatus = 'pending' | 'distributed' | 'failed'; export interface Product { id: string; name: string; description: string | null; agent_type: AgentType; min_investment: number; max_investment: number | null; performance_fee_percentage: number; target_annual_return: number | null; risk_level: RiskLevel; ml_agent_id: string; ml_config: Record | null; status: ProductStatus; is_accepting_new_investors: boolean; total_aum: number; total_investors: number; created_at: string; updated_at: string; } export interface Account { id: string; user_id: string; product_id: string; current_balance: number; initial_investment: number; total_deposited: number; total_withdrawn: number; total_profit_distributed: number; total_return_percentage: number | null; annualized_return_percentage: number | null; status: AccountStatus; opened_at: string; closed_at: string | null; created_at: string; updated_at: string; } export interface Transaction { id: string; account_id: string; user_id: string; type: TransactionType; status: TransactionStatus; amount: number; balance_before: number; balance_after: number | null; payment_id: string | null; stripe_payment_intent_id: string | null; withdrawal_request_id: string | null; withdrawal_method: WithdrawalMethod | null; withdrawal_destination_id: string | null; distribution_id: string | null; distribution_period: string | null; notes: string | null; processed_at: string | null; created_at: string; } export interface WithdrawalRequest { id: string; account_id: string; user_id: string; amount: number; withdrawal_method: WithdrawalMethod; destination_details: Record; status: WithdrawalStatus; requested_at: string; reviewed_at: string | null; reviewed_by: string | null; processed_at: string | null; rejection_reason: string | null; admin_notes: string | null; transaction_id: string | null; created_at: string; updated_at: string; } export interface DailyPerformance { id: string; account_id: string; product_id: string; date: string; opening_balance: number; closing_balance: number; daily_return: number; daily_return_percentage: number | null; cumulative_return: number | null; cumulative_return_percentage: number | null; trades_executed: number; winning_trades: number; losing_trades: number; ml_agent_data: Record | null; calculated_at: string; created_at: string; } export interface Distribution { id: string; account_id: string; product_id: string; user_id: string; period: string; period_start: string; period_end: string; opening_balance: number; closing_balance: number; gross_profit: number; performance_fee_percentage: number; performance_fee_amount: number; net_profit: number; status: DistributionStatus; distributed_at: string | null; transaction_id: string | null; created_at: string; updated_at: string; } ``` ### 4.2 DTOs para Creación ```typescript // src/types/investment.dtos.ts export interface CreateProductDto { name: string; description?: string; agent_type: AgentType; min_investment: number; max_investment?: number; performance_fee_percentage: number; target_annual_return?: number; risk_level: RiskLevel; ml_agent_id: string; ml_config?: Record; } export interface CreateAccountDto { user_id: string; product_id: string; initial_investment: number; } export interface CreateTransactionDto { account_id: string; user_id: string; type: TransactionType; amount: number; payment_id?: string; stripe_payment_intent_id?: string; notes?: string; } export interface CreateWithdrawalRequestDto { account_id: string; user_id: string; amount: number; withdrawal_method: WithdrawalMethod; destination_details: Record; } ``` --- ## 5. Funciones SQL Auxiliares ### 5.1 Función: `update_updated_at_column()` ```sql CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; ``` ### 5.2 Función: Actualizar AUM de producto ```sql CREATE OR REPLACE FUNCTION update_product_aum() RETURNS TRIGGER AS $$ BEGIN UPDATE investment.products SET total_aum = ( SELECT COALESCE(SUM(current_balance), 0) FROM investment.accounts WHERE product_id = NEW.product_id AND status = 'active' ) WHERE id = NEW.product_id; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER trigger_update_product_aum AFTER INSERT OR UPDATE OF current_balance ON investment.accounts FOR EACH ROW EXECUTE FUNCTION update_product_aum(); ``` --- ## 6. Scripts de Migración ### 6.1 Up Migration ```sql -- migrations/20250101_create_investment_schema.up.sql -- Crear schema CREATE SCHEMA IF NOT EXISTS investment; -- Habilitar extensiones necesarias CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- Crear función update_updated_at CREATE OR REPLACE FUNCTION update_updated_at_column() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Crear tablas (ver secciones 3.1 a 3.6) -- ... (incluir todas las sentencias CREATE TABLE) -- Crear funciones auxiliares -- ... (incluir funciones de la sección 5) COMMENT ON SCHEMA investment IS 'Schema para gestión de cuentas de inversión y productos ML'; ``` ### 6.2 Down Migration ```sql -- migrations/20250101_create_investment_schema.down.sql DROP SCHEMA IF EXISTS investment CASCADE; DROP FUNCTION IF EXISTS update_updated_at_column() CASCADE; ``` --- ## 7. Validaciones y Constraints ### 7.1 Reglas de Negocio Implementadas 1. **Productos:** - `min_investment` debe ser mayor a 0 - `max_investment` debe ser mayor o igual a `min_investment` - `performance_fee_percentage` entre 0 y 100 - Un usuario solo puede tener una cuenta por producto (`uq_user_product`) 2. **Cuentas:** - `current_balance` no puede ser negativo - No se puede eliminar un producto si tiene cuentas asociadas (`ON DELETE RESTRICT`) 3. **Transacciones:** - `amount` debe ser positivo - El tipo debe ser uno de los permitidos 4. **Retiros:** - Solo se permite `bank_transfer` o `stripe_payout` - Monto debe ser positivo y no exceder balance disponible 5. **Distribuciones:** - Una sola distribución por cuenta por período (`uq_account_period`) - `net_profit` no puede ser negativo --- ## 8. Seguridad ### 8.1 Row Level Security (RLS) ```sql -- Habilitar RLS en todas las tablas ALTER TABLE investment.products ENABLE ROW LEVEL SECURITY; ALTER TABLE investment.accounts ENABLE ROW LEVEL SECURITY; ALTER TABLE investment.transactions ENABLE ROW LEVEL SECURITY; ALTER TABLE investment.withdrawal_requests ENABLE ROW LEVEL SECURITY; ALTER TABLE investment.daily_performance ENABLE ROW LEVEL SECURITY; ALTER TABLE investment.distributions ENABLE ROW LEVEL SECURITY; -- Políticas para usuarios CREATE POLICY users_view_products ON investment.products FOR SELECT USING (status = 'active'); CREATE POLICY users_view_own_accounts ON investment.accounts FOR SELECT USING (user_id = auth.uid()); CREATE POLICY users_view_own_transactions ON investment.transactions FOR SELECT USING (user_id = auth.uid()); CREATE POLICY users_view_own_withdrawals ON investment.withdrawal_requests FOR SELECT USING (user_id = auth.uid()); -- Políticas para admins (asumiendo rol 'admin') CREATE POLICY admins_all_access ON investment.products FOR ALL USING (auth.jwt() ->> 'role' = 'admin'); ``` --- ## 9. Testing ### 9.1 Datos de Prueba ```sql -- Seed data para testing INSERT INTO investment.products ( name, description, agent_type, min_investment, performance_fee_percentage, risk_level, ml_agent_id ) VALUES ( 'Swing Trader Pro', 'Agente de swing trading con estrategias de mediano plazo', 'swing', 500.00, 20.00, 'medium', 'ml-agent-swing-001' ), ( 'Day Trader Elite', 'Trading intradía con alta frecuencia', 'day', 1000.00, 25.00, 'high', 'ml-agent-day-001' ); ``` ### 9.2 Tests de Integridad ```sql -- Verificar constraints DO $$ BEGIN -- Test: min_investment positivo BEGIN INSERT INTO investment.products (name, agent_type, min_investment, risk_level, ml_agent_id) VALUES ('Test', 'swing', -100, 'low', 'test-agent'); RAISE EXCEPTION 'Should not allow negative min_investment'; EXCEPTION WHEN check_violation THEN -- Expected END; -- Test: unique user_product BEGIN INSERT INTO investment.accounts (user_id, product_id) VALUES ('user-1', 'product-1'); INSERT INTO investment.accounts (user_id, product_id) VALUES ('user-1', 'product-1'); RAISE EXCEPTION 'Should not allow duplicate user-product'; EXCEPTION WHEN unique_violation THEN -- Expected END; END $$; ``` --- ## 10. Dependencias ### 10.1 Dependencias de Schemas - `auth.users`: Para relaciones de usuarios - `financial.payments`: Para integración con pagos (opcional) ### 10.2 Extensiones PostgreSQL - `uuid-ossp`: Generación de UUIDs - `pg_trgm`: Para búsquedas de texto (opcional) --- ## 11. Configuración ### 11.1 Variables de Entorno ```bash # Database DATABASE_URL=postgresql://user:password@localhost:5432/trading DATABASE_POOL_MIN=2 DATABASE_POOL_MAX=10 # Investment Schema INVESTMENT_DEFAULT_PERFORMANCE_FEE=20.00 INVESTMENT_MIN_WITHDRAWAL_AMOUNT=50.00 ``` --- ## 12. Mantenimiento ### 12.1 Índices y Performance ```sql -- Analizar uso de índices SELECT schemaname, tablename, indexname, idx_scan FROM pg_stat_user_indexes WHERE schemaname = 'investment' ORDER BY idx_scan ASC; -- Vacuum y analyze periódicos VACUUM ANALYZE investment.daily_performance; VACUUM ANALYZE investment.transactions; ``` ### 12.2 Respaldos - Backup diario de schema `investment` - Retention: 30 días - Point-in-time recovery habilitado --- ## 13. Referencias - PostgreSQL 15 Documentation - Schema de Stripe para payments - ML Engine API para integración de agentes