diff --git a/backend/app/modules/design/domain/entities.py b/backend/app/modules/design/domain/entities.py index e69de29..9c3bd72 100644 --- a/backend/app/modules/design/domain/entities.py +++ b/backend/app/modules/design/domain/entities.py @@ -0,0 +1,304 @@ +from dataclasses import dataclass + + +# ── Business Layer ── + +@dataclass +class Capability: + capability_id: str + name: str + description: str + priority: str # must / should / could + phase: str + related_value_flows: list[str] + + +@dataclass +class ValueFlow: + value_flow_id: str + name: str + trigger: str + actor: str + steps: str + outcome: str + phase: str + related_capabilities: list[str] + + +@dataclass +class UserJourney: + journey_id: str + name: str + actor: str + precondition: str + steps: str + postcondition: str + phase: str + related_value_flows: list[str] + + +@dataclass +class ScopeAndGoals: + doc_id: str + title: str + core_problem: str + users: str + constraints: str + + +# ── Application Layer ── + +@dataclass +class Module: + module_id: str + name: str + layer: str # backend / frontend + description: str + phase: str + depends_on: list[str] + capabilities: list[str] + + +@dataclass +class Integration: + integration_id: str + source_id: str + target_id: str + target_type: str + direction: str + protocol: str + trigger: str + phase: str + description: str + + +@dataclass +class ExternalSystem: + system_id: str + name: str + type: str + protocol: str + direction: str + phase: str + description: str + + +@dataclass +class ApiContract: + doc_id: str + path: str + method: str + operation_id: str + summary: str + + +@dataclass +class CodebaseAlignment: + module_id: str + repo_root: str + code_root: str + package_name: str + + +@dataclass +class ModuleBoundaryRule: + doc_id: str + title: str + content: str + + +@dataclass +class SystemContext: + doc_id: str + title: str + content: str + + +@dataclass +class SolutionLayer: + doc_id: str + title: str + content: str + + +# ── Data Layer ── + +@dataclass +class Entity: + entity_id: str + name: str + domain: str + owner_module: str + description: str + phase: str + source_file: str + + +@dataclass +class DataFlow: + data_flow_id: str + source: str + target: str + data_content: str + trigger: str + protocol: str + phase: str + description: str + + +@dataclass +class DataSecurity: + security_id: str + sensitivity: str + entities: str + protection: str + + +# ── Technology Layer ── + +@dataclass +class TechSelection: + category: str + technology: str + version: str + purpose: str + rationale: str + alternatives_considered: str + phase: str + + +@dataclass +class RuntimeComponent: + component_id: str + name: str + type: str + technology: str + port: str + + +@dataclass +class RuntimeTopology: + doc_id: str + title: str + content: str + + +@dataclass +class Environment: + env_id: str + name: str + purpose: str + infra: str + + +@dataclass +class OperationalBaseline: + doc_id: str + title: str + content: str + + +@dataclass +class ReleasePlan: + doc_id: str + title: str + content: str + + +# ── Cross-Layer ── + +@dataclass +class TraceabilityLink: + trace_id: str + capability_id: str + module_id: str + entity_ids: list[str] + value_flow_ids: list[str] + notes: str + + +@dataclass +class ChangeLogEntry: + change_id: str + date: str + scope: str + description: str + + +@dataclass +class ADR: + adr_id: str + title: str + status: str + context: str + decision: str + + +@dataclass +class DesignDocument: + doc_id: str + title: str + version: str + status: str + owners: list[str] + upstream: list[str] + downstream: list[str] + file_path: str + + +# ── Domain Layer ── + +@dataclass +class Domain: + domain_name: str + overview: str + modules: list[str] + entities: list[str] + + +@dataclass +class UbiquitousTerm: + term_id: str + term: str + english_term: str + code_symbol: str + domain: str + definition: str + + +@dataclass +class SharedTerm: + term_id: str + term: str + english_term: str + definition: str + used_by_domains: list[str] + + +@dataclass +class Scenario: + scenario_id: str + name: str + trigger: str + actors: str + steps: str + outcome: str + related_capabilities: list[str] + + +@dataclass +class DomainModule: + module_id: str + module_name: str + domain: str + description: str + layer_in_code: str + + +@dataclass +class DomainEntity: + entity_id: str + entity_name: str + type: str + description: str + key_attributes: str diff --git a/backend/tests/test_design_entities.py b/backend/tests/test_design_entities.py index 139c405..d49ecda 100644 --- a/backend/tests/test_design_entities.py +++ b/backend/tests/test_design_entities.py @@ -25,3 +25,105 @@ def test_module_layer_values(): assert ModuleLayer.APPLICATION == "application" assert ModuleLayer.INFRASTRUCTURE == "infrastructure" assert ModuleLayer.INTERFACES == "interfaces" + + +from app.modules.design.domain.entities import ( + ADR, + ApiContract, + Capability, + ChangeLogEntry, + CodebaseAlignment, + DataFlow, + DataSecurity, + DesignDocument, + Domain, + DomainEntity, + DomainModule, + Entity, + Environment, + ExternalSystem, + Integration, + Module, + ModuleBoundaryRule, + OperationalBaseline, + ReleasePlan, + RuntimeComponent, + RuntimeTopology, + Scenario, + ScopeAndGoals, + SharedTerm, + SolutionLayer, + SystemContext, + TechSelection, + TraceabilityLink, + UbiquitousTerm, + UserJourney, + ValueFlow, +) + + +def test_capability_creation(): + cap = Capability( + capability_id="CAP-01", + name="test", + description="desc", + priority="must", + phase="MVP", + related_value_flows=["VF-01"], + ) + assert cap.capability_id == "CAP-01" + assert cap.related_value_flows == ["VF-01"] + + +def test_module_creation(): + mod = Module( + module_id="MOD-01", + name="test", + layer="backend", + description="desc", + phase="MVP", + depends_on=["MOD-02"], + capabilities=["CAP-01"], + ) + assert mod.depends_on == ["MOD-02"] + + +def test_traceability_link_list_fields(): + tl = TraceabilityLink( + trace_id="TR-01", + capability_id="CAP-01", + module_id="MOD-01", + entity_ids=["ENT-01", "ENT-02"], + value_flow_ids=["VF-01"], + notes="test", + ) + assert len(tl.entity_ids) == 2 + + +def test_design_document_list_fields(): + dd = DesignDocument( + doc_id="DOC-01", + title="test", + version="0.1", + status="draft", + owners=["owner1"], + upstream=["a.md"], + downstream=["b.md"], + file_path="test.md", + ) + assert dd.owners == ["owner1"] + + +def test_all_31_entities_importable(): + """Verify all 31 entity classes can be imported.""" + entities = [ + Capability, ValueFlow, UserJourney, ScopeAndGoals, + Module, Integration, ExternalSystem, ApiContract, + CodebaseAlignment, ModuleBoundaryRule, SystemContext, SolutionLayer, + Entity, DataFlow, DataSecurity, + TechSelection, RuntimeComponent, RuntimeTopology, Environment, + OperationalBaseline, ReleasePlan, + TraceabilityLink, ChangeLogEntry, ADR, DesignDocument, + Domain, UbiquitousTerm, SharedTerm, Scenario, DomainModule, DomainEntity, + ] + assert len(entities) == 31