Files
nat-as-server/scripts/generate_dev_fixture.py

127 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""Generate dev-test-fixture.json for admin Dev tab import."""
import json
from pathlib import Path
PREFIX = "dev_"
PASSWORD = "socialvrlab"
CLIENT_PREFIX = "DEV-CL-"
SCALE = 5
# Newest questionnaire bundle (repo root); IDs are read from this file when present.
BUNDLE_PATH = Path(__file__).resolve().parents[2] / "questionnaires_bundle_2026-05-28.json"
FALLBACK_QUESTIONNAIRE_IDS = [
"questionnaire_1_demographic_information",
"questionnaire_2_rhs",
"questionnaire_3_integration_index",
"questionnaire_4_consultation_results",
"questionnaire_5_final_interview",
"questionnaire_6_follow_up_survey",
]
PER_QUESTIONNAIRE = 40 * SCALE
NUM_ADMINS = 2 * SCALE
NUM_SUPERVISORS = 3 * SCALE
NUM_COACHES = 20 * SCALE
NUM_CLIENTS = 100 * SCALE
CLIENTS_WITHOUT_COMPLETIONS = 15 * SCALE
def load_questionnaire_ids() -> list[str]:
if not BUNDLE_PATH.is_file():
return FALLBACK_QUESTIONNAIRE_IDS
bundle = json.loads(BUNDLE_PATH.read_text(encoding="utf-8"))
ids = [
item["questionnaire"]["questionnaireID"]
for item in bundle.get("questionnaires", [])
if item.get("questionnaire", {}).get("questionnaireID")
]
return ids or FALLBACK_QUESTIONNAIRE_IDS
def main():
questionnaire_ids = load_questionnaire_ids()
admins = [
{"username": f"{PREFIX}admin_{i}", "location": f"Dev Admin Standort {i}"}
for i in range(1, NUM_ADMINS + 1)
]
supervisors = [
{"username": f"{PREFIX}supervisor_{i}", "location": f"Dev Supervisor Region {i}"}
for i in range(1, NUM_SUPERVISORS + 1)
]
coaches = []
for i in range(1, NUM_COACHES + 1):
sv = (i - 1) % NUM_SUPERVISORS + 1
coaches.append({
"username": f"{PREFIX}coach_{i:02d}",
"supervisor": f"{PREFIX}supervisor_{sv}",
})
clients = []
for i in range(1, NUM_CLIENTS + 1):
coach_idx = (i - 1) // 5 + 1
if coach_idx > NUM_COACHES:
coach_idx = NUM_COACHES
clients.append({
"clientCode": f"{CLIENT_PREFIX}{i:04d}",
"coach": f"{PREFIX}coach_{coach_idx:02d}",
})
clients_with_data = [
c["clientCode"]
for c in clients
if int(c["clientCode"].split("-")[-1]) <= NUM_CLIENTS - CLIENTS_WITHOUT_COMPLETIONS
]
completions = []
slot = 0
for qn_id in questionnaire_ids:
for _ in range(PER_QUESTIONNAIRE):
client_code = clients_with_data[slot % len(clients_with_data)]
completions.append({
"clientCode": client_code,
"questionnaireID": qn_id,
})
slot += 1
bundle_note = BUNDLE_PATH.name if BUNDLE_PATH.is_file() else "fallback questionnaire list"
fixture = {
"fixtureVersion": 1,
"description": (
f"Dev/test users, clients, and completed questionnaires ({SCALE}x scale). "
f"Questionnaires aligned with {bundle_note}. Skip-on-conflict import; password socialvrlab."
),
"prefix": PREFIX,
"defaultPassword": PASSWORD,
"sourceBundle": bundle_note,
"questionnaireIDs": questionnaire_ids,
"admins": admins,
"supervisors": supervisors,
"coaches": coaches,
"clients": clients,
"completions": completions,
"stats": {
"scale": SCALE,
"admins": len(admins),
"supervisors": len(supervisors),
"coaches": len(coaches),
"clients": len(clients),
"clientsWithoutCompletions": CLIENTS_WITHOUT_COMPLETIONS,
"completions": len(completions),
"perQuestionnaire": PER_QUESTIONNAIRE,
"questionnaires": len(questionnaire_ids),
},
}
out = Path(__file__).resolve().parents[2] / "dev-test-fixture.json"
out.write_text(json.dumps(fixture, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
print(f"Wrote {out}")
print(json.dumps(fixture["stats"], indent=2))
if __name__ == "__main__":
main()