FASE 4: - Redis cache de stock con fallback graceful - Multi-moneda (MXN/USD) con contabilidad en MXN - Proveedores y ordenes de compra completo - Meilisearch 1.5M+ partes indexadas - Metabase KPIs con dashboard auto-generado FASE 5: - CRM mejorado: activities, tags, loyalty program, analytics - Imagenes de partes: upload, resize, thumbnails WebP - Ordenes de servicio Kanban: received->diagnosis->repair->ready->delivered - Garantias/RMA, alertas de reorden, multi-sucursal - Stubs BNPL (APLAZO) y ERP Sync (Aspel/Contpaqi) FASE 6: - Notificaciones automaticas: push/WhatsApp/email/in-app - Reportes de ahorro vs retail_price - Logistica + tracking: DHL, FedEx, Estafeta, 99min, Uber - API Publica: API keys, rate limiting, catalog search Migraciones: v1.9-v3.0 Tests: 93/93 pasando Backup: nexus_backup_20260427_045859.tar.gz
101 lines
6.3 KiB
SQL
101 lines
6.3 KiB
SQL
-- v1.8 Performance indexes and FK fixes
|
|
-- Applied to each tenant database
|
|
|
|
-- ═══════════════════════════════════════════════════════════════════════════
|
|
-- PERFORMANCE INDEXES
|
|
-- ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
-- Stock queries (used thousands of times per day)
|
|
CREATE INDEX IF NOT EXISTS idx_inv_ops_inventory_branch ON inventory_operations(inventory_id, branch_id);
|
|
CREATE INDEX IF NOT EXISTS idx_inv_ops_inventory_type_created ON inventory_operations(inventory_id, operation_type, created_at);
|
|
CREATE INDEX IF NOT EXISTS idx_inv_ops_inventory_created_desc ON inventory_operations(inventory_id, created_at DESC);
|
|
|
|
-- Cash register lookups
|
|
CREATE INDEX IF NOT EXISTS idx_cash_movements_register ON cash_movements(register_id);
|
|
CREATE INDEX IF NOT EXISTS idx_sales_register_status ON sales(register_id, status);
|
|
|
|
-- Inventory filtering
|
|
CREATE INDEX IF NOT EXISTS idx_inventory_branch_active ON inventory(branch_id, is_active);
|
|
|
|
-- Transaction tables
|
|
CREATE INDEX IF NOT EXISTS idx_sale_items_inventory ON sale_items(inventory_id);
|
|
CREATE INDEX IF NOT EXISTS idx_sale_payments_sale ON sale_payments(sale_id);
|
|
CREATE INDEX IF NOT EXISTS idx_sale_payments_register ON sale_payments(register_id);
|
|
CREATE INDEX IF NOT EXISTS idx_layaway_items_inventory ON layaway_items(inventory_id);
|
|
CREATE INDEX IF NOT EXISTS idx_layaway_items_layaway ON layaway_items(layaway_id);
|
|
CREATE INDEX IF NOT EXISTS idx_return_items_inventory ON return_items(inventory_id);
|
|
CREATE INDEX IF NOT EXISTS idx_return_items_return ON return_items(return_id);
|
|
|
|
-- Employees and permissions
|
|
CREATE INDEX IF NOT EXISTS idx_employees_email ON employees(email);
|
|
CREATE INDEX IF NOT EXISTS idx_employees_branch ON employees(branch_id);
|
|
CREATE INDEX IF NOT EXISTS idx_employee_permissions_employee ON employee_permissions(employee_id);
|
|
|
|
-- Customers and fleet
|
|
CREATE INDEX IF NOT EXISTS idx_customers_phone ON customers(phone);
|
|
CREATE INDEX IF NOT EXISTS idx_fleet_vehicles_branch_vin ON fleet_vehicles(branch_id, vin);
|
|
CREATE INDEX IF NOT EXISTS idx_fleet_maintenance_schedules_next_due ON fleet_maintenance_schedules(next_due_at);
|
|
|
|
-- WhatsApp and quotations
|
|
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_status ON whatsapp_messages(status);
|
|
CREATE INDEX IF NOT EXISTS idx_whatsapp_messages_related ON whatsapp_messages(related_type, related_id);
|
|
CREATE INDEX IF NOT EXISTS idx_quotations_branch ON quotations(branch_id);
|
|
|
|
-- Accounting
|
|
CREATE INDEX IF NOT EXISTS idx_accounts_parent ON accounts(parent_id);
|
|
CREATE INDEX IF NOT EXISTS idx_journal_entries_date ON journal_entries(date);
|
|
CREATE INDEX IF NOT EXISTS idx_fiscal_periods_year_month ON fiscal_periods(year, month);
|
|
|
|
-- Physical counts
|
|
CREATE INDEX IF NOT EXISTS idx_physical_counts_branch_status ON physical_counts(branch_id, status);
|
|
CREATE INDEX IF NOT EXISTS idx_physical_count_lines_inventory ON physical_count_lines(inventory_id);
|
|
|
|
-- ═══════════════════════════════════════════════════════════════════════════
|
|
-- FOREIGN KEY FIXES
|
|
-- ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
-- Sale dependencies
|
|
ALTER TABLE sale_items
|
|
ADD CONSTRAINT fk_sale_items_sale FOREIGN KEY (sale_id) REFERENCES sales(id) ON DELETE CASCADE;
|
|
ALTER TABLE sale_payments
|
|
ADD CONSTRAINT fk_sale_payments_sale FOREIGN KEY (sale_id) REFERENCES sales(id) ON DELETE CASCADE;
|
|
|
|
-- Quotation dependencies
|
|
ALTER TABLE quotation_items
|
|
ADD CONSTRAINT fk_quotation_items_quotation FOREIGN KEY (quotation_id) REFERENCES quotations(id) ON DELETE CASCADE;
|
|
|
|
-- Layaway dependencies
|
|
ALTER TABLE layaway_items
|
|
ADD CONSTRAINT fk_layaway_items_layaway FOREIGN KEY (layaway_id) REFERENCES layaways(id) ON DELETE CASCADE;
|
|
|
|
-- Return dependencies
|
|
ALTER TABLE return_items
|
|
ADD CONSTRAINT fk_return_items_return FOREIGN KEY (return_id) REFERENCES returns(id) ON DELETE CASCADE;
|
|
ALTER TABLE return_items
|
|
ADD CONSTRAINT fk_return_items_sale_item FOREIGN KEY (sale_item_id) REFERENCES sale_items(id) ON DELETE SET NULL;
|
|
|
|
-- Cash movements
|
|
ALTER TABLE cash_movements
|
|
ADD CONSTRAINT fk_cash_movements_register FOREIGN KEY (register_id) REFERENCES cash_registers(id) ON DELETE CASCADE;
|
|
|
|
-- ═══════════════════════════════════════════════════════════════════════════
|
|
-- DATA TYPE NORMALIZATION
|
|
-- ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
ALTER TABLE physical_counts ALTER COLUMN created_at TYPE TIMESTAMPTZ;
|
|
|
|
-- ═══════════════════════════════════════════════════════════════════════════
|
|
-- CONSTRAINT IMPROVEMENTS
|
|
-- ═══════════════════════════════════════════════════════════════════════════
|
|
|
|
-- Ensure unique entry numbers per date (fiscal period approximation)
|
|
-- Note: journal_entries uses 'date' column, not period_year/month
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_journal_entries_unique_number
|
|
ON journal_entries(date, entry_number);
|
|
|
|
-- Add CHECK constraint for sales.status (idempotent for VARCHAR)
|
|
-- Note: PostgreSQL does not support adding CHECK constraints via IF NOT EXISTS
|
|
-- This is left as documentation; apply manually if needed:
|
|
-- ALTER TABLE sales ADD CONSTRAINT chk_sales_status
|
|
-- CHECK (status IN ('completed', 'cancelled', 'returned', 'partially_returned'));
|