clearctx 3.0.0 → 3.1.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.
@@ -0,0 +1,796 @@
1
+ ---
2
+ name: api-design
3
+ description: Production-grade RESTful API design covering resources, status codes, pagination, auth, versioning, and error handling
4
+ domain: api
5
+ keywords: [api, rest, restful, http, endpoints, status-codes, pagination, authentication, openapi]
6
+ version: 1.0.0
7
+ ---
8
+
9
+ # API Design — Expertise Guide
10
+
11
+ ## Worker Context
12
+
13
+ You are an **API design specialist** for REST APIs. Your role: design clean, consistent, production-grade HTTP endpoints that follow REST principles and modern API best practices.
14
+
15
+ ### Resource Naming
16
+
17
+ **CRITICAL:** Use plural nouns for resource URLs. NEVER use verbs.
18
+
19
+ ```
20
+ GOOD:
21
+ GET /users
22
+ POST /users
23
+ GET /users/123
24
+ PUT /users/123
25
+ DELETE /users/123
26
+
27
+ BAD:
28
+ /getUsers ❌ verb in URL
29
+ /user ❌ singular form
30
+ /createNewUser ❌ verb + inconsistent naming
31
+ ```
32
+
33
+ **Nested resources** (max 2 levels deep):
34
+ ```
35
+ GET /users/123/orders ✅ user's orders
36
+ GET /users/123/orders/456 ✅ specific order
37
+ GET /orders?user_id=123 ✅ alternative, preferred for filtering
38
+ GET /users/123/orders/456/items ❌ too deep (use /order-items/789)
39
+ ```
40
+
41
+ **Multi-word resources:** lowercase with hyphens
42
+ ```
43
+ /order-items ✅
44
+ /orderItems ❌
45
+ /order_items ❌
46
+ ```
47
+
48
+ ### HTTP Methods
49
+
50
+ | Method | Purpose | Idempotent | Request Body | Success Code | Use When |
51
+ |--------|---------|------------|--------------|--------------|----------|
52
+ | GET | Read resource(s) | Yes | No | 200 | Fetching data, no side effects |
53
+ | POST | Create new resource | No | Yes | 201 | Creating new records |
54
+ | PUT | Full replacement | Yes | Yes | 200 | Replacing entire resource |
55
+ | PATCH | Partial update | No* | Yes | 200 | Updating specific fields |
56
+ | DELETE | Remove resource | Yes | No | 204 | Deleting records |
57
+
58
+ *PATCH idempotency depends on implementation — prefer making it idempotent.
59
+
60
+ **IMPORTANT:** POST creates, PUT replaces entirely (all fields required), PATCH updates partially (only changed fields).
61
+
62
+ ### Status Codes — Exact Usage
63
+
64
+ **CRITICAL:** Use the correct status code for each scenario. Status codes are semantic contracts.
65
+
66
+ | Code | Meaning | When to Use | Headers/Body |
67
+ |------|---------|-------------|--------------|
68
+ | 200 | OK | Successful GET, PUT, PATCH | Response body with data |
69
+ | 201 | Created | Successful POST | `Location: /resource/123` header + created resource in body |
70
+ | 204 | No Content | Successful DELETE | Empty body |
71
+ | 400 | Bad Request | Malformed JSON, invalid syntax | Error details |
72
+ | 401 | Unauthorized | Missing or invalid auth token | `WWW-Authenticate` header |
73
+ | 403 | Forbidden | Valid auth but insufficient permissions | Error details |
74
+ | 404 | Not Found | Resource doesn't exist | Error details |
75
+ | 409 | Conflict | Duplicate resource (unique constraint) | Error details with conflict info |
76
+ | 422 | Unprocessable Entity | Valid syntax but semantic errors (validation) | Field-level error details |
77
+ | 429 | Too Many Requests | Rate limit exceeded | `Retry-After` header (seconds) |
78
+ | 500 | Internal Server Error | Unhandled server error | Generic error, NEVER expose internals |
79
+
80
+ **Decision tree for validation errors:**
81
+ ```
82
+ Is the JSON malformed? → 400 Bad Request
83
+ Is a required field missing? → 422 Unprocessable Entity
84
+ Is an email format invalid? → 422 Unprocessable Entity
85
+ Does a username already exist? → 409 Conflict
86
+ ```
87
+
88
+ ### Response Envelope
89
+
90
+ **CRITICAL:** Use consistent response structure across ALL endpoints.
91
+
92
+ **Success responses:**
93
+ ```json
94
+ // Single resource
95
+ {
96
+ "data": {
97
+ "id": 123,
98
+ "name": "John Doe",
99
+ "email": "john@example.com"
100
+ }
101
+ }
102
+
103
+ // List (with pagination metadata)
104
+ {
105
+ "data": [
106
+ { "id": 1, "name": "Item 1" },
107
+ { "id": 2, "name": "Item 2" }
108
+ ],
109
+ "meta": {
110
+ "page": 1,
111
+ "limit": 20,
112
+ "total": 150,
113
+ "hasNext": true,
114
+ "nextCursor": "eyJpZCI6MjB9"
115
+ }
116
+ }
117
+ ```
118
+
119
+ **Error responses:**
120
+ ```json
121
+ // Simple error
122
+ {
123
+ "error": {
124
+ "code": "RESOURCE_NOT_FOUND",
125
+ "message": "User with ID 123 not found"
126
+ }
127
+ }
128
+
129
+ // Validation errors (422)
130
+ {
131
+ "error": {
132
+ "code": "VALIDATION_ERROR",
133
+ "message": "Request validation failed",
134
+ "details": [
135
+ {
136
+ "field": "email",
137
+ "message": "Invalid email format",
138
+ "value": "not-an-email"
139
+ },
140
+ {
141
+ "field": "age",
142
+ "message": "Must be at least 18",
143
+ "value": 15
144
+ }
145
+ ]
146
+ }
147
+ }
148
+ ```
149
+
150
+ **Error code naming:** `UPPER_SNAKE_CASE`, machine-readable, consistent across API.
151
+
152
+ **NEVER expose in error responses:**
153
+ - Stack traces
154
+ - SQL queries or database errors
155
+ - Internal file paths
156
+ - Sensitive configuration values
157
+ - Third-party service details
158
+
159
+ ### Pagination
160
+
161
+ **Prefer cursor-based pagination** (consistent results, no skip-scan overhead):
162
+ ```
163
+ GET /users?cursor=eyJpZCI6MjB9&limit=20
164
+
165
+ Response:
166
+ {
167
+ "data": [...],
168
+ "meta": {
169
+ "limit": 20,
170
+ "hasNext": true,
171
+ "nextCursor": "eyJpZCI6NDB9",
172
+ "prevCursor": "eyJpZCI6MH0"
173
+ }
174
+ }
175
+ ```
176
+
177
+ **Offset-based acceptable for small datasets** (< 10,000 records):
178
+ ```
179
+ GET /users?page=1&limit=20
180
+
181
+ Response:
182
+ {
183
+ "data": [...],
184
+ "meta": {
185
+ "page": 1,
186
+ "limit": 20,
187
+ "total": 150,
188
+ "totalPages": 8,
189
+ "hasNext": true
190
+ }
191
+ }
192
+ ```
193
+
194
+ **IMPORTANT:** Always include `hasNext` boolean. NEVER require clients to calculate page counts.
195
+
196
+ **Default limit:** 20 items. **Max limit:** 100 items. Reject requests exceeding max with 400.
197
+
198
+ ### Filtering, Sorting, Field Selection
199
+
200
+ **Query parameters for GET requests** (NEVER use request body for GET):
201
+
202
+ ```
203
+ // Filtering
204
+ GET /users?status=active&role=admin&created_after=2024-01-01
205
+
206
+ // Sorting (prefix - for descending)
207
+ GET /users?sort=-created_at,name
208
+ // Sorts by created_at DESC, then name ASC
209
+
210
+ // Field selection (reduce payload size)
211
+ GET /users?fields=id,name,email
212
+ // Returns only specified fields
213
+
214
+ // Combined
215
+ GET /users?status=active&sort=-created_at&fields=id,name&limit=50
216
+ ```
217
+
218
+ **Filtering conventions:**
219
+ - Exact match: `?status=active`
220
+ - Range: `?created_after=2024-01-01&created_before=2024-12-31`
221
+ - IN clause: `?status=active,pending` (comma-separated)
222
+ - Search: `?q=search+term` (full-text search)
223
+
224
+ ### Versioning
225
+
226
+ **CRITICAL:** Version your API from day one. Breaking changes require a new version.
227
+
228
+ **Preferred: URL path versioning**
229
+ ```
230
+ /api/v1/users
231
+ /api/v2/users
232
+ ```
233
+
234
+ **Alternative: Header versioning** (cleaner URLs, harder to debug):
235
+ ```
236
+ GET /api/users
237
+ Accept: application/vnd.myapi.v1+json
238
+ ```
239
+
240
+ **Breaking changes** (require new major version):
241
+ - Removing fields from responses
242
+ - Changing field types (string → number)
243
+ - Removing endpoints
244
+ - Changing required fields
245
+ - Renaming fields
246
+
247
+ **Non-breaking changes** (same version):
248
+ - Adding new fields to responses
249
+ - Adding new endpoints
250
+ - Adding optional parameters
251
+ - Adding new enum values (with defaults)
252
+
253
+ **NEVER:** Change behavior of existing endpoints in-place. Always increment version.
254
+
255
+ ### Authentication & Authorization
256
+
257
+ **Bearer token auth** (standard for modern APIs):
258
+ ```
259
+ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
260
+ ```
261
+
262
+ **Response codes:**
263
+ - Missing token → 401 Unauthorized + `WWW-Authenticate: Bearer realm="api"`
264
+ - Expired token → 401 Unauthorized
265
+ - Valid token, insufficient permissions → 403 Forbidden
266
+
267
+ **Token refresh flow:**
268
+ ```
269
+ POST /api/v1/auth/refresh
270
+ Content-Type: application/json
271
+
272
+ {
273
+ "refresh_token": "abc123..."
274
+ }
275
+
276
+ Response 200:
277
+ {
278
+ "data": {
279
+ "access_token": "new_token...",
280
+ "expires_in": 3600,
281
+ "refresh_token": "new_refresh..."
282
+ }
283
+ }
284
+ ```
285
+
286
+ **API keys for service-to-service:**
287
+ ```
288
+ X-API-Key: sk_live_abc123...
289
+ ```
290
+
291
+ ### Rate Limiting
292
+
293
+ **IMPORTANT:** Include rate limit headers on ALL responses (even successful ones):
294
+
295
+ ```
296
+ X-RateLimit-Limit: 1000 // Max requests per window
297
+ X-RateLimit-Remaining: 847 // Requests left in current window
298
+ X-RateLimit-Reset: 1640000000 // Unix timestamp when limit resets
299
+ ```
300
+
301
+ **When limit exceeded (429):**
302
+ ```
303
+ HTTP/1.1 429 Too Many Requests
304
+ Retry-After: 60
305
+ X-RateLimit-Limit: 1000
306
+ X-RateLimit-Remaining: 0
307
+ X-RateLimit-Reset: 1640000060
308
+
309
+ {
310
+ "error": {
311
+ "code": "RATE_LIMIT_EXCEEDED",
312
+ "message": "Rate limit exceeded. Retry after 60 seconds."
313
+ }
314
+ }
315
+ ```
316
+
317
+ ### HATEOAS (Hypermedia Links)
318
+
319
+ **Optional but valuable** for API discoverability:
320
+
321
+ ```json
322
+ {
323
+ "data": {
324
+ "id": 123,
325
+ "name": "John Doe",
326
+ "status": "active"
327
+ },
328
+ "_links": {
329
+ "self": "/api/v1/users/123",
330
+ "orders": "/api/v1/users/123/orders",
331
+ "update": {
332
+ "href": "/api/v1/users/123",
333
+ "method": "PUT"
334
+ },
335
+ "deactivate": {
336
+ "href": "/api/v1/users/123/deactivate",
337
+ "method": "POST"
338
+ }
339
+ }
340
+ }
341
+ ```
342
+
343
+ Use `_links` prefix to avoid collision with data fields.
344
+
345
+ ### Idempotency
346
+
347
+ **CRITICAL for payment/financial APIs:** Support idempotency keys for POST requests.
348
+
349
+ ```
350
+ POST /api/v1/orders
351
+ Idempotency-Key: a1b2c3d4-e5f6-7890-abcd-ef1234567890
352
+ Content-Type: application/json
353
+
354
+ { "amount": 100, "currency": "USD" }
355
+ ```
356
+
357
+ **Server behavior:**
358
+ 1. First request with key → process normally, cache response
359
+ 2. Duplicate request with same key → return cached response (201)
360
+ 3. Key expires after 24 hours
361
+
362
+ ### Request/Response Examples
363
+
364
+ **Complete POST example:**
365
+ ```http
366
+ POST /api/v1/users HTTP/1.1
367
+ Host: api.example.com
368
+ Authorization: Bearer eyJhbGc...
369
+ Content-Type: application/json
370
+
371
+ {
372
+ "name": "Jane Doe",
373
+ "email": "jane@example.com",
374
+ "role": "editor"
375
+ }
376
+
377
+ HTTP/1.1 201 Created
378
+ Location: /api/v1/users/456
379
+ Content-Type: application/json
380
+ X-RateLimit-Limit: 1000
381
+ X-RateLimit-Remaining: 999
382
+
383
+ {
384
+ "data": {
385
+ "id": 456,
386
+ "name": "Jane Doe",
387
+ "email": "jane@example.com",
388
+ "role": "editor",
389
+ "created_at": "2024-01-15T10:30:00Z"
390
+ }
391
+ }
392
+ ```
393
+
394
+ **Complete validation error (422):**
395
+ ```http
396
+ POST /api/v1/users HTTP/1.1
397
+ Content-Type: application/json
398
+
399
+ {
400
+ "name": "",
401
+ "email": "invalid-email"
402
+ }
403
+
404
+ HTTP/1.1 422 Unprocessable Entity
405
+ Content-Type: application/json
406
+
407
+ {
408
+ "error": {
409
+ "code": "VALIDATION_ERROR",
410
+ "message": "Request validation failed",
411
+ "details": [
412
+ {
413
+ "field": "name",
414
+ "message": "Name is required and cannot be empty"
415
+ },
416
+ {
417
+ "field": "email",
418
+ "message": "Email must be a valid email address",
419
+ "value": "invalid-email"
420
+ }
421
+ ]
422
+ }
423
+ }
424
+ ```
425
+
426
+ ## Conventions
427
+
428
+ **URL structure:**
429
+ - Base: `/api/v{version}/{resource}`
430
+ - Lowercase with hyphens for multi-word: `/order-items`
431
+ - Plural nouns: `/users`, `/products`
432
+ - Max 2 nesting levels: `/users/123/orders`
433
+
434
+ **Response format:**
435
+ - Success: `{ "data": <result> }` or `{ "data": <result>, "meta": {...} }`
436
+ - Error: `{ "error": { "code": "ERROR_CODE", "message": "...", "details": [...] } }`
437
+
438
+ **Status code selection:**
439
+ - Read success → 200
440
+ - Create success → 201 + Location header
441
+ - Delete success → 204
442
+ - Validation error → 422 (NOT 400)
443
+ - Duplicate resource → 409
444
+ - Auth missing/invalid → 401
445
+ - Insufficient permissions → 403
446
+
447
+ **Date/time format:** ISO 8601 with UTC timezone: `2024-01-15T10:30:00Z`
448
+
449
+ **Boolean values:** `true`/`false` (JSON boolean, not strings)
450
+
451
+ **Null handling:** Use `null` for missing optional fields. Omit field entirely if appropriate.
452
+
453
+ **Field naming:** `snake_case` in URLs/query params, match your shared conventions for JSON (typically camelCase for JS, snake_case for Python/Ruby).
454
+
455
+ ## Common Patterns
456
+
457
+ ### Pattern 1: Bulk Operations
458
+
459
+ **Use case:** Create/update/delete multiple resources in one request.
460
+
461
+ ```http
462
+ POST /api/v1/users/bulk
463
+ {
464
+ "operations": [
465
+ { "action": "create", "data": { "name": "User 1", "email": "u1@example.com" } },
466
+ { "action": "create", "data": { "name": "User 2", "email": "u2@example.com" } }
467
+ ]
468
+ }
469
+
470
+ Response 200:
471
+ {
472
+ "data": {
473
+ "results": [
474
+ { "index": 0, "status": "success", "id": 789 },
475
+ { "index": 1, "status": "error", "error": { "code": "DUPLICATE_EMAIL", "message": "..." } }
476
+ ],
477
+ "summary": { "total": 2, "succeeded": 1, "failed": 1 }
478
+ }
479
+ }
480
+ ```
481
+
482
+ **IMPORTANT:** Return partial success. Don't fail entire batch if one item fails.
483
+
484
+ ### Pattern 2: Async Operations
485
+
486
+ **Use case:** Long-running operations (report generation, data export, batch processing).
487
+
488
+ ```http
489
+ POST /api/v1/reports
490
+ { "type": "sales", "start_date": "2024-01-01", "end_date": "2024-01-31" }
491
+
492
+ Response 202 Accepted:
493
+ {
494
+ "data": {
495
+ "job_id": "job_abc123",
496
+ "status": "pending",
497
+ "created_at": "2024-01-15T10:30:00Z"
498
+ },
499
+ "_links": {
500
+ "status": "/api/v1/jobs/job_abc123"
501
+ }
502
+ }
503
+
504
+ // Check status
505
+ GET /api/v1/jobs/job_abc123
506
+
507
+ Response 200 (in progress):
508
+ {
509
+ "data": {
510
+ "job_id": "job_abc123",
511
+ "status": "processing",
512
+ "progress": 45,
513
+ "created_at": "2024-01-15T10:30:00Z"
514
+ }
515
+ }
516
+
517
+ Response 200 (completed):
518
+ {
519
+ "data": {
520
+ "job_id": "job_abc123",
521
+ "status": "completed",
522
+ "result": { "download_url": "/api/v1/reports/abc123.pdf" },
523
+ "created_at": "2024-01-15T10:30:00Z",
524
+ "completed_at": "2024-01-15T10:32:15Z"
525
+ }
526
+ }
527
+ ```
528
+
529
+ **Status values:** `pending`, `processing`, `completed`, `failed`
530
+
531
+ ### Pattern 3: Soft Delete with Trash
532
+
533
+ **Use case:** Allow recovery of deleted resources.
534
+
535
+ ```http
536
+ // Soft delete (move to trash)
537
+ DELETE /api/v1/users/123
538
+ Response 204 No Content
539
+
540
+ // List trashed items
541
+ GET /api/v1/users/trash
542
+ Response 200:
543
+ {
544
+ "data": [
545
+ { "id": 123, "name": "John Doe", "deleted_at": "2024-01-15T10:30:00Z" }
546
+ ]
547
+ }
548
+
549
+ // Restore
550
+ POST /api/v1/users/123/restore
551
+ Response 200:
552
+ {
553
+ "data": { "id": 123, "name": "John Doe", "deleted_at": null }
554
+ }
555
+
556
+ // Permanent delete
557
+ DELETE /api/v1/users/123/permanent
558
+ Response 204 No Content
559
+ ```
560
+
561
+ ### Pattern 4: Search Endpoint
562
+
563
+ **Use case:** Complex search across multiple fields.
564
+
565
+ ```http
566
+ POST /api/v1/search/users
567
+ {
568
+ "query": "john",
569
+ "filters": {
570
+ "status": ["active", "pending"],
571
+ "created_after": "2024-01-01"
572
+ },
573
+ "sort": ["-created_at", "name"],
574
+ "limit": 20
575
+ }
576
+
577
+ Response 200:
578
+ {
579
+ "data": [...],
580
+ "meta": {
581
+ "total": 47,
582
+ "limit": 20,
583
+ "hasNext": true,
584
+ "query": "john"
585
+ }
586
+ }
587
+ ```
588
+
589
+ **Why POST for search?** Complex filter objects don't fit cleanly in query strings. POST /search is acceptable when GET with query params becomes unwieldy.
590
+
591
+ ### Pattern 5: Health & Status Endpoints
592
+
593
+ **Use case:** Monitoring, load balancer health checks.
594
+
595
+ ```http
596
+ GET /health
597
+ Response 200:
598
+ {
599
+ "status": "healthy",
600
+ "version": "1.2.3",
601
+ "timestamp": "2024-01-15T10:30:00Z"
602
+ }
603
+
604
+ GET /health/detailed
605
+ Response 200:
606
+ {
607
+ "status": "healthy",
608
+ "version": "1.2.3",
609
+ "checks": {
610
+ "database": { "status": "healthy", "latency_ms": 12 },
611
+ "redis": { "status": "healthy", "latency_ms": 3 },
612
+ "external_api": { "status": "degraded", "latency_ms": 2500 }
613
+ },
614
+ "timestamp": "2024-01-15T10:30:00Z"
615
+ }
616
+ ```
617
+
618
+ **IMPORTANT:** `/health` should be unauthenticated for load balancer access.
619
+
620
+ ## Anti-Patterns
621
+
622
+ ### Anti-Pattern 1: Verbs in Resource URLs ❌
623
+
624
+ ```
625
+ BAD:
626
+ POST /api/v1/createUser
627
+ GET /api/v1/getUser/123
628
+ POST /api/v1/updateUser/123
629
+ DELETE /api/v1/deleteUser/123
630
+
631
+ GOOD:
632
+ POST /api/v1/users
633
+ GET /api/v1/users/123
634
+ PUT /api/v1/users/123
635
+ DELETE /api/v1/users/123
636
+ ```
637
+
638
+ **Why it's bad:** Violates REST principles. HTTP method already expresses the action.
639
+
640
+ ### Anti-Pattern 2: Inconsistent Plural/Singular Mixing ❌
641
+
642
+ ```
643
+ BAD:
644
+ GET /api/v1/user/123 ❌ singular
645
+ GET /api/v1/products ✅ plural
646
+ GET /api/v1/order/456 ❌ singular
647
+ GET /api/v1/customers ✅ plural
648
+
649
+ GOOD:
650
+ GET /api/v1/users/123 ✅ all plural
651
+ GET /api/v1/products ✅
652
+ GET /api/v1/orders/456 ✅
653
+ GET /api/v1/customers ✅
654
+ ```
655
+
656
+ **Why it's bad:** Forces clients to memorize which resources are plural vs singular. Cognitive overhead.
657
+
658
+ ### Anti-Pattern 3: Using 200 for All Responses ❌
659
+
660
+ ```
661
+ BAD:
662
+ POST /api/v1/users
663
+ Response 200:
664
+ {
665
+ "status": "success",
666
+ "data": { "id": 123, ... }
667
+ }
668
+
669
+ DELETE /api/v1/users/123
670
+ Response 200:
671
+ {
672
+ "status": "success",
673
+ "message": "User deleted"
674
+ }
675
+
676
+ GET /api/v1/users/999
677
+ Response 200:
678
+ {
679
+ "status": "error",
680
+ "message": "User not found"
681
+ }
682
+
683
+ GOOD:
684
+ POST /api/v1/users → 201 Created
685
+ DELETE /api/v1/users/123 → 204 No Content
686
+ GET /api/v1/users/999 → 404 Not Found
687
+ ```
688
+
689
+ **Why it's bad:** HTTP status codes ARE the status. Duplicating them in the body is redundant and breaks HTTP semantics. Clients can't rely on status codes.
690
+
691
+ ### Anti-Pattern 4: No Pagination on List Endpoints ❌
692
+
693
+ ```
694
+ BAD:
695
+ GET /api/v1/users
696
+ // Returns ALL users (10,000+ records)
697
+
698
+ GOOD:
699
+ GET /api/v1/users?limit=20
700
+ // Returns paginated results with meta.hasNext
701
+ ```
702
+
703
+ **Why it's bad:** Kills performance, timeouts, memory issues. ALWAYS paginate list endpoints.
704
+
705
+ ### Anti-Pattern 5: Exposing Internal Implementation in Errors ❌
706
+
707
+ ```
708
+ BAD:
709
+ Response 500:
710
+ {
711
+ "error": {
712
+ "message": "SQLException: Duplicate entry 'john@example.com' for key 'users.email'",
713
+ "stack": "at Database.query (/var/www/app/db.js:45:12)..."
714
+ }
715
+ }
716
+
717
+ GOOD:
718
+ Response 409:
719
+ {
720
+ "error": {
721
+ "code": "DUPLICATE_EMAIL",
722
+ "message": "A user with this email already exists"
723
+ }
724
+ }
725
+ ```
726
+
727
+ **Why it's bad:** Security risk (exposes database structure, file paths). Ugly for consumers. Use semantic error codes.
728
+
729
+ ## Integration Notes
730
+
731
+ **Multi-session orchestration context:**
732
+
733
+ 1. **Check inbox before starting:**
734
+ ```javascript
735
+ // Always first action
736
+ await mcp.team_check_inbox({ name: "api-dev" })
737
+ ```
738
+
739
+ 2. **Read shared conventions:**
740
+ ```javascript
741
+ const conventions = await mcp.artifact_get({
742
+ artifactId: "shared-conventions",
743
+ reader: "api-dev"
744
+ })
745
+ // Use conventions.data.responseFormat, .statusCodes, .enumValues, etc.
746
+ ```
747
+
748
+ 3. **Coordinate with DB worker:**
749
+ - Resource names must match table names (plural form)
750
+ - Use exact enum values from DB schema
751
+ - Align on `snake_case` vs `camelCase` for JSON fields
752
+ - Ask DB worker for foreign key constraints before designing nested resources
753
+
754
+ 4. **Publish API contract artifact:**
755
+ ```javascript
756
+ await mcp.artifact_publish({
757
+ artifactId: "api-contract",
758
+ type: "api-contract",
759
+ name: "REST API Contract v1",
760
+ publisher: "api-dev",
761
+ data: {
762
+ version: "v1",
763
+ baseUrl: "/api/v1",
764
+ endpoints: [
765
+ {
766
+ path: "/users",
767
+ methods: ["GET", "POST"],
768
+ auth: "required",
769
+ request: { /* schema */ },
770
+ response: { /* schema */ }
771
+ }
772
+ // ... all endpoints
773
+ ],
774
+ statusCodes: { /* map of codes to meanings */ },
775
+ errorCodes: ["VALIDATION_ERROR", "DUPLICATE_EMAIL", ...]
776
+ }
777
+ })
778
+ ```
779
+
780
+ 5. **Broadcast completion:**
781
+ ```javascript
782
+ await mcp.team_broadcast({
783
+ from: "api-dev",
784
+ content: "API contract published with 12 endpoints. All workers: read artifact 'api-contract' for request/response schemas and status codes."
785
+ })
786
+ ```
787
+
788
+ 6. **File paths:** Use relative paths only (`src/routes/users.js`, NOT `/home/user/project/src/routes/users.js`)
789
+
790
+ 7. **Consumed by:** Frontend workers (React, mobile apps) use this artifact to generate API client code and TypeScript types. Backend workers implement the contract.
791
+
792
+ 8. **Team communication:**
793
+ - If DB schema is unclear → `team_ask({ to: "db-dev", question: "What's the exact enum for user.status?" })`
794
+ - If frontend needs custom endpoint → they message you, you update contract, republish artifact
795
+
796
+ **Work autonomously:** Use shared conventions + DB schema. Only ask teammates when you hit genuine ambiguity (conflicting requirements, missing specs).