Spaces:
Sleeping
Sleeping
| """Pattern library service - wraps ArchitectureMemory with consistent error handling.""" | |
| import logging | |
| from typing import Any | |
| from fastapi import HTTPException | |
| from app.core.architecture_memory import get_architecture_memory, ArchitectureMemory | |
| logger = logging.getLogger("specs-before-code-api.services.architecture_patterns") | |
| class PatternService: | |
| """Facade over ArchitectureMemory (Redis-backed pattern library).""" | |
| def __init__(self) -> None: | |
| self._memory: ArchitectureMemory = get_architecture_memory() | |
| def is_configured(self) -> bool: | |
| return self._memory.is_configured | |
| async def list_patterns( | |
| self, | |
| tag: str | None = None, | |
| search: str | None = None, | |
| ) -> dict[str, Any]: | |
| if not self._memory.is_configured: | |
| return {"patterns": [], "message": "Redis not configured"} | |
| try: | |
| if tag: | |
| patterns = await self._memory.get_patterns_by_tag(tag) | |
| elif search: | |
| patterns = await self._memory.search_patterns(search) | |
| else: | |
| patterns = await self._memory.get_all_patterns() | |
| return { | |
| "patterns": [ | |
| { | |
| "id": p.id, | |
| "name": p.name, | |
| "description": p.description, | |
| "use_cases": p.use_cases, | |
| "tags": p.tags, | |
| "components": p.components, | |
| "pros": p.pros, | |
| "cons": p.cons, | |
| "tech_stack": p.tech_stack, | |
| "estimated_cost": p.estimated_cost, | |
| "estimated_setup_time": p.estimated_setup_time, | |
| } | |
| for p in patterns | |
| ] | |
| } | |
| except Exception as e: | |
| logger.error("Failed to list patterns: %s", e) | |
| return {"error": str(e)} | |
| async def get_pattern(self, pattern_id: str) -> dict[str, Any]: | |
| if not self._memory.is_configured: | |
| return {"error": "Redis not configured"} | |
| try: | |
| pattern = await self._memory.get_pattern(pattern_id) | |
| if not pattern: | |
| return {"error": "Pattern not found"} | |
| return { | |
| "id": pattern.id, | |
| "name": pattern.name, | |
| "description": pattern.description, | |
| "use_cases": pattern.use_cases, | |
| "tags": pattern.tags, | |
| "components": pattern.components, | |
| "pros": pattern.pros, | |
| "cons": pattern.cons, | |
| "tech_stack": pattern.tech_stack, | |
| "estimated_cost": pattern.estimated_cost, | |
| "estimated_setup_time": pattern.estimated_setup_time, | |
| } | |
| except Exception as e: | |
| logger.error("Failed to get pattern %s: %s", pattern_id, e) | |
| return {"error": str(e)} | |
| async def seed_patterns(self) -> dict[str, Any]: | |
| if not self._memory.is_configured: | |
| return {"error": "Redis not configured"} | |
| try: | |
| seeded = await self._memory.seed_default_patterns() | |
| return {"message": f"Seeded {seeded} default patterns", "seeded_count": seeded} | |
| except Exception as e: | |
| logger.error("Failed to seed patterns: %s", e) | |
| return {"error": str(e)} | |
| async def import_to_session(self, pattern_id: str) -> dict[str, Any] | None: | |
| """Fetch a pattern; returns the raw pattern dict or raises HTTPException.""" | |
| if not self._memory.is_configured: | |
| raise HTTPException(status_code=503, detail="Pattern library not available") | |
| pattern = await self._memory.get_pattern(pattern_id) | |
| if not pattern: | |
| raise HTTPException(status_code=404, detail="Pattern not found") | |
| return { | |
| "id": pattern.id, | |
| "name": pattern.name, | |
| "description": pattern.description, | |
| "use_cases": pattern.use_cases, | |
| "tags": pattern.tags, | |
| "components": pattern.components, | |
| "pros": pattern.pros, | |
| "cons": pattern.cons, | |
| "tech_stack": pattern.tech_stack, | |
| "estimated_cost": pattern.estimated_cost, | |
| "estimated_setup_time": pattern.estimated_setup_time, | |
| } | |
| async def get_pattern_raw(self, pattern_id: str) -> Any | None: | |
| if not self._memory.is_configured: | |
| raise HTTPException(status_code=503, detail="Pattern library not available") | |
| return await self._memory.get_pattern(pattern_id) | |