create-tigra 1.1.0 → 2.0.1

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 (243) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +80 -87
  3. package/bin/create-tigra.js +259 -308
  4. package/package.json +49 -41
  5. package/template/_claude/QUICK_REFERENCE.md +193 -0
  6. package/template/_claude/README.md +53 -0
  7. package/template/_claude/commands/create-client.md +881 -0
  8. package/template/_claude/commands/create-server.md +383 -0
  9. package/template/_claude/rules/client/01-project-structure.md +133 -0
  10. package/template/_claude/rules/client/02-components-and-types.md +146 -0
  11. package/template/_claude/rules/client/03-data-and-state.md +156 -0
  12. package/template/_claude/rules/client/04-design-system.md +185 -0
  13. package/template/_claude/rules/client/05-security.md +55 -0
  14. package/template/_claude/rules/client/06-ux-checklist.md +81 -0
  15. package/template/_claude/rules/client/core.md +42 -0
  16. package/template/_claude/rules/global/core.md +77 -0
  17. package/template/_claude/rules/server/core.md +50 -0
  18. package/template/_claude/rules/server/database.md +124 -0
  19. package/template/_claude/rules/server/project-conventions.md +150 -0
  20. package/template/_claude/rules/server/response-handling.md +144 -0
  21. package/template/client/.env.example +5 -0
  22. package/template/client/README.md +36 -0
  23. package/template/client/components.json +23 -0
  24. package/template/client/eslint.config.mjs +18 -0
  25. package/template/client/next.config.ts +34 -0
  26. package/template/client/package.json +44 -0
  27. package/template/client/postcss.config.mjs +7 -0
  28. package/template/client/src/app/(auth)/layout.tsx +18 -0
  29. package/template/client/src/app/(auth)/login/page.tsx +13 -0
  30. package/template/client/src/app/(auth)/register/page.tsx +13 -0
  31. package/template/client/src/app/(main)/dashboard/page.tsx +22 -0
  32. package/template/client/src/app/(main)/layout.tsx +11 -0
  33. package/template/client/src/app/error.tsx +27 -0
  34. package/template/client/src/app/favicon.ico +0 -0
  35. package/template/client/src/app/globals.css +145 -0
  36. package/template/client/src/app/layout.tsx +36 -0
  37. package/template/client/src/app/loading.tsx +11 -0
  38. package/template/client/src/app/not-found.tsx +23 -0
  39. package/template/client/src/app/page.tsx +45 -0
  40. package/template/client/src/app/providers.tsx +43 -0
  41. package/template/client/src/components/common/ConfirmDialog.tsx +56 -0
  42. package/template/client/src/components/common/EmptyState.tsx +31 -0
  43. package/template/client/src/components/common/LoadingSpinner.tsx +30 -0
  44. package/template/client/src/components/common/Pagination.tsx +55 -0
  45. package/template/client/src/components/layout/Footer.tsx +17 -0
  46. package/template/client/src/components/layout/Header.tsx +173 -0
  47. package/template/client/src/components/layout/MainLayout.tsx +18 -0
  48. package/template/client/src/components/ui/alert-dialog.tsx +196 -0
  49. package/template/client/src/components/ui/badge.tsx +48 -0
  50. package/template/client/src/components/ui/button.tsx +64 -0
  51. package/template/client/src/components/ui/card.tsx +92 -0
  52. package/template/client/src/components/ui/input.tsx +21 -0
  53. package/template/client/src/components/ui/label.tsx +24 -0
  54. package/template/client/src/components/ui/select.tsx +190 -0
  55. package/template/client/src/components/ui/skeleton.tsx +13 -0
  56. package/template/client/src/components/ui/table.tsx +116 -0
  57. package/template/client/src/features/auth/components/AuthInitializer.tsx +55 -0
  58. package/template/client/src/features/auth/components/LoginForm.tsx +107 -0
  59. package/template/client/src/features/auth/components/RegisterForm.tsx +178 -0
  60. package/template/client/src/features/auth/hooks/useAuth.ts +84 -0
  61. package/template/client/src/features/auth/services/auth.service.ts +52 -0
  62. package/template/client/src/features/auth/store/authSlice.ts +38 -0
  63. package/template/client/src/features/auth/types/auth.types.ts +32 -0
  64. package/template/client/src/hooks/useDebounce.ts +14 -0
  65. package/template/client/src/hooks/useLocalStorage.ts +55 -0
  66. package/template/client/src/hooks/useMediaQuery.ts +27 -0
  67. package/template/client/src/lib/api/api.types.ts +34 -0
  68. package/template/client/src/lib/api/axios.config.ts +98 -0
  69. package/template/client/src/lib/constants/api-endpoints.ts +18 -0
  70. package/template/client/src/lib/constants/app.constants.ts +12 -0
  71. package/template/client/src/lib/constants/routes.ts +9 -0
  72. package/template/client/src/lib/utils/error.ts +32 -0
  73. package/template/client/src/lib/utils/format.ts +37 -0
  74. package/template/client/src/lib/utils/security.ts +34 -0
  75. package/template/client/src/lib/utils.ts +6 -0
  76. package/template/client/src/middleware.ts +57 -0
  77. package/template/client/src/store/hooks.ts +7 -0
  78. package/template/client/src/store/index.ts +12 -0
  79. package/template/client/src/types/index.ts +3 -0
  80. package/template/client/tsconfig.json +34 -0
  81. package/template/gitignore +34 -0
  82. package/template/server/.dockerignore +66 -0
  83. package/template/server/.env.example +96 -69
  84. package/template/server/.env.production.example +90 -0
  85. package/template/server/Dockerfile +94 -0
  86. package/template/server/docker-compose.yml +82 -111
  87. package/template/server/docs/logging.md +62 -0
  88. package/template/server/eslint.config.mjs +17 -0
  89. package/template/server/package.json +68 -81
  90. package/template/server/phpmyadmin-config.php +26 -0
  91. package/template/server/postman_collection.json +666 -0
  92. package/template/server/prisma/schema.prisma +77 -93
  93. package/template/server/prisma/seed.ts +46 -142
  94. package/template/server/scripts/flush-redis.ts +41 -0
  95. package/template/server/src/app.ts +243 -71
  96. package/template/server/src/config/env.ts +67 -94
  97. package/template/server/src/libs/auth.ts +88 -0
  98. package/template/server/src/libs/cleanup.ts +35 -0
  99. package/template/server/src/libs/cookies.ts +46 -0
  100. package/template/server/src/libs/logger.ts +33 -60
  101. package/template/server/src/libs/monitoring.ts +205 -0
  102. package/template/server/src/libs/password.ts +38 -0
  103. package/template/server/src/libs/prisma.ts +68 -0
  104. package/template/server/src/libs/redis.ts +60 -79
  105. package/template/server/src/libs/requestLogger.ts +66 -0
  106. package/template/server/src/libs/storage/file-storage.service.ts +211 -0
  107. package/template/server/src/libs/storage/file-validator.ts +97 -0
  108. package/template/server/src/libs/storage/filename-sanitizer.ts +71 -0
  109. package/template/server/src/libs/storage/image-optimizer.service.ts +144 -0
  110. package/template/server/src/modules/auth/__tests__/auth.service.test.ts +365 -0
  111. package/template/server/src/modules/auth/auth.controller.ts +90 -141
  112. package/template/server/src/modules/auth/auth.repo.ts +120 -218
  113. package/template/server/src/modules/auth/auth.routes.ts +96 -83
  114. package/template/server/src/modules/auth/auth.schemas.ts +35 -137
  115. package/template/server/src/modules/auth/auth.service.ts +286 -329
  116. package/template/server/src/modules/auth/session.repo.ts +110 -0
  117. package/template/server/src/modules/users/users.controller.ts +120 -0
  118. package/template/server/src/modules/users/users.repo.ts +77 -0
  119. package/template/server/src/modules/users/users.routes.ts +89 -0
  120. package/template/server/src/modules/users/users.schemas.ts +21 -0
  121. package/template/server/src/modules/users/users.service.ts +169 -0
  122. package/template/server/src/server.ts +58 -139
  123. package/template/server/src/shared/errors/AppError.ts +21 -0
  124. package/template/server/src/shared/errors/errors.ts +43 -0
  125. package/template/server/src/shared/responses/paginatedResponse.ts +38 -0
  126. package/template/server/src/shared/responses/successResponse.ts +17 -0
  127. package/template/server/src/shared/schemas/pagination.schema.ts +12 -0
  128. package/template/server/src/shared/types/index.ts +26 -0
  129. package/template/server/src/test/setup.ts +74 -38
  130. package/template/server/tsconfig.json +27 -89
  131. package/template/server/uploads/avatars/.gitkeep +1 -0
  132. package/template/server/vitest.config.ts +43 -98
  133. package/template/.agent/rules/client/01-project-structure.md +0 -326
  134. package/template/.agent/rules/client/02-component-patterns.md +0 -249
  135. package/template/.agent/rules/client/03-typescript-rules.md +0 -226
  136. package/template/.agent/rules/client/04-state-management.md +0 -474
  137. package/template/.agent/rules/client/05-api-integration.md +0 -129
  138. package/template/.agent/rules/client/06-forms-validation.md +0 -129
  139. package/template/.agent/rules/client/07-common-patterns.md +0 -150
  140. package/template/.agent/rules/client/08-color-system.md +0 -93
  141. package/template/.agent/rules/client/09-security-rules.md +0 -97
  142. package/template/.agent/rules/client/10-testing-strategy.md +0 -370
  143. package/template/.agent/rules/global/ai-edit-safety.md +0 -38
  144. package/template/.agent/rules/server/01-db-and-migrations.md +0 -242
  145. package/template/.agent/rules/server/02-general-rules.md +0 -111
  146. package/template/.agent/rules/server/03-migrations.md +0 -20
  147. package/template/.agent/rules/server/04-pagination.md +0 -130
  148. package/template/.agent/rules/server/05-project-conventions.md +0 -71
  149. package/template/.agent/rules/server/06-response-handling.md +0 -173
  150. package/template/.agent/rules/server/07-testing-strategy.md +0 -506
  151. package/template/.agent/rules/server/08-observability.md +0 -180
  152. package/template/.agent/rules/server/10-background-jobs-v2.md +0 -185
  153. package/template/.agent/rules/server/11-rate-limiting-v2.md +0 -210
  154. package/template/.agent/rules/server/12-performance-optimization.md +0 -567
  155. package/template/.claude/rules/client-01-project-structure.md +0 -327
  156. package/template/.claude/rules/client-02-component-patterns.md +0 -250
  157. package/template/.claude/rules/client-03-typescript-rules.md +0 -227
  158. package/template/.claude/rules/client-04-state-management.md +0 -475
  159. package/template/.claude/rules/client-05-api-integration.md +0 -130
  160. package/template/.claude/rules/client-06-forms-validation.md +0 -130
  161. package/template/.claude/rules/client-07-common-patterns.md +0 -151
  162. package/template/.claude/rules/client-08-color-system.md +0 -94
  163. package/template/.claude/rules/client-09-security-rules.md +0 -98
  164. package/template/.claude/rules/client-10-testing-strategy.md +0 -371
  165. package/template/.claude/rules/global-ai-edit-safety.md +0 -39
  166. package/template/.claude/rules/server-01-db-and-migrations.md +0 -243
  167. package/template/.claude/rules/server-02-general-rules.md +0 -112
  168. package/template/.claude/rules/server-03-migrations.md +0 -21
  169. package/template/.claude/rules/server-04-pagination.md +0 -131
  170. package/template/.claude/rules/server-05-project-conventions.md +0 -72
  171. package/template/.claude/rules/server-06-response-handling.md +0 -174
  172. package/template/.claude/rules/server-07-testing-strategy.md +0 -507
  173. package/template/.claude/rules/server-08-observability.md +0 -181
  174. package/template/.claude/rules/server-10-background-jobs-v2.md +0 -186
  175. package/template/.claude/rules/server-11-rate-limiting-v2.md +0 -211
  176. package/template/.claude/rules/server-12-performance-optimization.md +0 -568
  177. package/template/.cursor/rules/client-01-project-structure.mdc +0 -327
  178. package/template/.cursor/rules/client-02-component-patterns.mdc +0 -250
  179. package/template/.cursor/rules/client-03-typescript-rules.mdc +0 -227
  180. package/template/.cursor/rules/client-04-state-management.mdc +0 -475
  181. package/template/.cursor/rules/client-05-api-integration.mdc +0 -130
  182. package/template/.cursor/rules/client-06-forms-validation.mdc +0 -130
  183. package/template/.cursor/rules/client-07-common-patterns.mdc +0 -151
  184. package/template/.cursor/rules/client-08-color-system.mdc +0 -94
  185. package/template/.cursor/rules/client-09-security-rules.mdc +0 -98
  186. package/template/.cursor/rules/client-10-testing-strategy.mdc +0 -371
  187. package/template/.cursor/rules/global-ai-edit-safety.mdc +0 -39
  188. package/template/.cursor/rules/server-01-db-and-migrations.mdc +0 -243
  189. package/template/.cursor/rules/server-02-general-rules.mdc +0 -112
  190. package/template/.cursor/rules/server-03-migrations.mdc +0 -21
  191. package/template/.cursor/rules/server-04-pagination.mdc +0 -131
  192. package/template/.cursor/rules/server-05-project-conventions.mdc +0 -72
  193. package/template/.cursor/rules/server-06-response-handling.mdc +0 -174
  194. package/template/.cursor/rules/server-07-testing-strategy.mdc +0 -507
  195. package/template/.cursor/rules/server-08-observability.mdc +0 -181
  196. package/template/.cursor/rules/server-09-api-documentation-v2.mdc +0 -169
  197. package/template/.cursor/rules/server-10-background-jobs-v2.mdc +0 -186
  198. package/template/.cursor/rules/server-11-rate-limiting-v2.mdc +0 -211
  199. package/template/.cursor/rules/server-12-performance-optimization.mdc +0 -568
  200. package/template/CLAUDE.md +0 -207
  201. package/template/server/.tsc-aliasrc.json +0 -13
  202. package/template/server/IMPORT_FIX_CHECKLIST.md +0 -98
  203. package/template/server/IMPORT_FIX_COMPLETE.md +0 -89
  204. package/template/server/README.md +0 -183
  205. package/template/server/REMAINING_IMPORT_FIXES.md +0 -150
  206. package/template/server/SECURITY.md +0 -190
  207. package/template/server/Tigra-API.postman_collection.json +0 -733
  208. package/template/server/biome.json +0 -42
  209. package/template/server/scripts/fix-all-imports.ps1 +0 -52
  210. package/template/server/scripts/fix-imports-reference.ps1 +0 -16
  211. package/template/server/scripts/fix-imports.mjs +0 -55
  212. package/template/server/scripts/setup-env.js +0 -50
  213. package/template/server/scripts/wait-for-db.js +0 -60
  214. package/template/server/src/hooks/request-timing.hook.ts +0 -26
  215. package/template/server/src/libs/auth/authenticate.middleware.ts +0 -22
  216. package/template/server/src/libs/auth/rbac.middleware.test.ts +0 -134
  217. package/template/server/src/libs/auth/rbac.middleware.ts +0 -147
  218. package/template/server/src/libs/db.ts +0 -76
  219. package/template/server/src/libs/error-handler.ts +0 -89
  220. package/template/server/src/libs/queue.ts +0 -79
  221. package/template/server/src/modules/admin/admin.controller.ts +0 -122
  222. package/template/server/src/modules/admin/admin.routes.ts +0 -62
  223. package/template/server/src/modules/admin/admin.schemas.ts +0 -35
  224. package/template/server/src/modules/admin/admin.service.ts +0 -167
  225. package/template/server/src/modules/auth/auth.integration.test.ts +0 -150
  226. package/template/server/src/modules/auth/auth.service.test.ts +0 -119
  227. package/template/server/src/modules/auth/auth.types.ts +0 -97
  228. package/template/server/src/modules/resources/resources.controller.ts +0 -218
  229. package/template/server/src/modules/resources/resources.repo.ts +0 -253
  230. package/template/server/src/modules/resources/resources.routes.ts +0 -116
  231. package/template/server/src/modules/resources/resources.schemas.ts +0 -146
  232. package/template/server/src/modules/resources/resources.service.ts +0 -218
  233. package/template/server/src/modules/resources/resources.types.ts +0 -73
  234. package/template/server/src/plugins/rate-limit.plugin.ts +0 -21
  235. package/template/server/src/plugins/security.plugin.ts +0 -21
  236. package/template/server/src/routes/health.routes.ts +0 -31
  237. package/template/server/src/types/fastify.d.ts +0 -36
  238. package/template/server/src/utils/errors.ts +0 -108
  239. package/template/server/src/utils/pagination.ts +0 -120
  240. package/template/server/src/utils/response.ts +0 -110
  241. package/template/server/src/workers/file.worker.ts +0 -106
  242. package/template/server/tsconfig.build.json +0 -30
  243. package/template/server/tsconfig.test.json +0 -22
@@ -1,111 +0,0 @@
1
- ---
2
- trigger: always_on
3
- ---
4
-
5
- > **SCOPE**: These rules apply specifically to the **server** directory.
6
-
7
- You are a senior backend engineer helping build a high-traffic API server.
8
-
9
- ### PROJECT CONTEXT
10
-
11
- - Stack:
12
-
13
- - Node.js (LTS, 20+)
14
- - Fastify as HTTP framework
15
- - TypeScript
16
- - MySQL as the primary relational database
17
- - Redis for caching, sessions, and rate limiting
18
- - Zod for runtime validation and type inference
19
- - Drizzle ORM (or Prisma) for DB access and migrations
20
- - Jest/Vitest for tests
21
-
22
- - Domain:
23
-
24
- - Users & Roles
25
- - Core Business Entities
26
- - Locations & Mapping
27
- - Media (images, galleries)
28
- - Resources Availability & Pricing
29
- - Transactions & Bookings
30
- - Payments (integration with external providers)
31
- - Messaging & Communications
32
-
33
- - Goals:
34
- - Clean, layered architecture: Routes → Controllers → Services → Repositories → DB
35
- - High performance (Fastify, Redis, proper indexes)
36
- - Easy to maintain and scale
37
- - Secure (auth, input validation, rate limiting)
38
- - Clear separation of concerns
39
-
40
- ### ARCHITECTURE & CODE STYLE
41
-
42
- 1. Use TypeScript everywhere. Always type function parameters and return types.
43
- 2. Organize by domain/module:
44
-
45
- src/modules/<domain>/
46
-
47
- - <domain>.routes.ts (Fastify route definitions)
48
- - <domain>.controller.ts (HTTP handlers only; no business logic)
49
- - <domain>.service.ts (business logic)
50
- - <domain>.repo.ts (DB queries)
51
- - <domain>.schemas.ts (Zod schemas for input/output)
52
-
53
- 3. Fastify:
54
-
55
- - Use plugins and route registration with prefixes (e.g., /api/v1/<resource>).
56
- - Use schemas for validation & serialization.
57
- - Implement centralized error handling.
58
-
59
- 4. Database:
60
-
61
- - Use migrations (via Drizzle/Prisma) for schema changes.
62
- - Add proper indexes for search-heavy fields (identifiers, price, date, type).
63
- - Avoid N+1 queries; prefer joins or batched queries.
64
-
65
- 5. Redis:
66
-
67
- - Use for caching frequently accessed data.
68
- - Use for rate limiting and potentially for background task signaling.
69
-
70
- 6. Auth:
71
-
72
- - Use JWT with HS256 or RS256.
73
- - Store only minimal user info in the token (id, role).
74
- - Implement role-based access control.
75
-
76
- 7. Security:
77
-
78
- - Validate all inputs with Zod and Fastify schemas.
79
- - Never interpolate raw values into SQL; always use the ORM query builder.
80
- - Implement sane rate limiting for public endpoints.
81
- - Sanitize outputs where necessary.
82
-
83
- 8. Coding constraints:
84
-
85
- - Do NOT break existing exports or types unless explicitly asked.
86
- - When modifying existing files, keep changes focused and minimal.
87
- - Reuse existing helpers (db, logger, env) instead of re-creating them.
88
- - Add TODO comments for non-trivial follow-up tasks.
89
-
90
- 9. When asked to implement a feature:
91
-
92
- - First, summarize what needs to be done.
93
- - Then list files to be created/modified.
94
- - Then provide code for each file in separate code blocks.
95
- - Ensure imports between files are correct and consistent with the project structure.
96
-
97
- 10. Testing:
98
-
99
- - For core logic (calculations, transactions, payment callbacks), provide Jest/Vitest tests.
100
- - Tests should be deterministic and not hit external APIs directly (use mocks).
101
-
102
- ### RESPONSE FORMAT
103
-
104
- Whenever you make changes:
105
-
106
- 1. Briefly explain the approach (1–2 paragraphs).
107
- 2. Show updated/created files with full content in code blocks.
108
- 3. Mention any migrations or environment variables that must be added.
109
- 4. If you are unsure, state your assumptions clearly.
110
-
111
- If instructions from earlier parts of the prompt conflict with the user’s new message, follow the user’s latest explicit instructions.
@@ -1,20 +0,0 @@
1
- ---
2
- trigger: always_on
3
- ---
4
-
5
- > **SCOPE**: These rules apply specifically to the **server** directory.
6
-
7
- # Migration Rules for AI Agent
8
-
9
- CRITICAL: When user asks for schema changes:
10
-
11
- 1. ALWAYS edit `prisma/schema.prisma` first
12
- 2. THEN run: `npm run prisma:migrate dev --name descriptive_name`
13
- 3. IF migration fails with conflicts:
14
- - DON'T try to fix manually
15
- - DO run: `npm run prisma:reset`
16
- - Then: `npm run prisma:seed`
17
- 4. NEVER use `prisma db push` unless explicitly asked
18
-
19
- Development = use prisma:reset freely
20
- Production = ONLY use prisma:migrate deploy
@@ -1,130 +0,0 @@
1
- ---
2
- trigger: always_on
3
- ---
4
-
5
- > **SCOPE**: These rules apply specifically to the **server** directory.
6
-
7
- ## Pagination Contract (MANDATORY)
8
-
9
- All paginated API responses MUST follow a unified structure. No exceptions are allowed.
10
-
11
- ### Paginated Response Format
12
-
13
- Every paginated response MUST follow this exact structure:
14
- ```json
15
- {
16
- "success": true,
17
- "message": "string",
18
- "data": {
19
- "items": [],
20
- "pagination": {
21
- "page": 1,
22
- "limit": 10,
23
- "totalItems": 237,
24
- "totalPages": 24,
25
- "hasNextPage": true,
26
- "hasPreviousPage": false
27
- }
28
- }
29
- }
30
- ```
31
-
32
- ### Response Rules
33
-
34
- - `success` is always `true`
35
- - `message` is REQUIRED and must be human-readable
36
- - `data.items` contains the array of results (can be empty array)
37
- - `data.pagination` is REQUIRED and contains:
38
- - `page` – current page number (starts at 1)
39
- - `limit` – items per page
40
- - `totalItems` – total count of items across all pages
41
- - `totalPages` – calculated as `Math.ceil(totalItems / limit)`
42
- - `hasNextPage` – boolean, `true` if `page < totalPages`
43
- - `hasPreviousPage` – boolean, `true` if `page > 1`
44
-
45
- ### Shared Pagination Helper (REQUIRED)
46
-
47
- Controllers MUST use a shared `paginatedResponse` helper:
48
- ```typescript
49
- function paginatedResponse<T>(
50
- message: string,
51
- items: T[],
52
- page: number,
53
- limit: number,
54
- totalItems: number
55
- )
56
- ```
57
-
58
- **Allowed example:**
59
- ```typescript
60
- return reply.send(paginatedResponse("Resources retrieved successfully", items, page, limit, totalCount));
61
- ```
62
-
63
- **Forbidden examples:**
64
- ```typescript
65
- reply.send({ items, page, total });
66
- reply.send({ success: true, data: items, pagination: {...} });
67
- reply.send({ items: items, meta: {...} });
68
- ```
69
-
70
- ### Pagination Input Validation (REQUIRED)
71
-
72
- All endpoints accepting pagination MUST validate using a shared Zod schema:
73
- ```typescript
74
- const PaginationSchema = z.object({
75
- page: z.coerce.number().int().min(1).default(1),
76
- limit: z.coerce.number().int().min(1).max(100).default(10)
77
- });
78
- ```
79
-
80
- **Rules:**
81
- - `page` defaults to `1`, must be positive integer
82
- - `limit` defaults to `10`, must be between 1 and 100
83
- - Use `z.coerce.number()` to handle query string conversion
84
- - Controllers MUST validate pagination inputs before calling services
85
-
86
- ### Service Layer Requirements
87
-
88
- Services handling pagination MUST:
89
- - Accept `page` and `limit` as parameters
90
- - Return both the `items` array AND `totalItems` count
91
- - NOT construct pagination metadata (controller responsibility)
92
- - Calculate offset as: `(page - 1) * limit`
93
-
94
- **Service return pattern:**
95
- ```typescript
96
- return {
97
- items: results,
98
- totalItems: count
99
- };
100
- ```
101
-
102
- ### Filter & Sort with Pagination
103
-
104
- When combining filters/sorting with pagination:
105
- - Filters come BEFORE pagination in query parameters
106
- - Pagination params (`page`, `limit`) are separate from filters
107
- - Apply filters/sorting to query BEFORE applying `limit` and `offset`
108
- - Count total items AFTER filters but BEFORE pagination
109
-
110
- **Example query string:**
111
- ```
112
- ?category=active&minPrice=100&sortBy=price&order=asc&page=2&limit=20
113
- ```
114
-
115
- ### Strict Prohibitions
116
-
117
- These patterns are NOT allowed:
118
- - Multiple pagination formats across endpoints
119
- - Returning raw arrays without pagination wrapper
120
- - Custom pagination field names (e.g., `pageNumber`, `perPage`, `count`)
121
- - Including pagination in query results instead of metadata
122
- - Zero-indexed pages (always start at 1)
123
- - Omitting `totalItems` or `totalPages`
124
-
125
- ### Enforcement Rule
126
-
127
- If a user instruction conflicts with this pagination contract:
128
- - Follow the user instruction ONLY if explicitly stated
129
- - Otherwise, this pagination contract is non-negotiable
130
- - Pagination structure MUST be consistent across ALL endpoints
@@ -1,71 +0,0 @@
1
- ---
2
- trigger: always_on
3
- ---
4
-
5
- > **SCOPE**: These rules apply specifically to the **server** directory.
6
-
7
- # API Server – Project Conventions
8
-
9
- ## Package manager
10
-
11
- - Detect the package manager from the lockfile:
12
- - If `pnpm-lock.yaml` exists → use `pnpm`
13
- - If `yarn.lock` exists → use `yarn`
14
- - Else → use `npm`
15
-
16
- ## File & folder structure
17
-
18
- - Keep everything under `src/`.
19
- - Prefer this layout:
20
-
21
- - `src/app.ts` → Fastify instance and plugin registration
22
- - `src/server.ts` → actual `listen()` call, no app logic
23
- - `src/config/` → env, config, constants
24
- - `src/libs/` → shared libraries (db, redis, logger, auth)
25
- - `src/modules/<domain>/` → domain modules:
26
- - `<domain>.routes.ts`
27
- - `<domain>.controller.ts`
28
- - `<domain>.service.ts`
29
- - `<domain>.repo.ts`
30
- - `<domain>.schemas.ts`
31
- - `<domain>.types.ts` (if needed)
32
-
33
- - When adding new modules, stick to `src/modules/<name>/` and keep the exact naming pattern.
34
-
35
- ## Coding style
36
-
37
- - Use TypeScript with `strict` mode ON.
38
- - Prefer `async/await` over `.then()`.
39
- - Prefer named exports over default exports, except for:
40
- - `src/app.ts` → default export is the Fastify instance
41
- - Frontend components (if any).
42
- - Use consistent import paths:
43
- - Use relative imports inside a module: `./user.service`
44
- - Use aliased imports for cross-module paths if configured (e.g. `@modules/users/...`).
45
-
46
- ## Error handling
47
-
48
- - Controllers must never throw raw errors; they should:
49
- - Either use a shared error helper, or
50
- - Let Fastify’s error handler handle typed errors.
51
- - Never `console.log` for production logic:
52
- - Use the shared `logger` from `src/libs/logger`.
53
-
54
- ## API versioning & routes
55
-
56
- - All API routes must be prefixed with `/api/v1`.
57
- - Group routes by domain:
58
- - `/api/v1/auth/...`
59
- - `/api/v1/users/...`
60
- - `/api/v1/<domain_resource>/...`
61
- - When adding new routes, register them in a Fastify plugin under `src/modules/<domain>/<domain>.routes.ts`.
62
-
63
- ## Service Layer Rules
64
-
65
- - Every domain module must include a `<domain>.service.ts` file.
66
- - Services contain all business logic and must NOT depend on Fastify, reply, request, or HTTP-specific concepts.
67
- - Controllers must call services instead of performing logic directly.
68
- - Services may call repositories for DB operations.
69
- - Services must throw typed AppError instances for failures.
70
- - Services must not return success or error responses; they only return data or throw errors.
71
- - Services must be stateless and reusable.
@@ -1,173 +0,0 @@
1
- ---
2
- trigger: always_on
3
- ---
4
-
5
- > **SCOPE**: These rules apply specifically to the **server** directory.
6
-
7
- API Server – Error & Success Response Rules
8
-
9
- These rules define the ONLY allowed way to return success and error responses from the API. All AI assistants MUST follow this contract strictly.
10
-
11
- Unified Response Contract (MANDATORY)
12
- The API uses a single, stable response structure for all endpoints. No exceptions are allowed.
13
-
14
- Success Response Format
15
- Every successful response MUST follow this exact structure:
16
-
17
- {
18
- "success": true,
19
- "message": "string",
20
- "data": {}
21
- }
22
-
23
- Rules:
24
-
25
- success is always true
26
-
27
- message is REQUIRED and must be human-readable
28
-
29
- data can be an object, array, or null
30
-
31
- Controllers MUST use a shared success helper (for example successResponse)
32
-
33
- Controllers MUST NOT return raw values or custom-shaped JSON
34
-
35
- Allowed example:
36
- return reply.send(successResponse("Resource created successfully", data));
37
-
38
- Forbidden examples:
39
- reply.send(data);
40
- reply.send({ data: data });
41
- reply.send({ success: true, data });
42
-
43
- Error Response Format
44
- Every error response MUST follow this exact structure:
45
-
46
- {
47
- "success": false,
48
- "error": {
49
- "code": "ERROR_CODE",
50
- "message": "Human readable message"
51
- }
52
- }
53
-
54
- Rules:
55
-
56
- success is always false
57
-
58
- code must be a stable machine-readable string (for example RESOURCE_NOT_FOUND)
59
-
60
- message must be safe for end users
61
-
62
- Internal details, stack traces, or SQL errors MUST NOT be exposed
63
-
64
- Controllers MUST NOT manually send error responses
65
-
66
- Global Error Handling Architecture
67
- The server MUST define ONE global Fastify error handler using fastify.setErrorHandler(...).
68
- This global handler is responsible for:
69
-
70
- Mapping errors to HTTP status codes
71
-
72
- Formatting the unified error response
73
-
74
- Logging internal error details on server side only
75
-
76
- Error Throwing Rules (CRITICAL)
77
- Controllers and services MUST throw typed errors ONLY.
78
- They MUST NOT throw:
79
-
80
- raw Error
81
-
82
- strings
83
-
84
- unstructured objects
85
-
86
- Required Error Base Class
87
- All custom errors MUST extend a shared AppError class which defines:
88
-
89
- code
90
-
91
- message
92
-
93
- statusCode
94
-
95
- Allowed Error Types
96
- Allowed subclasses:
97
-
98
- BadRequestError
99
-
100
- ValidationError
101
-
102
- UnauthorizedError
103
-
104
- ForbiddenError
105
-
106
- NotFoundError
107
-
108
- ConflictError
109
-
110
- InternalError
111
-
112
- Each subclass MUST:
113
-
114
- extend AppError
115
-
116
- set a meaningful code
117
-
118
- set an appropriate statusCode
119
-
120
- Controller Responsibilities
121
- Controllers MUST:
122
-
123
- Validate input using Zod schemas
124
-
125
- Call service-layer logic only
126
-
127
- Return success responses using the shared success helper
128
-
129
- Throw typed errors when something fails
130
-
131
- Controllers MUST NOT:
132
-
133
- Set HTTP status codes for errors
134
-
135
- Build custom error JSON structures
136
-
137
- Catch errors unless rethrowing typed errors
138
-
139
- Service Layer Responsibilities
140
- Services MUST:
141
-
142
- Contain business logic
143
-
144
- Throw typed AppError errors when needed
145
-
146
- NEVER depend on Fastify reply or HTTP objects
147
-
148
- Logging Rules
149
- Logging MUST occur only inside:
150
-
151
- The global error handler
152
-
153
- Shared logging utilities
154
-
155
- Controllers MUST NOT log unless explicitly instructed. Internal logs MUST NOT be sent to the client.
156
-
157
- Strict Prohibitions
158
- These patterns are NOT allowed anywhere:
159
-
160
- Multiple response formats
161
-
162
- reply.send({ error: "text" })
163
-
164
- throw new Error("message")
165
-
166
- Returning raw errors from services
167
-
168
- Leaking stack traces or database internals to users
169
-
170
- Final Enforcement Rule
171
- If a user instruction conflicts with this document:
172
- Follow the user instruction ONLY if explicitly stated.
173
- Otherwise, this response contract is non-negotiable.