from __future__ import annotations import json from pathlib import Path from typing import Dict, List, Optional from fastapi import HTTPException from ..schemas import TemplateCreate, TemplateRecord, TemplateUpdate class TemplateStore: """Simple JSON-file based store for template definitions.""" def __init__(self, data_path: Path): self.data_path = data_path self.data_path.parent.mkdir(parents=True, exist_ok=True) if not self.data_path.exists(): self.data_path.write_text(json.dumps([], ensure_ascii=False, indent=2)) self._cache: Dict[str, TemplateRecord] = {} self._load() def _load(self) -> None: raw = json.loads(self.data_path.read_text()) self._cache = {item["id"]: TemplateRecord(**item) for item in raw} def _persist(self) -> None: # Use JSON mode so datetime fields are converted to ISO strings. serializable = [record.model_dump(mode="json") for record in self._cache.values()] self.data_path.write_text( json.dumps(serializable, ensure_ascii=False, indent=2) ) def list_templates(self) -> List[TemplateRecord]: return list(self._cache.values()) def get_template(self, template_id: str) -> TemplateRecord: try: return self._cache[template_id] except KeyError as exc: raise HTTPException(status_code=404, detail="模板不存在") from exc def create_template(self, payload: TemplateCreate) -> TemplateRecord: record = TemplateRecord(**payload.model_dump()) self._cache[record.id] = record self._persist() return record def update_template(self, template_id: str, payload: TemplateUpdate) -> TemplateRecord: record = self.get_template(template_id) update_data = payload.model_dump(exclude_none=True) updated = record.model_copy(update=update_data) from datetime import datetime updated.updated_at = datetime.utcnow() self._cache[template_id] = updated self._persist() return updated def delete_template(self, template_id: str) -> None: if template_id not in self._cache: raise HTTPException(status_code=404, detail="模板不存在") del self._cache[template_id] self._persist() def list_categories(self) -> List[str]: categories = {record.category for record in self._cache.values()} return sorted(categories) def load_store(base_dir: Path) -> TemplateStore: data_path = base_dir / "data" / "templates.json" return TemplateStore(data_path)