@champpaba/claude-agent-kit 2.7.0 → 2.8.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.
Files changed (44) hide show
  1. package/.claude/CLAUDE.md +49 -0
  2. package/.claude/commands/csetup.md +364 -38
  3. package/.claude/commands/cview.md +364 -364
  4. package/.claude/contexts/design/accessibility.md +611 -611
  5. package/.claude/contexts/design/layout.md +400 -400
  6. package/.claude/contexts/design/responsive.md +551 -551
  7. package/.claude/contexts/design/shadows.md +522 -522
  8. package/.claude/contexts/design/typography.md +465 -465
  9. package/.claude/contexts/domain/README.md +164 -164
  10. package/.claude/contexts/patterns/agent-coordination.md +388 -388
  11. package/.claude/contexts/patterns/development-principles.md +513 -513
  12. package/.claude/contexts/patterns/error-handling.md +478 -478
  13. package/.claude/contexts/patterns/logging.md +424 -424
  14. package/.claude/contexts/patterns/tdd-classification.md +516 -516
  15. package/.claude/contexts/patterns/testing.md +413 -413
  16. package/.claude/lib/tdd-classifier.md +345 -345
  17. package/.claude/lib/validation-gates.md +484 -484
  18. package/.claude/settings.local.json +42 -42
  19. package/.claude/templates/context-template.md +45 -45
  20. package/.claude/templates/flags-template.json +42 -42
  21. package/.claude/templates/phases-sections/accessibility-test.md +17 -17
  22. package/.claude/templates/phases-sections/api-design.md +37 -37
  23. package/.claude/templates/phases-sections/backend-tests.md +16 -16
  24. package/.claude/templates/phases-sections/backend.md +37 -37
  25. package/.claude/templates/phases-sections/business-logic-validation.md +16 -16
  26. package/.claude/templates/phases-sections/component-tests.md +17 -17
  27. package/.claude/templates/phases-sections/contract-backend.md +16 -16
  28. package/.claude/templates/phases-sections/contract-frontend.md +16 -16
  29. package/.claude/templates/phases-sections/database.md +35 -35
  30. package/.claude/templates/phases-sections/e2e-tests.md +16 -16
  31. package/.claude/templates/phases-sections/fix-implementation.md +17 -17
  32. package/.claude/templates/phases-sections/frontend-integration.md +18 -18
  33. package/.claude/templates/phases-sections/manual-flow-test.md +15 -15
  34. package/.claude/templates/phases-sections/manual-ux-test.md +16 -16
  35. package/.claude/templates/phases-sections/refactor-implementation.md +17 -17
  36. package/.claude/templates/phases-sections/refactor.md +16 -16
  37. package/.claude/templates/phases-sections/regression-tests.md +15 -15
  38. package/.claude/templates/phases-sections/responsive-test.md +16 -16
  39. package/.claude/templates/phases-sections/script-implementation.md +43 -43
  40. package/.claude/templates/phases-sections/test-coverage.md +16 -16
  41. package/.claude/templates/phases-sections/user-approval.md +14 -14
  42. package/LICENSE +21 -21
  43. package/README.md +25 -0
  44. package/package.json +8 -4
@@ -1,424 +1,424 @@
1
- # Logging & Observability Patterns
2
-
3
- **Critical Rule:** Every API call, database operation, external service interaction, user action, and error MUST be logged with proper context.
4
-
5
- ---
6
-
7
- ## When to Log
8
-
9
- | Event Type | Log Level | Required Fields |
10
- |------------|-----------|-----------------|
11
- | **API Route Entry/Exit** | INFO | `route`, `method`, `requestId`, `duration` |
12
- | **Database Operations** | INFO | `operation`, `table`, `duration`, `rowCount` |
13
- | **External API Calls** | INFO | `service`, `endpoint`, `duration`, `statusCode` |
14
- | **User Actions** | INFO | `action`, `userId/sessionId`, `timestamp` |
15
- | **Errors & Exceptions** | ERROR | `error`, `stack`, `context`, `userId` |
16
- | **Performance Metrics** | INFO | `operation`, `duration`, `memoryUsage` |
17
- | **State Changes** | DEBUG | `store`, `action`, `prevState`, `nextState` |
18
-
19
- ---
20
-
21
- ## Implementation Patterns
22
-
23
- ### API Route Pattern (Next.js)
24
-
25
- ```typescript
26
- // app/api/items/route.ts
27
- import { NextRequest, NextResponse } from 'next/server'
28
- import { logger } from '@/lib/logger'
29
-
30
- export async function POST(request: NextRequest) {
31
- const startTime = Date.now()
32
- const requestId = crypto.randomUUID()
33
-
34
- logger.info('api_route_entry', {
35
- requestId,
36
- route: '/api/items',
37
- method: 'POST',
38
- timestamp: new Date().toISOString()
39
- })
40
-
41
- try {
42
- const body = await request.json()
43
- const result = await createItem(body)
44
-
45
- logger.info('api_route_success', {
46
- requestId,
47
- route: '/api/items',
48
- duration: Date.now() - startTime,
49
- resultSize: JSON.stringify(result).length
50
- })
51
-
52
- return NextResponse.json(result)
53
- } catch (error) {
54
- logger.error('api_route_error', {
55
- requestId,
56
- route: '/api/items',
57
- error: error instanceof Error ? error.message : 'Unknown error',
58
- stack: error instanceof Error ? error.stack : undefined,
59
- duration: Date.now() - startTime
60
- })
61
- throw error
62
- }
63
- }
64
- ```
65
-
66
- ---
67
-
68
- ### Database Operation Pattern (Prisma)
69
-
70
- ```typescript
71
- // lib/db-operations.ts
72
- import { prisma } from '@/lib/db'
73
- import { logger } from '@/lib/logger'
74
-
75
- export async function createUser(data: UserData) {
76
- const startTime = Date.now()
77
-
78
- logger.info('db_operation_start', {
79
- operation: 'createUser',
80
- table: 'User'
81
- })
82
-
83
- try {
84
- const user = await prisma.user.create({ data })
85
-
86
- logger.info('db_operation_success', {
87
- operation: 'createUser',
88
- table: 'User',
89
- userId: user.id,
90
- duration: Date.now() - startTime
91
- })
92
-
93
- return user
94
- } catch (error) {
95
- logger.error('db_operation_error', {
96
- operation: 'createUser',
97
- table: 'User',
98
- error: error instanceof Error ? error.message : 'Unknown error',
99
- duration: Date.now() - startTime
100
- })
101
- throw error
102
- }
103
- }
104
- ```
105
-
106
- ---
107
-
108
- ### Database Pattern (SQLAlchemy - Python)
109
-
110
- ```python
111
- # app/db/user.py
112
- from sqlalchemy.ext.asyncio import AsyncSession
113
- from app.models.user import User
114
- import logging
115
- import time
116
-
117
- logger = logging.getLogger(__name__)
118
-
119
- async def create_user(db: AsyncSession, email: str, name: str) -> User:
120
- start_time = time.time()
121
-
122
- logger.info({"event": "db_operation_start", "operation": "create_user", "table": "users"})
123
-
124
- try:
125
- user = User(email=email, name=name)
126
- db.add(user)
127
- await db.commit()
128
- await db.refresh(user)
129
-
130
- logger.info({
131
- "event": "db_operation_success",
132
- "operation": "create_user",
133
- "table": "users",
134
- "user_id": user.id,
135
- "duration": time.time() - start_time
136
- })
137
-
138
- return user
139
- except Exception as e:
140
- logger.error({
141
- "event": "db_operation_error",
142
- "operation": "create_user",
143
- "table": "users",
144
- "error": str(e),
145
- "duration": time.time() - start_time
146
- })
147
- raise
148
- ```
149
-
150
- ---
151
-
152
- ### External API Pattern
153
-
154
- ```typescript
155
- // lib/external-api.ts
156
- import { logger } from '@/lib/logger'
157
-
158
- export async function fetchExternalData(userId: string) {
159
- const startTime = Date.now()
160
-
161
- logger.info('external_api_start', {
162
- service: 'external-api',
163
- userId,
164
- endpoint: '/api/data'
165
- })
166
-
167
- try {
168
- const response = await fetch('https://api.example.com/data', {
169
- headers: { Authorization: `Bearer ${process.env.API_KEY}` }
170
- })
171
-
172
- const result = await response.json()
173
-
174
- logger.info('external_api_success', {
175
- service: 'external-api',
176
- userId,
177
- statusCode: response.status,
178
- duration: Date.now() - startTime
179
- })
180
-
181
- return result
182
- } catch (error) {
183
- logger.error('external_api_error', {
184
- service: 'external-api',
185
- userId,
186
- error: error instanceof Error ? error.message : 'Unknown error',
187
- duration: Date.now() - startTime
188
- })
189
- throw error
190
- }
191
- }
192
- ```
193
-
194
- ---
195
-
196
- ### State Management Logging (Zustand)
197
-
198
- ```typescript
199
- // lib/stores/app-store.ts
200
- import { create } from 'zustand'
201
- import { devtools, persist } from 'zustand/middleware'
202
- import { logger } from '@/lib/logger'
203
-
204
- interface AppState {
205
- userId: string | null
206
- currentView: string
207
- setUserId: (id: string) => void
208
- setCurrentView: (view: string) => void
209
- }
210
-
211
- export const useAppStore = create<AppState>()(
212
- devtools(
213
- persist(
214
- (set, get) => ({
215
- userId: null,
216
- currentView: 'home',
217
-
218
- setUserId: (id) => {
219
- logger.info('store_action', {
220
- store: 'app',
221
- action: 'setUserId',
222
- userId: id,
223
- prevState: get().userId
224
- })
225
- set({ userId: id })
226
- },
227
-
228
- setCurrentView: (view) => {
229
- logger.info('store_action', {
230
- store: 'app',
231
- action: 'setCurrentView',
232
- userId: get().userId,
233
- prevView: get().currentView,
234
- nextView: view
235
- })
236
- set({ currentView: view })
237
- }
238
- }),
239
- { name: 'app-storage' }
240
- )
241
- )
242
- )
243
- ```
244
-
245
- ---
246
-
247
- ### TanStack Query Logging Pattern
248
-
249
- ```typescript
250
- // hooks/use-create-item.ts
251
- import { useMutation, useQueryClient } from '@tanstack/react-query'
252
- import { logger } from '@/lib/logger'
253
-
254
- export function useCreateItem(userId: string) {
255
- const queryClient = useQueryClient()
256
-
257
- return useMutation({
258
- mutationFn: async (data: ItemData) => {
259
- logger.info('mutation_start', {
260
- mutation: 'createItem',
261
- userId,
262
- dataSize: JSON.stringify(data).length
263
- })
264
-
265
- const response = await fetch('/api/items', {
266
- method: 'POST',
267
- headers: { 'Content-Type': 'application/json' },
268
- body: JSON.stringify(data)
269
- })
270
-
271
- if (!response.ok) throw new Error('Creation failed')
272
- return response.json()
273
- },
274
-
275
- onSuccess: (result) => {
276
- logger.info('mutation_success', {
277
- mutation: 'createItem',
278
- userId,
279
- resultId: result.id
280
- })
281
- queryClient.invalidateQueries({ queryKey: ['items', userId] })
282
- },
283
-
284
- onError: (error) => {
285
- logger.error('mutation_error', {
286
- mutation: 'createItem',
287
- userId,
288
- error: error instanceof Error ? error.message : 'Unknown error'
289
- })
290
- }
291
- })
292
- }
293
- ```
294
-
295
- ---
296
-
297
- ## Logger Implementation
298
-
299
- ### TypeScript/JavaScript
300
-
301
- ```typescript
302
- // lib/logger.ts
303
- type LogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR'
304
-
305
- interface LogContext {
306
- [key: string]: unknown
307
- }
308
-
309
- class Logger {
310
- private log(level: LogLevel, event: string, context?: LogContext) {
311
- const timestamp = new Date().toISOString()
312
- const logEntry = {
313
- timestamp,
314
- level,
315
- event,
316
- ...context
317
- }
318
-
319
- // Development: Pretty console output
320
- if (process.env.NODE_ENV === 'development') {
321
- console[level.toLowerCase() as 'log'](`[${level}] ${event}`, context)
322
- }
323
-
324
- // Production: Structured JSON logs
325
- if (process.env.NODE_ENV === 'production') {
326
- console[level.toLowerCase() as 'log'](JSON.stringify(logEntry))
327
- // Optional: Send to monitoring service (Sentry, LogRocket, etc.)
328
- }
329
- }
330
-
331
- debug(event: string, context?: LogContext) {
332
- this.log('DEBUG', event, context)
333
- }
334
-
335
- info(event: string, context?: LogContext) {
336
- this.log('INFO', event, context)
337
- }
338
-
339
- warn(event: string, context?: LogContext) {
340
- this.log('WARN', event, context)
341
- }
342
-
343
- error(event: string, context?: LogContext) {
344
- this.log('ERROR', event, context)
345
- }
346
- }
347
-
348
- export const logger = new Logger()
349
- ```
350
-
351
- ### Python
352
-
353
- ```python
354
- # lib/logger.py
355
- import logging
356
- import json
357
- from datetime import datetime
358
- from typing import Any, Dict
359
-
360
- class StructuredLogger:
361
- def __init__(self, name: str):
362
- self.logger = logging.getLogger(name)
363
- self.logger.setLevel(logging.DEBUG)
364
-
365
- def _log(self, level: str, event: str, context: Dict[str, Any] = None):
366
- log_entry = {
367
- "timestamp": datetime.utcnow().isoformat(),
368
- "level": level,
369
- "event": event,
370
- **(context or {})
371
- }
372
-
373
- # Development: Human-readable
374
- if os.getenv("ENV") == "development":
375
- self.logger.log(getattr(logging, level), f"{event}: {context}")
376
- # Production: JSON
377
- else:
378
- self.logger.log(getattr(logging, level), json.dumps(log_entry))
379
-
380
- def debug(self, event: str, context: Dict[str, Any] = None):
381
- self._log("DEBUG", event, context)
382
-
383
- def info(self, event: str, context: Dict[str, Any] = None):
384
- self._log("INFO", event, context)
385
-
386
- def warning(self, event: str, context: Dict[str, Any] = None):
387
- self._log("WARNING", event, context)
388
-
389
- def error(self, event: str, context: Dict[str, Any] = None):
390
- self._log("ERROR", event, context)
391
-
392
- logger = StructuredLogger(__name__)
393
- ```
394
-
395
- ---
396
-
397
- ## Quick Reference
398
-
399
- ```typescript
400
- // API Route
401
- logger.info('api_route_entry', { route, method, requestId })
402
- logger.info('api_route_success', { route, duration, requestId })
403
- logger.error('api_route_error', { route, error, stack, requestId })
404
-
405
- // Database
406
- logger.info('db_operation_start', { operation, table })
407
- logger.info('db_operation_success', { operation, table, duration })
408
- logger.error('db_operation_error', { operation, table, error, duration })
409
-
410
- // External API
411
- logger.info('external_api_start', { service, endpoint })
412
- logger.info('external_api_success', { service, statusCode, duration })
413
- logger.error('external_api_error', { service, error, duration })
414
-
415
- // State Management
416
- logger.info('store_action', { store, action, context })
417
-
418
- // Performance
419
- logger.info('performance_metric', { operation, duration, memoryUsage })
420
- ```
421
-
422
- ---
423
-
424
- **💡 Remember:** If an action happens without logs, it's invisible in production!
1
+ # Logging & Observability Patterns
2
+
3
+ **Critical Rule:** Every API call, database operation, external service interaction, user action, and error MUST be logged with proper context.
4
+
5
+ ---
6
+
7
+ ## When to Log
8
+
9
+ | Event Type | Log Level | Required Fields |
10
+ |------------|-----------|-----------------|
11
+ | **API Route Entry/Exit** | INFO | `route`, `method`, `requestId`, `duration` |
12
+ | **Database Operations** | INFO | `operation`, `table`, `duration`, `rowCount` |
13
+ | **External API Calls** | INFO | `service`, `endpoint`, `duration`, `statusCode` |
14
+ | **User Actions** | INFO | `action`, `userId/sessionId`, `timestamp` |
15
+ | **Errors & Exceptions** | ERROR | `error`, `stack`, `context`, `userId` |
16
+ | **Performance Metrics** | INFO | `operation`, `duration`, `memoryUsage` |
17
+ | **State Changes** | DEBUG | `store`, `action`, `prevState`, `nextState` |
18
+
19
+ ---
20
+
21
+ ## Implementation Patterns
22
+
23
+ ### API Route Pattern (Next.js)
24
+
25
+ ```typescript
26
+ // app/api/items/route.ts
27
+ import { NextRequest, NextResponse } from 'next/server'
28
+ import { logger } from '@/lib/logger'
29
+
30
+ export async function POST(request: NextRequest) {
31
+ const startTime = Date.now()
32
+ const requestId = crypto.randomUUID()
33
+
34
+ logger.info('api_route_entry', {
35
+ requestId,
36
+ route: '/api/items',
37
+ method: 'POST',
38
+ timestamp: new Date().toISOString()
39
+ })
40
+
41
+ try {
42
+ const body = await request.json()
43
+ const result = await createItem(body)
44
+
45
+ logger.info('api_route_success', {
46
+ requestId,
47
+ route: '/api/items',
48
+ duration: Date.now() - startTime,
49
+ resultSize: JSON.stringify(result).length
50
+ })
51
+
52
+ return NextResponse.json(result)
53
+ } catch (error) {
54
+ logger.error('api_route_error', {
55
+ requestId,
56
+ route: '/api/items',
57
+ error: error instanceof Error ? error.message : 'Unknown error',
58
+ stack: error instanceof Error ? error.stack : undefined,
59
+ duration: Date.now() - startTime
60
+ })
61
+ throw error
62
+ }
63
+ }
64
+ ```
65
+
66
+ ---
67
+
68
+ ### Database Operation Pattern (Prisma)
69
+
70
+ ```typescript
71
+ // lib/db-operations.ts
72
+ import { prisma } from '@/lib/db'
73
+ import { logger } from '@/lib/logger'
74
+
75
+ export async function createUser(data: UserData) {
76
+ const startTime = Date.now()
77
+
78
+ logger.info('db_operation_start', {
79
+ operation: 'createUser',
80
+ table: 'User'
81
+ })
82
+
83
+ try {
84
+ const user = await prisma.user.create({ data })
85
+
86
+ logger.info('db_operation_success', {
87
+ operation: 'createUser',
88
+ table: 'User',
89
+ userId: user.id,
90
+ duration: Date.now() - startTime
91
+ })
92
+
93
+ return user
94
+ } catch (error) {
95
+ logger.error('db_operation_error', {
96
+ operation: 'createUser',
97
+ table: 'User',
98
+ error: error instanceof Error ? error.message : 'Unknown error',
99
+ duration: Date.now() - startTime
100
+ })
101
+ throw error
102
+ }
103
+ }
104
+ ```
105
+
106
+ ---
107
+
108
+ ### Database Pattern (SQLAlchemy - Python)
109
+
110
+ ```python
111
+ # app/db/user.py
112
+ from sqlalchemy.ext.asyncio import AsyncSession
113
+ from app.models.user import User
114
+ import logging
115
+ import time
116
+
117
+ logger = logging.getLogger(__name__)
118
+
119
+ async def create_user(db: AsyncSession, email: str, name: str) -> User:
120
+ start_time = time.time()
121
+
122
+ logger.info({"event": "db_operation_start", "operation": "create_user", "table": "users"})
123
+
124
+ try:
125
+ user = User(email=email, name=name)
126
+ db.add(user)
127
+ await db.commit()
128
+ await db.refresh(user)
129
+
130
+ logger.info({
131
+ "event": "db_operation_success",
132
+ "operation": "create_user",
133
+ "table": "users",
134
+ "user_id": user.id,
135
+ "duration": time.time() - start_time
136
+ })
137
+
138
+ return user
139
+ except Exception as e:
140
+ logger.error({
141
+ "event": "db_operation_error",
142
+ "operation": "create_user",
143
+ "table": "users",
144
+ "error": str(e),
145
+ "duration": time.time() - start_time
146
+ })
147
+ raise
148
+ ```
149
+
150
+ ---
151
+
152
+ ### External API Pattern
153
+
154
+ ```typescript
155
+ // lib/external-api.ts
156
+ import { logger } from '@/lib/logger'
157
+
158
+ export async function fetchExternalData(userId: string) {
159
+ const startTime = Date.now()
160
+
161
+ logger.info('external_api_start', {
162
+ service: 'external-api',
163
+ userId,
164
+ endpoint: '/api/data'
165
+ })
166
+
167
+ try {
168
+ const response = await fetch('https://api.example.com/data', {
169
+ headers: { Authorization: `Bearer ${process.env.API_KEY}` }
170
+ })
171
+
172
+ const result = await response.json()
173
+
174
+ logger.info('external_api_success', {
175
+ service: 'external-api',
176
+ userId,
177
+ statusCode: response.status,
178
+ duration: Date.now() - startTime
179
+ })
180
+
181
+ return result
182
+ } catch (error) {
183
+ logger.error('external_api_error', {
184
+ service: 'external-api',
185
+ userId,
186
+ error: error instanceof Error ? error.message : 'Unknown error',
187
+ duration: Date.now() - startTime
188
+ })
189
+ throw error
190
+ }
191
+ }
192
+ ```
193
+
194
+ ---
195
+
196
+ ### State Management Logging (Zustand)
197
+
198
+ ```typescript
199
+ // lib/stores/app-store.ts
200
+ import { create } from 'zustand'
201
+ import { devtools, persist } from 'zustand/middleware'
202
+ import { logger } from '@/lib/logger'
203
+
204
+ interface AppState {
205
+ userId: string | null
206
+ currentView: string
207
+ setUserId: (id: string) => void
208
+ setCurrentView: (view: string) => void
209
+ }
210
+
211
+ export const useAppStore = create<AppState>()(
212
+ devtools(
213
+ persist(
214
+ (set, get) => ({
215
+ userId: null,
216
+ currentView: 'home',
217
+
218
+ setUserId: (id) => {
219
+ logger.info('store_action', {
220
+ store: 'app',
221
+ action: 'setUserId',
222
+ userId: id,
223
+ prevState: get().userId
224
+ })
225
+ set({ userId: id })
226
+ },
227
+
228
+ setCurrentView: (view) => {
229
+ logger.info('store_action', {
230
+ store: 'app',
231
+ action: 'setCurrentView',
232
+ userId: get().userId,
233
+ prevView: get().currentView,
234
+ nextView: view
235
+ })
236
+ set({ currentView: view })
237
+ }
238
+ }),
239
+ { name: 'app-storage' }
240
+ )
241
+ )
242
+ )
243
+ ```
244
+
245
+ ---
246
+
247
+ ### TanStack Query Logging Pattern
248
+
249
+ ```typescript
250
+ // hooks/use-create-item.ts
251
+ import { useMutation, useQueryClient } from '@tanstack/react-query'
252
+ import { logger } from '@/lib/logger'
253
+
254
+ export function useCreateItem(userId: string) {
255
+ const queryClient = useQueryClient()
256
+
257
+ return useMutation({
258
+ mutationFn: async (data: ItemData) => {
259
+ logger.info('mutation_start', {
260
+ mutation: 'createItem',
261
+ userId,
262
+ dataSize: JSON.stringify(data).length
263
+ })
264
+
265
+ const response = await fetch('/api/items', {
266
+ method: 'POST',
267
+ headers: { 'Content-Type': 'application/json' },
268
+ body: JSON.stringify(data)
269
+ })
270
+
271
+ if (!response.ok) throw new Error('Creation failed')
272
+ return response.json()
273
+ },
274
+
275
+ onSuccess: (result) => {
276
+ logger.info('mutation_success', {
277
+ mutation: 'createItem',
278
+ userId,
279
+ resultId: result.id
280
+ })
281
+ queryClient.invalidateQueries({ queryKey: ['items', userId] })
282
+ },
283
+
284
+ onError: (error) => {
285
+ logger.error('mutation_error', {
286
+ mutation: 'createItem',
287
+ userId,
288
+ error: error instanceof Error ? error.message : 'Unknown error'
289
+ })
290
+ }
291
+ })
292
+ }
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Logger Implementation
298
+
299
+ ### TypeScript/JavaScript
300
+
301
+ ```typescript
302
+ // lib/logger.ts
303
+ type LogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR'
304
+
305
+ interface LogContext {
306
+ [key: string]: unknown
307
+ }
308
+
309
+ class Logger {
310
+ private log(level: LogLevel, event: string, context?: LogContext) {
311
+ const timestamp = new Date().toISOString()
312
+ const logEntry = {
313
+ timestamp,
314
+ level,
315
+ event,
316
+ ...context
317
+ }
318
+
319
+ // Development: Pretty console output
320
+ if (process.env.NODE_ENV === 'development') {
321
+ console[level.toLowerCase() as 'log'](`[${level}] ${event}`, context)
322
+ }
323
+
324
+ // Production: Structured JSON logs
325
+ if (process.env.NODE_ENV === 'production') {
326
+ console[level.toLowerCase() as 'log'](JSON.stringify(logEntry))
327
+ // Optional: Send to monitoring service (Sentry, LogRocket, etc.)
328
+ }
329
+ }
330
+
331
+ debug(event: string, context?: LogContext) {
332
+ this.log('DEBUG', event, context)
333
+ }
334
+
335
+ info(event: string, context?: LogContext) {
336
+ this.log('INFO', event, context)
337
+ }
338
+
339
+ warn(event: string, context?: LogContext) {
340
+ this.log('WARN', event, context)
341
+ }
342
+
343
+ error(event: string, context?: LogContext) {
344
+ this.log('ERROR', event, context)
345
+ }
346
+ }
347
+
348
+ export const logger = new Logger()
349
+ ```
350
+
351
+ ### Python
352
+
353
+ ```python
354
+ # lib/logger.py
355
+ import logging
356
+ import json
357
+ from datetime import datetime
358
+ from typing import Any, Dict
359
+
360
+ class StructuredLogger:
361
+ def __init__(self, name: str):
362
+ self.logger = logging.getLogger(name)
363
+ self.logger.setLevel(logging.DEBUG)
364
+
365
+ def _log(self, level: str, event: str, context: Dict[str, Any] = None):
366
+ log_entry = {
367
+ "timestamp": datetime.utcnow().isoformat(),
368
+ "level": level,
369
+ "event": event,
370
+ **(context or {})
371
+ }
372
+
373
+ # Development: Human-readable
374
+ if os.getenv("ENV") == "development":
375
+ self.logger.log(getattr(logging, level), f"{event}: {context}")
376
+ # Production: JSON
377
+ else:
378
+ self.logger.log(getattr(logging, level), json.dumps(log_entry))
379
+
380
+ def debug(self, event: str, context: Dict[str, Any] = None):
381
+ self._log("DEBUG", event, context)
382
+
383
+ def info(self, event: str, context: Dict[str, Any] = None):
384
+ self._log("INFO", event, context)
385
+
386
+ def warning(self, event: str, context: Dict[str, Any] = None):
387
+ self._log("WARNING", event, context)
388
+
389
+ def error(self, event: str, context: Dict[str, Any] = None):
390
+ self._log("ERROR", event, context)
391
+
392
+ logger = StructuredLogger(__name__)
393
+ ```
394
+
395
+ ---
396
+
397
+ ## Quick Reference
398
+
399
+ ```typescript
400
+ // API Route
401
+ logger.info('api_route_entry', { route, method, requestId })
402
+ logger.info('api_route_success', { route, duration, requestId })
403
+ logger.error('api_route_error', { route, error, stack, requestId })
404
+
405
+ // Database
406
+ logger.info('db_operation_start', { operation, table })
407
+ logger.info('db_operation_success', { operation, table, duration })
408
+ logger.error('db_operation_error', { operation, table, error, duration })
409
+
410
+ // External API
411
+ logger.info('external_api_start', { service, endpoint })
412
+ logger.info('external_api_success', { service, statusCode, duration })
413
+ logger.error('external_api_error', { service, error, duration })
414
+
415
+ // State Management
416
+ logger.info('store_action', { store, action, context })
417
+
418
+ // Performance
419
+ logger.info('performance_metric', { operation, duration, memoryUsage })
420
+ ```
421
+
422
+ ---
423
+
424
+ **💡 Remember:** If an action happens without logs, it's invisible in production!