codesyncer 1.0.5 → 2.0.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.
@@ -1,324 +1,582 @@
1
1
  # Comment Writing Guide
2
2
 
3
- > **CodeSyncer Comment System** - Permanently record all inferences and decisions
3
+ > **Manage All Context with Comments** - Code is the documentation
4
4
 
5
5
  ---
6
6
 
7
- ## 📋 Comment Tag Reference
7
+ ## 🎯 Core Principle
8
8
 
9
- ### 5 Essential Tags
9
+ **Record all decisions and context directly in code.**
10
10
 
11
- | Tag | Purpose | When to Use | Importance |
12
- |-----|---------|-------------|------------|
13
- | `@codesyncer-rule` | Special rules | Non-standard implementations | ⭐⭐⭐ |
14
- | `@codesyncer-inference` | Inference content | AI inferred content and rationale | ⭐⭐⭐⭐⭐ |
15
- | `@codesyncer-decision` | Decision made | Post-discussion decisions | ⭐⭐⭐⭐⭐ |
16
- | `@codesyncer-todo` | TODO | Needs user confirmation | ⭐⭐⭐⭐ |
17
- | `@codesyncer-context` | Business context | Domain knowledge, background | ⭐⭐⭐ |
11
+ - Write quality standards in separate docs AI can't read
12
+ - ✅ Explain quality standards in code comments → Permanent record
13
+
14
+ ---
15
+
16
+ ## 📋 Comment Tag System (10 Tags)
17
+
18
+ ### Basic Tags (5)
19
+
20
+ | Tag | Purpose | Required Info |
21
+ |-----|---------|--------------|
22
+ | `@codesyncer-inference` | Inference + rationale | "What" + "Why" |
23
+ | `@codesyncer-decision` | Decision made | [Date] + reason |
24
+ | `@codesyncer-todo` | Needs confirmation | Specific task |
25
+ | `@codesyncer-context` | Business context | Domain knowledge |
26
+ | `@codesyncer-rule` | Special rule | Exception case |
27
+
28
+ ### Extended Tags (5) - Complete Context Preservation
29
+
30
+ | Tag | Purpose | When to Use |
31
+ |-----|---------|-------------|
32
+ | `@codesyncer-why` | Detailed explanation | When code alone isn't clear |
33
+ | `@codesyncer-tradeoff` | Pros and cons | When there are trade-offs |
34
+ | `@codesyncer-alternative` | Other options | When alternatives considered |
35
+ | `@codesyncer-pattern` | Pattern name | Reusable pattern |
36
+ | `@codesyncer-reference` | Reference link | External docs/issues |
18
37
 
19
38
  ### Legacy Compatibility
20
39
 
21
- Existing `@claude-*` tags are fully compatible:
22
40
  ```typescript
23
- @claude-rule = @codesyncer-rule
24
- @claude-inference = @codesyncer-inference
25
- @claude-decision = @codesyncer-decision
26
- @claude-todo = @codesyncer-todo
27
- @claude-context = @codesyncer-context
41
+ @claude-* = @codesyncer-* // Legacy tags fully compatible
28
42
  ```
29
43
 
30
44
  ---
31
45
 
32
- ## 📝 Comment Levels
33
-
34
- ### 1. 📄 File Level (JSDoc)
46
+ ## 💡 Real Examples: All Context in Comments
35
47
 
36
- **When**: Top of file, module-wide description
48
+ ### 1️⃣ Quality Standards in Comments
37
49
 
38
50
  ```typescript
39
51
  /**
40
- * User authentication service
52
+ * Payment processing service
41
53
  *
42
- * @codesyncer-context JWT-based authentication system
43
- * @codesyncer-rule Store tokens in httpOnly cookies (XSS prevention)
44
- * @author CodeSyncer
45
- * @date 2024-10-17
54
+ * @codesyncer-context Real-time card payment (PG: Stripe)
55
+ * @codesyncer-rule All amounts as integers (avoid decimal errors)
56
+ * @codesyncer-pattern Transaction Script (simple payments don't need domain model)
57
+ *
58
+ * Quality standards:
59
+ * - Timeout: 30s (PG recommendation)
60
+ * - Retry: 3 times (idempotency required)
61
+ * - Logging: Record all payment attempts
62
+ * - Error handling: User-friendly messages
46
63
  */
47
- ```
64
+ export class PaymentService {
65
+ /**
66
+ * Process payment
67
+ *
68
+ * @codesyncer-why Synchronous implementation (need immediate confirmation)
69
+ * @codesyncer-tradeoff Sync: Fast feedback | Async: Higher throughput
70
+ * @codesyncer-decision [2024-11-12] Chose sync (UX priority)
71
+ */
72
+ async processPayment(
73
+ amount: number,
74
+ cardToken: string
75
+ ): Promise<PaymentResult> {
76
+ // @codesyncer-inference: Minimum 100 (PG policy)
77
+ if (amount < 100) {
78
+ throw new ValidationError('Minimum payment is 100');
79
+ }
80
+
81
+ // @codesyncer-why: Generate idempotency key (prevent duplicate charges)
82
+ const idempotencyKey = this.generateIdempotencyKey(amount, cardToken);
83
+
84
+ // @codesyncer-pattern: Retry with Exponential Backoff
85
+ return await this.retryWithBackoff(async () => {
86
+ return await stripe.charge({
87
+ amount,
88
+ source: cardToken,
89
+ idempotencyKey
90
+ });
91
+ }, {
92
+ maxRetries: 3,
93
+ initialDelay: 1000
94
+ });
95
+ }
48
96
 
49
- ### 2. 🔧 Function/Class/Component Level
97
+ /**
98
+ * @codesyncer-pattern Exponential Backoff
99
+ * @codesyncer-reference https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
100
+ */
101
+ private async retryWithBackoff<T>(
102
+ fn: () => Promise<T>,
103
+ options: RetryOptions
104
+ ): Promise<T> {
105
+ // ... implementation
106
+ }
107
+ }
108
+ ```
50
109
 
51
- **When**: Above each function, class, component definition
110
+ ### 2️⃣ Complex Business Logic Explanation
52
111
 
53
- ```tsx
112
+ ```typescript
54
113
  /**
55
- * Order creation form
114
+ * Discount calculator
56
115
  *
57
- * @codesyncer-context 6-step order process
58
- * @codesyncer-inference Auto-save at each step (common UX pattern)
59
- * @codesyncer-decision [2024-10-15] Zustand for state management (complex form state)
116
+ * @codesyncer-context Compound discount policy (stackable)
117
+ * - Member tier discount: 5-15%
118
+ * - Coupon discount: Fixed amount or percentage
119
+ * - Promotion discount: Conditional
120
+ *
121
+ * @codesyncer-decision [2024-11-10] Fixed discount order (marketing agreement)
122
+ * 1. Member tier discount
123
+ * 2. Coupon discount
124
+ * 3. Promotion discount
125
+ *
126
+ * @codesyncer-why Order matters (final amount differs)
127
+ * @codesyncer-alternative Sum discounts then apply → Rejected (complex cases)
60
128
  */
61
- export default function OrderForm() {
62
- // ...
63
- }
64
- ```
65
-
66
- ### 3. 📝 Inline Level
67
-
68
- **When**: Above or beside code lines
129
+ function calculateFinalPrice(
130
+ basePrice: number,
131
+ user: User,
132
+ coupon?: Coupon,
133
+ promotion?: Promotion
134
+ ): number {
135
+ // @codesyncer-context: Save all intermediate calculations (refund tracking)
136
+ const breakdown: PriceBreakdown = {
137
+ basePrice,
138
+ discounts: []
139
+ };
140
+
141
+ let currentPrice = basePrice;
142
+
143
+ // Step 1: Member tier discount
144
+ // @codesyncer-inference: GOLD 15%, SILVER 10%, BRONZE 5% (common pattern)
145
+ const memberDiscount = this.calculateMemberDiscount(user.tier);
146
+ if (memberDiscount > 0) {
147
+ currentPrice -= memberDiscount;
148
+ breakdown.discounts.push({
149
+ type: 'MEMBER',
150
+ amount: memberDiscount
151
+ });
152
+ }
69
153
 
70
- ```typescript
71
- // @codesyncer-inference: Page size 20 (standard table UX)
72
- const PAGE_SIZE = 20;
154
+ // Step 2: Coupon discount
155
+ // @codesyncer-rule: Apply coupon to discounted price (important!)
156
+ if (coupon) {
157
+ const couponDiscount = this.applyCoupon(currentPrice, coupon);
158
+ currentPrice -= couponDiscount;
159
+ breakdown.discounts.push({
160
+ type: 'COUPON',
161
+ amount: couponDiscount,
162
+ couponId: coupon.id
163
+ });
164
+ }
73
165
 
74
- // @codesyncer-todo: Need to confirm mainApi endpoint URL
75
- const API_URL = '/api/temp';
166
+ // Step 3: Promotion discount
167
+ // @codesyncer-todo: Confirm promotion stacking policy
168
+ if (promotion) {
169
+ const promoDiscount = this.applyPromotion(currentPrice, promotion);
170
+ currentPrice -= promoDiscount;
171
+ breakdown.discounts.push({
172
+ type: 'PROMOTION',
173
+ amount: promoDiscount,
174
+ promotionId: promotion.id
175
+ });
176
+ }
76
177
 
77
- // @codesyncer-decision: [2024-10-17] Soft Delete (30-day recovery)
78
- async function deleteUser(id: string) {
79
- // @codesyncer-inference: Using deleted_at flag (for recovery feature)
80
- return db.update(id, { deleted_at: new Date() });
178
+ // @codesyncer-rule: Final amount must be non-negative
179
+ return Math.max(0, currentPrice);
81
180
  }
82
-
83
- const maxRetry = 3; // @codesyncer-inference: 3 retries (stability)
84
181
  ```
85
182
 
86
- ---
87
-
88
- ## ✅ Good Comment Examples
89
-
90
- ### Example 1: Business Logic
183
+ ### 3️⃣ Performance Optimization Record
91
184
 
92
- ```tsx
185
+ ```typescript
93
186
  /**
94
- * Calculate shipping fee
187
+ * Order list API
95
188
  *
96
- * @codesyncer-context Shipping fee policy
97
- * - Over $300: Free shipping
98
- * - Under $300: $30
99
- * - Remote areas: +$30
189
+ * @codesyncer-context Heavy users have 100k+ orders (performance issue)
190
+ * @codesyncer-decision [2024-11-12] Pagination + Index + Caching
100
191
  *
101
- * @codesyncer-decision [2024-10-10] Policy finalized (Marketing team agreement)
102
- * @codesyncer-rule Policy changes require Marketing team approval
192
+ * Performance goals:
193
+ * - Response time: < 500ms (P95)
194
+ * - Concurrent users: 1000 TPS
195
+ * - Cache hit rate: > 80%
103
196
  */
104
- function calculateShippingFee(orderAmount: number, region: string): number {
105
- // @codesyncer-inference: $300 threshold (industry standard)
106
- const FREE_SHIPPING_THRESHOLD = 30000;
107
-
108
- // @codesyncer-decision: [2024-10-10] Base fee $30
109
- const BASIC_FEE = 3000;
110
-
111
- // @codesyncer-todo: Confirm remote area list
112
- const EXTRA_FEE_REGIONS = ['Jeju', 'Ulleungdo'];
113
-
114
- if (orderAmount >= FREE_SHIPPING_THRESHOLD) {
115
- return 0;
197
+ export class OrderController {
198
+ /**
199
+ * @codesyncer-pattern Cursor-based Pagination
200
+ * @codesyncer-why Offset pagination gets slower with depth (OFFSET 10000)
201
+ * @codesyncer-tradeoff Cursor: Fast | Offset: Page numbers
202
+ * @codesyncer-alternative Offset pagination → Test showed P95 3s (rejected)
203
+ * @codesyncer-reference https://use-the-index-luke.com/no-offset
204
+ */
205
+ async getOrders(userId: string, cursor?: string, limit = 20) {
206
+ // @codesyncer-inference: Redis cache 5min (real-time vs performance)
207
+ const cacheKey = `orders:${userId}:${cursor}`;
208
+ const cached = await redis.get(cacheKey);
209
+ if (cached) {
210
+ return JSON.parse(cached);
211
+ }
212
+
213
+ // @codesyncer-pattern: Index Hint
214
+ // @codesyncer-why Force use of userId + createdAt compound index
215
+ const orders = await db.query(`
216
+ SELECT /*+ INDEX(orders idx_user_created) */
217
+ id, total, status, created_at
218
+ FROM orders
219
+ WHERE user_id = ?
220
+ ${cursor ? 'AND created_at < ?' : ''}
221
+ ORDER BY created_at DESC
222
+ LIMIT ?
223
+ `, cursor ? [userId, cursor, limit] : [userId, limit]);
224
+
225
+ const result = {
226
+ data: orders,
227
+ nextCursor: orders.length === limit
228
+ ? orders[orders.length - 1].created_at
229
+ : null
230
+ };
231
+
232
+ // @codesyncer-inference: 5min TTL (orders rarely change)
233
+ await redis.setex(cacheKey, 300, JSON.stringify(result));
234
+
235
+ return result;
116
236
  }
117
-
118
- const baseFee = BASIC_FEE;
119
- const extraFee = EXTRA_FEE_REGIONS.includes(region) ? 3000 : 0;
120
-
121
- return baseFee + extraFee;
122
237
  }
123
238
  ```
124
239
 
125
- ### Example 2: Data Structure
240
+ ### 4️⃣ Security Requirements
126
241
 
127
- ```tsx
242
+ ```typescript
128
243
  /**
129
- * User interface
244
+ * Authentication middleware
245
+ *
246
+ * @codesyncer-context Financial service (security first)
247
+ * @codesyncer-rule OWASP Top 10 compliance required
130
248
  *
131
- * @codesyncer-context GDPR compliance required
132
- * @codesyncer-rule Personal data must be encrypted
249
+ * Security checklist:
250
+ * SQL Injection prevention (Prepared statements)
251
+ * ✅ XSS prevention (CSP headers)
252
+ * ✅ CSRF prevention (Token validation)
253
+ * ✅ Rate limiting (100 req/min)
254
+ * ✅ No sensitive info in logs
133
255
  */
134
- interface User {
135
- id: string;
136
-
137
- // @codesyncer-inference: Using email as username (common pattern)
138
- email: string;
256
+ export async function authenticate(req: Request, res: Response, next: NextFunction) {
257
+ try {
258
+ // @codesyncer-rule: Token from httpOnly cookie only (XSS prevention)
259
+ const token = req.cookies.access_token;
260
+
261
+ if (!token) {
262
+ // @codesyncer-why: 401 vs 403 distinction (security best practice)
263
+ // 401: Not authenticated | 403: Not authorized
264
+ return res.status(401).json({ error: 'Authentication required' });
265
+ }
266
+
267
+ // @codesyncer-decision [2024-11-12] Session over JWT (more secure)
268
+ // @codesyncer-tradeoff JWT: Stateless | Session: Revocable
269
+ const session = await sessionStore.get(token);
270
+
271
+ if (!session) {
272
+ // @codesyncer-why: Minimal error messages (reduce info leakage)
273
+ return res.status(401).json({ error: 'Invalid token' });
274
+ }
275
+
276
+ // @codesyncer-pattern: Session Rotation
277
+ // @codesyncer-reference: OWASP Session Management Cheat Sheet
278
+ if (session.shouldRotate()) {
279
+ const newToken = await sessionStore.rotate(session.id);
280
+ res.cookie('access_token', newToken, {
281
+ httpOnly: true,
282
+ secure: true,
283
+ sameSite: 'strict'
284
+ });
285
+ }
286
+
287
+ req.user = session.user;
288
+ next();
289
+
290
+ } catch (error) {
291
+ // @codesyncer-rule: Never log sensitive information
292
+ logger.error('Authentication error', {
293
+ // ❌ Never: token, password, email
294
+ ip: req.ip,
295
+ userAgent: req.get('user-agent')
296
+ });
297
+
298
+ return res.status(500).json({ error: 'Internal server error' });
299
+ }
300
+ }
301
+ ```
139
302
 
140
- // @codesyncer-decision: [2024-10-12] bcrypt hashing (security team recommendation)
141
- passwordHash: string;
303
+ ### 5️⃣ Error Handling Strategy
142
304
 
143
- // @codesyncer-context: For Soft Delete
144
- // @codesyncer-decision: [2024-10-15] Permanent delete after 30 days (GDPR)
145
- deletedAt?: Date;
305
+ ```typescript
306
+ /**
307
+ * External API wrapper
308
+ *
309
+ * @codesyncer-context External service unstable (95% SLA)
310
+ * @codesyncer-pattern Circuit Breaker + Retry + Timeout
311
+ * @codesyncer-reference Netflix Hystrix pattern
312
+ *
313
+ * Error handling strategy:
314
+ * - Timeout: 30s
315
+ * - Retry: 3 times (Exponential Backoff)
316
+ * - Circuit Breaker: Open after 5 failures
317
+ * - Fallback: Return cached data
318
+ */
319
+ export class ExternalApiClient {
320
+ private circuitBreaker = new CircuitBreaker({
321
+ failureThreshold: 5,
322
+ resetTimeout: 60000
323
+ });
324
+
325
+ /**
326
+ * @codesyncer-why Handle all errors in one place (consistency)
327
+ * @codesyncer-alternative Try-catch per call → Too much duplication
328
+ */
329
+ async call<T>(
330
+ endpoint: string,
331
+ options?: RequestOptions
332
+ ): Promise<Result<T>> {
333
+ // @codesyncer-pattern: Circuit Breaker
334
+ if (this.circuitBreaker.isOpen()) {
335
+ logger.warn('Circuit breaker is open', { endpoint });
336
+ return this.getFallback<T>(endpoint);
337
+ }
338
+
339
+ try {
340
+ // @codesyncer-inference: 30s timeout (external API recommendation)
341
+ const response = await this.retryWithTimeout(
342
+ () => fetch(endpoint, options),
343
+ { timeout: 30000, maxRetries: 3 }
344
+ );
345
+
346
+ this.circuitBreaker.recordSuccess();
347
+ return Result.ok(response.data);
348
+
349
+ } catch (error) {
350
+ this.circuitBreaker.recordFailure();
351
+
352
+ // @codesyncer-pattern: Error Classification
353
+ if (error instanceof TimeoutError) {
354
+ logger.warn('API timeout', { endpoint, duration: error.duration });
355
+ return this.getFallback<T>(endpoint);
356
+ }
357
+
358
+ if (error instanceof NetworkError) {
359
+ logger.error('Network error', { endpoint, error });
360
+ return this.getFallback<T>(endpoint);
361
+ }
362
+
363
+ // @codesyncer-why: Propagate unexpected errors (handle upstream)
364
+ throw error;
365
+ }
366
+ }
146
367
 
147
- createdAt: Date;
148
- updatedAt: Date;
368
+ /**
369
+ * @codesyncer-pattern: Fallback with Stale Cache
370
+ * @codesyncer-why Stale data better than no data
371
+ */
372
+ private async getFallback<T>(endpoint: string): Promise<Result<T>> {
373
+ const staleData = await cache.getStale<T>(endpoint);
374
+ if (staleData) {
375
+ logger.info('Returning stale cache', { endpoint });
376
+ return Result.ok(staleData, { isStale: true });
377
+ }
378
+
379
+ return Result.error('Service unavailable');
380
+ }
149
381
  }
150
382
  ```
151
383
 
152
- ### Example 3: Component
384
+ ### 6️⃣ Test Strategy Documentation
153
385
 
154
- ```tsx
386
+ ```typescript
155
387
  /**
156
- * Order list table component
388
+ * Payment service tests
157
389
  *
158
- * @codesyncer-context Customer order history view
159
- * @codesyncer-inference Pagination needed (large dataset)
160
- * @codesyncer-decision [2024-10-16] Using TanStack Table (performance)
390
+ * @codesyncer-context Payment is critical path (zero bugs tolerated)
391
+ *
392
+ * Test strategy:
393
+ * - Unit: All public methods
394
+ * - Integration: PG API calls (Mocked)
395
+ * - E2E: Full payment flow (Staging)
396
+ * - Coverage goal: 95%+
397
+ *
398
+ * @codesyncer-rule Payment changes require QA approval
161
399
  */
162
- export function OrderListTable({ orders }: OrderListTableProps) {
163
- // @codesyncer-inference: 20 items per page (UX standard)
164
- const [pageSize, setPageSize] = useState(20);
165
-
166
- // @codesyncer-todo: Add sorting options (date, amount, status)
167
-
168
- return (
169
- <Table>
170
- {/* @codesyncer-rule: Switch to card layout on mobile */}
171
- {/* ... */}
172
- </Table>
173
- );
174
- }
400
+ describe('PaymentService', () => {
401
+ describe('processPayment', () => {
402
+ /**
403
+ * @codesyncer-pattern: AAA (Arrange-Act-Assert)
404
+ * @codesyncer-why Test readability and maintainability
405
+ */
406
+ it('should process payment successfully', async () => {
407
+ // Arrange: Setup test data
408
+ const service = new PaymentService();
409
+ const amount = 10000;
410
+ const cardToken = 'tok_test_1234';
411
+
412
+ // @codesyncer-inference: Mock PG API (prevent actual charges)
413
+ const mockStripe = jest.spyOn(stripe, 'charge')
414
+ .mockResolvedValue({ id: 'ch_1234', status: 'succeeded' });
415
+
416
+ // Act: Execute
417
+ const result = await service.processPayment(amount, cardToken);
418
+
419
+ // Assert: Verify
420
+ expect(result.isSuccess).toBe(true);
421
+ expect(result.data.status).toBe('succeeded');
422
+
423
+ // @codesyncer-why: Verify call parameters (ensure correct values)
424
+ expect(mockStripe).toHaveBeenCalledWith({
425
+ amount,
426
+ source: cardToken,
427
+ idempotencyKey: expect.any(String)
428
+ });
429
+ });
430
+
431
+ /**
432
+ * @codesyncer-pattern: Edge Case Testing
433
+ * @codesyncer-why Bugs often occur at boundaries
434
+ */
435
+ it('should reject payment below minimum amount', async () => {
436
+ const service = new PaymentService();
437
+
438
+ // @codesyncer-context: Minimum 100 (PG policy)
439
+ await expect(
440
+ service.processPayment(99, 'tok_test')
441
+ ).rejects.toThrow('Minimum payment is 100');
442
+ });
443
+ });
444
+ });
175
445
  ```
176
446
 
177
447
  ---
178
448
 
179
- ## Bad Comment Examples
449
+ ## 🎯 Comment Writing Principles
180
450
 
181
- ### Comments to Avoid
451
+ ### DO (Best Practices)
182
452
 
183
- ```tsx
184
- // Too vague
185
- // @codesyncer-inference: Did this
186
- const value = 10;
453
+ ```typescript
454
+ // Specific reason and rationale
455
+ // @codesyncer-inference: Page size 20 (user research, <3 scrolls)
456
+ const PAGE_SIZE = 20;
187
457
 
188
- // No rationale
189
- // @codesyncer-decision: Changed
190
- const API_URL = '/api/new';
458
+ // Date and context
459
+ // @codesyncer-decision: [2024-11-12] PostgreSQL (complex queries + ACID)
191
460
 
192
- // Meaningless
193
- // @codesyncer-todo: Later
194
- function doSomething() {}
461
+ // Trade-offs explicit
462
+ // @codesyncer-tradeoff: Caching +50% perf, +20% memory
195
463
 
196
- // Lacks context
197
- // @codesyncer-context: Important
198
- const IMPORTANT_VALUE = 42;
199
- ```
464
+ // Record alternatives
465
+ // @codesyncer-alternative: MongoDB → Rejected (schema changes frequent)
200
466
 
201
- ### Improved Versions
467
+ // Pattern name (reusable)
468
+ // @codesyncer-pattern: Repository Pattern (data access abstraction)
469
+ ```
202
470
 
203
- ```tsx
204
- // ✅ Specific rationale
205
- // @codesyncer-inference: Default 10 (typical retry wait time)
206
- const RETRY_DELAY = 10;
471
+ ### ❌ DON'T (Anti-patterns)
207
472
 
208
- // ✅ Clear reason and date
209
- // @codesyncer-decision: [2024-10-17] Changed to /api/v2 (API version upgrade)
210
- const API_URL = '/api/v2';
473
+ ```typescript
474
+ // Too vague
475
+ // @codesyncer-inference: Did this
476
+ const value = 10;
211
477
 
212
- // Specific TODO
213
- // @codesyncer-todo: Add error handling (network errors, timeouts)
214
- function fetchData() {}
478
+ // Repeats code
479
+ // @codesyncer-context: Create user // Code already says this
480
+ function createUser() {}
215
481
 
216
- // Business context explanation
217
- // @codesyncer-context: VAT rate (10% as of 2024)
218
- const TAX_RATE = 0.1;
482
+ // No rationale
483
+ // @codesyncer-decision: Changed
484
+ const API_URL = '/new';
219
485
  ```
220
486
 
221
487
  ---
222
488
 
223
489
  ## 🔍 Comment Search
224
490
 
225
- ### Bash Commands
491
+ ### Project-wide Search
226
492
 
227
493
  ```bash
228
494
  # Find all inferences
229
495
  grep -r "@codesyncer-inference" ./src
230
496
 
231
- # Check TODO list
497
+ # Find TODOs
232
498
  grep -r "@codesyncer-todo" ./src
233
499
 
234
- # Discussion decisions
500
+ # Find decisions
235
501
  grep -r "@codesyncer-decision" ./src
236
502
 
237
- # Special rules
238
- grep -r "@codesyncer-rule" ./src
503
+ # Find patterns (reuse)
504
+ grep -r "@codesyncer-pattern" ./src
239
505
 
240
- # Business context
241
- grep -r "@codesyncer-context" ./src
506
+ # Find specific pattern
507
+ grep -r "@codesyncer-pattern.*Retry" ./src
242
508
  ```
243
509
 
244
510
  ### VS Code Search
245
511
 
246
- 1. `Cmd/Ctrl + Shift + F` (Global search)
247
- 2. Enter search term: `@codesyncer-todo`
248
- 3. File filter: `src/**/*.{ts,tsx,js,jsx}`
512
+ ```
513
+ Cmd/Ctrl + Shift + F
514
+ @codesyncer-todo
515
+ → src/**/*.{ts,tsx,js,jsx}
516
+ ```
249
517
 
250
518
  ---
251
519
 
252
520
  ## 📊 Comment Statistics
253
521
 
254
- ARCHITECTURE.md automatically provides statistics:
522
+ Auto-aggregated in ARCHITECTURE.md:
255
523
 
256
524
  ```markdown
257
525
  ## Comment Tag Statistics
258
526
  - @codesyncer-inference: 45
259
527
  - @codesyncer-decision: 12
260
- - @codesyncer-todo: 8
261
- - @codesyncer-rule: 5
262
- - @codesyncer-context: 15
528
+ - @codesyncer-pattern: 8
529
+ - @codesyncer-todo: 3
263
530
  ```
264
531
 
265
- Manual refresh with "update stats" command
532
+ Command: `"update stats"`
266
533
 
267
534
  ---
268
535
 
269
- ## 💡 Comment Writing Tips
536
+ ## 💡 Why Comments Replace Documentation
270
537
 
271
- ### 1. Always provide rationale for inferences
272
-
273
- ```tsx
274
- // ❌ @codesyncer-inference: Using useState
275
- // ✅ @codesyncer-inference: Using useState (simple local state, Zustand unnecessary)
538
+ ### Problems with Separate Docs
276
539
  ```
277
-
278
- ### 2. Include date and reason for decisions
279
-
280
- ```tsx
281
- // ❌ @codesyncer-decision: Using Stripe
282
- // @codesyncer-decision: [2024-10-15] Using Stripe (international payment support needed)
540
+ ❌ Separate documentation
541
+ AI can't read
542
+ → Code and docs diverge
543
+ → Docs never updated
544
+
545
+ Long guide documents
546
+ → Exceeds AI context
547
+ → Not actually applied
548
+ → Forgotten
283
549
  ```
284
550
 
285
- ### 3. Be specific with TODOs
286
-
287
- ```tsx
288
- // ❌ @codesyncer-todo: Needs fix
289
- // ✅ @codesyncer-todo: Add error boundary (fallback UI for API failures)
551
+ ### Benefits of Comment-based Approach
290
552
  ```
291
-
292
- ### 4. Focus on "why" for context
293
-
294
- ```tsx
295
- // ❌ @codesyncer-context: Authentication
296
- // @codesyncer-context: OAuth 2.0 authentication (Google, Kakao login support)
297
- ```
298
-
299
- ### 5. Rules only for exceptional cases
300
-
301
- ```tsx
302
- // ❌ @codesyncer-rule: Using TypeScript (this is obvious)
303
- // ✅ @codesyncer-rule: This file only allows any type (external library has no types)
553
+ ✅ Record directly in code
554
+ Permanent preservation
555
+ → Git version control
556
+ → Always in sync with code
557
+
558
+ Only where needed
559
+ → Context efficient
560
+ → Searchable
561
+ AI actually references
304
562
  ```
305
563
 
306
564
  ---
307
565
 
308
566
  ## 🎯 Checklist
309
567
 
310
- After writing code, verify:
568
+ After writing code:
311
569
 
312
- - [ ] Added `@codesyncer-inference` for inferences?
313
- - [ ] Recorded discussion decisions with `@codesyncer-decision`?
314
- - [ ] Marked items needing confirmation with `@codesyncer-todo`?
315
- - [ ] Explained business logic with `@codesyncer-context`?
316
- - [ ] Specified special rules with `@codesyncer-rule`?
317
- - [ ] Included specific rationale in all comments?
570
+ - [ ] All inferences have `@codesyncer-inference` + rationale
571
+ - [ ] Decisions have `@codesyncer-decision` + [date] + reason
572
+ - [ ] Trade-offs marked with `@codesyncer-tradeoff`
573
+ - [ ] Reusable patterns tagged `@codesyncer-pattern`
574
+ - [ ] Items needing confirmation have `@codesyncer-todo`
575
+ - [ ] Complex logic explained with `@codesyncer-why`
318
576
 
319
577
  ---
320
578
 
321
- **Version**: 1.0.0
579
+ **Version**: 2.0.0
322
580
  **Last Updated**: [TODAY]
323
581
 
324
- *This comment system permanently records all decisions in code.*
582
+ *Comments are the documentation. Record all context in code.*