diff --git a/backend/app/modules/project/application/services.py b/backend/app/modules/project/application/services.py index e69de29..2e9ae9b 100644 --- a/backend/app/modules/project/application/services.py +++ b/backend/app/modules/project/application/services.py @@ -0,0 +1,42 @@ +import uuid +from datetime import datetime, timezone +from pathlib import Path + +from app.modules.project.domain.entities import Project +from app.modules.project.domain.repositories import ProjectRepository +from app.shared.kernel.exceptions import NotFoundError, ValidationError + + +class ProjectService: + def __init__(self, repository: ProjectRepository) -> None: + self._repo = repository + + def list_projects(self) -> list[Project]: + return self._repo.list_all() + + def create_project( + self, name: str, design_dir: str, code_dir: str | None = None, + ) -> Project: + if not Path(design_dir).is_dir(): + raise ValidationError(f"Design directory does not exist: {design_dir}") + project = Project( + id=str(uuid.uuid4()), + name=name, + design_dir=design_dir, + code_dir=code_dir, + created_at=datetime.now(timezone.utc), + ) + self._repo.save(project) + return project + + def get_project(self, project_id: str) -> Project: + project = self._repo.get_by_id(project_id) + if project is None: + raise NotFoundError("Project", project_id) + return project + + def delete_project(self, project_id: str) -> None: + project = self._repo.get_by_id(project_id) + if project is None: + raise NotFoundError("Project", project_id) + self._repo.delete(project_id) diff --git a/backend/tests/test_project.py b/backend/tests/test_project.py index bc93340..8af535a 100644 --- a/backend/tests/test_project.py +++ b/backend/tests/test_project.py @@ -42,3 +42,42 @@ def test_delete(repo: JsonProjectRepository): def test_get_nonexistent_returns_none(repo: JsonProjectRepository): assert repo.get_by_id("nope") is None + + +# --- Service tests --- + +from app.modules.project.application.services import ProjectService +from app.shared.kernel.exceptions import NotFoundError, ValidationError + + +@pytest.fixture +def service(tmp_path: Path) -> ProjectService: + repo = JsonProjectRepository(tmp_path / "projects.json") + return ProjectService(repo) + + +def test_create_project_validates_design_dir(service: ProjectService, tmp_path: Path): + design_dir = tmp_path / "design" + design_dir.mkdir() + project = service.create_project("test", str(design_dir)) + assert project.name == "test" + assert project.id # UUID generated + + +def test_create_project_rejects_missing_dir(service: ProjectService): + with pytest.raises(ValidationError): + service.create_project("test", "/nonexistent/path") + + +def test_get_project_not_found(service: ProjectService): + with pytest.raises(NotFoundError): + service.get_project("nonexistent") + + +def test_delete_project(service: ProjectService, tmp_path: Path): + design_dir = tmp_path / "design" + design_dir.mkdir() + p = service.create_project("test", str(design_dir)) + service.delete_project(p.id) + with pytest.raises(NotFoundError): + service.get_project(p.id)