|
| 1 | +# Development Standards & Best Practices |
| 2 | + |
| 3 | +## Code Style & Formatting |
| 4 | + |
| 5 | +### Python Standards |
| 6 | +- **Indentation**: 4 spaces (never tabs) |
| 7 | +- **Type hints**: Required everywhere - functions, variables, class attributes |
| 8 | +- **Naming conventions**: |
| 9 | + - Functions/variables: `snake_case` |
| 10 | + - Classes: `PascalCase` |
| 11 | + - Constants: `SCREAMING_SNAKE_CASE` |
| 12 | + - Private methods: `_leading_underscore` |
| 13 | +- **Function length**: Keep under ~50 lines for readability |
| 14 | +- **Data structures**: Prefer dataclasses for structured payloads over dictionaries |
| 15 | + |
| 16 | +### HTML/CSS Standards |
| 17 | +- **Class naming**: BEM-like convention (`meetspot-header__title`, `card--featured`) |
| 18 | +- **Colors**: Always use design tokens from `static/css/design-tokens.css` |
| 19 | +- **Inline styles**: Minimize usage, only for generated HTML in `workspace/js_src/` |
| 20 | +- **Responsive design**: Mobile-first approach with progressive enhancement |
| 21 | +- **Accessibility**: All interactive elements must be keyboard accessible |
| 22 | + |
| 23 | +### JavaScript Standards |
| 24 | +- **ES6+**: Use modern JavaScript features |
| 25 | +- **Async/await**: Prefer over Promise chains |
| 26 | +- **Error handling**: Always wrap API calls in try-catch blocks |
| 27 | +- **DOM manipulation**: Use semantic HTML and ARIA attributes |
| 28 | + |
| 29 | +## Quality Gates |
| 30 | + |
| 31 | +### Pre-commit Requirements |
| 32 | +All of these must pass before opening a PR: |
| 33 | + |
| 34 | +```bash |
| 35 | +# Code formatting |
| 36 | +black . |
| 37 | + |
| 38 | +# Linting |
| 39 | +ruff check . |
| 40 | + |
| 41 | +# Type checking |
| 42 | +mypy app/ |
| 43 | + |
| 44 | +# Test coverage |
| 45 | +pytest --cov=app tests/ |
| 46 | +# Target: ≥80% coverage for app/ package |
| 47 | +``` |
| 48 | + |
| 49 | +### Testing Standards |
| 50 | +- **Test organization**: Place tests in `tests/` using `test_<feature>.py` naming |
| 51 | +- **Test types**: |
| 52 | + - Unit tests: Individual functions and classes |
| 53 | + - Integration tests: FastAPI routes + tool layer helpers |
| 54 | + - SEO tests: Meta tags, schema.org, sitemap validation |
| 55 | +- **Fixtures**: Create reusable fixtures for database, API clients, mock data |
| 56 | +- **Coverage**: Maintain ≥80% coverage for the `app/` package |
| 57 | +- **Focus areas**: Prioritize testing caching, concurrency, and SEO logic |
| 58 | + |
| 59 | +## Logging Standards |
| 60 | + |
| 61 | +### Structured Logging |
| 62 | +Use `app/logger.py` for all logging needs: |
| 63 | + |
| 64 | +```python |
| 65 | +from app.logger import logger |
| 66 | + |
| 67 | +# Good: Structured logging with context |
| 68 | +logger.info("geo_center_calculated", extra={ |
| 69 | + "center_lat": 39.9042, |
| 70 | + "center_lng": 116.4074, |
| 71 | + "locations_count": 3, |
| 72 | + "processing_time": 1.2 |
| 73 | +}) |
| 74 | + |
| 75 | +# Bad: Unstructured string logging |
| 76 | +logger.info("Calculated center at 39.9042, 116.4074") |
| 77 | +``` |
| 78 | + |
| 79 | +### Log Levels |
| 80 | +- **DEBUG**: Detailed diagnostic information |
| 81 | +- **INFO**: General operational messages |
| 82 | +- **WARNING**: Something unexpected but recoverable |
| 83 | +- **ERROR**: Error conditions that don't stop execution |
| 84 | +- **CRITICAL**: Serious errors that may abort execution |
| 85 | + |
| 86 | +## Performance Guidelines |
| 87 | + |
| 88 | +### Memory Management |
| 89 | +- **Concurrency**: Respect `MAX_CONCURRENT_REQUESTS = 3` semaphore |
| 90 | +- **Caching**: Use LRU cache with reasonable limits (30 geocodes, 15 POI searches) |
| 91 | +- **Cleanup**: Call `gc.collect()` after memory-intensive operations |
| 92 | +- **Agent mode**: Currently disabled to save memory on Render free tier |
| 93 | + |
| 94 | +### Async Best Practices |
| 95 | +- **All I/O async**: Use aiohttp, aiofiles, async database operations |
| 96 | +- **Concurrent operations**: Use `asyncio.gather()` for parallel API calls |
| 97 | +- **Error handling**: Always handle async exceptions properly |
| 98 | +- **Session management**: Reuse HTTP sessions, close properly |
| 99 | + |
| 100 | +### Caching Strategy |
| 101 | +- **HTTP caching**: Set appropriate Cache-Control headers |
| 102 | + - Immutable assets: 1 year |
| 103 | + - Images: 30 days |
| 104 | + - Dynamic content: no-cache |
| 105 | +- **Application caching**: Use LRU cache for expensive operations |
| 106 | +- **Database caching**: Cache frequently accessed data |
| 107 | + |
| 108 | +## Security Standards |
| 109 | + |
| 110 | +### API Security |
| 111 | +- **Authentication**: Use JWT tokens for protected endpoints |
| 112 | +- **Rate limiting**: Apply appropriate limits (default 60/minute) |
| 113 | +- **Input validation**: Validate all inputs using Pydantic models |
| 114 | +- **CORS**: Configure appropriately for production |
| 115 | +- **Environment variables**: Never hardcode secrets, use `.env` files |
| 116 | + |
| 117 | +### Data Protection |
| 118 | +- **PII handling**: Mask phone numbers in logs and responses |
| 119 | +- **Token security**: Use secure JWT signing, appropriate expiration |
| 120 | +- **Database**: Use parameterized queries (SQLAlchemy ORM handles this) |
| 121 | +- **File uploads**: Validate file types and sizes if implemented |
| 122 | + |
| 123 | +## Configuration Management |
| 124 | + |
| 125 | +### Environment Variables |
| 126 | +Required variables: |
| 127 | +```bash |
| 128 | +AMAP_API_KEY # Required: Amap API key |
| 129 | +``` |
| 130 | + |
| 131 | +Optional variables: |
| 132 | +```bash |
| 133 | +AMAP_SECURITY_JS_CODE # Amap JS security code |
| 134 | +AMAP_JS_API_KEY # Amap JS API key |
| 135 | +LLM_API_KEY # LLM API key |
| 136 | +LLM_API_BASE # LLM base URL |
| 137 | +LLM_MODEL # LLM model name |
| 138 | +OPENAI_API_KEY # Alternative OpenAI key |
| 139 | +PORT # Server port (default 8000) |
| 140 | +LOG_LEVEL # Logging level |
| 141 | +``` |
| 142 | + |
| 143 | +### Configuration Hierarchy |
| 144 | +1. Environment variables (highest priority) |
| 145 | +2. `config/config.toml` file |
| 146 | +3. `config/config.toml.example` (fallback) |
| 147 | +4. Hardcoded defaults (lowest priority) |
| 148 | + |
| 149 | +### Adding New Configuration |
| 150 | +1. Add to appropriate settings class in `app/config.py` |
| 151 | +2. Update `AppConfig` model |
| 152 | +3. Add environment variable support |
| 153 | +4. Update `config/config.toml.example` |
| 154 | +5. Document in README.md |
| 155 | + |
| 156 | +## Error Handling |
| 157 | + |
| 158 | +### Exception Handling |
| 159 | +- **Custom exceptions**: Use classes from `app/exceptions.py` |
| 160 | +- **HTTP errors**: Return appropriate status codes with meaningful messages |
| 161 | +- **Async exceptions**: Always handle in async contexts |
| 162 | +- **Logging**: Log errors with context for debugging |
| 163 | + |
| 164 | +### API Error Responses |
| 165 | +```python |
| 166 | +# Good: Structured error response |
| 167 | +{ |
| 168 | + "success": false, |
| 169 | + "error": "geocoding_failed", |
| 170 | + "message": "无法解析地址: 北京市朝阳区", |
| 171 | + "details": { |
| 172 | + "address": "北京市朝阳区", |
| 173 | + "provider": "amap" |
| 174 | + } |
| 175 | +} |
| 176 | +``` |
| 177 | + |
| 178 | +## Documentation Standards |
| 179 | + |
| 180 | +### Code Documentation |
| 181 | +- **Docstrings**: Use Google-style docstrings for all public functions/classes |
| 182 | +- **Type hints**: Comprehensive type annotations |
| 183 | +- **Comments**: Explain complex business logic, not obvious code |
| 184 | +- **README**: Keep up-to-date with setup instructions and API documentation |
| 185 | + |
| 186 | +### API Documentation |
| 187 | +- **FastAPI**: Automatic OpenAPI/Swagger documentation |
| 188 | +- **Endpoint descriptions**: Clear, concise descriptions of what each endpoint does |
| 189 | +- **Request/response examples**: Provide realistic examples |
| 190 | +- **Error codes**: Document all possible error responses |
0 commit comments