File size: 4,669 Bytes
e382248
b7e4cb3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""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()

    @property
    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)