Cycles/.cursor/rules/architecture.mdc

237 lines
7.2 KiB
Plaintext
Raw Normal View History

---
description: Modular design principles and architecture guidelines for scalable development
globs:
alwaysApply: false
---
# Rule: Architecture and Modular Design
## Goal
Maintain a clean, modular architecture that scales effectively and prevents the complexity issues that arise in AI-assisted development.
## Core Architecture Principles
### 1. Modular Design
- **Single Responsibility**: Each module has one clear purpose
- **Loose Coupling**: Modules depend on interfaces, not implementations
- **High Cohesion**: Related functionality is grouped together
- **Clear Boundaries**: Module interfaces are well-defined and stable
### 2. Size Constraints
- **Files**: Maximum 250 lines per file
- **Functions**: Maximum 50 lines per function
- **Classes**: Maximum 300 lines per class
- **Modules**: Maximum 10 public functions/classes per module
### 3. Dependency Management
- **Layer Dependencies**: Higher layers depend on lower layers only
- **No Circular Dependencies**: Modules cannot depend on each other cyclically
- **Interface Segregation**: Depend on specific interfaces, not broad ones
- **Dependency Injection**: Pass dependencies rather than creating them internally
## Modular Architecture Patterns
### Layer Structure
```
src/
├── presentation/ # UI, API endpoints, CLI interfaces
├── application/ # Business logic, use cases, workflows
├── domain/ # Core business entities and rules
├── infrastructure/ # Database, external APIs, file systems
└── shared/ # Common utilities, constants, types
```
### Module Organization
```
module_name/
├── __init__.py # Public interface exports
├── core.py # Main module logic
├── types.py # Type definitions and interfaces
├── utils.py # Module-specific utilities
├── tests/ # Module tests
└── README.md # Module documentation
```
## Design Patterns for AI Development
### 1. Repository Pattern
Separate data access from business logic:
```python
# Domain interface
class UserRepository:
def get_by_id(self, user_id: str) -> User: ...
def save(self, user: User) -> None: ...
# Infrastructure implementation
class SqlUserRepository(UserRepository):
def get_by_id(self, user_id: str) -> User:
# Database-specific implementation
pass
```
### 2. Service Pattern
Encapsulate business logic in focused services:
```python
class UserService:
def __init__(self, user_repo: UserRepository):
self._user_repo = user_repo
def create_user(self, data: UserData) -> User:
# Validation and business logic
# Single responsibility: user creation
pass
```
### 3. Factory Pattern
Create complex objects with clear interfaces:
```python
class DatabaseFactory:
@staticmethod
def create_connection(config: DatabaseConfig) -> Connection:
# Handle different database types
# Encapsulate connection complexity
pass
```
## Architecture Decision Guidelines
### When to Create New Modules
Create a new module when:
- **Functionality** exceeds size constraints (250 lines)
- **Responsibility** is distinct from existing modules
- **Dependencies** would create circular references
- **Reusability** would benefit other parts of the system
- **Testing** requires isolated test environments
### When to Split Existing Modules
Split modules when:
- **File size** exceeds 250 lines
- **Multiple responsibilities** are evident
- **Testing** becomes difficult due to complexity
- **Dependencies** become too numerous
- **Change frequency** differs significantly between parts
### Module Interface Design
```python
# Good: Clear, focused interface
class PaymentProcessor:
def process_payment(self, amount: Money, method: PaymentMethod) -> PaymentResult:
"""Process a single payment transaction."""
pass
# Bad: Unfocused, kitchen-sink interface
class PaymentManager:
def process_payment(self, ...): pass
def validate_card(self, ...): pass
def send_receipt(self, ...): pass
def update_inventory(self, ...): pass # Wrong responsibility!
```
## Architecture Validation
### Architecture Review Checklist
- [ ] **Dependencies flow in one direction** (no cycles)
- [ ] **Layers are respected** (presentation doesn't call infrastructure directly)
- [ ] **Modules have single responsibility**
- [ ] **Interfaces are stable** and well-defined
- [ ] **Size constraints** are maintained
- [ ] **Testing** is straightforward for each module
### Red Flags
- **God Objects**: Classes/modules that do too many things
- **Circular Dependencies**: Modules that depend on each other
- **Deep Inheritance**: More than 3 levels of inheritance
- **Large Interfaces**: Interfaces with more than 7 methods
- **Tight Coupling**: Modules that know too much about each other's internals
## Refactoring Guidelines
### When to Refactor
- Module exceeds size constraints
- Code duplication across modules
- Difficult to test individual components
- New features require changing multiple unrelated modules
- Performance bottlenecks due to poor separation
### Refactoring Process
1. **Identify** the specific architectural problem
2. **Design** the target architecture
3. **Create tests** to verify current behavior
4. **Implement changes** incrementally
5. **Validate** that tests still pass
6. **Update documentation** to reflect changes
### Safe Refactoring Practices
- **One change at a time**: Don't mix refactoring with new features
- **Tests first**: Ensure comprehensive test coverage before refactoring
- **Incremental changes**: Small steps with verification at each stage
- **Backward compatibility**: Maintain existing interfaces during transition
- **Documentation updates**: Keep architecture documentation current
## Architecture Documentation
### Architecture Decision Records (ADRs)
Document significant decisions in `./docs/decisions/`:
```markdown
# ADR-003: Service Layer Architecture
## Status
Accepted
## Context
As the application grows, business logic is scattered across controllers and models.
## Decision
Implement a service layer to encapsulate business logic.
## Consequences
**Positive:**
- Clear separation of concerns
- Easier testing of business logic
- Better reusability across different interfaces
**Negative:**
- Additional abstraction layer
- More files to maintain
```
### Module Documentation Template
```markdown
# Module: [Name]
## Purpose
What this module does and why it exists.
## Dependencies
- **Imports from**: List of modules this depends on
- **Used by**: List of modules that depend on this one
- **External**: Third-party dependencies
## Public Interface
```python
# Key functions and classes exposed by this module
```
## Architecture Notes
- Design patterns used
- Important architectural decisions
- Known limitations or constraints
```
## Migration Strategies
### Legacy Code Integration
- **Strangler Fig Pattern**: Gradually replace old code with new modules
- **Adapter Pattern**: Create interfaces to integrate old and new code
- **Facade Pattern**: Simplify complex legacy interfaces
### Gradual Modernization
1. **Identify boundaries** in existing code
2. **Extract modules** one at a time
3. **Create interfaces** for each extracted module
4. **Test thoroughly** at each step
5. **Update documentation** continuously