@su-record/vibe 2.4.72 → 2.4.76
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/CLAUDE.md +216 -215
- package/README.md +4 -4
- package/agents/research/best-practices-agent.md +13 -13
- package/agents/research/codebase-patterns-agent.md +33 -33
- package/agents/research/framework-docs-agent.md +23 -23
- package/agents/research/security-advisory-agent.md +29 -29
- package/agents/review/architecture-reviewer.md +31 -31
- package/agents/review/complexity-reviewer.md +21 -21
- package/agents/review/data-integrity-reviewer.md +29 -29
- package/agents/review/git-history-reviewer.md +24 -24
- package/agents/review/performance-reviewer.md +29 -29
- package/agents/review/python-reviewer.md +53 -53
- package/agents/review/rails-reviewer.md +40 -40
- package/agents/review/react-reviewer.md +40 -40
- package/agents/review/security-reviewer.md +29 -29
- package/agents/review/simplicity-reviewer.md +24 -24
- package/agents/review/test-coverage-reviewer.md +31 -31
- package/agents/review/typescript-reviewer.md +41 -41
- package/commands/vibe.analyze.md +103 -7
- package/commands/vibe.reason.md +106 -0
- package/commands/vibe.review.md +123 -38
- package/commands/vibe.run.md +286 -223
- package/commands/vibe.spec.md +425 -186
- package/commands/vibe.utils.md +104 -3
- package/commands/vibe.verify.md +179 -86
- package/dist/cli/detect.js +40 -40
- package/dist/cli/detect.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/llm.js +5 -5
- package/dist/cli/llm.js.map +1 -1
- package/dist/cli/setup.js +3 -3
- package/dist/cli/setup.js.map +1 -1
- package/dist/lib/ContextCompressor.js +1 -1
- package/dist/lib/ContextCompressor.js.map +1 -1
- package/dist/lib/MemoryManager.d.ts +13 -155
- package/dist/lib/MemoryManager.d.ts.map +1 -1
- package/dist/lib/MemoryManager.js +52 -617
- package/dist/lib/MemoryManager.js.map +1 -1
- package/dist/lib/gemini-api.js +12 -12
- package/dist/lib/gemini-api.js.map +1 -1
- package/dist/lib/gemini-oauth.js +22 -22
- package/dist/lib/gemini-oauth.js.map +1 -1
- package/dist/lib/gemini-storage.js +3 -3
- package/dist/lib/gemini-storage.js.map +1 -1
- package/dist/lib/gpt-api.js +11 -11
- package/dist/lib/gpt-api.js.map +1 -1
- package/dist/lib/gpt-oauth.js +28 -28
- package/dist/lib/gpt-oauth.js.map +1 -1
- package/dist/lib/gpt-storage.js +3 -3
- package/dist/lib/gpt-storage.js.map +1 -1
- package/dist/lib/memory/KnowledgeGraph.d.ts +34 -0
- package/dist/lib/memory/KnowledgeGraph.d.ts.map +1 -0
- package/dist/lib/memory/KnowledgeGraph.js +216 -0
- package/dist/lib/memory/KnowledgeGraph.js.map +1 -0
- package/dist/lib/memory/KnowledgeGraph.test.d.ts +2 -0
- package/dist/lib/memory/KnowledgeGraph.test.d.ts.map +1 -0
- package/dist/lib/memory/KnowledgeGraph.test.js +189 -0
- package/dist/lib/memory/KnowledgeGraph.test.js.map +1 -0
- package/dist/lib/memory/MemorySearch.d.ts +25 -0
- package/dist/lib/memory/MemorySearch.d.ts.map +1 -0
- package/dist/lib/memory/MemorySearch.js +85 -0
- package/dist/lib/memory/MemorySearch.js.map +1 -0
- package/dist/lib/memory/MemorySearch.test.d.ts +2 -0
- package/dist/lib/memory/MemorySearch.test.d.ts.map +1 -0
- package/dist/lib/memory/MemorySearch.test.js +149 -0
- package/dist/lib/memory/MemorySearch.test.js.map +1 -0
- package/dist/lib/memory/MemoryStorage.d.ts +77 -0
- package/dist/lib/memory/MemoryStorage.d.ts.map +1 -0
- package/dist/lib/memory/MemoryStorage.js +278 -0
- package/dist/lib/memory/MemoryStorage.js.map +1 -0
- package/dist/lib/memory/MemoryStorage.test.d.ts +2 -0
- package/dist/lib/memory/MemoryStorage.test.d.ts.map +1 -0
- package/dist/lib/memory/MemoryStorage.test.js +198 -0
- package/dist/lib/memory/MemoryStorage.test.js.map +1 -0
- package/dist/lib/memory/index.d.ts +4 -0
- package/dist/lib/memory/index.d.ts.map +1 -0
- package/dist/lib/memory/index.js +8 -0
- package/dist/lib/memory/index.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/orchestrator.js +4 -6
- package/dist/orchestrator/orchestrator.js.map +1 -1
- package/dist/tools/convention/analyzeComplexity.d.ts +3 -1
- package/dist/tools/convention/analyzeComplexity.d.ts.map +1 -1
- package/dist/tools/convention/analyzeComplexity.js +102 -4
- package/dist/tools/convention/analyzeComplexity.js.map +1 -1
- package/dist/tools/convention/analyzeComplexity.test.d.ts +2 -0
- package/dist/tools/convention/analyzeComplexity.test.d.ts.map +1 -0
- package/dist/tools/convention/analyzeComplexity.test.js +207 -0
- package/dist/tools/convention/analyzeComplexity.test.js.map +1 -0
- package/dist/tools/convention/applyQualityRules.js +1 -1
- package/dist/tools/convention/applyQualityRules.js.map +1 -1
- package/dist/tools/convention/checkCouplingCohesion.js +2 -2
- package/dist/tools/convention/checkCouplingCohesion.js.map +1 -1
- package/dist/tools/convention/suggestImprovements.js +1 -1
- package/dist/tools/convention/suggestImprovements.js.map +1 -1
- package/dist/tools/convention/validateCodeQuality.d.ts +3 -1
- package/dist/tools/convention/validateCodeQuality.d.ts.map +1 -1
- package/dist/tools/convention/validateCodeQuality.js +145 -2
- package/dist/tools/convention/validateCodeQuality.js.map +1 -1
- package/dist/tools/convention/validateCodeQuality.test.d.ts +2 -0
- package/dist/tools/convention/validateCodeQuality.test.d.ts.map +1 -0
- package/dist/tools/convention/validateCodeQuality.test.js +230 -0
- package/dist/tools/convention/validateCodeQuality.test.js.map +1 -0
- package/dist/tools/memory/autoSaveContext.js +1 -1
- package/dist/tools/memory/autoSaveContext.js.map +1 -1
- package/dist/tools/memory/createMemoryTimeline.js +27 -27
- package/dist/tools/memory/createMemoryTimeline.js.map +1 -1
- package/dist/tools/memory/deleteMemory.js +1 -1
- package/dist/tools/memory/deleteMemory.js.map +1 -1
- package/dist/tools/memory/getMemoryGraph.js +24 -24
- package/dist/tools/memory/getMemoryGraph.js.map +1 -1
- package/dist/tools/memory/getSessionContext.js +36 -36
- package/dist/tools/memory/getSessionContext.js.map +1 -1
- package/dist/tools/memory/linkMemories.js +21 -21
- package/dist/tools/memory/linkMemories.js.map +1 -1
- package/dist/tools/memory/prioritizeMemory.js +1 -1
- package/dist/tools/memory/prioritizeMemory.js.map +1 -1
- package/dist/tools/memory/restoreSessionContext.js +1 -1
- package/dist/tools/memory/restoreSessionContext.js.map +1 -1
- package/dist/tools/memory/searchMemories.js +1 -1
- package/dist/tools/memory/searchMemories.js.map +1 -1
- package/dist/tools/memory/searchMemoriesAdvanced.js +42 -42
- package/dist/tools/memory/searchMemoriesAdvanced.js.map +1 -1
- package/dist/tools/memory/startSession.js +2 -2
- package/dist/tools/memory/startSession.js.map +1 -1
- package/dist/tools/memory/updateMemory.js +1 -1
- package/dist/tools/memory/updateMemory.js.map +1 -1
- package/dist/tools/semantic/analyzeDependencyGraph.js +38 -38
- package/dist/tools/semantic/analyzeDependencyGraph.js.map +1 -1
- package/dist/tools/semantic/findReferences.js +1 -1
- package/dist/tools/semantic/findReferences.js.map +1 -1
- package/dist/tools/semantic/findSymbol.js +1 -1
- package/dist/tools/semantic/findSymbol.js.map +1 -1
- package/dist/tools/time/getCurrentTime.js +1 -1
- package/dist/tools/time/getCurrentTime.js.map +1 -1
- package/dist/tools/ui/previewUiAscii.js +2 -2
- package/dist/tools/ui/previewUiAscii.js.map +1 -1
- package/hooks/hooks.json +11 -2
- package/hooks/scripts/llm-orchestrate.js +1 -1
- package/hooks/scripts/utils.js +31 -6
- package/languages/csharp-unity.md +82 -83
- package/languages/dart-flutter.md +89 -88
- package/languages/go.md +76 -75
- package/languages/java-spring.md +85 -84
- package/languages/kotlin-android.md +64 -63
- package/languages/python-django.md +83 -82
- package/languages/python-fastapi.md +82 -81
- package/languages/rust.md +75 -74
- package/languages/swift-ios.md +73 -72
- package/languages/typescript-electron.md +70 -71
- package/languages/typescript-nextjs.md +93 -92
- package/languages/typescript-node.md +64 -63
- package/languages/typescript-nuxt.md +113 -112
- package/languages/typescript-react-native.md +82 -81
- package/languages/typescript-react.md +76 -75
- package/languages/typescript-tauri.md +74 -75
- package/languages/typescript-vue.md +73 -72
- package/package.json +1 -1
- package/skills/git-worktree.md +25 -25
- package/skills/multi-llm-orchestration.md +4 -6
- package/skills/priority-todos.md +39 -39
- package/skills/vibe-capabilities.md +2 -2
- package/vibe/config.json +2 -2
|
@@ -1,39 +1,40 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Python + FastAPI Quality Rules
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Core Principles (inherited from core)
|
|
4
4
|
|
|
5
5
|
```markdown
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
# Core Principles (inherited from core)
|
|
7
|
+
Single Responsibility (SRP)
|
|
8
|
+
No Duplication (DRY)
|
|
9
|
+
Reusability
|
|
10
|
+
Low Complexity
|
|
11
|
+
Function <= 30 lines (recommended), <= 50 lines (allowed)
|
|
12
|
+
Nesting <= 3 levels
|
|
13
|
+
Cyclomatic complexity <= 10
|
|
13
14
|
```
|
|
14
15
|
|
|
15
|
-
## Python
|
|
16
|
+
## Python Specific Rules
|
|
16
17
|
|
|
17
|
-
### 1.
|
|
18
|
+
### 1. 100% Type Hints Required
|
|
18
19
|
|
|
19
20
|
```python
|
|
20
|
-
#
|
|
21
|
+
# Bad: No type hints
|
|
21
22
|
def get_user(user_id):
|
|
22
23
|
return db.get(user_id)
|
|
23
24
|
|
|
24
|
-
#
|
|
25
|
+
# Good: Complete type hints
|
|
25
26
|
async def get_user(user_id: str, db: AsyncSession) -> User | None:
|
|
26
27
|
result = await db.execute(select(User).where(User.id == user_id))
|
|
27
28
|
return result.scalar_one_or_none()
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
### 2.
|
|
31
|
+
### 2. Define Contract with Pydantic
|
|
31
32
|
|
|
32
33
|
```python
|
|
33
34
|
from pydantic import BaseModel, Field, EmailStr, field_validator
|
|
34
35
|
|
|
35
36
|
class CreateUserRequest(BaseModel):
|
|
36
|
-
"""
|
|
37
|
+
"""User creation request schema"""
|
|
37
38
|
email: EmailStr
|
|
38
39
|
username: str = Field(min_length=3, max_length=50)
|
|
39
40
|
password: str = Field(min_length=8)
|
|
@@ -56,25 +57,25 @@ class CreateUserRequest(BaseModel):
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
class UserResponse(BaseModel):
|
|
59
|
-
"""
|
|
60
|
+
"""User response schema"""
|
|
60
61
|
id: str
|
|
61
62
|
email: str
|
|
62
63
|
username: str
|
|
63
64
|
created_at: datetime
|
|
64
65
|
|
|
65
66
|
class Config:
|
|
66
|
-
from_attributes = True # SQLAlchemy
|
|
67
|
+
from_attributes = True # SQLAlchemy compatible
|
|
67
68
|
```
|
|
68
69
|
|
|
69
|
-
### 3. async/await
|
|
70
|
+
### 3. async/await Pattern
|
|
70
71
|
|
|
71
72
|
```python
|
|
72
|
-
#
|
|
73
|
+
# Good: Async I/O (database, API calls)
|
|
73
74
|
async def get_user_with_posts(
|
|
74
75
|
user_id: str,
|
|
75
76
|
db: AsyncSession
|
|
76
77
|
) -> tuple[User, list[Post]]:
|
|
77
|
-
#
|
|
78
|
+
# Parallel execution
|
|
78
79
|
user_task = db.execute(select(User).where(User.id == user_id))
|
|
79
80
|
posts_task = db.execute(select(Post).where(Post.user_id == user_id))
|
|
80
81
|
|
|
@@ -85,15 +86,15 @@ async def get_user_with_posts(
|
|
|
85
86
|
|
|
86
87
|
return user, posts
|
|
87
88
|
|
|
88
|
-
#
|
|
89
|
+
# Bad: Synchronous function (blocking)
|
|
89
90
|
def get_user(user_id: str):
|
|
90
|
-
return requests.get(f"/users/{user_id}") #
|
|
91
|
+
return requests.get(f"/users/{user_id}") # Blocking!
|
|
91
92
|
```
|
|
92
93
|
|
|
93
|
-
### 4. Early Return
|
|
94
|
+
### 4. Prefer Early Return
|
|
94
95
|
|
|
95
96
|
```python
|
|
96
|
-
#
|
|
97
|
+
# Bad: Nested if statements
|
|
97
98
|
async def process_order(order_id: str, db: AsyncSession):
|
|
98
99
|
order = await get_order(order_id, db)
|
|
99
100
|
if order:
|
|
@@ -103,7 +104,7 @@ async def process_order(order_id: str, db: AsyncSession):
|
|
|
103
104
|
return await process_items(order.items)
|
|
104
105
|
return None
|
|
105
106
|
|
|
106
|
-
#
|
|
107
|
+
# Good: Early return
|
|
107
108
|
async def process_order(order_id: str, db: AsyncSession) -> ProcessResult | None:
|
|
108
109
|
order = await get_order(order_id, db)
|
|
109
110
|
if not order:
|
|
@@ -118,12 +119,12 @@ async def process_order(order_id: str, db: AsyncSession) -> ProcessResult | None
|
|
|
118
119
|
return await process_items(order.items)
|
|
119
120
|
```
|
|
120
121
|
|
|
121
|
-
### 5. Repository
|
|
122
|
+
### 5. Repository Pattern (Separate Data Access)
|
|
122
123
|
|
|
123
124
|
```python
|
|
124
|
-
#
|
|
125
|
+
# Good: Repository layer
|
|
125
126
|
class UserRepository:
|
|
126
|
-
"""
|
|
127
|
+
"""Handles data access only"""
|
|
127
128
|
|
|
128
129
|
def __init__(self, db: AsyncSession):
|
|
129
130
|
self.db = db
|
|
@@ -146,9 +147,9 @@ class UserRepository:
|
|
|
146
147
|
)
|
|
147
148
|
return result.scalar_one_or_none()
|
|
148
149
|
|
|
149
|
-
#
|
|
150
|
+
# Good: Service layer (business logic)
|
|
150
151
|
class UserService:
|
|
151
|
-
"""
|
|
152
|
+
"""Handles business logic only"""
|
|
152
153
|
|
|
153
154
|
def __init__(self, repository: UserRepository):
|
|
154
155
|
self.repository = repository
|
|
@@ -156,15 +157,15 @@ class UserService:
|
|
|
156
157
|
async def create_user(
|
|
157
158
|
self, request: CreateUserRequest
|
|
158
159
|
) -> UserResponse:
|
|
159
|
-
#
|
|
160
|
+
# Business rule: Check email duplication
|
|
160
161
|
existing = await self.repository.get_by_email(request.email)
|
|
161
162
|
if existing:
|
|
162
163
|
raise HTTPException(409, detail="Email already exists")
|
|
163
164
|
|
|
164
|
-
#
|
|
165
|
+
# Business rule: Hash password
|
|
165
166
|
hashed_password = hash_password(request.password)
|
|
166
167
|
|
|
167
|
-
#
|
|
168
|
+
# Create
|
|
168
169
|
user = User(
|
|
169
170
|
email=request.email,
|
|
170
171
|
username=request.username,
|
|
@@ -175,14 +176,14 @@ class UserService:
|
|
|
175
176
|
return UserResponse.model_validate(user)
|
|
176
177
|
```
|
|
177
178
|
|
|
178
|
-
### 6.
|
|
179
|
+
### 6. Dependency Injection (FastAPI Depends)
|
|
179
180
|
|
|
180
181
|
```python
|
|
181
182
|
# app/core/deps.py
|
|
182
183
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
183
184
|
|
|
184
185
|
async def get_db() -> AsyncSession:
|
|
185
|
-
"""
|
|
186
|
+
"""Database session dependency"""
|
|
186
187
|
async with async_session_maker() as session:
|
|
187
188
|
yield session
|
|
188
189
|
|
|
@@ -190,7 +191,7 @@ async def get_current_user(
|
|
|
190
191
|
token: str = Depends(oauth2_scheme),
|
|
191
192
|
db: AsyncSession = Depends(get_db)
|
|
192
193
|
) -> User:
|
|
193
|
-
"""
|
|
194
|
+
"""Current user dependency"""
|
|
194
195
|
payload = decode_jwt(token)
|
|
195
196
|
user = await get_user_by_id(payload["sub"], db)
|
|
196
197
|
if not user:
|
|
@@ -202,16 +203,16 @@ async def get_current_user(
|
|
|
202
203
|
async def get_current_user_profile(
|
|
203
204
|
current_user: User = Depends(get_current_user)
|
|
204
205
|
):
|
|
205
|
-
"""
|
|
206
|
+
"""Get current user profile"""
|
|
206
207
|
return UserResponse.model_validate(current_user)
|
|
207
208
|
```
|
|
208
209
|
|
|
209
|
-
### 7.
|
|
210
|
+
### 7. Error Handling Standard
|
|
210
211
|
|
|
211
212
|
```python
|
|
212
213
|
from fastapi import HTTPException
|
|
213
214
|
|
|
214
|
-
#
|
|
215
|
+
# Good: Clear error messages
|
|
215
216
|
async def get_user(user_id: str, db: AsyncSession) -> User:
|
|
216
217
|
user = await db.get(User, user_id)
|
|
217
218
|
if not user:
|
|
@@ -221,13 +222,13 @@ async def get_user(user_id: str, db: AsyncSession) -> User:
|
|
|
221
222
|
)
|
|
222
223
|
return user
|
|
223
224
|
|
|
224
|
-
#
|
|
225
|
+
# Good: Custom exception
|
|
225
226
|
class UserNotFoundError(Exception):
|
|
226
227
|
def __init__(self, user_id: str):
|
|
227
228
|
self.user_id = user_id
|
|
228
229
|
super().__init__(f"User {user_id} not found")
|
|
229
230
|
|
|
230
|
-
#
|
|
231
|
+
# Global exception handler
|
|
231
232
|
@app.exception_handler(UserNotFoundError)
|
|
232
233
|
async def user_not_found_handler(request: Request, exc: UserNotFoundError):
|
|
233
234
|
return JSONResponse(
|
|
@@ -236,13 +237,13 @@ async def user_not_found_handler(request: Request, exc: UserNotFoundError):
|
|
|
236
237
|
)
|
|
237
238
|
```
|
|
238
239
|
|
|
239
|
-
### 8. SQLAlchemy 2.0
|
|
240
|
+
### 8. SQLAlchemy 2.0 Style
|
|
240
241
|
|
|
241
242
|
```python
|
|
242
243
|
from sqlalchemy import select, func
|
|
243
244
|
from sqlalchemy.orm import selectinload
|
|
244
245
|
|
|
245
|
-
#
|
|
246
|
+
# Good: 2.0 style (async + select)
|
|
246
247
|
async def get_users_with_posts(db: AsyncSession) -> list[User]:
|
|
247
248
|
result = await db.execute(
|
|
248
249
|
select(User)
|
|
@@ -253,30 +254,30 @@ async def get_users_with_posts(db: AsyncSession) -> list[User]:
|
|
|
253
254
|
)
|
|
254
255
|
return list(result.scalars().all())
|
|
255
256
|
|
|
256
|
-
#
|
|
257
|
+
# Bad: 1.x style (legacy)
|
|
257
258
|
def get_users():
|
|
258
259
|
return session.query(User).filter_by(is_active=True).all()
|
|
259
260
|
```
|
|
260
261
|
|
|
261
|
-
### 9. Python
|
|
262
|
+
### 9. Python Idioms
|
|
262
263
|
|
|
263
264
|
```python
|
|
264
|
-
#
|
|
265
|
+
# Good: List comprehension
|
|
265
266
|
active_users = [u for u in users if u.is_active]
|
|
266
267
|
|
|
267
|
-
#
|
|
268
|
+
# Good: Dictionary comprehension
|
|
268
269
|
user_dict = {u.id: u.name for u in users}
|
|
269
270
|
|
|
270
|
-
#
|
|
271
|
+
# Good: Generator expression (memory efficient)
|
|
271
272
|
total = sum(u.age for u in users)
|
|
272
273
|
|
|
273
|
-
#
|
|
274
|
+
# Good: Context manager
|
|
274
275
|
async with db.begin():
|
|
275
276
|
user = User(...)
|
|
276
277
|
db.add(user)
|
|
277
|
-
#
|
|
278
|
+
# Auto commit/rollback
|
|
278
279
|
|
|
279
|
-
#
|
|
280
|
+
# Good: Dataclass (simple data structure)
|
|
280
281
|
from dataclasses import dataclass
|
|
281
282
|
|
|
282
283
|
@dataclass(frozen=True) # Immutable
|
|
@@ -285,14 +286,14 @@ class Point:
|
|
|
285
286
|
y: float
|
|
286
287
|
```
|
|
287
288
|
|
|
288
|
-
### 10.
|
|
289
|
+
### 10. Logging Standard
|
|
289
290
|
|
|
290
291
|
```python
|
|
291
292
|
import structlog
|
|
292
293
|
|
|
293
294
|
logger = structlog.get_logger()
|
|
294
295
|
|
|
295
|
-
#
|
|
296
|
+
# Good: Structured logging
|
|
296
297
|
async def create_user(request: CreateUserRequest):
|
|
297
298
|
logger.info(
|
|
298
299
|
"user_creation_started",
|
|
@@ -318,30 +319,30 @@ async def create_user(request: CreateUserRequest):
|
|
|
318
319
|
raise
|
|
319
320
|
```
|
|
320
321
|
|
|
321
|
-
##
|
|
322
|
+
## Anti-patterns
|
|
322
323
|
|
|
323
324
|
```python
|
|
324
|
-
#
|
|
325
|
-
def process_data(data: any): #
|
|
325
|
+
# Bad: any type
|
|
326
|
+
def process_data(data: any): # Type safety lost
|
|
326
327
|
return data
|
|
327
328
|
|
|
328
|
-
#
|
|
329
|
+
# Bad: Blocking I/O in async function
|
|
329
330
|
async def bad_example():
|
|
330
|
-
data = requests.get("https://api.example.com") #
|
|
331
|
+
data = requests.get("https://api.example.com") # Blocking!
|
|
331
332
|
return data
|
|
332
333
|
|
|
333
|
-
#
|
|
334
|
+
# Bad: Ignoring exceptions
|
|
334
335
|
try:
|
|
335
336
|
risky_operation()
|
|
336
337
|
except:
|
|
337
|
-
pass #
|
|
338
|
+
pass # Dangerous!
|
|
338
339
|
|
|
339
|
-
#
|
|
340
|
-
def append_to_list(item, my_list=[]): #
|
|
340
|
+
# Bad: Mutable default argument
|
|
341
|
+
def append_to_list(item, my_list=[]): # Bug!
|
|
341
342
|
my_list.append(item)
|
|
342
343
|
return my_list
|
|
343
344
|
|
|
344
|
-
#
|
|
345
|
+
# Good: Correct way
|
|
345
346
|
def append_to_list(item, my_list: list | None = None):
|
|
346
347
|
if my_list is None:
|
|
347
348
|
my_list = []
|
|
@@ -349,38 +350,38 @@ def append_to_list(item, my_list: list | None = None):
|
|
|
349
350
|
return my_list
|
|
350
351
|
```
|
|
351
352
|
|
|
352
|
-
##
|
|
353
|
+
## Code Quality Tools
|
|
353
354
|
|
|
354
355
|
```bash
|
|
355
|
-
#
|
|
356
|
+
# Formatting
|
|
356
357
|
black .
|
|
357
358
|
isort .
|
|
358
359
|
|
|
359
|
-
#
|
|
360
|
+
# Linting
|
|
360
361
|
flake8 .
|
|
361
362
|
ruff check .
|
|
362
363
|
|
|
363
|
-
#
|
|
364
|
+
# Type check
|
|
364
365
|
mypy app/ --strict
|
|
365
366
|
|
|
366
|
-
#
|
|
367
|
+
# Testing
|
|
367
368
|
pytest tests/ -v --cov=app
|
|
368
369
|
|
|
369
|
-
#
|
|
370
|
+
# Security check
|
|
370
371
|
bandit -r app/
|
|
371
372
|
```
|
|
372
373
|
|
|
373
|
-
##
|
|
374
|
+
## Checklist
|
|
374
375
|
|
|
375
|
-
Python/FastAPI
|
|
376
|
+
When writing Python/FastAPI code:
|
|
376
377
|
|
|
377
|
-
- [ ]
|
|
378
|
-
- [ ]
|
|
379
|
-
- [ ] async/await
|
|
380
|
-
- [ ] Early return
|
|
381
|
-
- [ ] Repository + Service
|
|
382
|
-
- [ ]
|
|
383
|
-
- [ ]
|
|
384
|
-
- [ ]
|
|
385
|
-
- [ ]
|
|
386
|
-
- [ ]
|
|
378
|
+
- [ ] 100% type hints (function signatures, variables)
|
|
379
|
+
- [ ] Define contract with Pydantic schema
|
|
380
|
+
- [ ] Use async/await (I/O operations)
|
|
381
|
+
- [ ] Early return pattern
|
|
382
|
+
- [ ] Repository + Service layer separation
|
|
383
|
+
- [ ] Dependency injection (Depends)
|
|
384
|
+
- [ ] Clear error messages
|
|
385
|
+
- [ ] Structured logging
|
|
386
|
+
- [ ] Function <= 30 lines (SRP)
|
|
387
|
+
- [ ] Complexity <= 10
|