feat: Refactor project creation and management to support modular project types
- Updated project creation modal to allow selection of optional modules (Sound and Vibration Monitoring). - Modified project dashboard and header to display active modules and provide options to add/remove them. - Enhanced project detail view to dynamically adjust UI based on enabled modules. - Implemented a new migration script to create a `project_modules` table and seed it based on existing project types. - Adjusted form submissions to handle module selections and ensure proper API interactions for module management.
This commit is contained in:
71
backend/migrate_add_project_modules.py
Normal file
71
backend/migrate_add_project_modules.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
Migration: Add project_modules table and seed from existing project_type_id values.
|
||||
|
||||
Safe to run multiple times — idempotent.
|
||||
"""
|
||||
import sqlite3
|
||||
import uuid
|
||||
import os
|
||||
|
||||
DB_PATH = os.path.join(os.path.dirname(__file__), "..", "data", "seismo_fleet.db")
|
||||
DB_PATH = os.path.abspath(DB_PATH)
|
||||
|
||||
|
||||
def run():
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
conn.row_factory = sqlite3.Row
|
||||
cur = conn.cursor()
|
||||
|
||||
# 1. Create project_modules table if not exists
|
||||
cur.execute("""
|
||||
CREATE TABLE IF NOT EXISTS project_modules (
|
||||
id TEXT PRIMARY KEY,
|
||||
project_id TEXT NOT NULL,
|
||||
module_type TEXT NOT NULL,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(project_id, module_type)
|
||||
)
|
||||
""")
|
||||
print(" Table 'project_modules' ready.")
|
||||
|
||||
# 2. Seed modules from existing project_type_id values
|
||||
cur.execute("SELECT id, project_type_id FROM projects WHERE project_type_id IS NOT NULL")
|
||||
projects = cur.fetchall()
|
||||
|
||||
seeded = 0
|
||||
for p in projects:
|
||||
pid = p["id"]
|
||||
ptype = p["project_type_id"]
|
||||
|
||||
modules_to_add = []
|
||||
if ptype == "sound_monitoring":
|
||||
modules_to_add = ["sound_monitoring"]
|
||||
elif ptype == "vibration_monitoring":
|
||||
modules_to_add = ["vibration_monitoring"]
|
||||
elif ptype == "combined":
|
||||
modules_to_add = ["sound_monitoring", "vibration_monitoring"]
|
||||
|
||||
for module_type in modules_to_add:
|
||||
# INSERT OR IGNORE — skip if already exists
|
||||
cur.execute("""
|
||||
INSERT OR IGNORE INTO project_modules (id, project_id, module_type, enabled)
|
||||
VALUES (?, ?, ?, 1)
|
||||
""", (str(uuid.uuid4()), pid, module_type))
|
||||
if cur.rowcount > 0:
|
||||
seeded += 1
|
||||
|
||||
conn.commit()
|
||||
print(f" Seeded {seeded} module record(s) from existing project_type_id values.")
|
||||
|
||||
# 3. Make project_type_id nullable (SQLite doesn't support ALTER COLUMN,
|
||||
# but since we're just loosening a constraint this is a no-op in SQLite —
|
||||
# the column already accepts NULL in practice. Nothing to do.)
|
||||
print(" project_type_id column is now treated as nullable (legacy field).")
|
||||
|
||||
conn.close()
|
||||
print("Migration complete.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
Reference in New Issue
Block a user