codeninja 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.
Files changed (140) hide show
  1. package/.gitattributes +11 -0
  2. package/README.md +293 -0
  3. package/agent/database-agent.md +504 -0
  4. package/agent/designs/README.md +10 -0
  5. package/agent/global-agent.md +236 -0
  6. package/agent/nodejs-agent.md +406 -0
  7. package/agent/reactjs-agent.md +260 -0
  8. package/cli.js +352 -0
  9. package/commands/audit.workflow.md +111 -0
  10. package/commands/create-api.workflow.md +99 -0
  11. package/commands/db-add-index.workflow.md +97 -0
  12. package/commands/db-create-table.workflow.md +132 -0
  13. package/commands/db-drop-table.workflow.md +103 -0
  14. package/commands/db-modify-table.workflow.md +159 -0
  15. package/commands/db-seed.workflow.md +99 -0
  16. package/commands/db-sync.workflow.md +100 -0
  17. package/commands/design.workflow.md +66 -0
  18. package/commands/initialize-project.workflow.md +500 -0
  19. package/commands/integrate-api.workflow.md +448 -0
  20. package/commands/modularize.workflow.md +329 -0
  21. package/commands/refactor.workflow.md +70 -0
  22. package/commands/sync.workflow.md +962 -0
  23. package/commands/test.workflow.md +40 -0
  24. package/commands/validate-page.workflow.md +543 -0
  25. package/mcp-server.js +842 -0
  26. package/package.json +24 -0
  27. package/tasks/README.md +283 -0
  28. package/tasks/add-health-route.task.md +103 -0
  29. package/tasks/ask-api-integration-scope.task.md +34 -0
  30. package/tasks/ask-api-key.task.md +23 -0
  31. package/tasks/ask-api-version.task.md +28 -0
  32. package/tasks/ask-client-type.task.md +24 -0
  33. package/tasks/ask-column-enum-values.task.md +51 -0
  34. package/tasks/ask-column-is-enum.task.md +39 -0
  35. package/tasks/ask-column-name.task.md +39 -0
  36. package/tasks/ask-column-position.task.md +39 -0
  37. package/tasks/ask-column-type.task.md +59 -0
  38. package/tasks/ask-database-config.task.md +66 -0
  39. package/tasks/ask-database-host.task.md +16 -0
  40. package/tasks/ask-database-name.task.md +18 -0
  41. package/tasks/ask-database-port.task.md +23 -0
  42. package/tasks/ask-database-type.task.md +30 -0
  43. package/tasks/ask-database-user.task.md +14 -0
  44. package/tasks/ask-design-description.task.md +16 -0
  45. package/tasks/ask-design-target.task.md +24 -0
  46. package/tasks/ask-encrypted-transport.task.md +25 -0
  47. package/tasks/ask-encryption-iv.task.md +23 -0
  48. package/tasks/ask-encryption-key.task.md +23 -0
  49. package/tasks/ask-feature-name.task.md +20 -0
  50. package/tasks/ask-http-method.task.md +21 -0
  51. package/tasks/ask-index-columns.task.md +46 -0
  52. package/tasks/ask-index-file-placement.task.md +33 -0
  53. package/tasks/ask-index-sort-order.task.md +37 -0
  54. package/tasks/ask-index-type.task.md +42 -0
  55. package/tasks/ask-init-mode.task.md +28 -0
  56. package/tasks/ask-linked-service.task.md +57 -0
  57. package/tasks/ask-modify-operation.task.md +36 -0
  58. package/tasks/ask-modularize-scope.task.md +31 -0
  59. package/tasks/ask-module-name.task.md +30 -0
  60. package/tasks/ask-new-column-name.task.md +21 -0
  61. package/tasks/ask-new-table-name.task.md +22 -0
  62. package/tasks/ask-old-column-name.task.md +22 -0
  63. package/tasks/ask-package-author.task.md +16 -0
  64. package/tasks/ask-package-name.task.md +23 -0
  65. package/tasks/ask-page-path.task.md +40 -0
  66. package/tasks/ask-primary-table.task.md +30 -0
  67. package/tasks/ask-project-figma.task.md +71 -0
  68. package/tasks/ask-project-info-doc.task.md +57 -0
  69. package/tasks/ask-project-scope-of-work.task.md +57 -0
  70. package/tasks/ask-project-type.task.md +24 -0
  71. package/tasks/ask-react-target-service.task.md +32 -0
  72. package/tasks/ask-redis-config.task.md +42 -0
  73. package/tasks/ask-redis-host.task.md +16 -0
  74. package/tasks/ask-redis-port.task.md +18 -0
  75. package/tasks/ask-refactor-type.task.md +26 -0
  76. package/tasks/ask-requires-auth.task.md +22 -0
  77. package/tasks/ask-response-mode.task.md +38 -0
  78. package/tasks/ask-route-description.task.md +20 -0
  79. package/tasks/ask-route-path.task.md +29 -0
  80. package/tasks/ask-seed-row-values.task.md +42 -0
  81. package/tasks/ask-seed-rows-count.task.md +22 -0
  82. package/tasks/ask-service-description.task.md +16 -0
  83. package/tasks/ask-service-name.task.md +27 -0
  84. package/tasks/ask-service-port.task.md +24 -0
  85. package/tasks/ask-supported-languages.task.md +40 -0
  86. package/tasks/ask-table-file-number.task.md +36 -0
  87. package/tasks/ask-table-indexes.task.md +47 -0
  88. package/tasks/ask-table-name.task.md +32 -0
  89. package/tasks/ask-table-needs-soft-delete.task.md +29 -0
  90. package/tasks/ask-table-needs-status.task.md +30 -0
  91. package/tasks/ask-table-purpose.task.md +28 -0
  92. package/tasks/ask-table-seed-data.task.md +44 -0
  93. package/tasks/ask-target-service.task.md +32 -0
  94. package/tasks/ask-test-type.task.md +20 -0
  95. package/tasks/ask-validation-library.task.md +38 -0
  96. package/tasks/detect-repository-state.task.md +92 -0
  97. package/tasks/generate-app.task.md +146 -0
  98. package/tasks/generate-common.task.md +330 -0
  99. package/tasks/generate-constants.task.md +123 -0
  100. package/tasks/generate-database.task.md +168 -0
  101. package/tasks/generate-docker-compose.task.md +298 -0
  102. package/tasks/generate-dockerfile.task.md +126 -0
  103. package/tasks/generate-dockerignore.task.md +123 -0
  104. package/tasks/generate-enc-dec-html.task.md +127 -0
  105. package/tasks/generate-enc-dec-php.task.md +145 -0
  106. package/tasks/generate-encryption.task.md +159 -0
  107. package/tasks/generate-fast-defaults.task.md +68 -0
  108. package/tasks/generate-gitignore.task.md +79 -0
  109. package/tasks/generate-headerValidator.task.md +377 -0
  110. package/tasks/generate-ide-configs.task.md +114 -0
  111. package/tasks/generate-ioRedis.task.md +120 -0
  112. package/tasks/generate-language-en.task.md +155 -0
  113. package/tasks/generate-logging.task.md +257 -0
  114. package/tasks/generate-model.task.md +180 -0
  115. package/tasks/generate-notification.task.md +251 -0
  116. package/tasks/generate-package-json.task.md +114 -0
  117. package/tasks/generate-rateLimiter.task.md +125 -0
  118. package/tasks/generate-react-api-client.task.md +169 -0
  119. package/tasks/generate-react-api-handler.task.md +102 -0
  120. package/tasks/generate-react-app-jsx.task.md +56 -0
  121. package/tasks/generate-react-dockerfile.task.md +175 -0
  122. package/tasks/generate-react-env.task.md +58 -0
  123. package/tasks/generate-react-gitignore.task.md +49 -0
  124. package/tasks/generate-react-htaccess.task.md +54 -0
  125. package/tasks/generate-react-index-html.task.md +53 -0
  126. package/tasks/generate-react-index-jsx.task.md +51 -0
  127. package/tasks/generate-react-package-json.task.md +77 -0
  128. package/tasks/generate-react-welcome-page.task.md +71 -0
  129. package/tasks/generate-readme.task.md +160 -0
  130. package/tasks/generate-response.task.md +202 -0
  131. package/tasks/generate-route-manager.task.md +173 -0
  132. package/tasks/generate-route.task.md +203 -0
  133. package/tasks/generate-swagger.task.md +290 -0
  134. package/tasks/generate-tbl-user-deviceinfo.task.md +75 -0
  135. package/tasks/generate-template.task.md +129 -0
  136. package/tasks/generate-validator.task.md +122 -0
  137. package/tasks/show-db-table-summary.task.md +66 -0
  138. package/tasks/show-final-summary.task.md +108 -0
  139. package/tasks/show-init-summary.task.md +257 -0
  140. package/tasks/write-context.task.md +314 -0
@@ -0,0 +1,203 @@
1
+ ---
2
+ type: task
3
+ name: generate-route
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: modules/v1/<ModuleName>/route.js
8
+
9
+ ## Purpose
10
+ The Express router for a single API module. Defines all HTTP routes for
11
+ this module, handles input validation inline using checkValidationRules,
12
+ calls the model function, and sends the response via sendResponse. This
13
+ file contains no business logic — it is purely a request/response
14
+ coordinator. Every route in this file follows the same structural pattern.
15
+
16
+ This file is generated fresh for every `@create-api` command. The agent
17
+ reads `context.current_api` to know the method, path, module name,
18
+ primary table, and auth requirements for the new route being added.
19
+
20
+ ---
21
+
22
+ ## Dependencies to Import
23
+
24
+ - `express` — for `express.Router()`
25
+ - `./<module>_model` — imported using the lowercase module name.
26
+ e.g. for module `Auth` → `require('./auth_model')`
27
+ - `../../../utilities/response` — imported as `{ sendResponse }`.
28
+ Used to send all responses. Never call `res.json()` directly.
29
+ - `../../../utilities/validator` — imported as `{ checkValidationRules }`.
30
+ Used for input validation on POST/PUT/PATCH routes.
31
+ - `../../../logger/logging` — imported as `log`. Used at the start of
32
+ every route handler.
33
+
34
+ ---
35
+
36
+ ## Router Initialization
37
+
38
+ Create the router: `const router = express.Router()`
39
+ Assign model: `const <moduleName>Model = require('./<module>_model')`
40
+
41
+ ---
42
+
43
+ ## Default Routes (generated during @initialize-project)
44
+
45
+ ```
46
+ The default route file must have a file-level header comment as
47
+ the first line of the file:
48
+ ```javascript
49
+ // <ModuleName> module routes. Handles validation and delegates to model.
50
+ ```
51
+
52
+ Each route handler must have a single-line comment above it
53
+ following the pattern defined in nodejs-agent.md Code Style Standards.
54
+ ```
55
+
56
+ ---
57
+
58
+ When the route.js file is first generated as part of
59
+ `@initialize-project`, it contains TWO default routes:
60
+
61
+ ### 1. Health Check Route (for Docker/monitoring)
62
+
63
+ **Route**: `GET /health`
64
+
65
+ **Handler flow**:
66
+ 1. Log at info level: module name + "health check called"
67
+ 2. Return JSON directly (no model, no sendResponse):
68
+ ```javascript
69
+ res.status(200).json({
70
+ status: 'healthy',
71
+ timestamp: new Date().toISOString(),
72
+ service: process.env.npm_package_name || 'unknown',
73
+ uptime: process.uptime()
74
+ });
75
+ ```
76
+
77
+ This route is PUBLIC (no auth middleware) and placed FIRST in the file.
78
+
79
+ ### 2. Test Route (for API testing)
80
+
81
+ **Route**: `GET /test`
82
+
83
+ **Handler flow**:
84
+ 1. Log at info level: module name + "test route called"
85
+ 2. Call `sendResponse` with:
86
+ - `req` and `res` passed through
87
+ - `statusCode` — `200`
88
+ - `responseCode` — `"1"`
89
+ - `messageKeyword` — `"rest_keywords_success"`
90
+ - `messageComponents` — `{}`
91
+ - `responseData` — object with one key: `{ service: process.env.PROJECT_NAME, module: "<ModuleName>", status: "ok" }`
92
+
93
+ These default routes are extended (not replaced) when `@create-api` generates
94
+ actual routes.
95
+
96
+ ---
97
+
98
+ ## Route Pattern for Generated Routes (used by @create-api)
99
+
100
+ Every route generated by @create-api follows the comment pattern
101
+ from nodejs-agent.md Code Style Standards — one single-line comment
102
+ above each router.get/post/put/patch/delete call.
103
+
104
+ Every route generated by `@create-api` follows this exact pattern:
105
+
106
+ ### GET route pattern
107
+
108
+ Handler receives `req` and `res`. Handler is async.
109
+
110
+ Flow:
111
+ 1. Extract query parameters or path params from `req.query` or
112
+ `req.params` as needed. Store as `request` object.
113
+ 2. Log at info level: route name + "request" with the request object.
114
+ 3. Call the model function:
115
+ `const { responsecode, responsemsg, responsedata } = await
116
+ <moduleName>Model.<functionName>(request, req.user_id, req.user_type)`
117
+ `req.user_id` and `req.user_type` are set by validateToken and always
118
+ available on protected routes. Pass them to model explicitly.
119
+ 4. Call `sendResponse(req, res, 200, responsecode, responsemsg, responsedata)`.
120
+
121
+ ### POST / PUT / PATCH route pattern
122
+
123
+ Handler receives `req` and `res`. Handler is async.
124
+
125
+ Flow:
126
+ 1. Assign `let request = req.body`. The body is already decrypted by
127
+ `decryptRequest` middleware if encrypted_transport is true.
128
+ 2. Define `rules` object — keys are field names, values are validatorjs
129
+ rule strings. Agent reads `context.current_api.primary_table` columns
130
+ from `context.db.schema` to suggest relevant rules.
131
+ 3. Define `messages` object — keys are rule names like `'required'`
132
+ and `'email'`, values use `req.languageData.<key>` to get the
133
+ translated rule message. For example:
134
+ `'required': req.languageData.required`
135
+ `'email': req.languageData.email`
136
+ Only include message overrides for rules actually used in `rules`.
137
+ 4. Log at info level: route name + "request" with the request object.
138
+ 5. Call `await checkValidationRules(req, res, rules, messages)`.
139
+ Store result as `isValid`.
140
+ 6. If `isValid` is false — return immediately. Response already sent.
141
+ 7. If `isValid` is true — call the model function same as GET pattern.
142
+ 8. Call `sendResponse`.
143
+
144
+ ### DELETE route pattern
145
+
146
+ Same as GET pattern. No body, no validation. Path params only.
147
+
148
+ ---
149
+
150
+ ## Auth Middleware Application (per-route)
151
+
152
+ Read `context.current_api.requires_auth`:
153
+
154
+ - If `"full"` — no extra middleware needed in route.js. validateToken
155
+ in route_manager already handles this globally. `req.user_id` and
156
+ `req.user_type` will be set.
157
+ - If `"api_key_only"` — same as full, validateToken is bypassed via
158
+ bypassMethod in headerValidator for this route. Document this in a
159
+ comment above the route.
160
+ - If `"none"` — same, bypass is configured in headerValidator. Document
161
+ in a comment above the route.
162
+
163
+ No middleware is applied directly inside route.js. All auth is
164
+ handled at the route_manager level via headerValidator. Route.js only
165
+ documents the auth requirement in a comment.
166
+
167
+ ---
168
+
169
+ ## Response Pattern Contract
170
+
171
+ Every route handler must call `sendResponse` exactly once and
172
+ immediately return after. Never call `sendResponse` inside a conditional
173
+ without a return. The model always returns three values destructured as:
174
+ `{ responsecode, responsemsg, responsedata }`
175
+
176
+ - `responsecode` — string `"1"` for success, `"0"` for failure
177
+ - `responsemsg` — object with `keyword` and `components` keys
178
+ - `responsedata` — the data payload or null
179
+
180
+ These are passed directly to `sendResponse` — route.js never inspects
181
+ or modifies them.
182
+
183
+ ---
184
+
185
+ ## Export
186
+ ```
187
+ module.exports = router
188
+ ```
189
+
190
+ ---
191
+
192
+ ## What This File Does NOT Do
193
+
194
+ - Does not import config/database — no DB queries in route files
195
+ - Does not import encryption utilities — decryption already done by
196
+ middleware before this runs
197
+ - Does not contain business logic — all logic is in the model file
198
+ - Does not import config/common — common is for model files
199
+ - Does not call res.json() directly — always uses sendResponse
200
+ - Does not import middleware from headerValidator for sendresponse or
201
+ checkValidationRules — those are now in their own utility files
202
+ - Does not define more than one module's routes — one route.js per
203
+ module always
@@ -0,0 +1,290 @@
1
+ ---
2
+ type: task
3
+ name: generate-swagger
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: document/v1/swagger_doc.json
8
+
9
+ ## Purpose
10
+ OpenAPI 3.0 specification file for the service. Documents all API
11
+ endpoints, request/response schemas, authentication requirements, and
12
+ error responses. Generated as an empty skeleton during
13
+ `@initialize-project` and updated every time `@create-api` adds a new
14
+ route. This file is the single source of API documentation — developers
15
+ and frontend teams reference it to understand what the API expects and
16
+ returns.
17
+
18
+ ---
19
+
20
+ ## Generation Modes
21
+
22
+ This task is called in two different situations. The agent reads the
23
+ call context to determine which mode applies:
24
+
25
+ ### Mode 1 — Skeleton (called from @initialize-project)
26
+ Generates the base swagger_doc.json with service metadata, security
27
+ scheme definitions, and no paths. Called once.
28
+
29
+ ### Mode 2 — Update (called from @create-api)
30
+ Reads the existing swagger_doc.json, adds the new endpoint path entry,
31
+ and writes the file back. Called every time a new route is created.
32
+
33
+ ---
34
+
35
+ ## Mode 1 — Skeleton Structure
36
+
37
+ Generate a valid OpenAPI 3.0 JSON file with this exact top-level
38
+ structure:
39
+
40
+ ### openapi
41
+ Value: `"3.0.0"` — always this version string.
42
+
43
+ ### info
44
+ Object with these keys:
45
+ - `title` — from `process.env.PROJECT_NAME` / `context.current_init.service_name`
46
+ - `description` — from `context.current_init.description`
47
+ - `version` — `"1.0.0"`
48
+ - `contact` — object with:
49
+ - `name` — from `context.current_init.author`
50
+
51
+ ### servers
52
+ Array with one entry:
53
+ - `url` — constructed as `http://localhost:<port>/api/v1` where port
54
+ comes from `context.current_init.port`
55
+ - `description` — `"Local development server"`
56
+
57
+ ### components
58
+
59
+ #### securitySchemes
60
+ Define two security schemes:
61
+
62
+ **ApiKeyAuth**:
63
+ ```json
64
+ {
65
+ "type": "apiKey",
66
+ "in": "header",
67
+ "name": "api-key",
68
+ "description": "AES encrypted API key. Encrypt the raw API_KEY value before sending."
69
+ }
70
+ ```
71
+
72
+ **TokenAuth**:
73
+ ```json
74
+ {
75
+ "type": "apiKey",
76
+ "in": "header",
77
+ "name": "token",
78
+ "description": "AES encrypted JWT token. Encrypt the JWT before sending."
79
+ }
80
+ ```
81
+
82
+ Note: Both use `apiKey` type because the headers are custom (`api-key`
83
+ and `token`) not the standard `Authorization: Bearer` pattern. OpenAPI
84
+ does not have a built-in type for custom encrypted headers — apiKey is
85
+ the closest match.
86
+
87
+ #### schemas
88
+ Define three reusable response schemas:
89
+
90
+ **SuccessResponse**:
91
+ ```json
92
+ {
93
+ "type": "object",
94
+ "properties": {
95
+ "code": { "type": "string", "example": "1" },
96
+ "message": { "type": "string", "example": "Success!" },
97
+ "data": { "type": "object" }
98
+ }
99
+ }
100
+ ```
101
+
102
+ **ErrorResponse**:
103
+ ```json
104
+ {
105
+ "type": "object",
106
+ "properties": {
107
+ "code": { "type": "string", "example": "0" },
108
+ "message": { "type": "string", "example": "Something went wrong" }
109
+ }
110
+ }
111
+ ```
112
+
113
+ **UnauthorizedResponse**:
114
+ ```json
115
+ {
116
+ "type": "object",
117
+ "properties": {
118
+ "code": { "type": "string", "example": "-1" },
119
+ "message": { "type": "string", "example": "Invalid token provided" }
120
+ }
121
+ }
122
+ ```
123
+
124
+ Note on `encrypted_transport`: If `encrypted_transport == true`, add
125
+ a note in the `info.description` field stating:
126
+ `"All request bodies must be AES-256-CBC encrypted. All response data
127
+ is AES-256-CBC encrypted. Use the enc_dec tool to test payloads."`
128
+
129
+ #### paths
130
+ Empty object `{}`. Populated by Mode 2 calls.
131
+
132
+ ---
133
+
134
+ ## Mode 2 — Adding a New Path Entry
135
+
136
+ Called from `@create-api` after the user confirms the new route.
137
+ The agent reads `context.current_api` for all values.
138
+
139
+ ### Steps
140
+ 1. Read the existing `document/v1/swagger_doc.json` file.
141
+ 2. Find or create the path key in `paths` using
142
+ `context.current_api.route_path` as the key.
143
+ Example: `"/products"` or `"/products/{id}"`
144
+ Note: path parameters use `{param}` format in OpenAPI, not `:param`
145
+ Express format. Convert `:id` → `{id}`, `:orderId` → `{orderId}`.
146
+ 3. Under the path key, add the HTTP method key in lowercase:
147
+ `context.current_api.method.toLowerCase()`
148
+ 4. Build the operation object as described below.
149
+ 5. Write the updated file back to disk.
150
+
151
+ ## Append Safety Rules for Mode 2
152
+
153
+ NEVER rewrite swagger_doc.json. The file grows with every @create-api
154
+ call. A full rewrite risks losing manually added documentation,
155
+ custom schema definitions, or endpoint notes that developers added
156
+ outside the agent.
157
+
158
+ The only permitted operation in Mode 2 is:
159
+ 1. Read the file into memory as a parsed JSON object
160
+ 2. Check if the path key already exists in `paths`
161
+ - If it exists → do not overwrite it. Log:
162
+ "Path [method] [path] already exists in swagger_doc.json.
163
+ Skipping to avoid overwriting existing documentation."
164
+ - If it does not exist → add the new path key and operation object
165
+ 3. Write the updated JSON object back to the file with 2-space
166
+ indentation (preserving formatting consistency)
167
+ 4. Never sort or reformat existing keys — preserve their order
168
+
169
+ The only change to the file is the addition of one new key in the
170
+ `paths` object. Everything else remains byte-for-byte identical.
171
+
172
+ ### Operation Object Structure
173
+
174
+ **summary**:
175
+ From `context.current_api.description`.
176
+
177
+ **tags**:
178
+ Array with one entry: `context.current_api.module_name`.
179
+ Tags group endpoints by module in the Swagger UI.
180
+
181
+ **security**:
182
+ Determined by `context.current_api.requires_auth`:
183
+ - `"full"` → `[{ "ApiKeyAuth": [] }, { "TokenAuth": [] }]`
184
+ - `"api_key_only"` → `[{ "ApiKeyAuth": [] }]`
185
+ - `"none"` → `[]` (empty array — no security on this endpoint)
186
+
187
+ **parameters** (for GET and DELETE routes):
188
+ If the route path contains `{param}` variables — add a parameters
189
+ array. For each path parameter:
190
+ ```json
191
+ {
192
+ "name": "",
193
+ "in": "path",
194
+ "required": true,
195
+ "schema": { "type": "integer" }
196
+ }
197
+ ```
198
+ For query parameters — agent reads `context.current_api.primary_table`
199
+ columns from `context.db.schema` to suggest relevant query params.
200
+ Common ones: `page`, `limit`, `search`. Add as `"in": "query"`,
201
+ `"required": false`.
202
+
203
+ **requestBody** (for POST, PUT, PATCH routes only):
204
+ ```json
205
+ {
206
+ "required": true,
207
+ "content": {
208
+ "application/json": {
209
+ "schema": {
210
+ "type": "object",
211
+ "properties": {}
212
+ }
213
+ }
214
+ }
215
+ }
216
+ ```
217
+ Agent reads `context.current_api.primary_table` columns from
218
+ `context.db.schema` to populate the `properties` object with the
219
+ relevant columns for this operation. Exclude system columns: `id`,
220
+ `created_at`, `is_deleted`, `status`. Include columns appropriate
221
+ for the HTTP method (e.g. POST includes all required fields, PUT/PATCH
222
+ includes updatable fields only).
223
+
224
+ If `encrypted_transport == true` — change the schema to:
225
+ ```json
226
+ {
227
+ "type": "string",
228
+ "description": "AES-256-CBC encrypted JSON payload"
229
+ }
230
+ ```
231
+ Because the body is a cipher string, not a JSON object.
232
+
233
+ **responses**:
234
+ Always include these three response codes:
235
+
236
+ `"200"`:
237
+ ```json
238
+ {
239
+ "description": "Successful operation",
240
+ "content": {
241
+ "application/json": {
242
+ "schema": { "$ref": "#/components/schemas/SuccessResponse" }
243
+ }
244
+ }
245
+ }
246
+ ```
247
+
248
+ `"401"`:
249
+ ```json
250
+ {
251
+ "description": "Unauthorized",
252
+ "content": {
253
+ "application/json": {
254
+ "schema": { "$ref": "#/components/schemas/UnauthorizedResponse" }
255
+ }
256
+ }
257
+ }
258
+ ```
259
+
260
+ `"200"` for validation failure (separate from success — same HTTP code
261
+ but different application code):
262
+ Add a note in the `"200"` response description:
263
+ `"Returns code 1 on success, code 0 on validation/business failure"`
264
+
265
+ ---
266
+
267
+ ## File Location
268
+
269
+ Always: `<service_name>/document/v1/swagger_doc.json`
270
+
271
+ The `document/v1/` folder is created during `@initialize-project`.
272
+ The file is created in Mode 1 and updated in Mode 2.
273
+
274
+ ---
275
+
276
+ ## Export
277
+
278
+ This is a JSON file. No module.exports. Read and written by the agent
279
+ using file system operations.
280
+
281
+ ---
282
+
283
+ ## What This File Does NOT Do
284
+
285
+ - Does not serve the Swagger UI — that requires a separate route
286
+ using `swagger-ui-express`. Adding a Swagger UI route is out of
287
+ scope for scaffolding — developer adds it manually when needed.
288
+ - Does not validate requests at runtime — it is documentation only
289
+ - Does not auto-generate from code — the agent writes it from context
290
+ - Does not include deprecated endpoints — only active routes
@@ -0,0 +1,75 @@
1
+ ---
2
+ type: task
3
+ name: generate-tbl-user-deviceinfo
4
+ agent: database-agent
5
+ ---
6
+
7
+ # File: <repo_root>/database/<db_type>/migrations/1-setup-tbl-user-deviceinfo.sql
8
+
9
+ ## Path Note
10
+ This file is generated at the REPOSITORY ROOT database directory,
11
+ not inside the service folder. The full path relative to repo root is:
12
+ `database/<db_type>/migrations/1-setup-tbl-user-deviceinfo.sql`
13
+
14
+ ## Purpose
15
+ Generates the default system table required by every NodeJS service.
16
+ This table stores device information and the JWT token per user per
17
+ user_type. It is the foundation of the session management system used
18
+ by common.generateSessionCode and validateToken. Always generated as
19
+ migration file number 1.
20
+
21
+ ## Table Name
22
+ `tbl_user_deviceinfo`
23
+
24
+ ## Columns
25
+
26
+ Follow all database-agent naming and type conventions exactly.
27
+
28
+ - `id` — bigint GENERATED ALWAYS AS IDENTITY, PRIMARY KEY
29
+ - `user_id` — BIGINT NOT NULL DEFAULT 0. Foreign key reference to the
30
+ users table conceptually, but no hard FK constraint — services may
31
+ have multiple user types.
32
+ - `user_type` — VARCHAR(32) NOT NULL DEFAULT ''. The user role or type
33
+ string. Combined with user_id forms the unique session key.
34
+ - `token` — TEXT NOT NULL DEFAULT ''. The signed JWT token string.
35
+ TEXT because JWT tokens are long.
36
+ - `version` — BIGINT NOT NULL DEFAULT 0. The current session version
37
+ for this user/type combination. Must match the version stored in
38
+ Redis and the version inside the JWT payload for validateToken to
39
+ pass.
40
+ - `uuid` — VARCHAR(255) NOT NULL DEFAULT ''. Device UUID.
41
+ - `ip` — VARCHAR(45) NOT NULL DEFAULT ''. Client IP address.
42
+ VARCHAR(45) to support IPv6.
43
+ - `os_version` — VARCHAR(64) NOT NULL DEFAULT ''. Operating system
44
+ version string.
45
+ - `model_name` — VARCHAR(128) NOT NULL DEFAULT ''. Device model name.
46
+ - `device_type` — VARCHAR(32) NOT NULL DEFAULT ''. Platform identifier
47
+ e.g. "ios", "android", "web".
48
+ - `device_token` — TEXT NOT NULL DEFAULT ''. FCM or APNs push
49
+ notification token. TEXT because push tokens are long.
50
+ - `is_deleted` — BOOLEAN NOT NULL DEFAULT FALSE
51
+ - `created_at` — TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
52
+
53
+ ## Indexes
54
+
55
+ - `idx_user_deviceinfo_user_id` ON (user_id)
56
+ - `idx_user_deviceinfo_user_id_user_type` ON (user_id, user_type)
57
+ — compound index. Most queries filter by both columns together.
58
+
59
+ ## File Number
60
+ Always 1. This is always the first migration file in any NodeJS service.
61
+
62
+ ## Database Type Handling
63
+ Generate SQL syntax appropriate for `context.db.type`:
64
+ - postgresql → use BIGINT GENERATED ALWAYS AS IDENTITY, TIMESTAMPTZ,
65
+ BOOLEAN, TEXT, parameterized queries with $1 style
66
+ - mysql → use BIGINT AUTO_INCREMENT, DATETIME DEFAULT CURRENT_TIMESTAMP,
67
+ TINYINT(1) for boolean, parameterized queries with ? style
68
+ - mongodb → generate a Mongoose schema file instead of SQL, placed in
69
+ database/mongodb/schemas/userDeviceinfo.schema.js
70
+
71
+ ## After Generation
72
+ - Update `<repo_root>/database/<db_type>/create-schema.sql` to
73
+ include this file as the first \i entry
74
+ - Update `context.db.schema.tables` with this table's full definition
75
+ - Append to `context.db.schema.change_log`
@@ -0,0 +1,129 @@
1
+ ---
2
+ type: task
3
+ name: generate-template
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: config/template.js
8
+
9
+ ## Purpose
10
+ Defines HTML email template functions for all transactional emails sent
11
+ by the service. Each template is a function that accepts a data object
12
+ and a callback. The callback is called with the complete HTML string.
13
+ All templates use GLOBALS from constants.js for branding values like
14
+ APP_NAME, LOGO, BASE_URL, and legal links. Templates are professional,
15
+ fully responsive, and styled for modern email clients.
16
+
17
+ ---
18
+
19
+ ## Dependencies to Import
20
+
21
+ - `./constants` — imported as `GLOBALS`. Used for APP_NAME, LOGO,
22
+ BASE_URL, UNSUBSCRIBE, TERMS_OF_USE, and PRIVACY_POLICY in all
23
+ templates.
24
+
25
+ ---
26
+
27
+ ## Template Structure Rules
28
+
29
+ Every template function follows this exact signature:
30
+ `exports.<templateName> = function(result, callback)`
31
+
32
+ Where:
33
+ - `result` — plain object containing the dynamic values specific to
34
+ this email (name, OTP, link, etc.)
35
+ - `callback` — function called with the complete HTML string as its
36
+ only argument: `callback(htmlString)`
37
+
38
+ The HTML structure for every template must follow this layout order:
39
+ 1. Full HTML document with DOCTYPE, head, viewport meta, and inline CSS
40
+ 2. Email container centered at max-width 600px
41
+ 3. Header section — dark background, logo image from `GLOBALS.LOGO`
42
+ 4. Body section — main content area with the email message
43
+ 5. Footer section — unsubscribe link, legal links, sent-to address
44
+
45
+ The CSS must be fully inlined or in a style block in head. No external
46
+ stylesheets. Use a professional color scheme derived from the project —
47
+ the agent reads `context.project_info.from_figma.color_theme` if
48
+ available, otherwise uses a professional neutral dark/light scheme.
49
+ Font: use a Google Fonts import for a clean sans-serif such as Lato
50
+ or Inter with a fallback stack.
51
+
52
+ ---
53
+
54
+ ## Templates to Generate
55
+
56
+ ---
57
+
58
+ ### exports.welcome(result, callback)
59
+
60
+ **Purpose**: Sent to a new user immediately after successful registration.
61
+
62
+ **Dynamic values in result**:
63
+ - `result.first_name` — the user's first name for the greeting
64
+ - `result.email` — the user's email address, shown in the footer
65
+
66
+ **Content**:
67
+ Header: APP_NAME logo
68
+ Body:
69
+ - Greeting: "Hello [first_name]!"
70
+ - Welcome message thanking the user for joining APP_NAME
71
+ - A brief description of what the platform offers (agent uses
72
+ `context.project_info.summary` to write one relevant sentence here)
73
+ - A closing line encouraging the user to explore the platform
74
+ - "Thank You!" sign-off
75
+
76
+ Footer:
77
+ - "This message was sent to [email]"
78
+ - Unsubscribe link using `GLOBALS.UNSUBSCRIBE`
79
+ - Terms of use and privacy policy links
80
+
81
+ ---
82
+
83
+ ### exports.forgotPassword(result, callback)
84
+
85
+ **Purpose**: Sent when a user requests a password reset OTP.
86
+
87
+ **Dynamic values in result**:
88
+ - `result.first_name` — user's first name
89
+ - `result.otp_code` — the generated OTP code to display
90
+ - `result.email` — shown in footer
91
+ - `result.encoded_user_id` — appended to the unsubscribe URL
92
+
93
+ **Content**:
94
+ Header: APP_NAME logo
95
+ Body:
96
+ - Greeting: "Hello [first_name]!"
97
+ - Explanation that they requested a verification code
98
+ - The OTP displayed prominently in a centered block, bold, large text
99
+ - Instruction to use this code to reset their password
100
+ - Note that this code expires (agent adds a sensible expiry note)
101
+ - "Thank You!" sign-off
102
+
103
+ Footer:
104
+ - Sent-to address with the user's email
105
+ - Unsubscribe link with encoded_user_id appended
106
+
107
+ ---
108
+
109
+ ## Email Client Compatibility Requirements
110
+
111
+ All templates must include:
112
+ - `xmlns` attributes on the html element for Outlook compatibility
113
+ - `border="0" cellspacing="0" cellpadding="0"` on all table elements
114
+ - `width="100%"` on outer tables
115
+ - Inline width constraints on inner divs for Gmail compatibility
116
+ - `@media` queries for mobile breakpoints at 320px, 375px, and 414px
117
+ - `content-type` meta for IE compatibility
118
+ - Apple mail data detector disabling via CSS
119
+
120
+ ---
121
+
122
+ ## What This File Does NOT Do
123
+
124
+ - Does not send emails — sending is done in `utilities/notification.js`
125
+ - Does not import nodemailer or any mail transport
126
+ - Does not generate plain text versions — HTML only
127
+ - Does not validate the result object — assumes caller provides correct
128
+ fields
129
+ - Does not use external template engines like Handlebars or EJS