HormoneTrack/scripts/seed-emulator.py

92 lines
3.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""Seed la DB Room d'un émulateur avec un backup JSON exporté par l'app.
OUTIL DE TEST MANUEL (post-v1.3.4) — cf recette complète dans
docs/DEVELOPPEMENT.md §16.ter « Test manuel sur émulateur ».
Constitue l'étape « données réelles dans l'émulateur » : lance l'APK debug une
fois (crée la DB via Room), récupère la DB via run-as, injecte les lignes du
backup passé en argument (SANS toucher au schéma ni à room_master_table — Room
valide le schéma, pas les lignes), puis la repousse.
Usage (le téléphone = émulateur démarré, avec com.hormonetrack - APK DEBUG -
installé et lancé au moins une fois) :
adb shell am force-stop com.hormonetrack
adb shell run-as com.hormonetrack cat databases/hormonetrack.db > /tmp/hrt.db
python3 scripts/seed-emulator.py /tmp/hrt.db <backup.json> # modifie la BD locale
adb push /tmp/hrt.db /data/local/tmp/hrt.db
adb shell run-as com.hormonetrack cp /data/local/tmp/hrt.db databases/hormonetrack.db
adb shell run-as com.hormonetrack rm -f databases/hormonetrack.db-wal databases/hormonetrack.db-shm
⚠️ PRIVATITÉ : le fichier backup contient des données de santé personnelles et
vit sous `local-test-data/` (gitignoré, cf §8.bis). Ce script ne contains
AUCUNE donnée : tout passe par arguments/lignes insérées à l'exécution. Ne
JAMAIS copier un backup dans le dépôt ni en nommer dans les commentaires.
"""
import json
import sqlite3
import sys
def main():
if len(sys.argv) != 3:
sys.exit("usage: seed-emulator.py <db-sqlite> <backup.json>")
db_path, backup_path = sys.argv[1], sys.argv[2]
data = json.load(open(backup_path, encoding="utf-8"))
con = sqlite3.connect(db_path)
cur = con.cursor()
# ⚠️ Les colonnes portent les noms des propriétés Kotlin SANS renommage
# (Room ne convertit pas en snake_case) ; les enums sont stockés en String.
for tr in data["treatments"]:
cur.execute(
"INSERT OR REPLACE INTO treatments (id, name, type, route, doseAmount,"
" doseUnit, isActive, notes, esterType, pkModel, absorptionHours,"
" eliminationHalfLifeHours, bioavailabilityFraction, scaleFactor,"
" forecastIntervalDays, reminderHour, reminderMinute, reminderEnabled,"
" calendarEventId, createdAt)"
" VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
(
tr["id"], tr["name"], tr["type"], tr["route"], tr["doseAmount"],
tr["doseUnit"], tr["isActive"], tr.get("notes"),
tr.get("esterType", "NONE"), tr.get("pkModel", "ESE"),
tr.get("absorptionHours", 4.0),
tr.get("eliminationHalfLifeHours", 24.0),
tr.get("bioavailabilityFraction", 1.0), tr.get("scaleFactor", 1.0),
tr.get("forecastIntervalDays"), tr.get("reminderHour"),
tr.get("reminderMinute"), tr.get("reminderEnabled", False),
tr.get("calendarEventId"), tr["createdAt"],
),
)
for d in data["doseLogs"]:
cur.execute(
"INSERT OR REPLACE INTO dose_logs (id, treatmentId, timestamp,"
" doseAmount, notes, esterType) VALUES (?,?,?,?,?,?)",
(d["id"], d["treatmentId"], d["timestamp"], d["doseAmount"],
d.get("notes"), d.get("esterType")),
)
for l in data["labResults"]:
cur.execute(
"INSERT OR REPLACE INTO lab_results (id, marker, value, unit,"
" timestamp, notes) VALUES (?,?,?,?,?,?)",
(l["id"], l["marker"], l["value"], l["unit"], l["timestamp"],
l.get("notes")),
)
con.commit()
cur.execute(
"SELECT (SELECT COUNT(*) FROM treatments), (SELECT COUNT(*) FROM dose_logs),"
" (SELECT COUNT(*) FROM lab_results)")
t, d, l = cur.fetchone()
print(f"seed OK : {t} traitements, {d} doses, {l} labs")
con.close()
if __name__ == "__main__":
main()