Fix 500 on /play/<token>/revise for missing revision_count column

Deployed DBs persisted without the revision_count column / revision_history
table, causing customer revision requests to 500.

- init_db() now migrates existing tables by adding missing columns.
- log_revision() falls back to init_db() on missing table for full repair.
- Bump version 0.4.1 -> 0.4.2.
This commit is contained in:
Troll (Hermes Agent) 2026-08-05 13:51:53 +00:00
parent 3f9de1449c
commit f5d3d487af
3 changed files with 34 additions and 7 deletions

View file

@ -20,6 +20,7 @@ Schema overview (see SCHEMA constant):
import sqlite3
import secrets
from datetime import datetime, timezone
from pathlib import Path
from flask import current_app, g
# SQL executed by init_db() to create the requests table and indexes.
@ -89,9 +90,35 @@ def close_db(e=None):
def init_db():
"""Create the database file and tables. Safe to run multiple times."""
db = sqlite3.connect(current_app.config['DATABASE'])
"""Create the database file and tables, adding any missing columns to existing tables."""
db_path = current_app.config['DATABASE']
Path(db_path).parent.mkdir(parents=True, exist_ok=True)
db = sqlite3.connect(db_path)
db.row_factory = sqlite3.Row
db.executescript(SCHEMA)
# SQLite ALTER TABLE is limited; add newer columns if they are missing.
expected_columns = {
'requests': [
'id', 'created_at', 'name', 'email', 'hobbies', 'notable_facts',
'style_genre', 'extra_requests', 'status', 'suno_title', 'suno_style',
'suno_lyrics', 'song_a_path', 'song_b_path', 'vocal_gender',
'customer_approved', 'approval_notified_at', 'preview_sent_at',
'delivery_sent_at', 'square_payment_ref', 'admin_alert_email',
'player_token', 'revision_count', 'revision_note', 'operator_notes',
'stems_link'
],
'revision_history': [
'id', 'created_at', 'request_id', 'revision_count', 'note',
'old_song_a_path', 'old_song_b_path', 'new_song_a_path', 'new_song_b_path'
]
}
for table, columns in expected_columns.items():
existing = {r['name'] for r in db.execute(f"PRAGMA table_info({table})")}
for col in columns:
if col not in existing:
# Use a safe default type; NULLable for all current optional columns.
db.execute(f'ALTER TABLE {table} ADD COLUMN {col} TEXT')
db.commit()
db.close()
@ -184,7 +211,7 @@ def delete_request(request_id):
def log_revision(request_id, revision_count, note, old_a=None, old_b=None, new_a=None, new_b=None):
"""Record a revision event in the revision_history table, creating the table if it is missing."""
"""Record a revision event in the revision_history table, creating it if it is missing."""
db = get_db()
try:
db.execute(
@ -196,8 +223,8 @@ def log_revision(request_id, revision_count, note, old_a=None, old_b=None, new_a
db.commit()
except sqlite3.OperationalError as e:
if 'no such table' in str(e):
# Schema drift: table missing. Recreate and retry once.
db.executescript(SCHEMA)
# Schema drift: table missing. Run init_db to add tables/columns, then retry once.
init_db()
db.execute(
"""INSERT INTO revision_history
(request_id, revision_count, note, old_song_a_path, old_song_b_path, new_song_a_path, new_song_b_path)