red64-cli 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/dist/cli/parseArgs.d.ts.map +1 -1
- package/dist/cli/parseArgs.js +5 -0
- package/dist/cli/parseArgs.js.map +1 -1
- package/dist/components/init/CompleteStep.d.ts.map +1 -1
- package/dist/components/init/CompleteStep.js +2 -2
- package/dist/components/init/CompleteStep.js.map +1 -1
- package/dist/components/init/TestCheckStep.d.ts +16 -0
- package/dist/components/init/TestCheckStep.d.ts.map +1 -0
- package/dist/components/init/TestCheckStep.js +120 -0
- package/dist/components/init/TestCheckStep.js.map +1 -0
- package/dist/components/init/index.d.ts +1 -0
- package/dist/components/init/index.d.ts.map +1 -1
- package/dist/components/init/index.js +1 -0
- package/dist/components/init/index.js.map +1 -1
- package/dist/components/init/types.d.ts +9 -0
- package/dist/components/init/types.d.ts.map +1 -1
- package/dist/components/screens/InitScreen.d.ts.map +1 -1
- package/dist/components/screens/InitScreen.js +69 -6
- package/dist/components/screens/InitScreen.js.map +1 -1
- package/dist/components/screens/ListScreen.d.ts.map +1 -1
- package/dist/components/screens/ListScreen.js +28 -3
- package/dist/components/screens/ListScreen.js.map +1 -1
- package/dist/components/screens/StartScreen.d.ts.map +1 -1
- package/dist/components/screens/StartScreen.js +212 -13
- package/dist/components/screens/StartScreen.js.map +1 -1
- package/dist/components/ui/ArtifactsSidebar.d.ts +19 -0
- package/dist/components/ui/ArtifactsSidebar.d.ts.map +1 -0
- package/dist/components/ui/ArtifactsSidebar.js +51 -0
- package/dist/components/ui/ArtifactsSidebar.js.map +1 -0
- package/dist/components/ui/FeatureSidebar.d.ts.map +1 -1
- package/dist/components/ui/FeatureSidebar.js +1 -1
- package/dist/components/ui/FeatureSidebar.js.map +1 -1
- package/dist/components/ui/index.d.ts +1 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +1 -0
- package/dist/components/ui/index.js.map +1 -1
- package/dist/services/ClaudeErrorDetector.js +3 -3
- package/dist/services/ClaudeErrorDetector.js.map +1 -1
- package/dist/services/ConfigService.d.ts +1 -0
- package/dist/services/ConfigService.d.ts.map +1 -1
- package/dist/services/ConfigService.js.map +1 -1
- package/dist/services/ProjectDetector.d.ts +28 -0
- package/dist/services/ProjectDetector.d.ts.map +1 -0
- package/dist/services/ProjectDetector.js +236 -0
- package/dist/services/ProjectDetector.js.map +1 -0
- package/dist/services/TestRunner.d.ts +46 -0
- package/dist/services/TestRunner.d.ts.map +1 -0
- package/dist/services/TestRunner.js +85 -0
- package/dist/services/TestRunner.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -0
- package/dist/services/index.js.map +1 -1
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/framework/.red64/settings/templates/specs/gap-analysis.md +163 -0
- package/framework/agents/claude/.claude/agents/red64/spec-impl.md +131 -2
- package/framework/agents/claude/.claude/agents/red64/validate-gap.md +13 -7
- package/framework/agents/claude/.claude/commands/red64/spec-impl.md +24 -0
- package/framework/agents/claude/.claude/commands/red64/validate-gap.md +4 -0
- package/framework/agents/codex/.codex/agents/red64/spec-impl.md +131 -2
- package/framework/agents/codex/.codex/agents/red64/validate-gap.md +13 -7
- package/framework/agents/codex/.codex/commands/red64/spec-impl.md +24 -0
- package/framework/agents/codex/.codex/commands/red64/validate-gap.md +4 -0
- package/framework/stacks/generic/feedback.md +80 -0
- package/framework/stacks/nextjs/accessibility.md +437 -0
- package/framework/stacks/nextjs/api.md +431 -0
- package/framework/stacks/nextjs/coding-style.md +282 -0
- package/framework/stacks/nextjs/commenting.md +226 -0
- package/framework/stacks/nextjs/components.md +411 -0
- package/framework/stacks/nextjs/conventions.md +333 -0
- package/framework/stacks/nextjs/css.md +310 -0
- package/framework/stacks/nextjs/error-handling.md +442 -0
- package/framework/stacks/nextjs/feedback.md +124 -0
- package/framework/stacks/nextjs/migrations.md +332 -0
- package/framework/stacks/nextjs/models.md +362 -0
- package/framework/stacks/nextjs/queries.md +410 -0
- package/framework/stacks/nextjs/responsive.md +338 -0
- package/framework/stacks/nextjs/tech-stack.md +177 -0
- package/framework/stacks/nextjs/test-writing.md +475 -0
- package/framework/stacks/nextjs/validation.md +467 -0
- package/framework/stacks/python/api.md +468 -0
- package/framework/stacks/python/authentication.md +342 -0
- package/framework/stacks/python/code-quality.md +283 -0
- package/framework/stacks/python/code-refactoring.md +315 -0
- package/framework/stacks/python/coding-style.md +462 -0
- package/framework/stacks/python/conventions.md +399 -0
- package/framework/stacks/python/error-handling.md +512 -0
- package/framework/stacks/python/feedback.md +92 -0
- package/framework/stacks/python/implement-ai-llm.md +468 -0
- package/framework/stacks/python/migrations.md +388 -0
- package/framework/stacks/python/models.md +399 -0
- package/framework/stacks/python/python.md +232 -0
- package/framework/stacks/python/queries.md +451 -0
- package/framework/stacks/python/structure.md +245 -58
- package/framework/stacks/python/tech.md +92 -35
- package/framework/stacks/python/testing.md +380 -0
- package/framework/stacks/python/validation.md +471 -0
- package/framework/stacks/rails/authentication.md +176 -0
- package/framework/stacks/rails/code-quality.md +287 -0
- package/framework/stacks/rails/code-refactoring.md +299 -0
- package/framework/stacks/rails/feedback.md +130 -0
- package/framework/stacks/rails/implement-ai-llm-with-rubyllm.md +342 -0
- package/framework/stacks/rails/rails.md +301 -0
- package/framework/stacks/rails/rails8-best-practices.md +498 -0
- package/framework/stacks/rails/rails8-css.md +573 -0
- package/framework/stacks/rails/structure.md +140 -0
- package/framework/stacks/rails/tech.md +108 -0
- package/framework/stacks/react/code-quality.md +521 -0
- package/framework/stacks/react/components.md +625 -0
- package/framework/stacks/react/data-fetching.md +586 -0
- package/framework/stacks/react/feedback.md +110 -0
- package/framework/stacks/react/forms.md +694 -0
- package/framework/stacks/react/performance.md +640 -0
- package/framework/stacks/react/product.md +22 -9
- package/framework/stacks/react/state-management.md +472 -0
- package/framework/stacks/react/structure.md +351 -44
- package/framework/stacks/react/tech.md +219 -30
- package/framework/stacks/react/testing.md +690 -0
- package/package.json +1 -1
- package/framework/stacks/node/product.md +0 -27
- package/framework/stacks/node/structure.md +0 -82
- package/framework/stacks/node/tech.md +0 -63
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
# Development Conventions
|
|
2
|
+
|
|
3
|
+
General development practices, workflow, and operational standards for Python projects.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
- **Predictable process**: Consistent workflows reduce friction and errors
|
|
10
|
+
- **Automated enforcement**: Linters and CI catch what humans miss
|
|
11
|
+
- **Observable systems**: If you cannot see it, you cannot fix it
|
|
12
|
+
- **Documentation as code**: Keep docs next to the code they describe
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Git Workflow
|
|
17
|
+
|
|
18
|
+
### Branch Strategy
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
main # Production-ready, always deployable
|
|
22
|
+
└── feat/... # Feature branches (short-lived)
|
|
23
|
+
└── fix/... # Bug fix branches
|
|
24
|
+
└── chore/... # Maintenance, dependency updates
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Branch Naming
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
feat/add-user-registration
|
|
31
|
+
fix/duplicate-email-validation
|
|
32
|
+
chore/upgrade-sqlalchemy
|
|
33
|
+
refactor/extract-payment-service
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Pattern**: `{type}/{short-description}` with lowercase and hyphens.
|
|
37
|
+
|
|
38
|
+
### Workflow
|
|
39
|
+
|
|
40
|
+
1. Create branch from `main`
|
|
41
|
+
2. Make small, focused commits
|
|
42
|
+
3. Open PR when ready for review
|
|
43
|
+
4. Squash merge into `main`
|
|
44
|
+
5. Delete branch after merge
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Commit Conventions
|
|
49
|
+
|
|
50
|
+
### Conventional Commits
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
feat: add user registration endpoint
|
|
54
|
+
fix: prevent duplicate email registration
|
|
55
|
+
refactor: extract password hashing to utility module
|
|
56
|
+
test: add integration tests for payment flow
|
|
57
|
+
docs: update API authentication guide
|
|
58
|
+
chore: upgrade pydantic to v2.10
|
|
59
|
+
ci: add migration check to CI pipeline
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Format
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
{type}: {short description}
|
|
66
|
+
|
|
67
|
+
{optional body explaining why, not what}
|
|
68
|
+
|
|
69
|
+
{optional footer: BREAKING CHANGE, Closes #123}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Types
|
|
73
|
+
|
|
74
|
+
| Type | Description |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `feat` | New feature or capability |
|
|
77
|
+
| `fix` | Bug fix |
|
|
78
|
+
| `refactor` | Code change that neither fixes nor adds |
|
|
79
|
+
| `test` | Adding or updating tests |
|
|
80
|
+
| `docs` | Documentation only |
|
|
81
|
+
| `chore` | Maintenance, dependencies, tooling |
|
|
82
|
+
| `ci` | CI/CD configuration changes |
|
|
83
|
+
| `perf` | Performance improvement |
|
|
84
|
+
|
|
85
|
+
**Rule**: One logical change per commit. If the commit message needs "and", split it.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Environment Configuration
|
|
90
|
+
|
|
91
|
+
### pydantic-settings
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
# app/config.py
|
|
95
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class Settings(BaseSettings):
|
|
99
|
+
model_config = SettingsConfigDict(
|
|
100
|
+
env_file=".env",
|
|
101
|
+
env_file_encoding="utf-8",
|
|
102
|
+
case_sensitive=False,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
# Application
|
|
106
|
+
app_name: str = "my-app"
|
|
107
|
+
debug: bool = False
|
|
108
|
+
environment: str = "development" # development | staging | production
|
|
109
|
+
|
|
110
|
+
# Database
|
|
111
|
+
database_url: str
|
|
112
|
+
database_pool_size: int = 20
|
|
113
|
+
database_max_overflow: int = 10
|
|
114
|
+
|
|
115
|
+
# Auth
|
|
116
|
+
secret_key: str
|
|
117
|
+
access_token_expire_minutes: int = 15
|
|
118
|
+
|
|
119
|
+
# External services
|
|
120
|
+
redis_url: str = "redis://localhost:6379/0"
|
|
121
|
+
sentry_dsn: str | None = None
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
settings = Settings()
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### .env Files
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# .env (local development -- NEVER commit)
|
|
131
|
+
DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/myapp
|
|
132
|
+
SECRET_KEY=dev-secret-key-not-for-production
|
|
133
|
+
DEBUG=true
|
|
134
|
+
|
|
135
|
+
# .env.example (committed, documents required vars)
|
|
136
|
+
DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/myapp
|
|
137
|
+
SECRET_KEY=change-me
|
|
138
|
+
DEBUG=false
|
|
139
|
+
REDIS_URL=redis://localhost:6379/0
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### .gitignore Rules
|
|
143
|
+
|
|
144
|
+
```gitignore
|
|
145
|
+
# Environment
|
|
146
|
+
.env
|
|
147
|
+
.env.local
|
|
148
|
+
.env.production
|
|
149
|
+
|
|
150
|
+
# Keep example
|
|
151
|
+
!.env.example
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Rules**:
|
|
155
|
+
- Never commit `.env` files with real values
|
|
156
|
+
- Always commit `.env.example` with placeholder values
|
|
157
|
+
- Use `pydantic-settings` for type-safe config with validation
|
|
158
|
+
- Fail fast on missing required variables (no defaults for secrets)
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Documentation Standards
|
|
163
|
+
|
|
164
|
+
### Code Documentation
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
# Module-level docstring (every module)
|
|
168
|
+
"""User service for account management.
|
|
169
|
+
|
|
170
|
+
Handles user registration, authentication, and profile updates.
|
|
171
|
+
"""
|
|
172
|
+
|
|
173
|
+
# Google-style docstrings for public functions
|
|
174
|
+
async def create_user(self, data: CreateUserRequest) -> User:
|
|
175
|
+
"""Create a new user account.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
data: Validated user creation request.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
The created User instance with generated ID.
|
|
182
|
+
|
|
183
|
+
Raises:
|
|
184
|
+
ConflictError: If email is already registered.
|
|
185
|
+
"""
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### When to Write Docstrings
|
|
189
|
+
|
|
190
|
+
| Element | Docstring Required? |
|
|
191
|
+
|---|---|
|
|
192
|
+
| Public module | Yes |
|
|
193
|
+
| Public class | Yes |
|
|
194
|
+
| Public function/method | Yes |
|
|
195
|
+
| Private function (`_func`) | Only if non-obvious |
|
|
196
|
+
| Test functions | No (test name is the doc) |
|
|
197
|
+
| Pydantic models | Yes (appears in OpenAPI) |
|
|
198
|
+
|
|
199
|
+
### Inline Comments
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
# GOOD: Explain WHY, not what
|
|
203
|
+
# Rate limit to 5/min to prevent brute force attacks
|
|
204
|
+
@limiter.limit("5/minute")
|
|
205
|
+
|
|
206
|
+
# BAD: Restates the code
|
|
207
|
+
# Set x to 5
|
|
208
|
+
x = 5
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## PR Review Checklist
|
|
214
|
+
|
|
215
|
+
### Author Checklist (Before Requesting Review)
|
|
216
|
+
|
|
217
|
+
- [ ] Tests pass locally (`uv run pytest`)
|
|
218
|
+
- [ ] Linting passes (`uv run ruff check .`)
|
|
219
|
+
- [ ] Types check (`uv run mypy src/`)
|
|
220
|
+
- [ ] New features have tests
|
|
221
|
+
- [ ] No secrets or credentials committed
|
|
222
|
+
- [ ] Migration is reversible (if applicable)
|
|
223
|
+
- [ ] PR description explains WHY, not just what
|
|
224
|
+
|
|
225
|
+
### Reviewer Checklist
|
|
226
|
+
|
|
227
|
+
- [ ] Code is clear and follows project conventions
|
|
228
|
+
- [ ] Error cases are handled
|
|
229
|
+
- [ ] No N+1 queries introduced
|
|
230
|
+
- [ ] No security concerns (injection, auth bypass, data exposure)
|
|
231
|
+
- [ ] Tests cover happy path and edge cases
|
|
232
|
+
- [ ] API changes are backward compatible (or versioned)
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Release Process
|
|
237
|
+
|
|
238
|
+
### Versioning
|
|
239
|
+
|
|
240
|
+
Follow semantic versioning: `MAJOR.MINOR.PATCH`
|
|
241
|
+
|
|
242
|
+
| Change | Version Bump | Example |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| Breaking API change | Major | 1.0.0 -> 2.0.0 |
|
|
245
|
+
| New feature, backward compatible | Minor | 1.0.0 -> 1.1.0 |
|
|
246
|
+
| Bug fix | Patch | 1.0.0 -> 1.0.1 |
|
|
247
|
+
|
|
248
|
+
### Release Steps
|
|
249
|
+
|
|
250
|
+
1. Update version in `pyproject.toml`
|
|
251
|
+
2. Update changelog
|
|
252
|
+
3. Create PR: `chore: release v1.2.0`
|
|
253
|
+
4. Merge to `main`
|
|
254
|
+
5. Tag: `git tag v1.2.0`
|
|
255
|
+
6. Push tag: `git push origin v1.2.0`
|
|
256
|
+
7. CI deploys from tag
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Logging Conventions
|
|
261
|
+
|
|
262
|
+
### Log Levels
|
|
263
|
+
|
|
264
|
+
| Level | Use Case | Example |
|
|
265
|
+
|---|---|---|
|
|
266
|
+
| `DEBUG` | Development details | SQL queries, cache hits |
|
|
267
|
+
| `INFO` | Normal operations | Request handled, user created |
|
|
268
|
+
| `WARNING` | Recoverable issues | Retry succeeded, deprecated usage |
|
|
269
|
+
| `ERROR` | Failed operations | Payment failed, external service down |
|
|
270
|
+
| `CRITICAL` | System unusable | Database connection lost, out of memory |
|
|
271
|
+
|
|
272
|
+
### Structured Logging
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
import structlog
|
|
276
|
+
|
|
277
|
+
logger = structlog.get_logger()
|
|
278
|
+
|
|
279
|
+
# GOOD: Structured key-value pairs
|
|
280
|
+
logger.info("user_created", user_id=42, email="a@b.com")
|
|
281
|
+
logger.error("payment_failed", order_id=123, provider="stripe", error="timeout")
|
|
282
|
+
|
|
283
|
+
# BAD: String interpolation
|
|
284
|
+
logger.info(f"User {user_id} created with email {email}")
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### What to Log
|
|
288
|
+
|
|
289
|
+
| Event | Level | Context |
|
|
290
|
+
|---|---|---|
|
|
291
|
+
| Request received | DEBUG | method, path, user_id |
|
|
292
|
+
| Business operation complete | INFO | entity_id, action |
|
|
293
|
+
| External service call | INFO | service, duration_ms |
|
|
294
|
+
| Retry attempt | WARNING | service, attempt, max_attempts |
|
|
295
|
+
| Operation failed | ERROR | operation, error, context |
|
|
296
|
+
| Startup/shutdown | INFO | version, environment |
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Monitoring and Observability
|
|
301
|
+
|
|
302
|
+
### Health Checks
|
|
303
|
+
|
|
304
|
+
```python
|
|
305
|
+
# Liveness: is the process running?
|
|
306
|
+
GET /api/v1/health -> {"status": "ok"}
|
|
307
|
+
|
|
308
|
+
# Readiness: can it serve traffic?
|
|
309
|
+
GET /api/v1/health/ready -> {"status": "ready", "database": "connected"}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Metrics to Track
|
|
313
|
+
|
|
314
|
+
| Metric | Type | Purpose |
|
|
315
|
+
|---|---|---|
|
|
316
|
+
| Request latency (p50, p95, p99) | Histogram | Performance monitoring |
|
|
317
|
+
| Request rate | Counter | Traffic patterns |
|
|
318
|
+
| Error rate (4xx, 5xx) | Counter | Reliability |
|
|
319
|
+
| Database query duration | Histogram | DB performance |
|
|
320
|
+
| External service latency | Histogram | Dependency health |
|
|
321
|
+
| Active connections (DB pool) | Gauge | Resource usage |
|
|
322
|
+
|
|
323
|
+
### Error Tracking
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
# Sentry integration
|
|
327
|
+
import sentry_sdk
|
|
328
|
+
|
|
329
|
+
sentry_sdk.init(
|
|
330
|
+
dsn=settings.sentry_dsn,
|
|
331
|
+
environment=settings.environment,
|
|
332
|
+
traces_sample_rate=0.1, # 10% of transactions
|
|
333
|
+
profiles_sample_rate=0.1,
|
|
334
|
+
)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Request Tracing
|
|
338
|
+
|
|
339
|
+
Include `X-Request-ID` in all log entries for request correlation:
|
|
340
|
+
|
|
341
|
+
```python
|
|
342
|
+
# Middleware sets request_id in structlog context
|
|
343
|
+
# All subsequent log entries include it automatically
|
|
344
|
+
logger.info("user_created", user_id=42)
|
|
345
|
+
# Output: {"event": "user_created", "user_id": 42, "request_id": "abc-123", ...}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Feature Flags
|
|
351
|
+
|
|
352
|
+
### Simple Implementation
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
# app/config.py
|
|
356
|
+
class Settings(BaseSettings):
|
|
357
|
+
# Feature flags
|
|
358
|
+
feature_new_onboarding: bool = False
|
|
359
|
+
feature_async_notifications: bool = False
|
|
360
|
+
|
|
361
|
+
# Usage
|
|
362
|
+
if settings.feature_new_onboarding:
|
|
363
|
+
await send_new_onboarding_email(user)
|
|
364
|
+
else:
|
|
365
|
+
await send_legacy_welcome_email(user)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
**Rule**: Use feature flags for incomplete features instead of long-lived branches. Remove flags promptly after rollout.
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Dependency Management
|
|
373
|
+
|
|
374
|
+
### uv for Package Management
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
# Add dependency
|
|
378
|
+
uv add fastapi
|
|
379
|
+
|
|
380
|
+
# Add dev dependency
|
|
381
|
+
uv add --dev pytest pytest-asyncio
|
|
382
|
+
|
|
383
|
+
# Update all dependencies
|
|
384
|
+
uv lock --upgrade
|
|
385
|
+
|
|
386
|
+
# Sync environment
|
|
387
|
+
uv sync
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Dependency Rules
|
|
391
|
+
|
|
392
|
+
- Pin major versions in `pyproject.toml`
|
|
393
|
+
- Run `uv lock --upgrade` regularly (weekly or per sprint)
|
|
394
|
+
- Audit for vulnerabilities: `uv run pip-audit`
|
|
395
|
+
- Document why non-obvious dependencies exist
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
_Conventions reduce cognitive load. Follow them consistently so the team can focus on solving problems, not debating style._
|