feat: add data collection mode to projects with UI updates and migration script

This commit is contained in:
2026-03-05 21:50:41 +00:00
parent ef8c046f31
commit 015ce0a254
6 changed files with 181 additions and 4 deletions

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""
Migration: Add data_collection_mode column to projects table.
Values:
"remote" — units have modems; data pulled via FTP/scheduler automatically
"manual" — no modem; SD cards retrieved daily and uploaded by hand
All existing projects are backfilled to "manual" (safe conservative default).
Run once inside the Docker container:
docker exec terra-view python3 backend/migrate_add_project_data_collection_mode.py
"""
from pathlib import Path
DB_PATH = Path("data/seismo_fleet.db")
def migrate():
import sqlite3
if not DB_PATH.exists():
print(f"Database not found at {DB_PATH}. Are you running from /home/serversdown/terra-view?")
return
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
cur = conn.cursor()
# ── 1. Add column (idempotent) ───────────────────────────────────────────
cur.execute("PRAGMA table_info(projects)")
existing_cols = {row["name"] for row in cur.fetchall()}
if "data_collection_mode" not in existing_cols:
cur.execute("ALTER TABLE projects ADD COLUMN data_collection_mode TEXT DEFAULT 'manual'")
conn.commit()
print("✓ Added column data_collection_mode to projects")
else:
print("○ Column data_collection_mode already exists — skipping ALTER TABLE")
# ── 2. Backfill NULLs to 'manual' ────────────────────────────────────────
cur.execute("UPDATE projects SET data_collection_mode = 'manual' WHERE data_collection_mode IS NULL")
updated = cur.rowcount
conn.commit()
conn.close()
if updated:
print(f"✓ Backfilled {updated} project(s) to data_collection_mode='manual'.")
print("Migration complete.")
if __name__ == "__main__":
migrate()

View File

@@ -157,6 +157,11 @@ class Project(Base):
project_type_id = Column(String, nullable=False) # FK to ProjectType.id
status = Column(String, default="active") # active, on_hold, completed, archived, deleted
# Data collection mode: how field data reaches Terra-View.
# "remote" — units have modems; data pulled via FTP/scheduler automatically
# "manual" — no modem; SD cards retrieved daily and uploaded by hand
data_collection_mode = Column(String, default="manual") # remote | manual
# Project metadata
client_name = Column(String, nullable=True, index=True) # Client name (e.g., "PJ Dick")
site_address = Column(String, nullable=True)

View File

@@ -613,6 +613,7 @@ async def get_project(project_id: str, db: Session = Depends(get_db)):
"site_coordinates": project.site_coordinates,
"start_date": project.start_date.isoformat() if project.start_date else None,
"end_date": project.end_date.isoformat() if project.end_date else None,
"data_collection_mode": project.data_collection_mode or "manual",
"created_at": project.created_at.isoformat(),
"updated_at": project.updated_at.isoformat(),
}
@@ -659,6 +660,8 @@ async def update_project(
project.start_date = datetime.fromisoformat(data["start_date"]) if data["start_date"] else None
if "end_date" in data:
project.end_date = datetime.fromisoformat(data["end_date"]) if data["end_date"] else None
if "data_collection_mode" in data and data["data_collection_mode"] in ("remote", "manual"):
project.data_collection_mode = data["data_collection_mode"]
project.updated_at = datetime.utcnow()