Cambios implementados:
1. Connection pooling (tenant_db.py):
- psycopg2.pool.ThreadedConnectionPool para master y tenants
- Wrapper _PooledConnection que devuelve al pool en .close()
- Cero cambios en blueprints (backward compatible)
2. Tabla inventory_stock_summary + triggers (v3.2):
- O(1) stock lookup en vez de SUM() sobre historial completo
- Trigger AFTER INSERT en inventory_operations recalcula stock
- Poblada inicialmente en ambos tenants
- Refactor en 6 archivos de servicios para usar la nueva tabla
3. Fix N+1 en process_sale (pos_engine.py):
- Precarga retail_price en bulk query FOR UPDATE
- Elimina SELECT individual por item en loop
4. Índices críticos:
- idx_parts_name_part + pattern_ops (master)
- idx_inv_ops_inventory_branch_created (tenants)
- idx_wi_part_stock_positive (master, ya existía desde Fase 1)
Tests: 73/73 pasando (compat + fase3 + fase5 + fase6)
Migración: v3.2_db_performance.sql
1. Spanish translations for TecDoc catalog (translations.py) applied to
catalog_service.py and dashboard server.py endpoints
2. Printable quotation HTML endpoint (/pos/api/quotations/<id>/pdf) with
@media print CSS for clean browser-to-PDF output
3. Web Push notifications to owner/admin on sale cancellation, stock zero,
and cash register differences > $500. Includes service worker, VAPID
key management, and subscription endpoints.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix sat_accounts.sql: split multi-row INSERT into individual statements
so parent_id subqueries resolve correctly (was producing all NULLs)
- Add tenant_config table to v1.0 schema (required by CFDI invoicing)
- Seed tenant_config with RFC/regimen during tenant provisioning
- Fix cancel_sale to pass complete sale data for accounting reversal
- Fix CFDI XML builder: use `or` instead of dict.get() defaults to
handle explicit None values from DB (clave_prod_serv, clave_unidad)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>