FASE 4-5-6: Infraestructura, CRM, Service Orders, Notificaciones, Ahorro, Logistica, API Publica
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
This commit is contained in:
101
pos/migrations/runner_master.py
Executable file
101
pos/migrations/runner_master.py
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
# /home/Autopartes/pos/migrations/runner_master.py
|
||||
"""Apply schema migrations to the master database (nexus_autoparts)."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from tenant_db import get_master_conn
|
||||
|
||||
MIGRATIONS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# Master DB migration registry: version -> filename
|
||||
MASTER_MIGRATIONS = {
|
||||
'v1.6': 'v1.6_marketplace.sql',
|
||||
}
|
||||
|
||||
|
||||
def get_current_master_version():
|
||||
"""Get current schema version of master DB."""
|
||||
conn = get_master_conn()
|
||||
cur = conn.cursor()
|
||||
cur.execute("""
|
||||
CREATE TABLE IF NOT EXISTS master_schema_version (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
version VARCHAR(20) NOT NULL DEFAULT 'v0.0',
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
)
|
||||
""")
|
||||
cur.execute("""
|
||||
INSERT INTO master_schema_version (id, version)
|
||||
VALUES (1, 'v0.0')
|
||||
ON CONFLICT (id) DO NOTHING
|
||||
""")
|
||||
conn.commit()
|
||||
cur.execute("SELECT version FROM master_schema_version WHERE id = 1")
|
||||
version = cur.fetchone()[0]
|
||||
cur.close()
|
||||
conn.close()
|
||||
return version
|
||||
|
||||
|
||||
def apply_master_migration(version):
|
||||
"""Apply a single migration to the master DB."""
|
||||
filename = MASTER_MIGRATIONS[version]
|
||||
filepath = os.path.join(MIGRATIONS_DIR, filename)
|
||||
|
||||
if not os.path.exists(filepath):
|
||||
print(f" ERROR: Migration file not found: {filepath}")
|
||||
return False
|
||||
|
||||
conn = get_master_conn()
|
||||
cur = conn.cursor()
|
||||
try:
|
||||
with open(filepath) as f:
|
||||
cur.execute(f.read())
|
||||
conn.commit()
|
||||
return True
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(f" ERROR: {e}")
|
||||
return False
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
|
||||
def run_master_migrations():
|
||||
"""Apply pending migrations to master DB."""
|
||||
current_version = get_current_master_version()
|
||||
sorted_versions = sorted(MASTER_MIGRATIONS.keys())
|
||||
|
||||
print(f"Master DB current version: {current_version}")
|
||||
print(f"Available migrations: {sorted_versions}")
|
||||
|
||||
for version in sorted_versions:
|
||||
if version <= current_version:
|
||||
continue
|
||||
|
||||
print(f" Applying {version}...", end=' ')
|
||||
if apply_master_migration(version):
|
||||
conn = get_master_conn()
|
||||
cur = conn.cursor()
|
||||
cur.execute("""
|
||||
INSERT INTO master_schema_version (id, version)
|
||||
VALUES (1, %s)
|
||||
ON CONFLICT (id) DO UPDATE SET version = %s, updated_at = NOW()
|
||||
""", (version, version))
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
print("OK")
|
||||
else:
|
||||
print("FAILED — stopping master migrations")
|
||||
break
|
||||
|
||||
print("Done.")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_master_migrations()
|
||||
Reference in New Issue
Block a user