diff --git a/backend/migrate_add_mic_unit_pref.py b/backend/migrate_add_mic_unit_pref.py new file mode 100644 index 0000000..b471949 --- /dev/null +++ b/backend/migrate_add_mic_unit_pref.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +""" +Database migration: Add mic_unit_pref column to user_preferences. + +Adds a single field controlling the mic channel's unit on the event- +report waveform chart in the SFM event detail modal. "dBL" (default) +or "psi". Peaks and KPI tiles elsewhere are always dBL regardless. + +Idempotent — safe to re-run. +""" + +import sqlite3 +from pathlib import Path + + +def migrate(): + possible_paths = [ + Path("data/seismo_fleet.db"), + Path("data/sfm.db"), + Path("data/seismo.db"), + ] + db_path = next((p for p in possible_paths if p.exists()), None) + if db_path is None: + print(f"Database not found in any of: {[str(p) for p in possible_paths]}") + print("Will be created with the new column when models.py initialises.") + return + + print(f"Using database: {db_path}") + conn = sqlite3.connect(db_path) + cur = conn.cursor() + + cur.execute("PRAGMA table_info(user_preferences)") + existing = {row[1] for row in cur.fetchall()} + + if "mic_unit_pref" in existing: + print("mic_unit_pref already exists — nothing to do.") + conn.close() + return + + cur.execute( + "ALTER TABLE user_preferences " + "ADD COLUMN mic_unit_pref TEXT DEFAULT 'dBL'" + ) + # Backfill the single row that should exist (id=1) to the default, + # in case the column ends up NULL on existing rows. + cur.execute( + "UPDATE user_preferences SET mic_unit_pref = 'dBL' " + "WHERE mic_unit_pref IS NULL" + ) + conn.commit() + conn.close() + print("Added mic_unit_pref to user_preferences (default 'dBL').") + + +if __name__ == "__main__": + migrate() diff --git a/backend/models.py b/backend/models.py index 3ba1e11..5be50ea 100644 --- a/backend/models.py +++ b/backend/models.py @@ -135,6 +135,9 @@ class UserPreferences(Base): calibration_warning_days = Column(Integer, default=30) status_ok_threshold_hours = Column(Integer, default=12) status_pending_threshold_hours = Column(Integer, default=24) + # Mic display units on the event-report waveform chart only — peaks + # and KPI tiles elsewhere are always dBL. "dBL" (default) or "psi". + mic_unit_pref = Column(String, default="dBL") updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) diff --git a/backend/routers/settings.py b/backend/routers/settings.py index e32f4d6..3b01e70 100644 --- a/backend/routers/settings.py +++ b/backend/routers/settings.py @@ -267,6 +267,7 @@ class PreferencesUpdate(BaseModel): calibration_warning_days: Optional[int] = None status_ok_threshold_hours: Optional[int] = None status_pending_threshold_hours: Optional[int] = None + mic_unit_pref: Optional[str] = None @router.get("/preferences") @@ -293,6 +294,7 @@ def get_preferences(db: Session = Depends(get_db)): "calibration_warning_days": prefs.calibration_warning_days, "status_ok_threshold_hours": prefs.status_ok_threshold_hours, "status_pending_threshold_hours": prefs.status_pending_threshold_hours, + "mic_unit_pref": prefs.mic_unit_pref or "dBL", "updated_at": prefs.updated_at.isoformat() if prefs.updated_at else None } @@ -334,6 +336,7 @@ def update_preferences( "calibration_warning_days": prefs.calibration_warning_days, "status_ok_threshold_hours": prefs.status_ok_threshold_hours, "status_pending_threshold_hours": prefs.status_pending_threshold_hours, + "mic_unit_pref": prefs.mic_unit_pref or "dBL", "updated_at": prefs.updated_at.isoformat() if prefs.updated_at else None } diff --git a/templates/settings.html b/templates/settings.html index ba5532e..662a70e 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -122,6 +122,21 @@ How often the dashboard should refresh automatically

+ + +
+ + +

+ Applies only to the waveform chart inside the event detail modal. Peak values everywhere else (tables, KPIs, modal summary) stay in dB(L) regardless. +

+