Spaces:
Sleeping
Sleeping
| """Thư viện drill chuẩn hệ thống — đọc từ `app/drills.json` (BRIEF 04/08/2026). | |
| File JSON trong repo chứ KHÔNG phải bảng `drills` trong DB, cố ý (khác design | |
| FullVision §7): Space không có Postgres vẫn phải demo được F3 — degraded mode | |
| là công dân hạng nhất. Bảng `drills` (tenant/HLV soạn) thuộc BRIEF sau khi có | |
| auth/roles. Vì thế `/api/drills` sống từ giây đầu boot, không cần engine/DB. | |
| Module cố ý KHÔNG import pooltool/poolcoach_rl — cùng lý do `app/db.py`: | |
| đọc drill không được kéo 40s JIT vào. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| from pathlib import Path | |
| DRILLS_FILE = Path(__file__).resolve().parent / "drills.json" | |
| _cache: dict[str, dict] | None = None | |
| def all_drills() -> dict[str, dict]: | |
| """{id: drill} theo thứ tự file — nạp lần đầu rồi cache (file nằm trong | |
| repo, đổi nội dung là một lần deploy mới, không cần invalidate).""" | |
| global _cache | |
| if _cache is None: | |
| data = json.loads(DRILLS_FILE.read_text(encoding="utf-8")) | |
| _cache = {d["id"]: d for d in data["drills"]} | |
| return _cache | |
| def get_drill(drill_id: str) -> dict | None: | |
| return all_drills().get(drill_id) | |