@aicgen/aicgen 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aicgen/aicgen",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "AI Config Generator - Automated AI assistant configuration for your projects",
5
5
  "keywords": [
6
6
  "ai",
@@ -1,649 +0,0 @@
1
- # API Design Rules
2
-
3
- # API Basics
4
-
5
- ## HTTP Methods
6
-
7
- Use the right method for each operation:
8
-
9
- | Method | Purpose | Example |
10
- |--------|---------|---------|
11
- | GET | Read data | Get list of users |
12
- | POST | Create new resource | Create a new user |
13
- | PUT | Replace entire resource | Update all user fields |
14
- | PATCH | Update part of resource | Update user's email only |
15
- | DELETE | Remove resource | Delete a user |
16
-
17
- ## GET - Reading Data
18
-
19
- ```pseudocode
20
- // Get all items
21
- route GET "/api/users":
22
- users = getAllUsers()
23
- return JSON(users)
24
-
25
- // Get single item by ID
26
- route GET "/api/users/:id":
27
- user = getUserById(params.id)
28
- if user is null:
29
- return status 404, JSON({ error: "User not found" })
30
- return JSON(user)
31
- ```
32
-
33
- ## POST - Creating Data
34
-
35
- ```pseudocode
36
- route POST "/api/users":
37
- name = request.body.name
38
- email = request.body.email
39
-
40
- // Validate input
41
- if name is empty or email is empty:
42
- return status 400, JSON({ error: "Name and email required" })
43
-
44
- newUser = createUser({ name, email })
45
-
46
- // Return 201 Created with new resource
47
- return status 201, JSON(newUser)
48
- ```
49
-
50
- ## PUT - Replacing Data
51
-
52
- ```pseudocode
53
- route PUT "/api/users/:id":
54
- id = params.id
55
- name = request.body.name
56
- email = request.body.email
57
-
58
- user = getUserById(id)
59
- if user is null:
60
- return status 404, JSON({ error: "User not found" })
61
-
62
- updated = replaceUser(id, { name, email })
63
- return JSON(updated)
64
- ```
65
-
66
- ## PATCH - Updating Data
67
-
68
- ```pseudocode
69
- route PATCH "/api/users/:id":
70
- id = params.id
71
- updates = request.body // Only fields to update
72
-
73
- user = getUserById(id)
74
- if user is null:
75
- return status 404, JSON({ error: "User not found" })
76
-
77
- updated = updateUser(id, updates)
78
- return JSON(updated)
79
- ```
80
-
81
- ## DELETE - Removing Data
82
-
83
- ```pseudocode
84
- route DELETE "/api/users/:id":
85
- id = params.id
86
-
87
- user = getUserById(id)
88
- if user is null:
89
- return status 404, JSON({ error: "User not found" })
90
-
91
- deleteUser(id)
92
-
93
- // 204 No Content - successful deletion
94
- return status 204
95
- ```
96
-
97
- ## HTTP Status Codes
98
-
99
- ### Success Codes (2xx)
100
-
101
- ```pseudocode
102
- // 200 OK - Request succeeded
103
- return status 200, JSON(data)
104
-
105
- // 201 Created - New resource created
106
- return status 201, JSON(newResource)
107
-
108
- // 204 No Content - Success with no response body
109
- return status 204
110
- ```
111
-
112
- ### Client Error Codes (4xx)
113
-
114
- ```pseudocode
115
- // 400 Bad Request - Invalid input
116
- return status 400, JSON({ error: "Invalid email format" })
117
-
118
- // 401 Unauthorized - Not authenticated
119
- return status 401, JSON({ error: "Login required" })
120
-
121
- // 403 Forbidden - Authenticated but not allowed
122
- return status 403, JSON({ error: "Admin access required" })
123
-
124
- // 404 Not Found - Resource doesn't exist
125
- return status 404, JSON({ error: "User not found" })
126
-
127
- // 409 Conflict - Resource already exists
128
- return status 409, JSON({ error: "Email already registered" })
129
- ```
130
-
131
- ### Server Error Codes (5xx)
132
-
133
- ```pseudocode
134
- // 500 Internal Server Error - Unexpected error
135
- return status 500, JSON({ error: "Internal server error" })
136
-
137
- // 503 Service Unavailable - Temporary issue
138
- return status 503, JSON({ error: "Database unavailable" })
139
- ```
140
-
141
- ## URL Structure
142
-
143
- Use clear, hierarchical URLs:
144
-
145
- ```
146
- ✅ Good
147
- GET /api/users # List all users
148
- GET /api/users/123 # Get user 123
149
- POST /api/users # Create user
150
- GET /api/users/123/posts # Get posts by user 123
151
-
152
- ❌ Bad
153
- GET /api/getUsers
154
- POST /api/createUser
155
- GET /api/user?id=123
156
- ```
157
-
158
- ## Request and Response Format
159
-
160
- ### JSON Request Body
161
-
162
- ```
163
- // Client sends
164
- POST /api/users
165
- Content-Type: application/json
166
-
167
- {
168
- "name": "Alice",
169
- "email": "alice@example.com"
170
- }
171
- ```
172
-
173
- ### JSON Response
174
-
175
- ```
176
- // Server responds
177
- HTTP/1.1 201 Created
178
- Content-Type: application/json
179
-
180
- {
181
- "id": 123,
182
- "name": "Alice",
183
- "email": "alice@example.com",
184
- "createdAt": "2024-01-15T10:30:00Z"
185
- }
186
- ```
187
-
188
- ## Query Parameters
189
-
190
- Use query parameters for filtering, sorting, and pagination:
191
-
192
- ```pseudocode
193
- // Filter by status
194
- // GET /api/orders?status=pending
195
- route GET "/api/orders":
196
- status = query.status
197
- orders = getOrders({ status })
198
- return JSON(orders)
199
-
200
- // Sort by field
201
- // GET /api/users?sort=name
202
-
203
- // Pagination
204
- // GET /api/users?page=2&limit=20
205
- ```
206
-
207
- ## Error Responses
208
-
209
- Always return consistent error format:
210
-
211
- ```pseudocode
212
- // ✅ Good: Structured error
213
- return status 400, JSON({
214
- error: {
215
- code: "VALIDATION_ERROR",
216
- message: "Invalid input",
217
- details: {
218
- email: "Email format is invalid"
219
- }
220
- }
221
- })
222
-
223
- // ❌ Bad: Inconsistent
224
- return status 400, "Bad request"
225
- return status 400, JSON({ msg: "Error" })
226
- ```
227
-
228
- ## Best Practices
229
-
230
- 1. **Use correct HTTP methods** - GET for reading, POST for creating, etc.
231
- 2. **Use appropriate status codes** - 200 for success, 404 for not found, etc.
232
- 3. **Return JSON** - Standard format for APIs
233
- 4. **Validate input** - Check data before processing
234
- 5. **Handle errors** - Return clear error messages
235
-
236
- ```pseudocode
237
- // Complete example
238
- route POST "/api/products":
239
- name = request.body.name
240
- price = request.body.price
241
-
242
- // Validate
243
- if name is empty or price is empty:
244
- return status 400, JSON({
245
- error: "Name and price are required"
246
- })
247
-
248
- if price < 0:
249
- return status 400, JSON({
250
- error: "Price cannot be negative"
251
- })
252
-
253
- // Check for duplicates
254
- if productExists(name):
255
- return status 409, JSON({
256
- error: "Product already exists"
257
- })
258
-
259
- // Create
260
- product = createProduct({ name, price })
261
-
262
- // Return success
263
- return status 201, JSON(product)
264
- ```
265
-
266
- ## Common Mistakes
267
-
268
- ```pseudocode
269
- // ❌ Wrong method for operation
270
- route GET "/api/users/delete/:id" // Should be DELETE
271
-
272
- // ❌ Wrong status code
273
- route POST "/api/users":
274
- user = createUser(body)
275
- return status 200, JSON(user) // Should be 201
276
-
277
- // ❌ Not handling missing resources
278
- route GET "/api/users/:id":
279
- user = getUserById(params.id)
280
- return JSON(user) // What if user is null?
281
-
282
- // ✅ Correct
283
- route DELETE "/api/users/:id"
284
-
285
- route POST "/api/users":
286
- user = createUser(body)
287
- return status 201, JSON(user)
288
-
289
- route GET "/api/users/:id":
290
- user = getUserById(params.id)
291
- if user is null:
292
- return status 404, JSON({ error: "User not found" })
293
- return JSON(user)
294
- ```
295
-
296
-
297
- ---
298
-
299
- # REST API Design
300
-
301
- ## Resource-Oriented URLs
302
-
303
- ```
304
- ✅ Good (nouns, plural)
305
- GET /api/v1/books # List books
306
- GET /api/v1/books/123 # Get book
307
- POST /api/v1/books # Create book
308
- PUT /api/v1/books/123 # Replace book
309
- PATCH /api/v1/books/123 # Update book
310
- DELETE /api/v1/books/123 # Delete book
311
-
312
- ❌ Bad (verbs, actions)
313
- POST /api/v1/createBook
314
- GET /api/v1/getBookById/123
315
- POST /api/v1/updateBook/123
316
- ```
317
-
318
- ## HTTP Methods
319
-
320
- ```typescript
321
- // GET - Read (safe, idempotent)
322
- app.get('/api/v1/users/:id', async (req, res) => {
323
- const user = await userService.findById(req.params.id);
324
- res.json({ data: user });
325
- });
326
-
327
- // POST - Create (not idempotent)
328
- app.post('/api/v1/users', async (req, res) => {
329
- const user = await userService.create(req.body);
330
- res.status(201)
331
- .location(`/api/v1/users/${user.id}`)
332
- .json({ data: user });
333
- });
334
-
335
- // PUT - Replace entire resource (idempotent)
336
- app.put('/api/v1/users/:id', async (req, res) => {
337
- const user = await userService.replace(req.params.id, req.body);
338
- res.json({ data: user });
339
- });
340
-
341
- // PATCH - Partial update (idempotent)
342
- app.patch('/api/v1/users/:id', async (req, res) => {
343
- const user = await userService.update(req.params.id, req.body);
344
- res.json({ data: user });
345
- });
346
-
347
- // DELETE - Remove (idempotent)
348
- app.delete('/api/v1/users/:id', async (req, res) => {
349
- await userService.delete(req.params.id);
350
- res.status(204).end();
351
- });
352
- ```
353
-
354
- ## Status Codes
355
-
356
- ```typescript
357
- // Success
358
- 200 OK // GET, PUT, PATCH succeeded
359
- 201 Created // POST succeeded
360
- 204 No Content // DELETE succeeded
361
-
362
- // Client errors
363
- 400 Bad Request // Validation failed
364
- 401 Unauthorized // Not authenticated
365
- 403 Forbidden // Authenticated but not allowed
366
- 404 Not Found // Resource doesn't exist
367
- 409 Conflict // Duplicate, version conflict
368
- 422 Unprocessable // Business rule violation
369
-
370
- // Server errors
371
- 500 Internal Server Error
372
- ```
373
-
374
- ## Response Format
375
-
376
- ```typescript
377
- // Single resource
378
- {
379
- "data": {
380
- "id": 123,
381
- "name": "John Doe",
382
- "email": "john@example.com"
383
- }
384
- }
385
-
386
- // Collection with pagination
387
- {
388
- "data": [
389
- { "id": 1, "name": "Item 1" },
390
- { "id": 2, "name": "Item 2" }
391
- ],
392
- "pagination": {
393
- "page": 1,
394
- "limit": 20,
395
- "total": 150,
396
- "totalPages": 8
397
- }
398
- }
399
-
400
- // Error response
401
- {
402
- "error": {
403
- "code": "VALIDATION_ERROR",
404
- "message": "The request contains invalid data",
405
- "details": [
406
- { "field": "email", "message": "Invalid email format" }
407
- ]
408
- }
409
- }
410
- ```
411
-
412
- ## Hierarchical Resources
413
-
414
- ```
415
- ✅ Limit nesting to 2-3 levels
416
- GET /api/v1/authors/456/books # Books by author
417
- GET /api/v1/orders/789/items # Items in order
418
-
419
- ❌ Too deep
420
- GET /api/v1/publishers/1/authors/2/books/3/reviews/4
421
-
422
- ✅ Use query parameters instead
423
- GET /api/v1/reviews?bookId=3
424
- ```
425
-
426
- ## API Versioning
427
-
428
- ```
429
- ✅ Always version from the start
430
- /api/v1/books
431
- /api/v2/books
432
-
433
- ❌ No version
434
- /api/books
435
- ```
436
-
437
-
438
- ---
439
-
440
- # API Pagination
441
-
442
- ## Always Paginate Collections
443
-
444
- ```typescript
445
- // ✅ Paginated endpoint
446
- app.get('/api/v1/books', async (req, res) => {
447
- const page = parseInt(req.query.page as string) || 1;
448
- const limit = Math.min(parseInt(req.query.limit as string) || 20, 100);
449
-
450
- const { data, total } = await bookService.findAll({ page, limit });
451
-
452
- res.json({
453
- data,
454
- pagination: {
455
- page,
456
- limit,
457
- total,
458
- totalPages: Math.ceil(total / limit),
459
- hasNext: page * limit < total,
460
- hasPrevious: page > 1
461
- }
462
- });
463
- });
464
- ```
465
-
466
- ## Offset-Based Pagination
467
-
468
- ```typescript
469
- // Simple but has issues with large datasets
470
- GET /api/v1/books?page=1&limit=20
471
- GET /api/v1/books?page=2&limit=20
472
-
473
- // Implementation
474
- const getBooks = async (page: number, limit: number) => {
475
- const offset = (page - 1) * limit;
476
-
477
- const [data, total] = await Promise.all([
478
- db.query('SELECT * FROM books ORDER BY id LIMIT ? OFFSET ?', [limit, offset]),
479
- db.query('SELECT COUNT(*) FROM books')
480
- ]);
481
-
482
- return { data, total };
483
- };
484
- ```
485
-
486
- ## Cursor-Based Pagination
487
-
488
- ```typescript
489
- // Better for large datasets and real-time data
490
- GET /api/v1/books?cursor=eyJpZCI6MTIzfQ&limit=20
491
-
492
- // Response includes next cursor
493
- {
494
- "data": [...],
495
- "pagination": {
496
- "nextCursor": "eyJpZCI6MTQzfQ",
497
- "hasMore": true
498
- }
499
- }
500
-
501
- // Implementation
502
- const getBooks = async (cursor: string | null, limit: number) => {
503
- let query = 'SELECT * FROM books';
504
-
505
- if (cursor) {
506
- const { id } = decodeCursor(cursor);
507
- query += ` WHERE id > ${id}`;
508
- }
509
-
510
- query += ` ORDER BY id LIMIT ${limit + 1}`;
511
- const data = await db.query(query);
512
-
513
- const hasMore = data.length > limit;
514
- const items = hasMore ? data.slice(0, limit) : data;
515
-
516
- return {
517
- data: items,
518
- pagination: {
519
- nextCursor: hasMore ? encodeCursor({ id: items[items.length - 1].id }) : null,
520
- hasMore
521
- }
522
- };
523
- };
524
- ```
525
-
526
- ## Keyset Pagination
527
-
528
- ```sql
529
- -- Most efficient for large tables
530
- -- First page
531
- SELECT * FROM products
532
- ORDER BY created_at DESC, id DESC
533
- LIMIT 20;
534
-
535
- -- Next page (using last item's values)
536
- SELECT * FROM products
537
- WHERE (created_at, id) < ('2024-01-15 10:00:00', 12345)
538
- ORDER BY created_at DESC, id DESC
539
- LIMIT 20;
540
- ```
541
-
542
- ## HATEOAS Links
543
-
544
- ```typescript
545
- // Include navigation links
546
- {
547
- "data": [...],
548
- "pagination": {
549
- "page": 2,
550
- "limit": 20,
551
- "total": 150
552
- },
553
- "links": {
554
- "self": "/api/v1/books?page=2&limit=20",
555
- "first": "/api/v1/books?page=1&limit=20",
556
- "prev": "/api/v1/books?page=1&limit=20",
557
- "next": "/api/v1/books?page=3&limit=20",
558
- "last": "/api/v1/books?page=8&limit=20"
559
- }
560
- }
561
- ```
562
-
563
- ## Pagination Best Practices
564
-
565
- ```typescript
566
- // ✅ Set reasonable defaults and limits
567
- const page = parseInt(req.query.page) || 1;
568
- const limit = Math.min(parseInt(req.query.limit) || 20, 100);
569
-
570
- // ✅ Include total count (when practical)
571
- const total = await db.count('books');
572
-
573
- // ✅ Use consistent response structure
574
- {
575
- "data": [],
576
- "pagination": { ... }
577
- }
578
-
579
- // ❌ Don't return unlimited results
580
- // ❌ Don't allow page < 1 or limit < 1
581
- ```
582
-
583
-
584
- ---
585
-
586
- # API Versioning
587
-
588
- ## Versioning Strategies
589
-
590
- ### URL Path Versioning
591
- ```
592
- GET /api/v1/users
593
- GET /api/v2/users
594
- ```
595
-
596
- ### Header Versioning
597
- ```
598
- GET /api/users
599
- Accept: application/vnd.api+json; version=2
600
- ```
601
-
602
- ### Query Parameter
603
- ```
604
- GET /api/users?version=2
605
- ```
606
-
607
- ## Implementation
608
-
609
- ```typescript
610
- // URL path versioning
611
- app.use('/api/v1', v1Router);
612
- app.use('/api/v2', v2Router);
613
-
614
- // Header versioning middleware
615
- function versionMiddleware(req, res, next) {
616
- const version = req.headers['api-version'] || '1';
617
- req.apiVersion = parseInt(version);
618
- next();
619
- }
620
-
621
- app.get('/users', versionMiddleware, (req, res) => {
622
- if (req.apiVersion >= 2) {
623
- return handleV2(req, res);
624
- }
625
- return handleV1(req, res);
626
- });
627
- ```
628
-
629
- ## Deprecation Strategy
630
-
631
- ```typescript
632
- // Add deprecation headers
633
- res.setHeader('Deprecation', 'true');
634
- res.setHeader('Sunset', 'Sat, 01 Jan 2025 00:00:00 GMT');
635
- res.setHeader('Link', '</api/v2/users>; rel="successor-version"');
636
- ```
637
-
638
- ## Best Practices
639
-
640
- - Version from the start
641
- - Support at least N-1 versions
642
- - Document deprecation timeline
643
- - Provide migration guides
644
- - Use semantic versioning for breaking changes
645
- - Consider backwards-compatible changes first
646
-
647
-
648
- ---
649
- *Generated by aicgen*