julee 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- julee/__init__.py +1 -1
- julee/api/tests/routers/test_assembly_specifications.py +2 -0
- julee/api/tests/routers/test_documents.py +2 -0
- julee/api/tests/routers/test_knowledge_service_configs.py +2 -0
- julee/api/tests/routers/test_knowledge_service_queries.py +2 -0
- julee/api/tests/routers/test_system.py +2 -0
- julee/api/tests/routers/test_workflows.py +2 -0
- julee/api/tests/test_app.py +2 -0
- julee/api/tests/test_dependencies.py +2 -0
- julee/api/tests/test_requests.py +2 -0
- julee/contrib/polling/__init__.py +22 -19
- julee/contrib/polling/apps/__init__.py +17 -0
- julee/contrib/polling/apps/worker/__init__.py +17 -0
- julee/contrib/polling/apps/worker/pipelines.py +288 -0
- julee/contrib/polling/domain/__init__.py +7 -9
- julee/contrib/polling/domain/models/__init__.py +6 -7
- julee/contrib/polling/domain/models/polling_config.py +18 -1
- julee/contrib/polling/domain/services/__init__.py +6 -5
- julee/contrib/polling/domain/services/poller.py +1 -1
- julee/contrib/polling/infrastructure/__init__.py +9 -8
- julee/contrib/polling/infrastructure/services/__init__.py +6 -5
- julee/contrib/polling/infrastructure/services/polling/__init__.py +6 -5
- julee/contrib/polling/infrastructure/services/polling/http/__init__.py +6 -5
- julee/contrib/polling/infrastructure/services/polling/http/http_poller_service.py +5 -2
- julee/contrib/polling/infrastructure/temporal/__init__.py +12 -12
- julee/contrib/polling/infrastructure/temporal/activities.py +1 -1
- julee/contrib/polling/infrastructure/temporal/manager.py +291 -0
- julee/contrib/polling/infrastructure/temporal/proxies.py +1 -1
- julee/contrib/polling/tests/unit/apps/worker/test_pipelines.py +580 -0
- julee/contrib/polling/tests/unit/infrastructure/services/polling/http/test_http_poller_service.py +40 -2
- julee/contrib/polling/tests/unit/infrastructure/temporal/__init__.py +7 -0
- julee/contrib/polling/tests/unit/infrastructure/temporal/test_manager.py +475 -0
- julee/docs/sphinx_hcd/__init__.py +146 -13
- julee/docs/sphinx_hcd/domain/__init__.py +5 -0
- julee/docs/sphinx_hcd/domain/models/__init__.py +32 -0
- julee/docs/sphinx_hcd/domain/models/accelerator.py +152 -0
- julee/docs/sphinx_hcd/domain/models/app.py +151 -0
- julee/docs/sphinx_hcd/domain/models/code_info.py +121 -0
- julee/docs/sphinx_hcd/domain/models/epic.py +79 -0
- julee/docs/sphinx_hcd/domain/models/integration.py +230 -0
- julee/docs/sphinx_hcd/domain/models/journey.py +222 -0
- julee/docs/sphinx_hcd/domain/models/persona.py +106 -0
- julee/docs/sphinx_hcd/domain/models/story.py +128 -0
- julee/docs/sphinx_hcd/domain/repositories/__init__.py +25 -0
- julee/docs/sphinx_hcd/domain/repositories/accelerator.py +98 -0
- julee/docs/sphinx_hcd/domain/repositories/app.py +57 -0
- julee/docs/sphinx_hcd/domain/repositories/base.py +89 -0
- julee/docs/sphinx_hcd/domain/repositories/code_info.py +69 -0
- julee/docs/sphinx_hcd/domain/repositories/epic.py +62 -0
- julee/docs/sphinx_hcd/domain/repositories/integration.py +79 -0
- julee/docs/sphinx_hcd/domain/repositories/journey.py +106 -0
- julee/docs/sphinx_hcd/domain/repositories/story.py +68 -0
- julee/docs/sphinx_hcd/domain/use_cases/__init__.py +64 -0
- julee/docs/sphinx_hcd/domain/use_cases/derive_personas.py +166 -0
- julee/docs/sphinx_hcd/domain/use_cases/resolve_accelerator_references.py +236 -0
- julee/docs/sphinx_hcd/domain/use_cases/resolve_app_references.py +144 -0
- julee/docs/sphinx_hcd/domain/use_cases/resolve_story_references.py +121 -0
- julee/docs/sphinx_hcd/parsers/__init__.py +48 -0
- julee/docs/sphinx_hcd/parsers/ast.py +150 -0
- julee/docs/sphinx_hcd/parsers/gherkin.py +155 -0
- julee/docs/sphinx_hcd/parsers/yaml.py +184 -0
- julee/docs/sphinx_hcd/repositories/__init__.py +4 -0
- julee/docs/sphinx_hcd/repositories/memory/__init__.py +25 -0
- julee/docs/sphinx_hcd/repositories/memory/accelerator.py +86 -0
- julee/docs/sphinx_hcd/repositories/memory/app.py +45 -0
- julee/docs/sphinx_hcd/repositories/memory/base.py +106 -0
- julee/docs/sphinx_hcd/repositories/memory/code_info.py +59 -0
- julee/docs/sphinx_hcd/repositories/memory/epic.py +54 -0
- julee/docs/sphinx_hcd/repositories/memory/integration.py +70 -0
- julee/docs/sphinx_hcd/repositories/memory/journey.py +96 -0
- julee/docs/sphinx_hcd/repositories/memory/story.py +63 -0
- julee/docs/sphinx_hcd/sphinx/__init__.py +28 -0
- julee/docs/sphinx_hcd/sphinx/adapters.py +116 -0
- julee/docs/sphinx_hcd/sphinx/context.py +163 -0
- julee/docs/sphinx_hcd/sphinx/directives/__init__.py +160 -0
- julee/docs/sphinx_hcd/sphinx/directives/accelerator.py +576 -0
- julee/docs/sphinx_hcd/sphinx/directives/app.py +349 -0
- julee/docs/sphinx_hcd/sphinx/directives/base.py +211 -0
- julee/docs/sphinx_hcd/sphinx/directives/epic.py +434 -0
- julee/docs/sphinx_hcd/sphinx/directives/integration.py +220 -0
- julee/docs/sphinx_hcd/sphinx/directives/journey.py +642 -0
- julee/docs/sphinx_hcd/sphinx/directives/persona.py +345 -0
- julee/docs/sphinx_hcd/sphinx/directives/story.py +575 -0
- julee/docs/sphinx_hcd/sphinx/event_handlers/__init__.py +16 -0
- julee/docs/sphinx_hcd/sphinx/event_handlers/builder_inited.py +31 -0
- julee/docs/sphinx_hcd/sphinx/event_handlers/doctree_read.py +27 -0
- julee/docs/sphinx_hcd/sphinx/event_handlers/doctree_resolved.py +43 -0
- julee/docs/sphinx_hcd/sphinx/event_handlers/env_purge_doc.py +42 -0
- julee/docs/sphinx_hcd/sphinx/initialization.py +139 -0
- julee/docs/sphinx_hcd/tests/__init__.py +9 -0
- julee/docs/sphinx_hcd/tests/conftest.py +6 -0
- julee/docs/sphinx_hcd/tests/domain/__init__.py +1 -0
- julee/docs/sphinx_hcd/tests/domain/models/__init__.py +1 -0
- julee/docs/sphinx_hcd/tests/domain/models/test_accelerator.py +266 -0
- julee/docs/sphinx_hcd/tests/domain/models/test_app.py +258 -0
- julee/docs/sphinx_hcd/tests/domain/models/test_code_info.py +231 -0
- julee/docs/sphinx_hcd/tests/domain/models/test_epic.py +163 -0
- julee/docs/sphinx_hcd/tests/domain/models/test_integration.py +327 -0
- julee/docs/sphinx_hcd/tests/domain/models/test_journey.py +249 -0
- julee/docs/sphinx_hcd/tests/domain/models/test_persona.py +172 -0
- julee/docs/sphinx_hcd/tests/domain/models/test_story.py +216 -0
- julee/docs/sphinx_hcd/tests/domain/use_cases/__init__.py +1 -0
- julee/docs/sphinx_hcd/tests/domain/use_cases/test_derive_personas.py +314 -0
- julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_accelerator_references.py +476 -0
- julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_app_references.py +265 -0
- julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_story_references.py +229 -0
- julee/docs/sphinx_hcd/tests/integration/__init__.py +1 -0
- julee/docs/sphinx_hcd/tests/parsers/__init__.py +1 -0
- julee/docs/sphinx_hcd/tests/parsers/test_ast.py +298 -0
- julee/docs/sphinx_hcd/tests/parsers/test_gherkin.py +282 -0
- julee/docs/sphinx_hcd/tests/parsers/test_yaml.py +496 -0
- julee/docs/sphinx_hcd/tests/repositories/__init__.py +1 -0
- julee/docs/sphinx_hcd/tests/repositories/test_accelerator.py +298 -0
- julee/docs/sphinx_hcd/tests/repositories/test_app.py +218 -0
- julee/docs/sphinx_hcd/tests/repositories/test_base.py +151 -0
- julee/docs/sphinx_hcd/tests/repositories/test_code_info.py +253 -0
- julee/docs/sphinx_hcd/tests/repositories/test_epic.py +237 -0
- julee/docs/sphinx_hcd/tests/repositories/test_integration.py +268 -0
- julee/docs/sphinx_hcd/tests/repositories/test_journey.py +294 -0
- julee/docs/sphinx_hcd/tests/repositories/test_story.py +236 -0
- julee/docs/sphinx_hcd/tests/sphinx/__init__.py +1 -0
- julee/docs/sphinx_hcd/tests/sphinx/directives/__init__.py +1 -0
- julee/docs/sphinx_hcd/tests/sphinx/directives/test_base.py +160 -0
- julee/docs/sphinx_hcd/tests/sphinx/test_adapters.py +176 -0
- julee/docs/sphinx_hcd/tests/sphinx/test_context.py +257 -0
- julee/domain/models/assembly/tests/test_assembly.py +2 -0
- julee/domain/models/assembly_specification/tests/test_assembly_specification.py +2 -0
- julee/domain/models/assembly_specification/tests/test_knowledge_service_query.py +2 -0
- julee/domain/models/custom_fields/tests/test_custom_fields.py +2 -0
- julee/domain/models/document/tests/test_document.py +2 -0
- julee/domain/models/policy/tests/test_document_policy_validation.py +2 -0
- julee/domain/models/policy/tests/test_policy.py +2 -0
- julee/domain/use_cases/tests/test_extract_assemble_data.py +2 -0
- julee/domain/use_cases/tests/test_initialize_system_data.py +2 -0
- julee/domain/use_cases/tests/test_validate_document.py +2 -0
- julee/maintenance/release.py +10 -5
- julee/repositories/memory/tests/test_document.py +2 -0
- julee/repositories/memory/tests/test_document_policy_validation.py +2 -0
- julee/repositories/memory/tests/test_policy.py +2 -0
- julee/repositories/minio/tests/test_assembly.py +2 -0
- julee/repositories/minio/tests/test_assembly_specification.py +2 -0
- julee/repositories/minio/tests/test_client_protocol.py +3 -0
- julee/repositories/minio/tests/test_document.py +2 -0
- julee/repositories/minio/tests/test_document_policy_validation.py +2 -0
- julee/repositories/minio/tests/test_knowledge_service_config.py +2 -0
- julee/repositories/minio/tests/test_knowledge_service_query.py +2 -0
- julee/repositories/minio/tests/test_policy.py +2 -0
- julee/services/knowledge_service/anthropic/tests/test_knowledge_service.py +2 -0
- julee/services/knowledge_service/memory/test_knowledge_service.py +2 -0
- julee/services/knowledge_service/test_factory.py +2 -0
- julee/util/tests/test_decorators.py +2 -0
- julee-0.1.6.dist-info/METADATA +104 -0
- julee-0.1.6.dist-info/RECORD +288 -0
- julee/docs/sphinx_hcd/accelerators.py +0 -1175
- julee/docs/sphinx_hcd/apps.py +0 -518
- julee/docs/sphinx_hcd/epics.py +0 -453
- julee/docs/sphinx_hcd/integrations.py +0 -310
- julee/docs/sphinx_hcd/journeys.py +0 -797
- julee/docs/sphinx_hcd/personas.py +0 -457
- julee/docs/sphinx_hcd/stories.py +0 -960
- julee-0.1.4.dist-info/METADATA +0 -197
- julee-0.1.4.dist-info/RECORD +0 -196
- {julee-0.1.4.dist-info → julee-0.1.6.dist-info}/WHEEL +0 -0
- {julee-0.1.4.dist-info → julee-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {julee-0.1.4.dist-info → julee-0.1.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Repository protocols for sphinx_hcd.
|
|
2
|
+
|
|
3
|
+
Defines async repository interfaces following julee patterns.
|
|
4
|
+
Implementations live in the repositories/ directory.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .accelerator import AcceleratorRepository
|
|
8
|
+
from .app import AppRepository
|
|
9
|
+
from .base import BaseRepository
|
|
10
|
+
from .code_info import CodeInfoRepository
|
|
11
|
+
from .epic import EpicRepository
|
|
12
|
+
from .integration import IntegrationRepository
|
|
13
|
+
from .journey import JourneyRepository
|
|
14
|
+
from .story import StoryRepository
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"AcceleratorRepository",
|
|
18
|
+
"AppRepository",
|
|
19
|
+
"BaseRepository",
|
|
20
|
+
"CodeInfoRepository",
|
|
21
|
+
"EpicRepository",
|
|
22
|
+
"IntegrationRepository",
|
|
23
|
+
"JourneyRepository",
|
|
24
|
+
"StoryRepository",
|
|
25
|
+
]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""AcceleratorRepository protocol.
|
|
2
|
+
|
|
3
|
+
Defines the interface for accelerator data access.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from ..models.accelerator import Accelerator
|
|
9
|
+
from .base import BaseRepository
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class AcceleratorRepository(BaseRepository[Accelerator], Protocol):
|
|
14
|
+
"""Repository protocol for Accelerator entities.
|
|
15
|
+
|
|
16
|
+
Extends BaseRepository with accelerator-specific query methods.
|
|
17
|
+
Accelerators are defined in RST documents and support incremental builds
|
|
18
|
+
via docname tracking.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
async def get_by_status(self, status: str) -> list[Accelerator]:
|
|
22
|
+
"""Get all accelerators with a specific status.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
status: Status to filter by (case-insensitive)
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List of accelerators with matching status
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
async def get_by_docname(self, docname: str) -> list[Accelerator]:
|
|
33
|
+
"""Get all accelerators defined in a specific document.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
docname: RST document name
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
List of accelerators from that document
|
|
40
|
+
"""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
async def clear_by_docname(self, docname: str) -> int:
|
|
44
|
+
"""Remove all accelerators defined in a specific document.
|
|
45
|
+
|
|
46
|
+
Used during incremental builds when a document is re-read.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
docname: RST document name
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Number of accelerators removed
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
async def get_by_integration(
|
|
57
|
+
self, integration_slug: str, relationship: str
|
|
58
|
+
) -> list[Accelerator]:
|
|
59
|
+
"""Get accelerators that have a relationship with an integration.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
integration_slug: Integration slug to search for
|
|
63
|
+
relationship: Either "sources_from" or "publishes_to"
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
List of accelerators with this integration relationship
|
|
67
|
+
"""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
async def get_dependents(self, accelerator_slug: str) -> list[Accelerator]:
|
|
71
|
+
"""Get accelerators that depend on a specific accelerator.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
accelerator_slug: Slug of the accelerator to find dependents of
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
List of accelerators that have this accelerator in depends_on
|
|
78
|
+
"""
|
|
79
|
+
...
|
|
80
|
+
|
|
81
|
+
async def get_fed_by(self, accelerator_slug: str) -> list[Accelerator]:
|
|
82
|
+
"""Get accelerators that feed into a specific accelerator.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
accelerator_slug: Slug of the accelerator
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
List of accelerators that have this accelerator in feeds_into
|
|
89
|
+
"""
|
|
90
|
+
...
|
|
91
|
+
|
|
92
|
+
async def get_all_statuses(self) -> set[str]:
|
|
93
|
+
"""Get all unique statuses across all accelerators.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
Set of status strings (normalized to lowercase)
|
|
97
|
+
"""
|
|
98
|
+
...
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""AppRepository protocol.
|
|
2
|
+
|
|
3
|
+
Defines the interface for app data access.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from ..models.app import App, AppType
|
|
9
|
+
from .base import BaseRepository
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class AppRepository(BaseRepository[App], Protocol):
|
|
14
|
+
"""Repository protocol for App entities.
|
|
15
|
+
|
|
16
|
+
Extends BaseRepository with app-specific query methods.
|
|
17
|
+
Apps are indexed from YAML manifests and are read-only during
|
|
18
|
+
a Sphinx build (populated at builder-inited, queried during rendering).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
async def get_by_type(self, app_type: AppType) -> list[App]:
|
|
22
|
+
"""Get all apps of a specific type.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
app_type: Application type to filter by
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List of apps matching the type
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
async def get_by_name(self, name: str) -> App | None:
|
|
33
|
+
"""Get an app by its display name (case-insensitive).
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
name: Display name to search for
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
App if found, None otherwise
|
|
40
|
+
"""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
async def get_all_types(self) -> set[AppType]:
|
|
44
|
+
"""Get all unique app types that have apps.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
Set of app types with at least one app
|
|
48
|
+
"""
|
|
49
|
+
...
|
|
50
|
+
|
|
51
|
+
async def get_apps_with_accelerators(self) -> list[App]:
|
|
52
|
+
"""Get all apps that have accelerators defined.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
List of apps with non-empty accelerators list
|
|
56
|
+
"""
|
|
57
|
+
...
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""Base repository protocol for sphinx_hcd.
|
|
2
|
+
|
|
3
|
+
Defines the generic repository interface following julee clean architecture
|
|
4
|
+
patterns. All repository operations are async for consistency with julee,
|
|
5
|
+
with sync adapters provided in the sphinx/ application layer.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Protocol, TypeVar, runtime_checkable
|
|
9
|
+
|
|
10
|
+
from pydantic import BaseModel
|
|
11
|
+
|
|
12
|
+
T = TypeVar("T", bound=BaseModel)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@runtime_checkable
|
|
16
|
+
class BaseRepository(Protocol[T]):
|
|
17
|
+
"""Generic base repository protocol for HCD entities.
|
|
18
|
+
|
|
19
|
+
This protocol defines the common interface shared by all domain
|
|
20
|
+
repositories in sphinx_hcd. It uses generics to provide type safety
|
|
21
|
+
while eliminating code duplication.
|
|
22
|
+
|
|
23
|
+
Type Parameter:
|
|
24
|
+
T: The domain entity type (must extend Pydantic BaseModel)
|
|
25
|
+
|
|
26
|
+
All methods are async for consistency with julee patterns. The sphinx/
|
|
27
|
+
application layer provides SyncRepositoryAdapter for use in Sphinx
|
|
28
|
+
directives which are synchronous.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
async def get(self, entity_id: str) -> T | None:
|
|
32
|
+
"""Retrieve an entity by ID.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
entity_id: Unique entity identifier (typically a slug)
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Entity if found, None otherwise
|
|
39
|
+
"""
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
async def get_many(self, entity_ids: list[str]) -> dict[str, T | None]:
|
|
43
|
+
"""Retrieve multiple entities by ID.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
entity_ids: List of unique entity identifiers
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Dict mapping entity_id to entity (or None if not found)
|
|
50
|
+
"""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
async def save(self, entity: T) -> None:
|
|
54
|
+
"""Save an entity.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
entity: Complete entity to save
|
|
58
|
+
|
|
59
|
+
Note:
|
|
60
|
+
Must be idempotent - saving the same entity state is safe.
|
|
61
|
+
"""
|
|
62
|
+
...
|
|
63
|
+
|
|
64
|
+
async def list_all(self) -> list[T]:
|
|
65
|
+
"""List all entities.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
List of all entities in the repository
|
|
69
|
+
"""
|
|
70
|
+
...
|
|
71
|
+
|
|
72
|
+
async def delete(self, entity_id: str) -> bool:
|
|
73
|
+
"""Delete an entity by ID.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
entity_id: Unique entity identifier
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
True if entity was deleted, False if not found
|
|
80
|
+
"""
|
|
81
|
+
...
|
|
82
|
+
|
|
83
|
+
async def clear(self) -> None:
|
|
84
|
+
"""Remove all entities from the repository.
|
|
85
|
+
|
|
86
|
+
Used primarily for testing and re-initialization during
|
|
87
|
+
Sphinx incremental builds.
|
|
88
|
+
"""
|
|
89
|
+
...
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""CodeInfoRepository protocol.
|
|
2
|
+
|
|
3
|
+
Defines the interface for bounded context code introspection data access.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from ..models.code_info import BoundedContextInfo
|
|
9
|
+
from .base import BaseRepository
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class CodeInfoRepository(BaseRepository[BoundedContextInfo], Protocol):
|
|
14
|
+
"""Repository protocol for BoundedContextInfo entities.
|
|
15
|
+
|
|
16
|
+
Extends BaseRepository with code introspection-specific query methods.
|
|
17
|
+
Code info is populated once at builder-inited by scanning src/ directories.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
async def get_by_code_dir(self, code_dir: str) -> BoundedContextInfo | None:
|
|
21
|
+
"""Get bounded context info by its code directory name.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
code_dir: Directory name in src/ (may differ from slug)
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
BoundedContextInfo if found, None otherwise
|
|
28
|
+
"""
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
async def get_with_entities(self) -> list[BoundedContextInfo]:
|
|
32
|
+
"""Get all bounded contexts that have domain entities.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
List of bounded contexts with at least one entity
|
|
36
|
+
"""
|
|
37
|
+
...
|
|
38
|
+
|
|
39
|
+
async def get_with_use_cases(self) -> list[BoundedContextInfo]:
|
|
40
|
+
"""Get all bounded contexts that have use cases.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
List of bounded contexts with at least one use case
|
|
44
|
+
"""
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
async def get_with_infrastructure(self) -> list[BoundedContextInfo]:
|
|
48
|
+
"""Get all bounded contexts that have infrastructure.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
List of bounded contexts where has_infrastructure is True
|
|
52
|
+
"""
|
|
53
|
+
...
|
|
54
|
+
|
|
55
|
+
async def get_all_entity_names(self) -> set[str]:
|
|
56
|
+
"""Get all unique entity class names across all bounded contexts.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Set of entity class names
|
|
60
|
+
"""
|
|
61
|
+
...
|
|
62
|
+
|
|
63
|
+
async def get_all_use_case_names(self) -> set[str]:
|
|
64
|
+
"""Get all unique use case class names across all bounded contexts.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Set of use case class names
|
|
68
|
+
"""
|
|
69
|
+
...
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""EpicRepository protocol.
|
|
2
|
+
|
|
3
|
+
Defines the interface for epic data access.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from ..models.epic import Epic
|
|
9
|
+
from .base import BaseRepository
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class EpicRepository(BaseRepository[Epic], Protocol):
|
|
14
|
+
"""Repository protocol for Epic entities.
|
|
15
|
+
|
|
16
|
+
Extends BaseRepository with epic-specific query methods.
|
|
17
|
+
Epics are defined in RST documents and support incremental builds
|
|
18
|
+
via docname tracking.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
async def get_by_docname(self, docname: str) -> list[Epic]:
|
|
22
|
+
"""Get all epics defined in a specific document.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
docname: RST document name
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List of epics from that document
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
async def clear_by_docname(self, docname: str) -> int:
|
|
33
|
+
"""Remove all epics defined in a specific document.
|
|
34
|
+
|
|
35
|
+
Used during incremental builds when a document is re-read.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
docname: RST document name
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Number of epics removed
|
|
42
|
+
"""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
async def get_with_story_ref(self, story_title: str) -> list[Epic]:
|
|
46
|
+
"""Get epics that contain a specific story.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
story_title: Story feature title (case-insensitive)
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
List of epics containing this story in story_refs
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
async def get_all_story_refs(self) -> set[str]:
|
|
57
|
+
"""Get all unique story references across all epics.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Set of story titles (normalized)
|
|
61
|
+
"""
|
|
62
|
+
...
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""IntegrationRepository protocol.
|
|
2
|
+
|
|
3
|
+
Defines the interface for integration data access.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from ..models.integration import Direction, Integration
|
|
9
|
+
from .base import BaseRepository
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class IntegrationRepository(BaseRepository[Integration], Protocol):
|
|
14
|
+
"""Repository protocol for Integration entities.
|
|
15
|
+
|
|
16
|
+
Extends BaseRepository with integration-specific query methods.
|
|
17
|
+
Integrations are indexed from YAML manifests and are read-only during
|
|
18
|
+
a Sphinx build (populated at builder-inited, queried during rendering).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
async def get_by_direction(self, direction: Direction) -> list[Integration]:
|
|
22
|
+
"""Get all integrations with a specific data flow direction.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
direction: Direction to filter by
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List of integrations matching the direction
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
async def get_by_module(self, module: str) -> Integration | None:
|
|
33
|
+
"""Get an integration by its module name.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
module: Python module name (e.g., "pilot_data_collection")
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
Integration if found, None otherwise
|
|
40
|
+
"""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
async def get_by_name(self, name: str) -> Integration | None:
|
|
44
|
+
"""Get an integration by its display name (case-insensitive).
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
name: Display name to search for
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Integration if found, None otherwise
|
|
51
|
+
"""
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
async def get_all_directions(self) -> set[Direction]:
|
|
55
|
+
"""Get all unique directions that have integrations.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Set of directions with at least one integration
|
|
59
|
+
"""
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
async def get_with_dependencies(self) -> list[Integration]:
|
|
63
|
+
"""Get all integrations that have external dependencies.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
List of integrations with non-empty depends_on list
|
|
67
|
+
"""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
async def get_by_dependency(self, dep_name: str) -> list[Integration]:
|
|
71
|
+
"""Get all integrations that depend on a specific external system.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
dep_name: External dependency name (case-insensitive)
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
List of integrations that have this dependency
|
|
78
|
+
"""
|
|
79
|
+
...
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""JourneyRepository protocol.
|
|
2
|
+
|
|
3
|
+
Defines the interface for journey data access.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from ..models.journey import Journey
|
|
9
|
+
from .base import BaseRepository
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class JourneyRepository(BaseRepository[Journey], Protocol):
|
|
14
|
+
"""Repository protocol for Journey entities.
|
|
15
|
+
|
|
16
|
+
Extends BaseRepository with journey-specific query methods.
|
|
17
|
+
Journeys are defined in RST documents and support incremental builds
|
|
18
|
+
via docname tracking.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
async def get_by_persona(self, persona: str) -> list[Journey]:
|
|
22
|
+
"""Get all journeys for a persona.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
persona: Persona name (case-insensitive matching)
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List of journeys where the persona matches
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
async def get_by_docname(self, docname: str) -> list[Journey]:
|
|
33
|
+
"""Get all journeys defined in a specific document.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
docname: RST document name
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
List of journeys from that document
|
|
40
|
+
"""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
async def clear_by_docname(self, docname: str) -> int:
|
|
44
|
+
"""Remove all journeys defined in a specific document.
|
|
45
|
+
|
|
46
|
+
Used during incremental builds when a document is re-read.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
docname: RST document name
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Number of journeys removed
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
async def get_dependents(self, journey_slug: str) -> list[Journey]:
|
|
57
|
+
"""Get journeys that depend on a specific journey.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
journey_slug: Slug of the journey to find dependents of
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
List of journeys that have this journey in depends_on
|
|
64
|
+
"""
|
|
65
|
+
...
|
|
66
|
+
|
|
67
|
+
async def get_dependencies(self, journey_slug: str) -> list[Journey]:
|
|
68
|
+
"""Get journeys that a specific journey depends on.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
journey_slug: Slug of the journey to find dependencies of
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
List of journeys that this journey depends on
|
|
75
|
+
"""
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
async def get_all_personas(self) -> set[str]:
|
|
79
|
+
"""Get all unique personas across all journeys.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Set of persona names (normalized)
|
|
83
|
+
"""
|
|
84
|
+
...
|
|
85
|
+
|
|
86
|
+
async def get_with_story_ref(self, story_title: str) -> list[Journey]:
|
|
87
|
+
"""Get journeys that reference a specific story.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
story_title: Story feature title (case-insensitive)
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
List of journeys containing this story in steps
|
|
94
|
+
"""
|
|
95
|
+
...
|
|
96
|
+
|
|
97
|
+
async def get_with_epic_ref(self, epic_slug: str) -> list[Journey]:
|
|
98
|
+
"""Get journeys that reference a specific epic.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
epic_slug: Epic slug
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
List of journeys containing this epic in steps
|
|
105
|
+
"""
|
|
106
|
+
...
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""StoryRepository protocol.
|
|
2
|
+
|
|
3
|
+
Defines the interface for story data access.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Protocol, runtime_checkable
|
|
7
|
+
|
|
8
|
+
from ..models.story import Story
|
|
9
|
+
from .base import BaseRepository
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@runtime_checkable
|
|
13
|
+
class StoryRepository(BaseRepository[Story], Protocol):
|
|
14
|
+
"""Repository protocol for Story entities.
|
|
15
|
+
|
|
16
|
+
Extends BaseRepository with story-specific query methods.
|
|
17
|
+
Stories are indexed from .feature files and are read-only during
|
|
18
|
+
a Sphinx build (populated at builder-inited, queried during rendering).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
async def get_by_app(self, app_slug: str) -> list[Story]:
|
|
22
|
+
"""Get all stories for an application.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
app_slug: Application slug (e.g., "staff-portal")
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List of stories belonging to the app
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
async def get_by_persona(self, persona: str) -> list[Story]:
|
|
33
|
+
"""Get all stories for a persona.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
persona: Persona name (case-insensitive matching)
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
List of stories where the persona matches
|
|
40
|
+
"""
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
async def get_by_feature_title(self, feature_title: str) -> Story | None:
|
|
44
|
+
"""Get a story by its feature title.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
feature_title: The Feature: line content (case-insensitive)
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Story if found, None otherwise
|
|
51
|
+
"""
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
async def get_apps_with_stories(self) -> set[str]:
|
|
55
|
+
"""Get the set of app slugs that have stories.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Set of app slugs (normalized)
|
|
59
|
+
"""
|
|
60
|
+
...
|
|
61
|
+
|
|
62
|
+
async def get_all_personas(self) -> set[str]:
|
|
63
|
+
"""Get all unique personas across all stories.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Set of persona names (normalized)
|
|
67
|
+
"""
|
|
68
|
+
...
|