codeninja 3.1.0 → 3.2.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.
- package/ide/antigravity/.agents/personas/global-orchestrator.md +103 -84
- package/ide/antigravity/.agents/workflows/codeninja-api.md +98 -15
- package/ide/antigravity/.agents/workflows/codeninja-audit.md +69 -11
- package/ide/antigravity/.agents/workflows/codeninja-db-create.md +118 -5
- package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +81 -5
- package/ide/antigravity/.agents/workflows/codeninja-db-index.md +64 -5
- package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +100 -5
- package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +70 -4
- package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +64 -6
- package/ide/antigravity/.agents/workflows/codeninja-debug.md +76 -6
- package/ide/antigravity/.agents/workflows/codeninja-design.md +45 -12
- package/ide/antigravity/.agents/workflows/codeninja-explain.md +35 -6
- package/ide/antigravity/.agents/workflows/codeninja-init.md +329 -22
- package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +334 -9
- package/ide/antigravity/.agents/workflows/codeninja-modularize.md +214 -9
- package/ide/antigravity/.agents/workflows/codeninja-optimize.md +78 -7
- package/ide/antigravity/.agents/workflows/codeninja-refactor.md +58 -13
- package/ide/antigravity/.agents/workflows/codeninja-review.md +64 -6
- package/ide/antigravity/.agents/workflows/codeninja-sync.md +172 -12
- package/ide/antigravity/.agents/workflows/codeninja-test.md +51 -9
- package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +248 -9
- package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +35 -32
- package/ide/cursor/.cursor/rules/03-api-builder.mdc +100 -50
- package/ide/cursor/.cursor/rules/04-database.mdc +73 -70
- package/ide/cursor/.cursor/rules/05-reactjs.mdc +133 -69
- package/ide/vscode/.github/copilot-instructions.md +304 -190
- package/package.json +1 -1
|
@@ -1,11 +1,250 @@
|
|
|
1
1
|
---
|
|
2
|
-
slash_command:
|
|
2
|
+
slash_command: /codeninja:validate-page
|
|
3
3
|
personas: [global-orchestrator, reactjs-frontend]
|
|
4
|
-
skills: [mcp-and-context, reactjs]
|
|
5
|
-
description:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
skills: [mcp-and-context, reactjs, code-intelligence]
|
|
5
|
+
description: >
|
|
6
|
+
Add complete client-side form validation to a ReactJS page.
|
|
7
|
+
Scans all inputs, assigns name/id attributes where missing, installs
|
|
8
|
+
the chosen validation library if needed, and wires error messages.
|
|
9
|
+
Never touches API calls or business logic.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# /codeninja:validate-page
|
|
13
|
+
|
|
14
|
+
## Before Running
|
|
15
|
+
1. Call `context_check_stale`
|
|
16
|
+
2. Call `context_read` — load `context.services`
|
|
17
|
+
3. Call `service_scan` — verify service on disk
|
|
18
|
+
|
|
19
|
+
## Rules
|
|
20
|
+
- Target ONE specific page per run — never multiple pages at once
|
|
21
|
+
- NEVER modify API call logic, submit handlers (beyond adding a validation gate), or non-form code
|
|
22
|
+
- NEVER overwrite existing validation if the field already has it — only fill gaps
|
|
23
|
+
- Assign `name` and `id` to every input/select/textarea that is missing them
|
|
24
|
+
- ONE confirmation before any file is written
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Execution — Full Step-by-Step
|
|
29
|
+
|
|
30
|
+
### Phase 1 — Target Selection
|
|
31
|
+
|
|
32
|
+
**Step 1.** Ask: "Which ReactJS service?" (list ReactJS services from `context.services`)
|
|
33
|
+
- Store: `context.current_action.service_name`
|
|
34
|
+
|
|
35
|
+
**Step 2.** Ask: "Which page path?" (e.g. `src/pages/Login/index.jsx`)
|
|
36
|
+
- Store: `context.current_action.page_path`, `context.current_action.page_name`
|
|
37
|
+
|
|
38
|
+
**Step 3.** Ask: "Which validation library?"
|
|
39
|
+
1. Yup — schema-based async validation
|
|
40
|
+
2. React Hook Form — controlled forms with built-in validation
|
|
41
|
+
3. Parsley — jQuery-based HTML5 validation (CDN, no npm)
|
|
42
|
+
4. Validator.js — utility functions (validator npm package)
|
|
43
|
+
5. Custom — plain JavaScript, no library
|
|
44
|
+
- Store: `context.current_action.validation_library`
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### Phase 2 — Scan the Page
|
|
49
|
+
|
|
50
|
+
Read the full file at `context.current_action.page_path`.
|
|
51
|
+
|
|
52
|
+
#### 2a — Find All Form Elements
|
|
53
|
+
Scan JSX for every `<form>`, `<input>`, `<select>`, `<textarea>`, `<button type="submit">`.
|
|
54
|
+
|
|
55
|
+
For each `<input>` record:
|
|
56
|
+
- `type`, `name`, `id`, `value`/`defaultValue`, `onChange`, `required`, `placeholder`
|
|
57
|
+
- Any existing validation attributes (minLength, maxLength, pattern, min, max)
|
|
58
|
+
- Adjacent label text (`<label htmlFor="...">` or sibling `<label>`)
|
|
59
|
+
- Any existing error display nearby (`<span className="error">`, `{errors.<n>}`, etc.)
|
|
60
|
+
|
|
61
|
+
For each `<select>` record: `name`, `id`, available `<option>` values, default empty option.
|
|
62
|
+
For each `<textarea>` record: `name`, `id`, `rows`, `cols`, character limit hints.
|
|
63
|
+
|
|
64
|
+
#### 2b — Group Fields Into Forms
|
|
65
|
+
If multiple `<form>` elements → group by parent form (each gets its own validation schema).
|
|
66
|
+
If no `<form>` but inputs present → treat all as one implicit form.
|
|
67
|
+
|
|
68
|
+
#### 2c — Detect Existing Validation
|
|
69
|
+
Check for any existing patterns:
|
|
70
|
+
- `yup.object()` / `yup.string()` imports → Yup schema exists
|
|
71
|
+
- `useForm()` from react-hook-form → RHF wired
|
|
72
|
+
- `.parsley()` calls → Parsley initialized
|
|
73
|
+
- Manual `if (!value)` checks in submit handler
|
|
74
|
+
- `errors` state object
|
|
75
|
+
|
|
76
|
+
Mark fields with existing validation as "already validated" — skip them.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### Phase 3 — Infer Field Semantics and Error Messages
|
|
81
|
+
|
|
82
|
+
For each field, detect semantic type using label text → name attribute → placeholder → input type:
|
|
83
|
+
|
|
84
|
+
| Signal | Semantic | Required error | Format error |
|
|
85
|
+
|---|---|---|---|
|
|
86
|
+
| "first name" | first_name | "Please enter your first name." | "First name must be at least 2 characters." |
|
|
87
|
+
| "last name" | last_name | "Please enter your last name." | "Last name must be at least 2 characters." |
|
|
88
|
+
| "full name" / "name" | full_name | "Please enter your full name." | "Full name must be at least 3 characters." |
|
|
89
|
+
| "email" | email | "Please enter your email address." | "Please enter a valid email address." |
|
|
90
|
+
| "phone" / "mobile" | phone | "Please enter your phone number." | "Please enter a valid phone number." |
|
|
91
|
+
| "password" (no "confirm") | password | "Please enter your password." | "Password must be at least 8 characters." |
|
|
92
|
+
| "confirm" + "password" | confirm_password | "Please confirm your password." | "Password and confirm password do not match." |
|
|
93
|
+
| "username" | username | "Please enter a username." | "Username must be 3–20 characters, letters and numbers only." |
|
|
94
|
+
| "address" | address | "Please enter your address." | — |
|
|
95
|
+
| "city" | city | "Please enter your city." | — |
|
|
96
|
+
| "zip" / "postal" | zip_code | "Please enter your zip/postal code." | "Please enter a valid zip/postal code." |
|
|
97
|
+
| "country" | country | "Please select your country." | — |
|
|
98
|
+
| "state" / "province" | state | "Please select your state/province." | — |
|
|
99
|
+
| "date" / "dob" / "birth" | date | "Please select a date." | "Please enter a valid date." |
|
|
100
|
+
| "amount" / "price" | amount | "Please enter an amount." | "Please enter a valid amount greater than 0." |
|
|
101
|
+
| "description" / "message" | description | "Please enter a description." | — |
|
|
102
|
+
| "otp" / "code" / "pin" | otp | "Please enter the OTP." | "OTP must be [n] digits." |
|
|
103
|
+
| type="file" | file_upload | "Please select a file." | "File size must not exceed [n]MB." |
|
|
104
|
+
| "agree" / "terms" (checkbox) | terms | "Please accept the terms and conditions." | — |
|
|
105
|
+
| select (no clear label) | dropdown | "Please make a selection." | — |
|
|
106
|
+
| anything else | generic | "This field is required." | — |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### Phase 4 — Assign Missing name and id Attributes
|
|
111
|
+
|
|
112
|
+
For each field missing `name` or `id`:
|
|
113
|
+
1. Derive from label text or placeholder: strip non-alphanumeric, convert to camelCase
|
|
114
|
+
e.g. "First Name" → `firstName`, "Email Address" → `emailAddress`
|
|
115
|
+
2. If no label/placeholder → use semantic type: `email`, `password`, `phone`, etc.
|
|
116
|
+
3. If would duplicate → append number: `phone2`, `address2`
|
|
117
|
+
4. Set both `name` and `id` to the same derived value.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
### Phase 5 — Show Validation Plan
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
┌──────────────────────────────────────────────────────┐
|
|
125
|
+
│ VALIDATION PLAN │
|
|
126
|
+
├──────────────────────────────────────────────────────┤
|
|
127
|
+
│ Page : [page_name] │
|
|
128
|
+
│ Library : [validation_library] │
|
|
129
|
+
│ Install pkg : [package_name] (if needed) │
|
|
130
|
+
├──────────────────────────────────────────────────────┤
|
|
131
|
+
│ FIELDS TO VALIDATE │
|
|
132
|
+
│ ✓ firstName (text) — "Please enter your first name." │
|
|
133
|
+
│ ✓ email (email) — "Please enter a valid email." │
|
|
134
|
+
│ ✓ password (password)— "Please enter your password." │
|
|
135
|
+
│ ✓ confirmPw (password)— "Passwords do not match." │
|
|
136
|
+
│ │
|
|
137
|
+
│ FIELDS SKIPPED (already validated) │
|
|
138
|
+
│ — phone (has existing required check) │
|
|
139
|
+
├──────────────────────────────────────────────────────┤
|
|
140
|
+
│ ATTRIBUTES TO ASSIGN │
|
|
141
|
+
│ confirmPassword → add name="confirmPassword", id="confirmPassword" │
|
|
142
|
+
├──────────────────────────────────────────────────────┤
|
|
143
|
+
│ FILES TO MODIFY │
|
|
144
|
+
│ → src/pages/[PageName]/index.jsx │
|
|
145
|
+
│ → package.json (add: [library_package]) │
|
|
146
|
+
└──────────────────────────────────────────────────────┘
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Ask: "Apply this validation plan? (yes / no / adjust)"
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### Phase 6 — Apply Validation by Library
|
|
154
|
+
|
|
155
|
+
Read current page file. Apply ALL edits surgically — never rewrite the whole file.
|
|
156
|
+
|
|
157
|
+
#### If library == "yup"
|
|
158
|
+
- Add import: `import * as Yup from 'yup';`
|
|
159
|
+
- Create `validationSchema` above component:
|
|
160
|
+
```jsx
|
|
161
|
+
const validationSchema = Yup.object({
|
|
162
|
+
firstName: Yup.string().required('Please enter your first name.').min(2, '...'),
|
|
163
|
+
email: Yup.string().required('...').email('Please enter a valid email address.'),
|
|
164
|
+
password: Yup.string().required('...').min(8, '...'),
|
|
165
|
+
confirmPassword: Yup.string().required('...').oneOf([Yup.ref('password')], '...'),
|
|
166
|
+
// one entry per field
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
- Add state: `const [errors, setErrors] = React.useState({});`
|
|
170
|
+
- Add `validateForm` async function inside component
|
|
171
|
+
- Add validation gate at top of submit handler: `const isValid = await validateForm({...}); if (!isValid) return;`
|
|
172
|
+
- Add `{errors.<field> && <span className={styles.errorMsg}>{errors.<field>}</span>}` after each input
|
|
173
|
+
- Add `.errorMsg` CSS class to page's `.module.css`
|
|
174
|
+
|
|
175
|
+
#### If library == "react-hook-form"
|
|
176
|
+
- Add import: `import { useForm } from 'react-hook-form';`
|
|
177
|
+
- Add hook: `const { register, handleSubmit, watch, formState: { errors } } = useForm();`
|
|
178
|
+
- Wrap form: `<form onSubmit={handleSubmit(onSubmit)}>`
|
|
179
|
+
- Add `{...register('fieldName', { required: '...', pattern/min/validate rules })}` to each input
|
|
180
|
+
- For confirmPassword: `validate: (val) => val === watch('password') || '...'`
|
|
181
|
+
- Add error display after each input
|
|
182
|
+
- Remove redundant `value`/`onChange` props only if purely for controlled form state
|
|
183
|
+
|
|
184
|
+
#### If library == "parsley"
|
|
185
|
+
- Add to `public/index.html` before `</body>`: jQuery CDN + Parsley CDN + Parsley CSS link
|
|
186
|
+
- Add `data-parsley-required`, `data-parsley-required-message`, `data-parsley-type`, etc. to each input
|
|
187
|
+
- Add `id` to `<form>` element (derive: `[pageName]Form`)
|
|
188
|
+
- Initialize via `useEffect`: `window.$('#loginForm').parsley()`
|
|
189
|
+
- Gate in submit handler: `if (!window.$('#loginForm').parsley().validate()) return;`
|
|
190
|
+
|
|
191
|
+
#### If library == "validatorjs"
|
|
192
|
+
- Add import: `import validator from 'validator';`
|
|
193
|
+
- Add state: `const [errors, setErrors] = React.useState({});`
|
|
194
|
+
- Add `validateForm` function with per-field checks using `validator.isEmail()`, `validator.isEmpty()`, etc.
|
|
195
|
+
- Add gate: `if (!validateForm()) return;`
|
|
196
|
+
- Add error display + `.errorMsg` CSS
|
|
197
|
+
|
|
198
|
+
#### If library == "custom"
|
|
199
|
+
- No imports needed — plain JavaScript only
|
|
200
|
+
- Same `validateForm` pattern as validatorjs but using native JS:
|
|
201
|
+
- `value.trim().length > 0` for required
|
|
202
|
+
- `/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)` for email
|
|
203
|
+
- `value.length >= 8` for min length
|
|
204
|
+
- `value === otherValue` for match
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### Phase 7 — Install Package (if needed)
|
|
209
|
+
|
|
210
|
+
If library is yup/react-hook-form/validatorjs AND not in `package.json`:
|
|
211
|
+
- Read current `package.json`
|
|
212
|
+
- Add to dependencies:
|
|
213
|
+
- yup → `"yup": "^1.3.3"`
|
|
214
|
+
- react-hook-form → `"react-hook-form": "^7.51.0"`
|
|
215
|
+
- validatorjs → `"validator": "^13.12.0"`
|
|
216
|
+
- Update `package.json` on disk
|
|
217
|
+
- Display: "📦 Package added to package.json. Run `npm install` in [service_name]/ before testing."
|
|
218
|
+
|
|
219
|
+
For parsley → CDN only, no npm needed.
|
|
220
|
+
For custom → no package.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
### Phase 8 — Finalize
|
|
225
|
+
|
|
226
|
+
**Step 1.** Call `context_write`:
|
|
227
|
+
- Append to `context.services[<service_name>].validated_pages`:
|
|
228
|
+
`{ page, library, fields_validated: [...], timestamp: ISO now }`
|
|
229
|
+
- Set `last_command` = "validate-page"
|
|
230
|
+
- Append to `change_log`
|
|
231
|
+
|
|
232
|
+
**Step 2.** Call `context_clear_scratchpad` with keys: ["current_action"]
|
|
233
|
+
|
|
234
|
+
**Step 3.** Show completion report:
|
|
235
|
+
```
|
|
236
|
+
/codeninja:validate-page Complete
|
|
237
|
+
─────────────────────────────────────────
|
|
238
|
+
Page : [page_name]
|
|
239
|
+
Library : [library]
|
|
240
|
+
─────────────────────────────────────────
|
|
241
|
+
Fields validated : [n]
|
|
242
|
+
Fields skipped : [n] (already had validation)
|
|
243
|
+
Attributes added : [n] (name/id assigned)
|
|
244
|
+
─────────────────────────────────────────
|
|
245
|
+
✓ src/pages/[PageName]/index.jsx — updated
|
|
246
|
+
✓ src/pages/[PageName]/[PageName].module.css — .errorMsg class added
|
|
247
|
+
[✓ package.json — [package] added (run npm install)]
|
|
248
|
+
─────────────────────────────────────────
|
|
249
|
+
Next: /codeninja:integrate-api to wire forms to the backend
|
|
250
|
+
```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: codeninja global orchestrator — routing, context,
|
|
2
|
+
description: codeninja global orchestrator — routing, context, and command execution. Always applied.
|
|
3
3
|
globs: ["**/*"]
|
|
4
4
|
alwaysApply: true
|
|
5
5
|
---
|
|
@@ -10,51 +10,54 @@ You are a Senior Software Architect managing this project via the codeninja agen
|
|
|
10
10
|
|
|
11
11
|
## Activation Sequence (every session)
|
|
12
12
|
1. Call `context_check_stale` — resolve stale operations first
|
|
13
|
-
2. Call `context_read` — load full context
|
|
13
|
+
2. Call `context_read` — load full project context
|
|
14
14
|
3. Call `service_scan` — compare with `context.services`; if drift detected, suggest `/codeninja:sync`
|
|
15
|
-
4. Load `context.project_info` for all suggestions
|
|
16
|
-
|
|
17
|
-
## Routing
|
|
18
|
-
| Keyword | Specialist |
|
|
19
|
-
|---------|-----------|
|
|
20
|
-
| express, node, api, service, encryption | nodejs-backend rules |
|
|
21
|
-
| react, frontend, ui, component | reactjs-frontend rules |
|
|
22
|
-
| postgres, mysql, db, schema, migration, table | database-architect rules |
|
|
23
|
-
| /codeninja:db:* | always database-architect |
|
|
15
|
+
4. Load `context.project_info` — use for all suggestions throughout session
|
|
24
16
|
|
|
25
17
|
## Context Rules
|
|
26
18
|
- NEVER read/write context.json directly — always use `context_read` / `context_write`
|
|
27
19
|
- `context_write` deep-merges — never overwrites
|
|
28
|
-
- `change_log` append-only
|
|
20
|
+
- `change_log` is append-only — never delete entries
|
|
21
|
+
- After every completed workflow → call `context_clear_scratchpad` for the relevant `current_*` key
|
|
22
|
+
|
|
23
|
+
## Keyword Routing
|
|
24
|
+
| Trigger | Specialist Domain |
|
|
25
|
+
|---|---|
|
|
26
|
+
| express, node, api, service, encryption | NodeJS / API Builder rules |
|
|
27
|
+
| react, frontend, ui, component, page | ReactJS rules |
|
|
28
|
+
| postgres, mysql, db, schema, migration, table | Database rules |
|
|
29
|
+
| `/codeninja:db:*` | always Database rules |
|
|
29
30
|
|
|
30
31
|
## Batch Generation Rule
|
|
31
|
-
ONE confirmation per operation.
|
|
32
|
+
ONE confirmation per operation.
|
|
33
|
+
After user confirms → generate ALL files silently — no per-file prompts.
|
|
32
34
|
|
|
33
35
|
## Response Style
|
|
34
36
|
- One question at a time
|
|
35
37
|
- Confirm before creating or modifying files
|
|
36
|
-
- `database/` folder ALWAYS at repository root — never inside a service
|
|
38
|
+
- `database/` folder ALWAYS at repository root — never inside a service folder
|
|
39
|
+
- After every scaffolding operation → show final summary
|
|
37
40
|
|
|
38
|
-
##
|
|
39
|
-
| Command |
|
|
40
|
-
|
|
41
|
+
## All Available Commands
|
|
42
|
+
| Command | Action |
|
|
43
|
+
|---|---|
|
|
41
44
|
| `/codeninja:init` | Bootstrap NodeJS service, ReactJS app, or database |
|
|
42
|
-
| `/codeninja:api` | Add API endpoint (
|
|
45
|
+
| `/codeninja:api` | Add new API endpoint (route.js + model.js) |
|
|
43
46
|
| `/codeninja:design` | Plan feature before coding |
|
|
44
47
|
| `/codeninja:audit` | Security and quality review |
|
|
45
|
-
| `/codeninja:test` | Generate Jest tests |
|
|
46
|
-
| `/codeninja:refactor` | Rename with context tracking |
|
|
47
|
-
| `/codeninja:sync` | Rebuild context from repo |
|
|
48
|
-
| `/codeninja:explain` | Explain any file or
|
|
49
|
-
| `/codeninja:review` | Code review with findings |
|
|
50
|
-
| `/codeninja:debug` |
|
|
51
|
-
| `/codeninja:optimize` | Performance
|
|
52
|
-
| `/codeninja:db:create` | New table
|
|
53
|
-
| `/codeninja:db:modify` | Alter
|
|
48
|
+
| `/codeninja:test` | Generate Jest + Supertest tests |
|
|
49
|
+
| `/codeninja:refactor` | Rename/restructure with context tracking |
|
|
50
|
+
| `/codeninja:sync` | Rebuild context.json from entire repo |
|
|
51
|
+
| `/codeninja:explain` | Explain any file, function, or concept |
|
|
52
|
+
| `/codeninja:review` | Code review with severity-ranked findings |
|
|
53
|
+
| `/codeninja:debug` | Diagnose and fix bugs |
|
|
54
|
+
| `/codeninja:optimize` | Performance analysis |
|
|
55
|
+
| `/codeninja:db:create` | New table with migration file |
|
|
56
|
+
| `/codeninja:db:modify` | Alter table via migration |
|
|
54
57
|
| `/codeninja:db:index` | Add index |
|
|
55
|
-
| `/codeninja:db:drop` | Drop table |
|
|
58
|
+
| `/codeninja:db:drop` | Drop table (safety-checked) |
|
|
56
59
|
| `/codeninja:db:seed` | Add seed data |
|
|
57
|
-
| `/codeninja:db:sync` | Rebuild DB schema |
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
|
60
|
+
| `/codeninja:db:sync` | Rebuild DB schema from migration files |
|
|
61
|
+
| `/codeninja:modularize` | Extract ReactJS layout components |
|
|
62
|
+
| `/codeninja:validate-page` | Add form validation to ReactJS page |
|
|
63
|
+
| `/codeninja:integrate-api` | Wire ReactJS page forms to backend |
|
|
@@ -1,74 +1,124 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: codeninja API
|
|
3
|
-
globs: ["**/
|
|
2
|
+
description: codeninja NodeJS API Builder — service scaffolding and API creation
|
|
3
|
+
globs: ["**/app.js", "**/route.js", "**/*_model.js", "**/route_manager.js", "**/middleware/**", "**/utilities/**", "**/config/**"]
|
|
4
4
|
alwaysApply: false
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# codeninja — API Builder
|
|
7
|
+
# codeninja — NodeJS API Builder
|
|
8
8
|
|
|
9
9
|
## 2-Layer Architecture (enforced)
|
|
10
|
-
|
|
11
10
|
```
|
|
12
11
|
modules/v1/<ModuleName>/
|
|
13
12
|
├── route.js ← HTTP only: validation, middleware, res.json()
|
|
14
|
-
└── <module>_model.js ← DB only:
|
|
13
|
+
└── <module>_model.js ← DB only: queries, business logic
|
|
15
14
|
```
|
|
16
|
-
|
|
17
15
|
Never SQL in `route.js`. Never `res.json()` in `_model.js`.
|
|
18
16
|
|
|
19
|
-
##
|
|
17
|
+
## /codeninja:init — NodeJS Service Scaffolding
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
### Phase 0 — Project Info (runs ONCE per repo, skip if context.project_info populated)
|
|
20
|
+
- Ask for project info doc (URL or paste) — store in context.project_info
|
|
21
|
+
- Ask for scope of work doc — store in context.project_info
|
|
22
|
+
- Ask for Figma URL — store in context.project_info
|
|
23
|
+
- Synthesize project summary and detected_entities[] from all provided docs
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
### Phase 1 — Mode and Type
|
|
26
|
+
- Ask: Fast setup (9 questions, auto-generate secure values) OR Manual setup (22 questions)
|
|
27
|
+
- Ask: NodeJS service | ReactJS app | Database only
|
|
28
|
+
- For NodeJS: ask client_type (reactjs|app), encrypted_transport, supported_languages[]
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
### Phase 2 — Database
|
|
31
|
+
- Ask: database type (postgresql|mysql|mongodb)
|
|
32
|
+
- Fast mode: ask db name and user only; auto-set host/port
|
|
33
|
+
- Manual mode: ask name, host, port, user individually
|
|
34
|
+
- Generate database folder at REPOSITORY ROOT (never inside service folder):
|
|
35
|
+
`database/<db_type>/migrations/`, `create-schema.sql`, `setup-database.sh`,
|
|
36
|
+
`setup-database.ps1`, `reset-database.sh`, `seeds/`, `database/README.md`
|
|
37
|
+
- Only if folder doesn't already exist — skip if it does
|
|
38
|
+
- Generate tbl_user_deviceinfo migration for nodejs projects
|
|
39
|
+
|
|
40
|
+
### Phase 3–5 — Service Identity, Package Info, Runtime Config
|
|
41
|
+
- Ask: service_name, port (manual), description
|
|
42
|
+
- Manual mode also: package_name, author, api_key, encryption_key (32 chars), redis config
|
|
43
|
+
- Fast mode: auto-generate all above values; encryption_iv = first 16 chars of encryption_key
|
|
44
|
+
|
|
45
|
+
### Phase 6 — Single Confirmation, Then Generate ALL Files
|
|
46
|
+
|
|
47
|
+
Show summary with ALL values (auto-generated marked). Run validation:
|
|
48
|
+
- BLOCKER: service name conflict, port conflict, key/iv wrong length, required fields missing
|
|
49
|
+
Ask: "Confirm and generate all files? (yes / no / change a value)"
|
|
50
|
+
ONE confirmation only — no per-file prompts after this.
|
|
51
|
+
|
|
52
|
+
**Wave 1:** package.json, .env, .env.example, .gitignore, README.md,
|
|
53
|
+
config/constants.js, config/template.js, logger/logging.js,
|
|
54
|
+
utilities/encryption.js, languages/<lang>.js for each language,
|
|
55
|
+
enc_dec.html (reactjs client) OR enc_dec.php (app client),
|
|
56
|
+
pem/ + images/ + logger/logs/ directories
|
|
57
|
+
|
|
58
|
+
**Wave 2:** config/database.js, utilities/ioRedis.js, utilities/response.js
|
|
59
|
+
|
|
60
|
+
**Wave 3:** config/common.js, utilities/validator.js,
|
|
61
|
+
utilities/notification.js, middleware/rateLimiter.js
|
|
62
|
+
|
|
63
|
+
**Wave 4:** middleware/headerValidator.js,
|
|
64
|
+
modules/v1/<ServiceName>/route.js, modules/v1/<ServiceName>/<service>_model.js,
|
|
65
|
+
document/v1/swagger_doc.json (skeleton)
|
|
66
|
+
|
|
67
|
+
**Wave 5:** modules/v1/route_manager.js, app.js
|
|
68
|
+
|
|
69
|
+
**Wave 6:** Dockerfile, .dockerignore
|
|
40
70
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
All other files use `sendResponse()`, `getMessage()`, or `req.t("key")`.
|
|
44
|
-
Never call `setLocale` from model files — race condition under concurrent requests.
|
|
71
|
+
**After all waves:** generate IDE configs (.vscode/mcp.json, .cursor/mcp.json),
|
|
72
|
+
generate/update docker-compose.yml at repo root.
|
|
45
73
|
|
|
46
|
-
|
|
47
|
-
Patch `swagger_doc.json` only — never rewrite it.
|
|
48
|
-
Add new path key only via `file_insert_after`. Update `info.version` timestamp.
|
|
74
|
+
Call `context_write` → append service to context.services. Call `context_clear_scratchpad`.
|
|
49
75
|
|
|
50
|
-
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## /codeninja:api — Add API Endpoint
|
|
79
|
+
|
|
80
|
+
1. Review 1–2 existing modules for naming/auth patterns — surface summary
|
|
81
|
+
2. Ask: which service, API version (default v1)
|
|
82
|
+
3. Ask: module name, HTTP method, route path, description
|
|
83
|
+
4. Ask: primary table (from context.db.schema.tables), requires auth (yes/no)
|
|
84
|
+
5. Confirm: "Generate [METHOD] [path] in [service]/modules/[version]/[Module]?"
|
|
85
|
+
6. Generate:
|
|
86
|
+
- `modules/<v>/<Module>/route.js` — validation, middleware, res.json()
|
|
87
|
+
- `modules/<v>/<Module>/<module>_model.js` — parameterized queries only
|
|
88
|
+
- Append to `route_manager.js` via `file_insert_after` MCP — NEVER rewrite
|
|
89
|
+
- Patch `swagger_doc.json` via `file_insert_after` MCP — add path key only
|
|
90
|
+
7. Call `context_write` — append to context.api_routes, update modules list
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Code Standards (every generated file)
|
|
95
|
+
|
|
96
|
+
### JSDoc (every exported function — no exceptions)
|
|
51
97
|
```javascript
|
|
52
98
|
/**
|
|
53
99
|
* One-sentence description. Active voice.
|
|
54
|
-
*
|
|
100
|
+
*
|
|
101
|
+
* @param {type} paramName - Description.
|
|
55
102
|
* @returns {Promise<Object>} Description.
|
|
56
103
|
*/
|
|
57
104
|
```
|
|
58
|
-
|
|
59
|
-
Route
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
105
|
+
|
|
106
|
+
### Route comments
|
|
107
|
+
```javascript
|
|
108
|
+
// POST /login — Authenticates user credentials and returns a session token.
|
|
109
|
+
router.post('/login', async (req, res) => {
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Model return shape (always exactly this — no extra keys)
|
|
113
|
+
```javascript
|
|
114
|
+
return { responsecode: 1, responsemsg: 'success', responsedata: data };
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Encryption library selection
|
|
118
|
+
- `client_type == "reactjs"` → use `crypto-js` + generate `enc_dec.html`
|
|
119
|
+
- `client_type == "app"` → use `cryptlib` + generate `enc_dec.php`
|
|
120
|
+
|
|
121
|
+
### DB driver selection
|
|
122
|
+
- postgresql → `pg`
|
|
123
|
+
- mysql → `mysql2`
|
|
124
|
+
- mongodb → `mongoose`
|