import os import sys import json import glob from pathlib import Path sys.stdout.reconfigure(encoding='utf-8') def validate_scenario_json(target_project_id=None): # 1. Load A13.json schema keys with open('data/A13.json', 'r', encoding='utf-8') as f: template = json.load(f) top_keys = set(template.keys()) mission_keys = set(template['missions'][0].keys()) guide_step_keys = set(template['missions'][0]['guideSteps'][0].keys()) print("=" * 60) print("A13.json Schema Reference:") print(f" Top-level keys ({len(top_keys)}): {sorted(top_keys)}") print(f" Mission keys ({len(mission_keys)}): {sorted(mission_keys)}") print(f" GuideStep keys ({len(guide_step_keys)}): {sorted(guide_step_keys)}") print("=" * 60) if target_project_id: json_files = sorted(glob.glob(f'scenario_json/{target_project_id}.json')) else: json_files = sorted(glob.glob('scenario_json/*.json')) print(f"Found {len(json_files)} generated JSON files to validate.") errors = [] for jf in json_files: fname = Path(jf).name with open(jf, 'r', encoding='utf-8') as f: try: data = json.load(f) except Exception as e: errors.append(f"[{fname}] Invalid JSON format: {e}") continue # Validate Top-level keys missing_top = top_keys - set(data.keys()) if missing_top: errors.append(f"[{fname}] Missing top-level keys: {missing_top}") # Validate Summary is empty string as requested if data.get('summary') != "": errors.append(f"[{fname}] summary is not empty string: {data.get('summary')}") # Validate Objectives exists and not empty obj_text = data.get('objectives', '') if not obj_text or len(obj_text.strip()) == 0: errors.append(f"[{fname}] objectives is empty") # Validate Missions count missions = data.get('missions', []) if len(missions) != 10: errors.append(f"[{fname}] Invalid missions count: {len(missions)} (expected 10)") # Validate Mission fields for idx, m in enumerate(missions, start=1): m_id = m.get('id', f'M{idx}') missing_m_keys = mission_keys - set(m.keys()) if missing_m_keys: errors.append(f"[{fname} -> {m_id}] Missing mission keys: {missing_m_keys}") if m.get('sequence') != idx: errors.append(f"[{fname} -> {m_id}] Invalid sequence: {m.get('sequence')} (expected {idx})") if not m.get('overview'): errors.append(f"[{fname} -> {m_id}] overview is empty") if not m.get('objectives'): errors.append(f"[{fname} -> {m_id}] objectives is empty") # Validate guideSteps g_steps = m.get('guideSteps', []) if not g_steps: errors.append(f"[{fname} -> {m_id}] guideSteps is empty") for s in g_steps: missing_step_keys = guide_step_keys - set(s.keys()) if missing_step_keys: errors.append(f"[{fname} -> {m_id} -> Step {s.get('step')}] Missing step keys: {missing_step_keys}") print("\nValidation Results:") if errors: print(f" ❌ Validation Failed with {len(errors)} errors:") for err in errors[:20]: print(f" - {err}") else: print(f" ✅ All {len(json_files)} JSON files perfectly passed schema validation!") print(" - All top-level keys matched A13.json") print(" - All missions verified (10 per project)") print(" - All guideSteps, evaluationKeys, objectives/overview structured properly") print(" - Summary field set to empty string") print("=" * 60) if __name__ == '__main__': target = sys.argv[1] if len(sys.argv) > 1 else None validate_scenario_json(target)