@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.
Files changed (164) hide show
  1. package/CLAUDE.md +216 -215
  2. package/README.md +4 -4
  3. package/agents/research/best-practices-agent.md +13 -13
  4. package/agents/research/codebase-patterns-agent.md +33 -33
  5. package/agents/research/framework-docs-agent.md +23 -23
  6. package/agents/research/security-advisory-agent.md +29 -29
  7. package/agents/review/architecture-reviewer.md +31 -31
  8. package/agents/review/complexity-reviewer.md +21 -21
  9. package/agents/review/data-integrity-reviewer.md +29 -29
  10. package/agents/review/git-history-reviewer.md +24 -24
  11. package/agents/review/performance-reviewer.md +29 -29
  12. package/agents/review/python-reviewer.md +53 -53
  13. package/agents/review/rails-reviewer.md +40 -40
  14. package/agents/review/react-reviewer.md +40 -40
  15. package/agents/review/security-reviewer.md +29 -29
  16. package/agents/review/simplicity-reviewer.md +24 -24
  17. package/agents/review/test-coverage-reviewer.md +31 -31
  18. package/agents/review/typescript-reviewer.md +41 -41
  19. package/commands/vibe.analyze.md +103 -7
  20. package/commands/vibe.reason.md +106 -0
  21. package/commands/vibe.review.md +123 -38
  22. package/commands/vibe.run.md +286 -223
  23. package/commands/vibe.spec.md +425 -186
  24. package/commands/vibe.utils.md +104 -3
  25. package/commands/vibe.verify.md +179 -86
  26. package/dist/cli/detect.js +40 -40
  27. package/dist/cli/detect.js.map +1 -1
  28. package/dist/cli/index.d.ts +1 -1
  29. package/dist/cli/index.js +1 -1
  30. package/dist/cli/llm.js +5 -5
  31. package/dist/cli/llm.js.map +1 -1
  32. package/dist/cli/setup.js +3 -3
  33. package/dist/cli/setup.js.map +1 -1
  34. package/dist/lib/ContextCompressor.js +1 -1
  35. package/dist/lib/ContextCompressor.js.map +1 -1
  36. package/dist/lib/MemoryManager.d.ts +13 -155
  37. package/dist/lib/MemoryManager.d.ts.map +1 -1
  38. package/dist/lib/MemoryManager.js +52 -617
  39. package/dist/lib/MemoryManager.js.map +1 -1
  40. package/dist/lib/gemini-api.js +12 -12
  41. package/dist/lib/gemini-api.js.map +1 -1
  42. package/dist/lib/gemini-oauth.js +22 -22
  43. package/dist/lib/gemini-oauth.js.map +1 -1
  44. package/dist/lib/gemini-storage.js +3 -3
  45. package/dist/lib/gemini-storage.js.map +1 -1
  46. package/dist/lib/gpt-api.js +11 -11
  47. package/dist/lib/gpt-api.js.map +1 -1
  48. package/dist/lib/gpt-oauth.js +28 -28
  49. package/dist/lib/gpt-oauth.js.map +1 -1
  50. package/dist/lib/gpt-storage.js +3 -3
  51. package/dist/lib/gpt-storage.js.map +1 -1
  52. package/dist/lib/memory/KnowledgeGraph.d.ts +34 -0
  53. package/dist/lib/memory/KnowledgeGraph.d.ts.map +1 -0
  54. package/dist/lib/memory/KnowledgeGraph.js +216 -0
  55. package/dist/lib/memory/KnowledgeGraph.js.map +1 -0
  56. package/dist/lib/memory/KnowledgeGraph.test.d.ts +2 -0
  57. package/dist/lib/memory/KnowledgeGraph.test.d.ts.map +1 -0
  58. package/dist/lib/memory/KnowledgeGraph.test.js +189 -0
  59. package/dist/lib/memory/KnowledgeGraph.test.js.map +1 -0
  60. package/dist/lib/memory/MemorySearch.d.ts +25 -0
  61. package/dist/lib/memory/MemorySearch.d.ts.map +1 -0
  62. package/dist/lib/memory/MemorySearch.js +85 -0
  63. package/dist/lib/memory/MemorySearch.js.map +1 -0
  64. package/dist/lib/memory/MemorySearch.test.d.ts +2 -0
  65. package/dist/lib/memory/MemorySearch.test.d.ts.map +1 -0
  66. package/dist/lib/memory/MemorySearch.test.js +149 -0
  67. package/dist/lib/memory/MemorySearch.test.js.map +1 -0
  68. package/dist/lib/memory/MemoryStorage.d.ts +77 -0
  69. package/dist/lib/memory/MemoryStorage.d.ts.map +1 -0
  70. package/dist/lib/memory/MemoryStorage.js +278 -0
  71. package/dist/lib/memory/MemoryStorage.js.map +1 -0
  72. package/dist/lib/memory/MemoryStorage.test.d.ts +2 -0
  73. package/dist/lib/memory/MemoryStorage.test.d.ts.map +1 -0
  74. package/dist/lib/memory/MemoryStorage.test.js +198 -0
  75. package/dist/lib/memory/MemoryStorage.test.js.map +1 -0
  76. package/dist/lib/memory/index.d.ts +4 -0
  77. package/dist/lib/memory/index.d.ts.map +1 -0
  78. package/dist/lib/memory/index.js +8 -0
  79. package/dist/lib/memory/index.js.map +1 -0
  80. package/dist/orchestrator/orchestrator.d.ts.map +1 -1
  81. package/dist/orchestrator/orchestrator.js +4 -6
  82. package/dist/orchestrator/orchestrator.js.map +1 -1
  83. package/dist/tools/convention/analyzeComplexity.d.ts +3 -1
  84. package/dist/tools/convention/analyzeComplexity.d.ts.map +1 -1
  85. package/dist/tools/convention/analyzeComplexity.js +102 -4
  86. package/dist/tools/convention/analyzeComplexity.js.map +1 -1
  87. package/dist/tools/convention/analyzeComplexity.test.d.ts +2 -0
  88. package/dist/tools/convention/analyzeComplexity.test.d.ts.map +1 -0
  89. package/dist/tools/convention/analyzeComplexity.test.js +207 -0
  90. package/dist/tools/convention/analyzeComplexity.test.js.map +1 -0
  91. package/dist/tools/convention/applyQualityRules.js +1 -1
  92. package/dist/tools/convention/applyQualityRules.js.map +1 -1
  93. package/dist/tools/convention/checkCouplingCohesion.js +2 -2
  94. package/dist/tools/convention/checkCouplingCohesion.js.map +1 -1
  95. package/dist/tools/convention/suggestImprovements.js +1 -1
  96. package/dist/tools/convention/suggestImprovements.js.map +1 -1
  97. package/dist/tools/convention/validateCodeQuality.d.ts +3 -1
  98. package/dist/tools/convention/validateCodeQuality.d.ts.map +1 -1
  99. package/dist/tools/convention/validateCodeQuality.js +145 -2
  100. package/dist/tools/convention/validateCodeQuality.js.map +1 -1
  101. package/dist/tools/convention/validateCodeQuality.test.d.ts +2 -0
  102. package/dist/tools/convention/validateCodeQuality.test.d.ts.map +1 -0
  103. package/dist/tools/convention/validateCodeQuality.test.js +230 -0
  104. package/dist/tools/convention/validateCodeQuality.test.js.map +1 -0
  105. package/dist/tools/memory/autoSaveContext.js +1 -1
  106. package/dist/tools/memory/autoSaveContext.js.map +1 -1
  107. package/dist/tools/memory/createMemoryTimeline.js +27 -27
  108. package/dist/tools/memory/createMemoryTimeline.js.map +1 -1
  109. package/dist/tools/memory/deleteMemory.js +1 -1
  110. package/dist/tools/memory/deleteMemory.js.map +1 -1
  111. package/dist/tools/memory/getMemoryGraph.js +24 -24
  112. package/dist/tools/memory/getMemoryGraph.js.map +1 -1
  113. package/dist/tools/memory/getSessionContext.js +36 -36
  114. package/dist/tools/memory/getSessionContext.js.map +1 -1
  115. package/dist/tools/memory/linkMemories.js +21 -21
  116. package/dist/tools/memory/linkMemories.js.map +1 -1
  117. package/dist/tools/memory/prioritizeMemory.js +1 -1
  118. package/dist/tools/memory/prioritizeMemory.js.map +1 -1
  119. package/dist/tools/memory/restoreSessionContext.js +1 -1
  120. package/dist/tools/memory/restoreSessionContext.js.map +1 -1
  121. package/dist/tools/memory/searchMemories.js +1 -1
  122. package/dist/tools/memory/searchMemories.js.map +1 -1
  123. package/dist/tools/memory/searchMemoriesAdvanced.js +42 -42
  124. package/dist/tools/memory/searchMemoriesAdvanced.js.map +1 -1
  125. package/dist/tools/memory/startSession.js +2 -2
  126. package/dist/tools/memory/startSession.js.map +1 -1
  127. package/dist/tools/memory/updateMemory.js +1 -1
  128. package/dist/tools/memory/updateMemory.js.map +1 -1
  129. package/dist/tools/semantic/analyzeDependencyGraph.js +38 -38
  130. package/dist/tools/semantic/analyzeDependencyGraph.js.map +1 -1
  131. package/dist/tools/semantic/findReferences.js +1 -1
  132. package/dist/tools/semantic/findReferences.js.map +1 -1
  133. package/dist/tools/semantic/findSymbol.js +1 -1
  134. package/dist/tools/semantic/findSymbol.js.map +1 -1
  135. package/dist/tools/time/getCurrentTime.js +1 -1
  136. package/dist/tools/time/getCurrentTime.js.map +1 -1
  137. package/dist/tools/ui/previewUiAscii.js +2 -2
  138. package/dist/tools/ui/previewUiAscii.js.map +1 -1
  139. package/hooks/hooks.json +11 -2
  140. package/hooks/scripts/llm-orchestrate.js +1 -1
  141. package/hooks/scripts/utils.js +31 -6
  142. package/languages/csharp-unity.md +82 -83
  143. package/languages/dart-flutter.md +89 -88
  144. package/languages/go.md +76 -75
  145. package/languages/java-spring.md +85 -84
  146. package/languages/kotlin-android.md +64 -63
  147. package/languages/python-django.md +83 -82
  148. package/languages/python-fastapi.md +82 -81
  149. package/languages/rust.md +75 -74
  150. package/languages/swift-ios.md +73 -72
  151. package/languages/typescript-electron.md +70 -71
  152. package/languages/typescript-nextjs.md +93 -92
  153. package/languages/typescript-node.md +64 -63
  154. package/languages/typescript-nuxt.md +113 -112
  155. package/languages/typescript-react-native.md +82 -81
  156. package/languages/typescript-react.md +76 -75
  157. package/languages/typescript-tauri.md +74 -75
  158. package/languages/typescript-vue.md +73 -72
  159. package/package.json +1 -1
  160. package/skills/git-worktree.md +25 -25
  161. package/skills/multi-llm-orchestration.md +4 -6
  162. package/skills/priority-todos.md +39 -39
  163. package/skills/vibe-capabilities.md +2 -2
  164. package/vibe/config.json +2 -2
@@ -1,39 +1,40 @@
1
- # 🐍 Python + FastAPI 품질 규칙
1
+ # Python + FastAPI Quality Rules
2
2
 
3
- ## 핵심 원칙 (core에서 상속)
3
+ ## Core Principles (inherited from core)
4
4
 
5
5
  ```markdown
6
- 단일 책임 (SRP)
7
- 중복 제거 (DRY)
8
- 재사용성
9
- ✅ 낮은 복잡도
10
- 함수 ≤ 30줄 (권장), ≤ 50줄 (허용)
11
- 중첩 3단계
12
- Cyclomatic complexity ≤ 10
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. 타입 힌트 100% 필수
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. Pydantic으로 Contract 정의
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
- # 비동기 I/O (데이터베이스, API 호출)
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
- # 중첩된 if
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
- # Early return
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
- # Repository 레이어
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
- # Service 레이어 (비즈니스 로직)
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. 의존성 주입 (FastAPI Depends)
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
- # 2.0 스타일 (async + select)
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
- # 1.x 스타일 (레거시)
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
- # List comprehension
265
+ # Good: List comprehension
265
266
  active_users = [u for u in users if u.is_active]
266
267
 
267
- # Dictionary comprehension
268
+ # Good: Dictionary comprehension
268
269
  user_dict = {u.id: u.name for u in users}
269
270
 
270
- # Generator expression (메모리 효율)
271
+ # Good: Generator expression (memory efficient)
271
272
  total = sum(u.age for u in users)
272
273
 
273
- # Context manager
274
+ # Good: Context manager
274
275
  async with db.begin():
275
276
  user = User(...)
276
277
  db.add(user)
277
- # 자동 commit/rollback
278
+ # Auto commit/rollback
278
279
 
279
- # Dataclass (간단한 데이터 구조)
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
- # any 타입
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
- # 블로킹 I/O in async 함수
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
- # Mutable default argument
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
- - [ ] 타입 힌트 100% (함수 시그니처, 변수)
378
- - [ ] Pydantic 스키마로 Contract 정의
379
- - [ ] async/await 사용 (I/O 작업)
380
- - [ ] Early return 패턴
381
- - [ ] Repository + Service 레이어 분리
382
- - [ ] 의존성 주입 (Depends)
383
- - [ ] 명확한 에러 메시지
384
- - [ ] 구조화된 로깅
385
- - [ ] 함수 30 (SRP 준수)
386
- - [ ] 복잡도 10
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