feat: Implement domain logic separation with clean architecture
- Created complete domain layer with pure business logic - Implemented Issue domain models with 48 passing tests - Implemented Project domain models with 31 passing tests - Added domain services for complex business operations - Established clean separation between domain, application, and infrastructure - All 250 tests passing with no breaking changes 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
116
domain/issues/repositories.py
Normal file
116
domain/issues/repositories.py
Normal file
@@ -0,0 +1,116 @@
|
||||
"""
|
||||
Repository interfaces for issue domain.
|
||||
|
||||
Defines contracts for data access without infrastructure dependencies.
|
||||
"""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List, Optional, Dict, Any
|
||||
from .models import Issue
|
||||
|
||||
|
||||
class IssueRepository(ABC):
|
||||
"""Repository interface for issue persistence."""
|
||||
|
||||
@abstractmethod
|
||||
async def get_issue(self, issue_number: int) -> Issue:
|
||||
"""Retrieve issue by number.
|
||||
|
||||
Args:
|
||||
issue_number: The issue number to retrieve
|
||||
|
||||
Returns:
|
||||
Issue domain object
|
||||
|
||||
Raises:
|
||||
IssueNotFoundError: If issue doesn't exist
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def list_issues(self, state: Optional[str] = None, limit: Optional[int] = None) -> List[Issue]:
|
||||
"""List issues, optionally filtered by state.
|
||||
|
||||
Args:
|
||||
state: Optional state filter (open, closed)
|
||||
limit: Optional limit on number of results
|
||||
|
||||
Returns:
|
||||
List of Issue domain objects
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def save_issue(self, issue: Issue) -> None:
|
||||
"""Save issue changes.
|
||||
|
||||
Args:
|
||||
issue: Issue domain object to save
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def create_issue(self, title: str, description: str, labels: List[str]) -> Issue:
|
||||
"""Create a new issue.
|
||||
|
||||
Args:
|
||||
title: Issue title
|
||||
description: Issue description
|
||||
labels: List of label names
|
||||
|
||||
Returns:
|
||||
Created Issue domain object
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def delete_issue(self, issue_number: int) -> None:
|
||||
"""Delete an issue.
|
||||
|
||||
Args:
|
||||
issue_number: The issue number to delete
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ProjectRepository(ABC):
|
||||
"""Repository interface for project information."""
|
||||
|
||||
@abstractmethod
|
||||
async def get_issue_project_info(self, issue_number: int) -> Dict[str, Any]:
|
||||
"""Get project information for an issue.
|
||||
|
||||
Args:
|
||||
issue_number: The issue number
|
||||
|
||||
Returns:
|
||||
Dictionary containing project context information
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_kanban_columns(self) -> List[str]:
|
||||
"""Get available kanban columns for the project.
|
||||
|
||||
Returns:
|
||||
List of kanban column names
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_project_labels(self) -> List[Dict[str, Any]]:
|
||||
"""Get available labels for the project.
|
||||
|
||||
Returns:
|
||||
List of label definitions
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def get_milestones(self) -> List[Dict[str, Any]]:
|
||||
"""Get available milestones for the project.
|
||||
|
||||
Returns:
|
||||
List of milestone information
|
||||
"""
|
||||
pass
|
||||
Reference in New Issue
Block a user