fix(whatsapp,roles): self-heal legacy whatsapp_log schema; map underscore role aliases
CT115 (Mumuni relay #747) — two live-instance defects after PR #12:
1. GET /api/whatsapp/mock-log 500'd with a valid admin token:
'no such column: whatsapp_log.message_text'. The model gained
message_text/wa_message_id/ticket_number (and dropped command) in
4afdc36 with no migration, so legacy DBs keep the (command, ...) shape.
ensure_legacy_schema (startup, app/main.py) now adds the three missing
columns idempotently and backfills legacy command bodies into
message_text before dropping the obsolete NOT NULL command column, so
both the mock-log read path and the ORM write path work on healed DBs.
New producer/consumer regression (tests/test_whatsapp_log_legacy_heal.py)
reproduces the exact OperationalError, then asserts 200 + data.
2. ROLE_ALIASES gap: underscore legacy roles (cs_rep, cs_manager,
fm_dispatcher) were not mapped, so normalize_legacy_user_roles could not
converge rows like user 18 (test@denya.com, role 'cs_rep') and the
frontend stranded them on /tickets. Added the underscore aliases; tests
assert normalize_role('cs_rep') == 'CS Rep' and a cs_rep row converges
and authenticates.
This commit is contained in:
+41
@@ -52,6 +52,47 @@ async def ensure_legacy_schema(conn) -> None:
|
||||
text("UPDATE tickets SET reported_at = created_at WHERE reported_at IS NULL")
|
||||
)
|
||||
logger.info("Added missing tickets.reported_at column (legacy database)")
|
||||
|
||||
# whatsapp_log predates the real Meta webhook (the model gained
|
||||
# message_text/wa_message_id/ticket_number and dropped `command` in commit
|
||||
# 4afdc36 with no migration), so legacy DBs still carry the old shape and
|
||||
# every read/write through the ORM 500s (no such column: message_text).
|
||||
result = await conn.execute(
|
||||
text("SELECT name FROM sqlite_master WHERE type='table' AND name='whatsapp_log'")
|
||||
)
|
||||
if result.scalar():
|
||||
result = await conn.execute(text("PRAGMA table_info(whatsapp_log)"))
|
||||
log_columns = {row[1] for row in result}
|
||||
if "message_text" not in log_columns:
|
||||
await conn.execute(
|
||||
text("ALTER TABLE whatsapp_log ADD COLUMN message_text TEXT NOT NULL DEFAULT ''")
|
||||
)
|
||||
logger.info("Added missing whatsapp_log.message_text column (legacy database)")
|
||||
if "wa_message_id" not in log_columns:
|
||||
await conn.execute(
|
||||
text("ALTER TABLE whatsapp_log ADD COLUMN wa_message_id VARCHAR(100)")
|
||||
)
|
||||
logger.info("Added missing whatsapp_log.wa_message_id column (legacy database)")
|
||||
if "ticket_number" not in log_columns:
|
||||
await conn.execute(
|
||||
text("ALTER TABLE whatsapp_log ADD COLUMN ticket_number VARCHAR(30)")
|
||||
)
|
||||
logger.info("Added missing whatsapp_log.ticket_number column (legacy database)")
|
||||
if "command" in log_columns:
|
||||
# Legacy rows stored the message body in `command`, which the model
|
||||
# no longer defines (NOT NULL, no default): any ORM insert omitting
|
||||
# it would violate NOT NULL. Preserve the old bodies in
|
||||
# message_text, then drop the obsolete column to match the model.
|
||||
await conn.execute(
|
||||
text(
|
||||
"UPDATE whatsapp_log SET message_text = command "
|
||||
"WHERE (message_text IS NULL OR message_text = '') "
|
||||
"AND command IS NOT NULL AND command != ''"
|
||||
)
|
||||
)
|
||||
await conn.execute(text("ALTER TABLE whatsapp_log DROP COLUMN command"))
|
||||
logger.info("Dropped obsolete whatsapp_log.command column (legacy database)")
|
||||
|
||||
result = await conn.execute(
|
||||
text(
|
||||
"UPDATE categories SET name = 'Missing Item' "
|
||||
|
||||
Reference in New Issue
Block a user