trax/.cursor/rules/backend-first.mdc

76 lines
2.8 KiB
Plaintext

---
description: Backend-first development approach for robust architecture
globs: **/*.py, **/*.js, **/*.ts, **/services/*.py, **/repositories/*.py, **/models/*.py
alwaysApply: false
---
# Backend-First Development Rule
## Core Principles
- **Data First**: Design data models before UI components
- **Business Logic Priority**: Implement core logic before presentation
- **API Contract Design**: Define stable APIs before consumers
- **Solid Foundation**: Build on reliable data and service layers
## Implementation Patterns
### Data Model First
```python
# ✅ DO: Define data models before UI components
# Step 1: Define the data model
@register_model
class Project(Base):
__tablename__ = "projects"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4)
name = Column(String, nullable=False)
description = Column(Text)
created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
# Step 2: Create repository layer
class ProjectRepository:
async def create(self, data: Dict[str, Any]) -> Project:
# Implementation
# Step 3: Create service layer with business logic
class ProjectService:
def __init__(self, repository: ProjectRepository):
self.repository = repository
async def create_project(self, data: Dict[str, Any]) -> Project:
# Validation and business logic
# Step 4 (LAST): Create UI components that use the service
```
### API Contract Design
```python
# ✅ DO: Define API contracts before implementation
# Step 1: Define the protocol/interface
@runtime_checkable
class UserServiceProtocol(Protocol):
async def get_user(self, user_id: UUID) -> Optional[User]: ...
async def create_user(self, data: Dict[str, Any]) -> User: ...
async def update_user(self, user_id: UUID, data: Dict[str, Any]) -> User: ...
# Step 2: Implement the service
class UserService:
# Implementation of the protocol
# Step 3: Create API endpoints using the service
@router.post("/users")
async def create_user(data: UserCreateSchema, service: UserServiceProtocol = Depends(get_user_service)):
return await service.create_user(data.dict())
```
### Anti-Patterns
```python
# ❌ DON'T: Build UI first without backend services
# Creating UI components that assume backend behavior
# before defining the actual data models and services
# ❌ DON'T: Design APIs without data models
# Defining API endpoints without understanding
# the underlying data structure and relationships
```
When developing new features, ALWAYS get the data layer right before building UI. Focus on backend services, database models, and API endpoints first. Ensure data integrity and business logic are solid before adding presentation layers. This prevents rework and ensures consistent architecture.