-
Notifications
You must be signed in to change notification settings - Fork 0
feat: ディレクトリ構成の見直し #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ dist/ | |
| build/ | ||
| .pytest_cache/ | ||
| .mypy_cache/ | ||
| .ruff_cache | ||
| .coverage | ||
| htmlcov/ | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| from .k8s_client import K8sClient | ||
|
|
||
| __all__ = ["K8sClient"] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| from .mock_iteration_repository import MockIterationRepository | ||
| from .mock_proposal_repository import MockProposalRepository | ||
| from .mock_session_repository import MockSessionRepository | ||
|
|
||
| __all__ = [ | ||
| "MockSessionRepository", | ||
| "MockIterationRepository", | ||
| "MockProposalRepository", | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| from uuid import UUID | ||
|
|
||
| from app.model.session import Iteration, IterationStatus | ||
|
|
||
|
|
||
| class MockIterationRepository: | ||
| def __init__(self) -> None: | ||
| self._store: dict[UUID, Iteration] = {} | ||
|
|
||
| def create(self, iteration: Iteration) -> Iteration: | ||
| self._store[iteration.id] = iteration | ||
| return iteration | ||
|
|
||
| def get_by_id(self, iteration_id: UUID) -> Iteration | None: | ||
| return self._store.get(iteration_id) | ||
|
|
||
| def get_by_session_and_index(self, session_id: UUID, iteration_index: int) -> Iteration | None: | ||
| for it in self._store.values(): | ||
| if it.session_id == session_id and it.iteration_index == iteration_index: | ||
| return it | ||
| return None | ||
|
|
||
| def get_latest_for_session(self, session_id: UUID) -> Iteration | None: | ||
| iters = [it for it in self._store.values() if it.session_id == session_id] | ||
| if not iters: | ||
| return None | ||
| return max(iters, key=lambda it: it.iteration_index) | ||
|
|
||
| def get_all_for_session(self, session_id: UUID) -> list[Iteration]: | ||
| return sorted( | ||
| [it for it in self._store.values() if it.session_id == session_id], | ||
| key=lambda it: it.iteration_index, | ||
| ) | ||
|
|
||
| def update_status_optimistic( | ||
| self, | ||
| iteration_id: UUID, | ||
| expected_version: int, | ||
| status: IterationStatus, | ||
| **kwargs: object, | ||
| ) -> Iteration | None: | ||
| iteration = self._store.get(iteration_id) | ||
| if not iteration or iteration.version != expected_version: | ||
| return None | ||
| iteration.status = status | ||
| iteration.version += 1 | ||
| for k, v in kwargs.items(): | ||
| if hasattr(iteration, k): | ||
| setattr(iteration, k, v) | ||
| return iteration | ||
|
|
||
| def update_selected_proposal(self, iteration_id: UUID, proposal_index: int) -> Iteration | None: | ||
| iteration = self._store.get(iteration_id) | ||
| if iteration: | ||
| iteration.selected_proposal_index = proposal_index | ||
| return iteration | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| from uuid import UUID | ||
|
|
||
| from app.model.session import Proposal, ProposalStatus | ||
|
|
||
|
|
||
| class MockProposalRepository: | ||
| def __init__(self) -> None: | ||
| self._store: dict[UUID, Proposal] = {} | ||
|
|
||
| def create(self, proposal: Proposal) -> Proposal: | ||
| self._store[proposal.id] = proposal | ||
| return proposal | ||
|
Comment on lines
+10
to
+12
|
||
|
|
||
| def get_by_id(self, proposal_id: UUID) -> Proposal | None: | ||
| return self._store.get(proposal_id) | ||
|
|
||
| def get_by_iteration_and_index( | ||
| self, iteration_id: UUID, proposal_index: int | ||
| ) -> Proposal | None: | ||
| for p in self._store.values(): | ||
| if p.iteration_id == iteration_id and p.proposal_index == proposal_index: | ||
| return p | ||
| return None | ||
|
|
||
| def get_all_by_status(self, status: ProposalStatus) -> list[Proposal]: | ||
| return [p for p in self._store.values() if p.status == status] | ||
|
|
||
| def get_all_for_iteration(self, iteration_id: UUID) -> list[Proposal]: | ||
| return sorted( | ||
| [p for p in self._store.values() if p.iteration_id == iteration_id], | ||
| key=lambda p: p.proposal_index, | ||
| ) | ||
|
|
||
| def update_status_optimistic( | ||
| self, | ||
| proposal_id: UUID, | ||
| expected_version: int, | ||
| status: ProposalStatus, | ||
| **kwargs: object, | ||
| ) -> Proposal | None: | ||
| proposal = self._store.get(proposal_id) | ||
| if not proposal or proposal.version != expected_version: | ||
| return None | ||
| proposal.status = status | ||
| proposal.version += 1 | ||
| for k, v in kwargs.items(): | ||
| if hasattr(proposal, k): | ||
| setattr(proposal, k, v) | ||
| return proposal | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| from uuid import UUID | ||
|
|
||
| from app.model.session import Session, SessionStatus | ||
|
|
||
|
|
||
| class MockSessionRepository: | ||
| def __init__(self) -> None: | ||
| self._store: dict[UUID, Session] = {} | ||
|
|
||
| def create(self, session: Session) -> Session: | ||
| self._store[session.id] = session | ||
| return session | ||
|
Comment on lines
+10
to
+12
|
||
|
|
||
| def get_by_id(self, session_id: UUID) -> Session | None: | ||
| return self._store.get(session_id) | ||
|
|
||
| def update_status(self, session_id: UUID, status: SessionStatus) -> Session | None: | ||
| session = self._store.get(session_id) | ||
| if session: | ||
| session.status = status | ||
| return session | ||
|
|
||
| def list_all(self) -> list[Session]: | ||
| return list(self._store.values()) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| from typing import Protocol | ||
| from uuid import UUID | ||
|
|
||
| from app.model.session import ( | ||
| Iteration, | ||
| IterationStatus, | ||
| Proposal, | ||
| ProposalStatus, | ||
| Session, | ||
| SessionStatus, | ||
| Setting, | ||
| ) | ||
|
|
||
|
|
||
| class SessionRepositoryProtocol(Protocol): | ||
| def create(self, session: Session) -> Session: ... | ||
| def get_by_id(self, session_id: UUID) -> Session | None: ... | ||
| def update_status(self, session_id: UUID, status: SessionStatus) -> Session | None: ... | ||
| def list_all(self) -> list[Session]: ... | ||
|
|
||
|
|
||
| class IterationRepositoryProtocol(Protocol): | ||
| def create(self, iteration: Iteration) -> Iteration: ... | ||
| def get_by_id(self, iteration_id: UUID) -> Iteration | None: ... | ||
| def get_by_session_and_index( | ||
| self, session_id: UUID, iteration_index: int | ||
| ) -> Iteration | None: ... | ||
| def get_latest_for_session(self, session_id: UUID) -> Iteration | None: ... | ||
| def get_all_for_session(self, session_id: UUID) -> list[Iteration]: ... | ||
| def update_status_optimistic( | ||
| self, | ||
| iteration_id: UUID, | ||
| expected_version: int, | ||
| status: IterationStatus, | ||
| **kwargs: object, | ||
| ) -> Iteration | None: ... | ||
| def update_selected_proposal( | ||
| self, iteration_id: UUID, proposal_index: int | ||
| ) -> Iteration | None: ... | ||
|
|
||
|
|
||
| class ProposalRepositoryProtocol(Protocol): | ||
| def create(self, proposal: Proposal) -> Proposal: ... | ||
| def get_by_id(self, proposal_id: UUID) -> Proposal | None: ... | ||
| def get_by_iteration_and_index( | ||
| self, iteration_id: UUID, proposal_index: int | ||
| ) -> Proposal | None: ... | ||
| def get_all_by_status(self, status: ProposalStatus) -> list[Proposal]: ... | ||
| def get_all_for_iteration(self, iteration_id: UUID) -> list[Proposal]: ... | ||
| def update_status_optimistic( | ||
| self, | ||
| proposal_id: UUID, | ||
| expected_version: int, | ||
| status: ProposalStatus, | ||
| **kwargs: object, | ||
| ) -> Proposal | None: ... | ||
|
|
||
|
|
||
| class SettingRepositoryProtocol(Protocol): | ||
| def get_by_key(self, key: str) -> Setting | None: ... | ||
| def upsert(self, key: str, value: str) -> Setting: ... | ||
| def list_all(self) -> list[Setting]: ... | ||
| def delete(self, key: str) -> bool: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MockIterationRepository.create()assumesiteration.idis already set. In code paths that constructIteration(...)without flushing (e.g., usecase unit tests), the SQLAlchemy default UUID may not be assigned yet. To emulate the DB-backed repository behavior, generate and set an ID in the mock when it’s missing before storing the object.