#!/usr/bin/env python3 from __future__ import annotations import argparse import hashlib import json import sys from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[1] API_ROOT = REPO_ROOT / "apps" / "api" sys.path.insert(0, str(API_ROOT)) from app.services.case_worksheet_rubric import load_rubric, validate_rubric # noqa: E402 from app.session_read_model import case_worksheet_template_item_keys # noqa: E402 def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="Validate the case worksheet rubric scaffold.") parser.add_argument( "--rubric", default=str(REPO_ROOT / "data" / "rubrics" / "case-worksheet-rubric.json"), ) parser.add_argument("--json", action="store_true") return parser def main() -> int: args = build_parser().parse_args() rubric_path = Path(args.rubric) report = validate_rubric( load_rubric(rubric_path), expected_item_keys=case_worksheet_template_item_keys(), ) content = rubric_path.read_bytes() report["rubric_path"] = _display_path(rubric_path) report["content_sha256"] = hashlib.sha256(content).hexdigest() if args.json: print(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True)) else: status = "PASS" if report["passed"] else "FAIL" print( f"{status}: {report['rubric_id']} status={report['status']} " f"sections={report['sections_total']} items={report['items_total']} " f"scoring_enabled={str(report['scoring_enabled']).lower()}" ) for warning in report["warnings"]: print(f"WARN: {warning}") for error in report["errors"]: print(f"ERROR: {error}") return 0 if report["passed"] else 1 def _display_path(path: Path) -> str: try: return path.resolve().relative_to(REPO_ROOT).as_posix() except ValueError: return str(path) if __name__ == "__main__": raise SystemExit(main())