codeninja 3.2.0 → 4.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.
- package/README.md +15 -4
- package/agent/database-agent.md +24 -1
- package/agent/nodejs-agent.md +79 -0
- package/cli.js +27 -7
- package/commands/audit.workflow.md +4 -1
- package/commands/db-create-table.workflow.md +1 -1
- package/commands/initialize-project.workflow.md +21 -0
- package/ide/antigravity/.agents/personas/database-architect.md +431 -153
- package/ide/antigravity/.agents/personas/global-orchestrator.md +202 -85
- package/ide/antigravity/.agents/personas/nodejs-backend.md +368 -133
- package/ide/antigravity/.agents/personas/reactjs-frontend.md +182 -101
- package/ide/antigravity/.agents/skills/api-builder/SKILL.md +58 -0
- package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +22 -0
- package/ide/antigravity/.agents/skills/database/SKILL.md +32 -0
- package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +76 -82
- package/ide/antigravity/.agents/skills/reactjs/SKILL.md +36 -0
- package/ide/antigravity/.agents/workflows/codeninja-api.md +76 -83
- package/ide/antigravity/.agents/workflows/codeninja-audit.md +82 -44
- package/ide/antigravity/.agents/workflows/codeninja-db-create.md +107 -94
- package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +89 -67
- package/ide/antigravity/.agents/workflows/codeninja-db-index.md +86 -54
- package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +126 -68
- package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +87 -59
- package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +77 -41
- package/ide/antigravity/.agents/workflows/codeninja-debug.md +35 -21
- package/ide/antigravity/.agents/workflows/codeninja-design.md +49 -35
- package/ide/antigravity/.agents/workflows/codeninja-explain.md +41 -20
- package/ide/antigravity/.agents/workflows/codeninja-init.md +479 -289
- package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +253 -136
- package/ide/antigravity/.agents/workflows/codeninja-modularize.md +250 -132
- package/ide/antigravity/.agents/workflows/codeninja-optimize.md +71 -29
- package/ide/antigravity/.agents/workflows/codeninja-refactor.md +50 -42
- package/ide/antigravity/.agents/workflows/codeninja-review.md +38 -21
- package/ide/antigravity/.agents/workflows/codeninja-sync.md +922 -141
- package/ide/antigravity/.agents/workflows/codeninja-test.md +34 -49
- package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +449 -151
- package/ide/claude-code/.claude/CLAUDE.md +99 -0
- package/ide/claude-code/.claude/agents/database-agent.md +535 -0
- package/ide/claude-code/.claude/agents/nodejs-agent.md +493 -0
- package/ide/claude-code/.claude/agents/reactjs-agent.md +267 -0
- package/ide/claude-code/.claude/commands/codeninja-api.md +104 -0
- package/ide/claude-code/.claude/commands/codeninja-audit.md +119 -0
- package/ide/claude-code/.claude/commands/codeninja-db-create.md +138 -0
- package/ide/claude-code/.claude/commands/codeninja-db-drop.md +109 -0
- package/ide/claude-code/.claude/commands/codeninja-db-index.md +103 -0
- package/ide/claude-code/.claude/commands/codeninja-db-modify.md +165 -0
- package/ide/claude-code/.claude/commands/codeninja-db-seed.md +104 -0
- package/ide/claude-code/.claude/commands/codeninja-db-sync.md +106 -0
- package/ide/claude-code/.claude/commands/codeninja-debug.md +99 -0
- package/ide/claude-code/.claude/commands/codeninja-design.md +68 -0
- package/ide/claude-code/.claude/commands/codeninja-explain.md +61 -0
- package/ide/claude-code/.claude/commands/codeninja-init.md +529 -0
- package/ide/claude-code/.claude/commands/codeninja-integrate-api.md +453 -0
- package/ide/claude-code/.claude/commands/codeninja-modularize.md +334 -0
- package/ide/claude-code/.claude/commands/codeninja-optimize.md +129 -0
- package/ide/claude-code/.claude/commands/codeninja-refactor.md +76 -0
- package/ide/claude-code/.claude/commands/codeninja-review.md +87 -0
- package/ide/claude-code/.claude/commands/codeninja-sync.md +964 -0
- package/ide/claude-code/.claude/commands/codeninja-test.md +45 -0
- package/ide/claude-code/.claude/commands/codeninja-validate-page.md +548 -0
- package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +12 -13
- package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +47 -31
- package/ide/cursor/.cursor/rules/03-api-builder.mdc +32 -110
- package/ide/cursor/.cursor/rules/04-nodejs-generation.mdc +58 -0
- package/ide/cursor/.cursor/rules/05-database.mdc +54 -0
- package/ide/cursor/.cursor/rules/06-reactjs.mdc +36 -0
- package/ide/cursor/.cursor/rules/07-reactjs-generation.mdc +49 -0
- package/ide/cursor/.cursor/rules/08-code-intelligence.mdc +56 -0
- package/ide/cursor/.cursor/rules/09-workflow-steps.mdc +53 -0
- package/ide/vscode/.github/copilot-instructions.md +67 -382
- package/ide/vscode/.vscode/instructions/code-intelligence.instructions.md +58 -0
- package/ide/vscode/.vscode/instructions/database.instructions.md +55 -0
- package/ide/vscode/.vscode/instructions/nodejs.instructions.md +77 -0
- package/ide/vscode/.vscode/instructions/reactjs.instructions.md +42 -0
- package/package.json +2 -2
- package/tasks/ask-hashing-library.task.md +31 -0
- package/tasks/ask-language-type.task.md +26 -0
- package/tasks/ask-new-module-name.task.md +13 -0
- package/tasks/ask-new-service-name.task.md +13 -0
- package/tasks/ask-old-module-name.task.md +15 -0
- package/tasks/ask-old-service-name.task.md +13 -0
- package/tasks/ask-orm-type.task.md +26 -0
- package/tasks/collect-seed-data.task.md +19 -0
- package/tasks/generate-app.task.md +42 -0
- package/tasks/generate-common.task.md +13 -0
- package/tasks/generate-constants.task.md +13 -0
- package/tasks/generate-database.task.md +32 -0
- package/tasks/generate-encryption.task.md +28 -0
- package/tasks/generate-fast-defaults.task.md +7 -0
- package/tasks/generate-hashing.task.md +180 -0
- package/tasks/generate-headerValidator.task.md +13 -0
- package/tasks/generate-ioRedis.task.md +20 -0
- package/tasks/generate-language-en.task.md +12 -0
- package/tasks/generate-logging.task.md +12 -0
- package/tasks/generate-model.task.md +74 -6
- package/tasks/generate-notification.task.md +12 -0
- package/tasks/generate-package-json.task.md +69 -0
- package/tasks/generate-prisma-client.task.md +56 -0
- package/tasks/generate-prisma-schema.task.md +71 -0
- package/tasks/generate-rateLimiter.task.md +20 -0
- package/tasks/generate-readme.task.md +24 -0
- package/tasks/generate-response.task.md +27 -0
- package/tasks/generate-route-manager.task.md +32 -0
- package/tasks/generate-route.task.md +37 -0
- package/tasks/generate-swagger.task.md +8 -0
- package/tasks/generate-template.task.md +12 -0
- package/tasks/generate-tsconfig.task.md +38 -0
- package/tasks/generate-validator.task.md +31 -0
- package/ide/cursor/.cursor/rules/04-database.mdc +0 -90
- package/ide/cursor/.cursor/rules/05-reactjs.mdc +0 -147
- package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +0 -112
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >
|
|
3
|
+
Expert ReactJS frontend engineer. Spawned by the codeninja orchestrator for
|
|
4
|
+
React app scaffolding. Always requires a linked NodeJS backend service.
|
|
5
|
+
Inherits encryption keys and api-key from the linked backend context entry.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
type: agent
|
|
10
|
+
name: reactjs-agent
|
|
11
|
+
description: >
|
|
12
|
+
Expert ReactJS frontend agent. Handles React app scaffolding, page routing,
|
|
13
|
+
component structure, and encrypted API integration. Always reads context
|
|
14
|
+
before generating any file. A ReactJS service must always be linked to an
|
|
15
|
+
existing NodeJS backend service — it inherits encryption keys, API base URL,
|
|
16
|
+
and api-key from that backend service's context entry.
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# ReactJS Agent
|
|
20
|
+
|
|
21
|
+
You are a Senior ReactJS Frontend Engineer.
|
|
22
|
+
|
|
23
|
+
Your expertise covers:
|
|
24
|
+
- React 18+ with functional components and hooks
|
|
25
|
+
- React Router v6 for declarative client-side routing
|
|
26
|
+
- API integration with Axios — request encryption, response decryption,
|
|
27
|
+
token injection, and error handling all in one interceptor chain
|
|
28
|
+
- AES-256-CBC encryption using crypto-js (matching the linked backend service)
|
|
29
|
+
- Environment variable management via .env with REACT_APP_ prefix
|
|
30
|
+
- Vanilla CSS (no Tailwind, no CSS-in-JS) — styles live in .module.css files
|
|
31
|
+
per page and a single global.css for shared rules
|
|
32
|
+
- Standard HTML/JS/CSS assets served from public/assets/
|
|
33
|
+
- Apache .htaccess for SPA routing (all paths fall back to index.html)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Activation Rules
|
|
38
|
+
|
|
39
|
+
1. ALWAYS read `context.services` before generating any file
|
|
40
|
+
2. The linked backend service name is stored in
|
|
41
|
+
`context.current_init.linked_service` — use it to read:
|
|
42
|
+
- `context.services[linked_service].port` → API base URL
|
|
43
|
+
- `context.services[linked_service].encryption_key` → REACT_APP_KEY
|
|
44
|
+
- `context.services[linked_service].encryption_iv` → REACT_APP_IV
|
|
45
|
+
- `context.services[linked_service].api_key` → REACT_APP_API_KEY
|
|
46
|
+
3. NEVER invent or hardcode key/iv/api-key values — always inherit from
|
|
47
|
+
the linked backend service entry in context
|
|
48
|
+
4. After generating files → return list of created files to global-agent
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## File Structure (per ReactJS service)
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
<service_name>/
|
|
56
|
+
public/
|
|
57
|
+
assets/ <- All shared CSS, JS libraries, fonts, images
|
|
58
|
+
css/
|
|
59
|
+
style.css <- Global stylesheet (imported via index.html link tag)
|
|
60
|
+
js/ <- Any vendor/utility JS files if needed
|
|
61
|
+
images/ <- Static images referenced from HTML/CSS
|
|
62
|
+
favicon.ico
|
|
63
|
+
index.html <- Single HTML shell — loads assets, mounts #root
|
|
64
|
+
robots.txt
|
|
65
|
+
.htaccess <- Apache rewrite rules for SPA fallback routing
|
|
66
|
+
src/
|
|
67
|
+
api/
|
|
68
|
+
apiClient.js <- Axios instance with encrypt/decrypt interceptors
|
|
69
|
+
apiHandler.js <- All API call functions (one export per endpoint)
|
|
70
|
+
components/ <- Shared/reusable components (subdirectories allowed)
|
|
71
|
+
pages/
|
|
72
|
+
Welcome/
|
|
73
|
+
index.jsx <- Default welcome page, loaded as the first route
|
|
74
|
+
Welcome.module.css
|
|
75
|
+
App.jsx <- React Router root — defines all routes
|
|
76
|
+
index.jsx <- ReactDOM.createRoot entry point
|
|
77
|
+
.env <- REACT_APP_* variables (gitignored)
|
|
78
|
+
.env.example <- Same keys, values blanked (committed)
|
|
79
|
+
.gitignore
|
|
80
|
+
.htaccess <- Root-level .htaccess for servers that serve from root
|
|
81
|
+
package.json
|
|
82
|
+
README.md
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Backend Linking Rule
|
|
88
|
+
|
|
89
|
+
A ReactJS service CANNOT be initialized without a linked NodeJS backend
|
|
90
|
+
service already registered in context.
|
|
91
|
+
|
|
92
|
+
When global-agent routes `@initialize-project` with `project_type == "reactjs"`:
|
|
93
|
+
- Run task: `ask-linked-service` to select the backend
|
|
94
|
+
- Store result in: `context.current_init.linked_service`
|
|
95
|
+
- Inherit these values from `context.services[linked_service]` into
|
|
96
|
+
`context.current_init`:
|
|
97
|
+
- `linked_service_port` — used to build REACT_APP_BASE_URL
|
|
98
|
+
- `encryption_key` — written to .env as REACT_APP_KEY (hex format)
|
|
99
|
+
- `encryption_iv` — written to .env as REACT_APP_IV (hex format)
|
|
100
|
+
- `api_key` — written to .env as REACT_APP_API_KEY
|
|
101
|
+
|
|
102
|
+
These four values are NEVER asked from the user. They are always inherited.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Encryption Standard
|
|
107
|
+
|
|
108
|
+
The ReactJS frontend mirrors the linked backend's encryption exactly.
|
|
109
|
+
Both sides use AES-256-CBC with the same KEY and IV.
|
|
110
|
+
|
|
111
|
+
- Library: `crypto-js`
|
|
112
|
+
- Key format in .env: raw string (32 chars), parsed as Hex by CryptoJS
|
|
113
|
+
- IV format in .env: raw string (16 chars), parsed as Hex by CryptoJS
|
|
114
|
+
- Every outgoing request body is encrypted before send
|
|
115
|
+
- Every incoming response body is decrypted before the caller sees it
|
|
116
|
+
- The `token` header (when present) is also AES-encrypted
|
|
117
|
+
|
|
118
|
+
The KEY and IV values written to .env are copied exactly as stored in
|
|
119
|
+
`context.services[linked_service]` — no re-encoding or reformatting.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## API Client Standard (apiClient.js)
|
|
124
|
+
|
|
125
|
+
The Axios instance in `src/api/apiClient.js` is the only file that
|
|
126
|
+
communicates with the backend. It handles all cross-cutting concerns
|
|
127
|
+
so that `apiHandler.js` functions can stay simple.
|
|
128
|
+
|
|
129
|
+
The client has four responsibilities:
|
|
130
|
+
1. Set static headers: `api-key`, `Accept-Language`, `Content-Type: text/plain`
|
|
131
|
+
2. Request interceptor: encrypt the request body before it is sent;
|
|
132
|
+
also attach the session token from localStorage (key: `wa_token`) as
|
|
133
|
+
an encrypted `token` header if present
|
|
134
|
+
3. Response interceptor (success path): decrypt the response body;
|
|
135
|
+
parse the JSON; if response code is -1 trigger a logout redirect;
|
|
136
|
+
if decryption or parsing fails return the raw payload without crashing
|
|
137
|
+
4. Response interceptor (error path): handle ERR_NETWORK and 401 status
|
|
138
|
+
by triggering logout redirect and showing an error message
|
|
139
|
+
|
|
140
|
+
The `baseURL` is read from `process.env.REACT_APP_BASE_URL`.
|
|
141
|
+
The `api-key` header is read from `process.env.REACT_APP_API_KEY`.
|
|
142
|
+
The `key` and `iv` for encryption are parsed from
|
|
143
|
+
`process.env.REACT_APP_KEY` and `process.env.REACT_APP_IV` using
|
|
144
|
+
`CryptoJS.enc.Hex.parse()` — matching the backend's CryptoJS setup.
|
|
145
|
+
|
|
146
|
+
`logOutRedirectCall` and `showErrorMessage` are imported from
|
|
147
|
+
`../pages/common/Utils` — these are placeholder imports that the
|
|
148
|
+
developer implements in their pages layer. The agent generates the
|
|
149
|
+
import lines; the developer fills in the implementations.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## API Handler Standard (apiHandler.js)
|
|
154
|
+
|
|
155
|
+
`src/api/apiHandler.js` exports one async function per API endpoint.
|
|
156
|
+
Each function calls `axiosClient.post(path, payload)` and returns the
|
|
157
|
+
result directly — no try/catch, no decryption, no response shaping here.
|
|
158
|
+
All of that is handled by the interceptors in `apiClient.js`.
|
|
159
|
+
|
|
160
|
+
The handler file is the only place in the frontend codebase where
|
|
161
|
+
API endpoint paths are written. It is the frontend's equivalent of a
|
|
162
|
+
route registry.
|
|
163
|
+
|
|
164
|
+
Functions follow a consistent signature:
|
|
165
|
+
- Simple endpoints: accept a plain `data` parameter passed straight through
|
|
166
|
+
- Auth endpoints: destructure only the fields needed and build the payload
|
|
167
|
+
explicitly (e.g. webLogin destructures `{ email, password }` and constructs
|
|
168
|
+
a full device-info payload before sending)
|
|
169
|
+
|
|
170
|
+
Session saving (e.g. `saveWebSession(res.data)` after login) is called
|
|
171
|
+
in the handler function itself, not in the UI layer.
|
|
172
|
+
|
|
173
|
+
The agent generates handler functions matching the routes registered in
|
|
174
|
+
`context.api_routes` for the linked backend service. For each route, one
|
|
175
|
+
exported function is generated.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Welcome Page Standard
|
|
180
|
+
|
|
181
|
+
The default `pages/Welcome/index.jsx` is a minimal functional React
|
|
182
|
+
component that renders a centered welcome message using the project name
|
|
183
|
+
from `context.current_init.service_name`. It imports `Welcome.module.css`
|
|
184
|
+
for its styles. No external UI library. No data fetching.
|
|
185
|
+
|
|
186
|
+
This page is the first route in `App.jsx` at path `/`.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## App.jsx Standard
|
|
191
|
+
|
|
192
|
+
Uses React Router v6 `BrowserRouter`, `Routes`, and `Route`.
|
|
193
|
+
The initial route `/` renders the Welcome page.
|
|
194
|
+
Additional routes are added via `@create-api` as the project grows.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## .env Contents
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
REACT_APP_BASE_URL=http://localhost:<linked_service_port>/api/v1/
|
|
202
|
+
REACT_APP_API_KEY=<inherited from linked backend service>
|
|
203
|
+
REACT_APP_KEY=<inherited from linked backend service>
|
|
204
|
+
REACT_APP_IV=<inherited from linked backend service>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
All four values are auto-populated from the linked backend service.
|
|
208
|
+
The user does not enter any of these manually.
|
|
209
|
+
|
|
210
|
+
`.env.example` contains the same four keys with empty values.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## .htaccess Standard
|
|
215
|
+
|
|
216
|
+
Two `.htaccess` files are generated — one inside `public/` and one at
|
|
217
|
+
the service root. Both instruct Apache to serve `index.html` for any
|
|
218
|
+
URL that does not match a real file, enabling React Router to handle
|
|
219
|
+
client-side navigation.
|
|
220
|
+
|
|
221
|
+
The rewrite rule pattern: if the requested path is not a real file and
|
|
222
|
+
not a real directory, rewrite to `index.html`.
|
|
223
|
+
|
|
224
|
+
The root-level `.htaccess` sets the document root context.
|
|
225
|
+
The `public/.htaccess` sets the rewrite base for when Apache serves
|
|
226
|
+
directly from the `public/` folder.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## package.json Standard
|
|
231
|
+
|
|
232
|
+
- `name` — from `context.current_init.service_name`
|
|
233
|
+
- `version` — `"1.0.0"`
|
|
234
|
+
- `description` — from `context.current_init.description`
|
|
235
|
+
- Scripts: `start` (react-scripts start), `build` (react-scripts build),
|
|
236
|
+
`test` (react-scripts test)
|
|
237
|
+
- Core dependencies: `react`, `react-dom`, `react-router-dom`,
|
|
238
|
+
`react-scripts`, `axios`, `crypto-js`
|
|
239
|
+
- No TypeScript, no Tailwind, no UI component library by default
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Code Style Standards
|
|
244
|
+
|
|
245
|
+
- Functional components only — no class components
|
|
246
|
+
- JSDoc comment block above every exported function and component
|
|
247
|
+
- No inline styles — all styles go in `.module.css` or `global.css`
|
|
248
|
+
- No direct `console.log` in production components — use the
|
|
249
|
+
`showMessage` / `showErrorMessage` utilities
|
|
250
|
+
- No hardcoded API paths in component files — all API calls go through
|
|
251
|
+
`apiHandler.js`
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Workflow Capabilities
|
|
256
|
+
|
|
257
|
+
- `initialize-project` → scaffold full React app baseline
|
|
258
|
+
- `@create-api` on the linked backend → agent can generate a matching
|
|
259
|
+
handler function in `apiHandler.js` for the new route
|
|
260
|
+
- `@modularize` → scan pages, extract layout components, rewrite pages
|
|
261
|
+
to use them. Read `.codeninja/commands/modularize.workflow.md`.
|
|
262
|
+
- `@validate-page` → add client-side form validation with library of
|
|
263
|
+
user's choice and standard error messages to a specific page.
|
|
264
|
+
Read `.codeninja/commands/validate-page.workflow.md`.
|
|
265
|
+
- `@integrate-api` → wire forms and action buttons to apiHandler functions,
|
|
266
|
+
add loading/error/success states, update apiHandler.js with new functions.
|
|
267
|
+
Read `.codeninja/commands/integrate-api.workflow.md`.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
This command runs when user types /codeninja:api
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
type: workflow
|
|
5
|
+
name: create-api
|
|
6
|
+
description: >
|
|
7
|
+
Add a new API module (route.js + model.js) to an existing NodeJS service.
|
|
8
|
+
Appends to route_manager.js and patches swagger_doc.json surgically —
|
|
9
|
+
never rewrites existing files. Fully context-aware.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Workflow: @create-api
|
|
13
|
+
|
|
14
|
+
## Goal
|
|
15
|
+
Scaffold a complete API module inside an existing NodeJS service.
|
|
16
|
+
Every generated file references actual DB columns from context.
|
|
17
|
+
|
|
18
|
+
## Rules
|
|
19
|
+
- Ask ONE question at a time
|
|
20
|
+
- Never invent table or column names — read from `context.db.schema`
|
|
21
|
+
- Always add the new route to `context.api_routes`
|
|
22
|
+
- Always update `swagger_doc.json` with the new endpoint
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Step-by-Step Execution
|
|
27
|
+
|
|
28
|
+
### Phase 0 — Existing Pattern Review
|
|
29
|
+
Before asking any questions, read the existing modules in
|
|
30
|
+
context.services[<service_name>].modules and scan 1–2 existing
|
|
31
|
+
route.js and _model.js files from the service.
|
|
32
|
+
|
|
33
|
+
Identify:
|
|
34
|
+
- Naming conventions in use (camelCase vs PascalCase for functions)
|
|
35
|
+
- Common validation patterns (which fields always get required rules)
|
|
36
|
+
- Any project-specific response patterns beyond the standard contract
|
|
37
|
+
- Auth pattern used across existing routes (all full? mixed?)
|
|
38
|
+
|
|
39
|
+
Surface a one-line summary: "I've reviewed [n] existing modules.
|
|
40
|
+
I'll follow the same structure." Then proceed to Phase 1.
|
|
41
|
+
|
|
42
|
+
### Phase 1 — Target Service
|
|
43
|
+
1. Run task: `ask-target-service`
|
|
44
|
+
- List available services from `context.services`
|
|
45
|
+
- Stores: `context.current_api.service_name`
|
|
46
|
+
|
|
47
|
+
2. Run task: `ask-api-version`
|
|
48
|
+
- Default: v1
|
|
49
|
+
- Stores: `context.current_api.version`
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### Phase 2 — Module Identity
|
|
54
|
+
3. Run task: `ask-module-name`
|
|
55
|
+
- Example: Products, Orders, Invoice
|
|
56
|
+
- Stores: `context.current_api.module_name`
|
|
57
|
+
|
|
58
|
+
4. Run task: `ask-http-method`
|
|
59
|
+
- Options: GET, POST, PUT, PATCH, DELETE
|
|
60
|
+
- Stores: `context.current_api.method`
|
|
61
|
+
|
|
62
|
+
5. Run task: `ask-route-path`
|
|
63
|
+
- Example: /products, /products/:id
|
|
64
|
+
- Stores: `context.current_api.route_path`
|
|
65
|
+
|
|
66
|
+
6. Run task: `ask-route-description`
|
|
67
|
+
- Stores: `context.current_api.description`
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
### Phase 3 — Database Binding
|
|
72
|
+
7. Run task: `ask-primary-table`
|
|
73
|
+
- Show available tables from `context.db.schema.tables`
|
|
74
|
+
- Stores: `context.current_api.primary_table`
|
|
75
|
+
|
|
76
|
+
8. Run task: `ask-requires-auth`
|
|
77
|
+
- Options: yes / no
|
|
78
|
+
- Stores: `context.current_api.requires_auth`
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### Phase 4 — Generate
|
|
83
|
+
9. Confirm with user: "Generate [METHOD] [path] in [service]/modules/[version]/[Module]? (yes/no)"
|
|
84
|
+
|
|
85
|
+
10. Delegate to `nodejs-agent`:
|
|
86
|
+
- Generate: `route.js` — run task: generate-route
|
|
87
|
+
(new file — always a full write)
|
|
88
|
+
- Generate: `<module>_model.js` — run task: generate-model
|
|
89
|
+
(new file — always a full write)
|
|
90
|
+
- Append to: `modules/<version>/route_manager.js`
|
|
91
|
+
run task: generate-route-manager (Mode 2 — append only)
|
|
92
|
+
NEVER rewrite this file — surgical insert only
|
|
93
|
+
- Patch: `document/<version>/swagger_doc.json`
|
|
94
|
+
run task: generate-swagger (Mode 2 — patch paths object only)
|
|
95
|
+
NEVER rewrite this file — add new path key only
|
|
96
|
+
|
|
97
|
+
> **Claude Code sub-agent:** At Phase 4 generate step: Spawn sub-agent: Task(nodejs-agent)
|
|
98
|
+
> The spawned agent reads `.codeninja/tasks/generate-*.task.md` for generation standards.
|
|
99
|
+
|
|
100
|
+
11. Run task: `write-context`
|
|
101
|
+
- Append to `context.api_routes`
|
|
102
|
+
- Update `context.services[<service>].modules`
|
|
103
|
+
|
|
104
|
+
12. Run task: `show-final-summary`
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
This command runs when user types /codeninja:audit
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
type: workflow
|
|
5
|
+
name: audit
|
|
6
|
+
description: >
|
|
7
|
+
Review an existing service for code quality, security issues, naming
|
|
8
|
+
consistency, missing middleware, and context alignment.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Workflow: @audit
|
|
12
|
+
|
|
13
|
+
## Goal
|
|
14
|
+
Produce a structured audit report for a service. Identify issues by severity.
|
|
15
|
+
Optionally auto-fix low-risk issues.
|
|
16
|
+
|
|
17
|
+
## When to use @audit vs @sync drift detection
|
|
18
|
+
|
|
19
|
+
`@sync` drift detection: runs automatically with every @sync. Checks
|
|
20
|
+
structural markers only — middleware order, library consistency,
|
|
21
|
+
export patterns. Fast, read-only, always safe.
|
|
22
|
+
|
|
23
|
+
`@audit`: run manually when you want deep code quality analysis —
|
|
24
|
+
security checks, SQL injection patterns, response format consistency,
|
|
25
|
+
context alignment. Slower, comprehensive, covers logic not just structure.
|
|
26
|
+
|
|
27
|
+
Run @sync regularly. Run @audit before releasing a service or after
|
|
28
|
+
a major refactor.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Step-by-Step Execution
|
|
33
|
+
|
|
34
|
+
1. Run task: `ask-target-service`
|
|
35
|
+
|
|
36
|
+
2. Delegate to relevant agent(s) based on service type.
|
|
37
|
+
|
|
38
|
+
> **Claude Code sub-agent:** At step 2: Spawn appropriate sub-agent: Task(nodejs-agent) for NodeJS services, Task(database-agent) for DB-only
|
|
39
|
+
> The spawned agent reads `.codeninja/tasks/generate-*.task.md` for generation standards.
|
|
40
|
+
|
|
41
|
+
3. Agent checks:
|
|
42
|
+
|
|
43
|
+
### Security Checks
|
|
44
|
+
- [ ] API key validation middleware applied to all routes?
|
|
45
|
+
- [ ] Input validation on all POST/PUT/PATCH routes?
|
|
46
|
+
- [ ] SQL injection prevention (parameterized queries)?
|
|
47
|
+
- [ ] Sensitive values only from env vars (no hardcoded keys/passwords)?
|
|
48
|
+
- [ ] `.env` in `.gitignore`?
|
|
49
|
+
- [ ] Encryption using real AES-256-CBC (not base64)?
|
|
50
|
+
- [ ] utilities/encryption.js is the only file importing crypto-js or cryptlib?
|
|
51
|
+
- [ ] res.json() is never called directly in route.js or model files?
|
|
52
|
+
- [ ] Validator package never imported directly in route files?
|
|
53
|
+
- [ ] SMTP credentials only in .env — never hardcoded in
|
|
54
|
+
notification.js or template.js?
|
|
55
|
+
- [ ] Firebase service account file in pem/ and in .gitignore?
|
|
56
|
+
- [ ] GLOBALS object is frozen using Object.freeze?
|
|
57
|
+
|
|
58
|
+
### Code Quality Checks
|
|
59
|
+
- [ ] Controllers only call services (no DB queries in controllers)?
|
|
60
|
+
- [ ] Services contain business logic (no Express req/res objects)?
|
|
61
|
+
- [ ] Models contain only DB queries?
|
|
62
|
+
- [ ] Global error handler present and used?
|
|
63
|
+
- [ ] All routes call checkValidationRules from utilities/validator.js
|
|
64
|
+
before calling model functions?
|
|
65
|
+
- [ ] No separate _validator.js files exist per module?
|
|
66
|
+
- [ ] rateLimiter is the first middleware in route_manager.js?
|
|
67
|
+
- [ ] extractLanguage runs before validateApiKey in route_manager.js?
|
|
68
|
+
- [ ] decryptRequest is the last middleware in the chain?
|
|
69
|
+
- [ ] No route handlers defined directly in route_manager.js?
|
|
70
|
+
- [ ] asyncHandler wraps every middleware in route_manager.js?
|
|
71
|
+
- [ ] All model functions return exactly { responsecode, responsemsg,
|
|
72
|
+
responsedata } — no extra keys, no throws?
|
|
73
|
+
- [ ] No req/res objects in any model file?
|
|
74
|
+
- [ ] Passwords HASHED (not encrypted) using `utilities/hashing.js` before storage?
|
|
75
|
+
Correct: `await hashPassword(plainText)` — one-way bcrypt/argon2 hash
|
|
76
|
+
Wrong: `encrypt(password)` from encryption.js — reversible AES, not safe for passwords
|
|
77
|
+
- [ ] No direct bcrypt/argon2 imports in route.js or model files? All hashing routed through utilities/hashing.js?
|
|
78
|
+
- [ ] Session tokens generated only via common.generateSessionCode?
|
|
79
|
+
- [ ] No crypto-js or cryptlib imported directly in model files?
|
|
80
|
+
- [ ] No direct res.json() calls in route.js files?
|
|
81
|
+
|
|
82
|
+
### Consistency Checks
|
|
83
|
+
- [ ] All routes documented in `swagger_doc.json`?
|
|
84
|
+
- [ ] Response format consistent (success, message, data, timestamp)?
|
|
85
|
+
- [ ] Naming follows snake_case for DB, camelCase for JS?
|
|
86
|
+
- [ ] Port matches `context.services[<name>].port`?
|
|
87
|
+
- [ ] DB config matches `context.db`?
|
|
88
|
+
- [ ] All message keywords used in sendResponse calls exist in
|
|
89
|
+
languages/en.js?
|
|
90
|
+
- [ ] All language files contain the same set of keys as en.js?
|
|
91
|
+
- [ ] No two services share the same port in context.services?
|
|
92
|
+
- [ ] All encryption keys in context.services are exactly 32 characters?
|
|
93
|
+
- [ ] All encryption IVs in context.services are exactly 16 characters?
|
|
94
|
+
- [ ] No service name in context.services conflicts with a folder name
|
|
95
|
+
that already exists on disk for a different service?
|
|
96
|
+
|
|
97
|
+
### Context Alignment
|
|
98
|
+
- [ ] All routes present in `context.api_routes`?
|
|
99
|
+
- [ ] All DB tables referenced match `context.db.schema`?
|
|
100
|
+
- [ ] All router.use() lines in route_manager.js have a corresponding
|
|
101
|
+
entry in context.services[<name>].modules?
|
|
102
|
+
- [ ] All context.services[<name>].modules entries have a corresponding
|
|
103
|
+
router.use() line in route_manager.js?
|
|
104
|
+
- [ ] All paths in swagger_doc.json have a corresponding entry in
|
|
105
|
+
context.api_routes?
|
|
106
|
+
|
|
107
|
+
4. Present audit report:
|
|
108
|
+
```
|
|
109
|
+
AUDIT REPORT — <service_name>
|
|
110
|
+
══════════════════════════════════════
|
|
111
|
+
🔴 CRITICAL (must fix)
|
|
112
|
+
🟡 WARNING (should fix)
|
|
113
|
+
🟢 INFO (nice to have)
|
|
114
|
+
══════════════════════════════════════
|
|
115
|
+
[list findings with file + line context]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
5. Ask: "Auto-fix critical issues? (yes/no)"
|
|
119
|
+
6. If yes → delegate to relevant agent for fixes → run task: `write-context`
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
This command runs when user types /codeninja:db-create
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
type: workflow
|
|
5
|
+
name: db-create-table
|
|
6
|
+
command: "@db:create-table"
|
|
7
|
+
description: >
|
|
8
|
+
Design and generate a new database table following all project conventions.
|
|
9
|
+
Collects table purpose, name, columns one at a time, then generates the
|
|
10
|
+
numbered SQL file, updates create-schema.sql, and records in context.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Workflow: @db:create-table
|
|
14
|
+
|
|
15
|
+
## Goal
|
|
16
|
+
Generate a complete, convention-compliant SQL table file. Every generated
|
|
17
|
+
file must pass ALL rules defined in database-agent.md.
|
|
18
|
+
|
|
19
|
+
## Rules
|
|
20
|
+
- Ask ONE question at a time — never bundle column definitions
|
|
21
|
+
- Always enforce tbl_ prefix and snake_case naming
|
|
22
|
+
- Never create a table file without updating create-schema.sql
|
|
23
|
+
- Always record in context.db.schema after generation
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Step-by-Step Execution
|
|
28
|
+
|
|
29
|
+
### Phase 1 — Table Identity
|
|
30
|
+
1. Run task: `ask-table-purpose`
|
|
31
|
+
- Stores: `context.current_db.table_purpose`
|
|
32
|
+
- Used by agent to suggest column names and structure
|
|
33
|
+
|
|
34
|
+
2. Run task: `ask-table-name`
|
|
35
|
+
- Enforce: lowercase, snake_case, must start with `tbl_`
|
|
36
|
+
- Stores: `context.current_db.table_name`
|
|
37
|
+
|
|
38
|
+
3. Run task: `ask-table-file-number`
|
|
39
|
+
- Agent reads existing files in `database/<db_type>/migrations/`
|
|
40
|
+
- Suggests next available number
|
|
41
|
+
- Stores: `context.current_db.file_number`
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### Phase 2 — Standard Columns Decision
|
|
46
|
+
4. Run task: `ask-table-needs-status`
|
|
47
|
+
- Ask: "Does this table need status and is_deleted columns?"
|
|
48
|
+
- Agent guidance: suggest YES for user/entity tables, NO for event/log tables
|
|
49
|
+
- Stores: `context.current_db.needs_status`
|
|
50
|
+
|
|
51
|
+
5. Run task: `ask-table-needs-soft-delete`
|
|
52
|
+
- Ask: "Does this table support soft delete (is_deleted)?"
|
|
53
|
+
- Auto-suggest: YES if needs_status is YES
|
|
54
|
+
- Stores: `context.current_db.needs_soft_delete`
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
### Phase 3 — Column Collection (repeat until done)
|
|
59
|
+
6. Run task: `ask-column-name`
|
|
60
|
+
- Show columns collected so far
|
|
61
|
+
- Ask: "Enter the next column name (or type 'done' to finish)"
|
|
62
|
+
- Enforce: snake_case, lowercase
|
|
63
|
+
- Stores: appends to `context.current_db.columns[]`
|
|
64
|
+
|
|
65
|
+
7. Run task: `ask-column-type`
|
|
66
|
+
- Show suggested type based on column name pattern:
|
|
67
|
+
- `*_id` → BIGINT NOT NULL DEFAULT 0
|
|
68
|
+
- When a column name ends in `_id`:
|
|
69
|
+
- Cross-reference context.db.schema.tables for a table whose name
|
|
70
|
+
matches the prefix (e.g. user_id → tbl_users)
|
|
71
|
+
- If found → suggest: "This looks like a foreign key to tbl_users.
|
|
72
|
+
Add FK constraint? (yes/no)"
|
|
73
|
+
- If yes → add REFERENCES clause to the column definition
|
|
74
|
+
- `is_*` → BOOLEAN NOT NULL DEFAULT FALSE
|
|
75
|
+
- `*_at` → TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
76
|
+
- `status` → INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0,1))
|
|
77
|
+
- `*_count` → BIGINT NOT NULL DEFAULT 0
|
|
78
|
+
- `*_price`, `*_amount` → NUMERIC(18,8) NOT NULL DEFAULT 0.00000000
|
|
79
|
+
- `email` → VARCHAR(132) NOT NULL DEFAULT ''
|
|
80
|
+
- `phone` → VARCHAR(16) NOT NULL DEFAULT ''
|
|
81
|
+
- `password` → TEXT NOT NULL DEFAULT ''
|
|
82
|
+
- `*_image`, `*_url` → VARCHAR(255) NOT NULL DEFAULT ''
|
|
83
|
+
- `payload`, `metadata`, `*_result` → JSON NOT NULL DEFAULT '{}'
|
|
84
|
+
- default → VARCHAR(255) NOT NULL DEFAULT ''
|
|
85
|
+
- Stores: in current column entry
|
|
86
|
+
|
|
87
|
+
8. Run task: `ask-column-is-enum`
|
|
88
|
+
- Ask: "Does this column have a fixed set of allowed values? (enum-like)"
|
|
89
|
+
- If yes → run task: `ask-column-enum-values`
|
|
90
|
+
- Stores: check constraint and comment text
|
|
91
|
+
|
|
92
|
+
9. Return to step 6 until user types 'done'
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### Phase 4 — Index Decision
|
|
97
|
+
10. Run task: `ask-table-indexes`
|
|
98
|
+
- Agent auto-suggests indexes based on collected columns:
|
|
99
|
+
- Every `*_id` (foreign key) column → suggest index
|
|
100
|
+
- `status + is_deleted` compound → suggest if both exist
|
|
101
|
+
- `created_at DESC` → suggest for event/log tables
|
|
102
|
+
- Ask user to confirm suggested indexes or add custom ones
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### Phase 5 — Seed Data
|
|
107
|
+
11. Run task: `ask-table-seed-data`
|
|
108
|
+
- Ask: "Does this table need seed/initial data?"
|
|
109
|
+
- Guidance: suggest YES only for reference/master data tables
|
|
110
|
+
- If yes → run task: `collect-seed-data`
|
|
111
|
+
- Stores: `context.current_db.seed_rows[]`
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### Phase 6 — Summary and Generate
|
|
116
|
+
12. Run task: `show-db-table-summary`
|
|
117
|
+
- Display complete table definition as it will be generated
|
|
118
|
+
- Show: table name, file number, all columns with types, indexes, seed data
|
|
119
|
+
- Ask: "Generate this table? (yes / no / change a value)"
|
|
120
|
+
- If change → re-run specific task → return to this step
|
|
121
|
+
- If no → abort, nothing created
|
|
122
|
+
- If yes → proceed
|
|
123
|
+
|
|
124
|
+
13. Delegate to `database-agent`:
|
|
125
|
+
|
|
126
|
+
> **Claude Code sub-agent:** Spawn sub-agent: Task(database-agent) for SQL generation.
|
|
127
|
+
> The spawned agent reads `.codeninja/tasks/generate-*.task.md` for generation standards.
|
|
128
|
+
|
|
129
|
+
- Generate: `<repo_root>/database/<db_type>/migrations/<number>-setup-tbl-<name>.sql`
|
|
130
|
+
- Update: `<repo_root>/database/<db_type>/create-schema.sql`
|
|
131
|
+
- If any indexes belong in shared file → update: `111-setup-database-indexes.sql`
|
|
132
|
+
|
|
133
|
+
14. Run task: `write-context`
|
|
134
|
+
- Append table to `context.db.schema.tables`
|
|
135
|
+
- Append to `context.db.schema.change_log`
|
|
136
|
+
- Clear `context.current_db`
|
|
137
|
+
|
|
138
|
+
15. Run task: `show-final-summary`
|