codeninja 3.2.0 → 4.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 (111) hide show
  1. package/README.md +13 -1
  2. package/agent/database-agent.md +24 -1
  3. package/agent/nodejs-agent.md +79 -0
  4. package/cli.js +27 -7
  5. package/commands/audit.workflow.md +4 -1
  6. package/commands/db-create-table.workflow.md +1 -1
  7. package/commands/initialize-project.workflow.md +21 -0
  8. package/ide/antigravity/.agents/personas/database-architect.md +431 -153
  9. package/ide/antigravity/.agents/personas/global-orchestrator.md +202 -85
  10. package/ide/antigravity/.agents/personas/nodejs-backend.md +368 -133
  11. package/ide/antigravity/.agents/personas/reactjs-frontend.md +182 -101
  12. package/ide/antigravity/.agents/skills/api-builder/SKILL.md +58 -0
  13. package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +22 -0
  14. package/ide/antigravity/.agents/skills/database/SKILL.md +32 -0
  15. package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +76 -82
  16. package/ide/antigravity/.agents/skills/reactjs/SKILL.md +36 -0
  17. package/ide/antigravity/.agents/workflows/codeninja-api.md +76 -83
  18. package/ide/antigravity/.agents/workflows/codeninja-audit.md +82 -44
  19. package/ide/antigravity/.agents/workflows/codeninja-db-create.md +107 -94
  20. package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +89 -67
  21. package/ide/antigravity/.agents/workflows/codeninja-db-index.md +86 -54
  22. package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +126 -68
  23. package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +87 -59
  24. package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +77 -41
  25. package/ide/antigravity/.agents/workflows/codeninja-debug.md +35 -21
  26. package/ide/antigravity/.agents/workflows/codeninja-design.md +49 -35
  27. package/ide/antigravity/.agents/workflows/codeninja-explain.md +41 -20
  28. package/ide/antigravity/.agents/workflows/codeninja-init.md +479 -289
  29. package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +253 -136
  30. package/ide/antigravity/.agents/workflows/codeninja-modularize.md +250 -132
  31. package/ide/antigravity/.agents/workflows/codeninja-optimize.md +71 -29
  32. package/ide/antigravity/.agents/workflows/codeninja-refactor.md +50 -42
  33. package/ide/antigravity/.agents/workflows/codeninja-review.md +38 -21
  34. package/ide/antigravity/.agents/workflows/codeninja-sync.md +922 -141
  35. package/ide/antigravity/.agents/workflows/codeninja-test.md +34 -49
  36. package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +449 -151
  37. package/ide/claude-code/.claude/CLAUDE.md +99 -0
  38. package/ide/claude-code/.claude/agents/database-agent.md +535 -0
  39. package/ide/claude-code/.claude/agents/nodejs-agent.md +493 -0
  40. package/ide/claude-code/.claude/agents/reactjs-agent.md +267 -0
  41. package/ide/claude-code/.claude/commands/codeninja-api.md +104 -0
  42. package/ide/claude-code/.claude/commands/codeninja-audit.md +119 -0
  43. package/ide/claude-code/.claude/commands/codeninja-db-create.md +138 -0
  44. package/ide/claude-code/.claude/commands/codeninja-db-drop.md +109 -0
  45. package/ide/claude-code/.claude/commands/codeninja-db-index.md +103 -0
  46. package/ide/claude-code/.claude/commands/codeninja-db-modify.md +165 -0
  47. package/ide/claude-code/.claude/commands/codeninja-db-seed.md +104 -0
  48. package/ide/claude-code/.claude/commands/codeninja-db-sync.md +106 -0
  49. package/ide/claude-code/.claude/commands/codeninja-debug.md +99 -0
  50. package/ide/claude-code/.claude/commands/codeninja-design.md +68 -0
  51. package/ide/claude-code/.claude/commands/codeninja-explain.md +61 -0
  52. package/ide/claude-code/.claude/commands/codeninja-init.md +529 -0
  53. package/ide/claude-code/.claude/commands/codeninja-integrate-api.md +453 -0
  54. package/ide/claude-code/.claude/commands/codeninja-modularize.md +334 -0
  55. package/ide/claude-code/.claude/commands/codeninja-optimize.md +129 -0
  56. package/ide/claude-code/.claude/commands/codeninja-refactor.md +76 -0
  57. package/ide/claude-code/.claude/commands/codeninja-review.md +87 -0
  58. package/ide/claude-code/.claude/commands/codeninja-sync.md +964 -0
  59. package/ide/claude-code/.claude/commands/codeninja-test.md +45 -0
  60. package/ide/claude-code/.claude/commands/codeninja-validate-page.md +548 -0
  61. package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +12 -13
  62. package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +47 -31
  63. package/ide/cursor/.cursor/rules/03-api-builder.mdc +32 -110
  64. package/ide/cursor/.cursor/rules/04-nodejs-generation.mdc +58 -0
  65. package/ide/cursor/.cursor/rules/05-database.mdc +54 -0
  66. package/ide/cursor/.cursor/rules/06-reactjs.mdc +36 -0
  67. package/ide/cursor/.cursor/rules/07-reactjs-generation.mdc +49 -0
  68. package/ide/cursor/.cursor/rules/08-code-intelligence.mdc +56 -0
  69. package/ide/cursor/.cursor/rules/09-workflow-steps.mdc +53 -0
  70. package/ide/vscode/.github/copilot-instructions.md +67 -382
  71. package/ide/vscode/.vscode/instructions/code-intelligence.instructions.md +58 -0
  72. package/ide/vscode/.vscode/instructions/database.instructions.md +55 -0
  73. package/ide/vscode/.vscode/instructions/nodejs.instructions.md +77 -0
  74. package/ide/vscode/.vscode/instructions/reactjs.instructions.md +42 -0
  75. package/package.json +2 -2
  76. package/tasks/ask-hashing-library.task.md +31 -0
  77. package/tasks/ask-language-type.task.md +26 -0
  78. package/tasks/ask-new-module-name.task.md +13 -0
  79. package/tasks/ask-new-service-name.task.md +13 -0
  80. package/tasks/ask-old-module-name.task.md +15 -0
  81. package/tasks/ask-old-service-name.task.md +13 -0
  82. package/tasks/ask-orm-type.task.md +26 -0
  83. package/tasks/collect-seed-data.task.md +19 -0
  84. package/tasks/generate-app.task.md +42 -0
  85. package/tasks/generate-common.task.md +13 -0
  86. package/tasks/generate-constants.task.md +13 -0
  87. package/tasks/generate-database.task.md +32 -0
  88. package/tasks/generate-encryption.task.md +28 -0
  89. package/tasks/generate-fast-defaults.task.md +7 -0
  90. package/tasks/generate-hashing.task.md +180 -0
  91. package/tasks/generate-headerValidator.task.md +13 -0
  92. package/tasks/generate-ioRedis.task.md +20 -0
  93. package/tasks/generate-language-en.task.md +12 -0
  94. package/tasks/generate-logging.task.md +12 -0
  95. package/tasks/generate-model.task.md +74 -6
  96. package/tasks/generate-notification.task.md +12 -0
  97. package/tasks/generate-package-json.task.md +69 -0
  98. package/tasks/generate-prisma-client.task.md +56 -0
  99. package/tasks/generate-prisma-schema.task.md +71 -0
  100. package/tasks/generate-rateLimiter.task.md +20 -0
  101. package/tasks/generate-readme.task.md +24 -0
  102. package/tasks/generate-response.task.md +27 -0
  103. package/tasks/generate-route-manager.task.md +32 -0
  104. package/tasks/generate-route.task.md +37 -0
  105. package/tasks/generate-swagger.task.md +8 -0
  106. package/tasks/generate-template.task.md +12 -0
  107. package/tasks/generate-tsconfig.task.md +38 -0
  108. package/tasks/generate-validator.task.md +31 -0
  109. package/ide/cursor/.cursor/rules/04-database.mdc +0 -90
  110. package/ide/cursor/.cursor/rules/05-reactjs.mdc +0 -147
  111. package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +0 -112
@@ -1,115 +1,162 @@
1
+ This workflow runs when user invokes /codeninja:integrate-api
2
+
1
3
  ---
2
- slash_command: /codeninja:integrate-api
3
- personas: [global-orchestrator, reactjs-frontend]
4
- skills: [mcp-and-context, reactjs, api-builder]
4
+ type: workflow
5
+ name: integrate-api
5
6
  description: >
6
- Wire a ReactJS page's forms and action buttons to backend API calls
7
- through apiHandler.js and apiClient.js. Adds loading states, error
8
- display, and success feedback. Never touches validation or layout.
7
+ Wires a ReactJS page's forms and action buttons to backend API calls
8
+ through apiHandler.js and apiClient.js. Creates or updates submit
9
+ handler functions, adds loading states, and wires success/error
10
+ responses back to the UI. Never touches validation logic or component
11
+ layout — API integration only.
9
12
  ---
10
13
 
11
- # /codeninja:integrate-api
14
+ # Workflow: @integrate-api
12
15
 
13
- ## Before Running
14
- 1. Call `context_check_stale`
15
- 2. Call `context_read` load `context.services` and `context.api_routes`
16
- 3. Call `service_scan` verify services on disk
16
+ ## Goal
17
+ Connect the frontend page to the backend. After this workflow runs,
18
+ every form submit and action button on the target page calls the
19
+ correct API handler function, handles the loading state, and processes
20
+ the response correctly.
17
21
 
18
22
  ## Rules
19
- - Target ONE specific page per run
23
+ - Target one specific page per run
20
24
  - NEVER modify layout, CSS, or validation logic
21
- - ALWAYS use `apiHandler.js` for API calls — never call `axiosClient` directly from a page
22
- - ALWAYS add handler functions to `apiHandler.js` if the needed function doesn't exist
25
+ - ALWAYS use `apiHandler.js` for API calls — never call `axiosClient`
26
+ directly from a page component
27
+ - ALWAYS add handler functions to `apiHandler.js` if the needed function
28
+ does not already exist there — never inline API calls in the page
23
29
  - NEVER hardcode API endpoints in page files
24
30
  - ONE confirmation before any file is written
25
- - After writing files → call `context_write`
31
+ - After writing files → run task: `write-context`
26
32
 
27
33
  ---
28
34
 
29
- ## Execution — Full Step-by-Step
35
+ ## Step-by-Step Execution
36
+
37
+ ---
30
38
 
31
39
  ### Phase 1 — Target Selection
32
40
 
33
- **Step 1.** Ask: "Which ReactJS service?" (list ReactJS services from `context.services`)
34
- - Store: `context.current_action.service_name`
41
+ 1. Run task: `ask-react-target-service`
42
+ Stores: `context.current_action.service_name`
35
43
 
36
- **Step 2.** Ask: "Which page path?" (e.g. `src/pages/Login/index.jsx`)
37
- - Store: `context.current_action.page_path`, `context.current_action.page_name`
44
+ 2. Run task: `ask-page-path`
45
+ Stores: `context.current_action.page_path`
46
+ Stores: `context.current_action.page_name`
38
47
 
39
- **Step 3.** Ask: "What scope of integration?"
40
- 1. All forms and buttons on this page
41
- 2. Specific form or button only
42
- - Store: `context.current_action.api_integration_scope`
43
- - If specific → ask: "Which form or button?" → Store: `context.current_action.api_integration_target`
48
+ 3. Run task: `ask-api-integration-scope`
49
+ Stores: `context.current_action.api_integration_scope`
50
+ If scope == "specific" also stores `context.current_action.api_integration_target`
44
51
 
45
52
  ---
46
53
 
47
54
  ### Phase 2 — Read Service Context
48
55
 
49
56
  Read from context:
50
- - `context.services[<service_name>].linked_service` → the NodeJS backend
51
- - `context.api_routes` filtered by linked NodeJS service → available API routes
57
+ - `context.current_action.service_name` → the ReactJS service
58
+ - `context.services[<service_name>].linked_service` the backend NodeJS service name
59
+ - `context.api_routes` filtered by the linked NodeJS service → available API routes
52
60
 
53
61
  Read from disk:
54
- - Full content of `context.current_action.page_path` (target page)
55
- - Full content of `src/api/apiHandler.js`
56
- - Full content of `src/api/apiClient.js` (read-only reference)
62
+ - Full content of `context.current_action.page_path` (the target page)
63
+ - Full content of `src/api/apiHandler.js` in the target service
64
+ - Full content of `src/api/apiClient.js` in the target service (read-only reference)
57
65
 
58
66
  ---
59
67
 
60
68
  ### Phase 3 — Scan the Page for Integration Points
61
69
 
70
+ Read the page file and identify every place that could trigger an API call:
71
+
62
72
  #### 3a — Forms
63
- For each `<form>` found:
64
- - Note the form's apparent purpose (infer from field names, labels, heading text)
65
- - Check if `onSubmit` is already connected
66
- - Check if form imports anything from `apiHandler.js`
73
+
74
+ For each `<form>` element found:
75
+ - Note the form's apparent purpose (login, register, search, update
76
+ profile, etc.) infer from field names, labels, heading text nearby
77
+ - Check if an `onSubmit` handler is already connected:
78
+ - `<form onSubmit={...}>` → handler exists, note the function name
79
+ - No `onSubmit` → no handler yet
80
+ - Check if a submit button exists: `<button type="submit">` or
81
+ `<input type="submit">`
82
+ - Note whether the form already imports anything from `apiHandler.js`
67
83
 
68
84
  #### 3b — Action Buttons
69
- For each `<button>` NOT a submit button:
70
- - Check if `onClick` is connected
71
- - Infer action from button text: Delete/Remove → delete, Edit/Update → update,
72
- Save save/create, Logout logout, Load more/Next → pagination, Export/Download → export
85
+
86
+ For each `<button>` or clickable element that is NOT a submit button:
87
+ - Check if an `onClick` handler is connected
88
+ - Infer the action from button text or aria-label:
89
+ - "Delete", "Remove" → delete action
90
+ - "Edit", "Update" → update action
91
+ - "Save" → save/create action
92
+ - "Logout", "Sign out" → logout action
93
+ - "Load more", "Next page" → pagination/fetch action
94
+ - "Export", "Download" → export action
95
+ - "Approve", "Reject" → status change action
96
+ - Note if the handler already contains an API call
73
97
 
74
98
  #### 3c — Existing API Calls
75
- Detect any existing API calls:
76
- - Imports from `apiHandler.js` (existing — note them)
77
- - Direct `axiosClient` calls (flag — should be moved to apiHandler)
78
- - `fetch(` or `axios.` direct calls (flag — should be moved)
79
99
 
80
- If scope == "specific" focus only on the matching form/button.
100
+ Detect any API calls already in the file:
101
+ - Imports from `apiHandler.js`
102
+ - `axiosClient` direct calls (flag these — they should be moved to apiHandler)
103
+ - `fetch(` or `axios.` calls (flag — should be moved to apiHandler)
104
+
105
+ If scope == "specific":
106
+ Apply the same scan but focus only on the form or action matching
107
+ `context.current_action.api_integration_target`. Other forms/buttons
108
+ are noted but not modified.
81
109
 
82
110
  ---
83
111
 
84
112
  ### Phase 4 — Match Forms to API Routes
85
113
 
86
- For each integration point, determine which API route it should call:
114
+ For each integration point found, determine which backend API route it
115
+ should call. Use this priority:
116
+
117
+ 1. **Exact match** — an `apiHandler.js` function already exists for
118
+ this purpose (e.g. `webLogin` for a login form). Use it as-is.
87
119
 
88
- 1. **Exact match** — `apiHandler.js` function already exists for this purpose → use as-is
89
- 2. **Route match** matching route exists in `context.api_routes` for linked backend →
90
- new handler function will be added to `apiHandler.js`
91
- 3. **No match** — no suitable route exists yet → scaffold with TODO placeholder
120
+ 2. **Route match** — a route exists in `context.api_routes` for the
121
+ linked backend service that matches the form's apparent purpose.
122
+ A new handler function will be added to `apiHandler.js` for it.
92
123
 
93
- Record: `{ form_purpose, handler_function_name, route_path, route_method, match_type }`
124
+ 3. **No match** no suitable route exists yet in either place.
125
+ The integration plan will note this as a gap. The form's submit
126
+ handler will be scaffolded with a `// TODO: connect to API` comment
127
+ and a placeholder structure so the page is functional once the
128
+ route is added. Do NOT create a route in the backend — that is
129
+ `@create-api`'s job.
130
+
131
+ For each match or gap, record:
132
+ `{ form_purpose, handler_function_name, route_path, route_method,
133
+ match_type: "existing_handler" | "new_handler" | "no_route" }`
94
134
 
95
135
  ---
96
136
 
97
137
  ### Phase 5 — Design the Integration
98
138
 
99
- For each integration point:
139
+ For each integration point, design what needs to be generated:
140
+
141
+ #### 5a — State requirements
100
142
 
101
- #### State requirements
102
- - `loading` state — boolean, false by default
103
- - `error` state — string or null
104
- - Response data state based on form type:
105
- - Auth forms no data state (session stored by apiHandler)
106
- - List/search`data` state (array, [])
107
- - Single item `item` state (object, null)
108
- - Delete/updatelist refresh or redirect
143
+ Every API call needs at minimum:
144
+ - `loading` state — boolean, `false` by default
145
+ - `error` state — string or null, for displaying API error messages
146
+ to the user
147
+ - Response data state depends on the form type:
148
+ - Auth forms (login/register)no response data state needed
149
+ (session is stored by apiHandler)
150
+ - List/search forms `data` state (array, `[]` default)
151
+ - Single-item fetch → `item` state (object, `null` default)
152
+ - Delete/update → may use a list refresh or a redirect
109
153
 
110
- #### Submit handler patterns
154
+ Identify existing state in the page to avoid duplicates. Only add
155
+ state that does not already exist.
111
156
 
112
- **Auth / destructive (login, delete, logout):**
157
+ #### 5b Submit handler pattern
158
+
159
+ **Auth / destructive action pattern (login, delete, logout):**
113
160
  ```jsx
114
161
  const handle[Action] = async (e) => {
115
162
  e?.preventDefault();
@@ -118,14 +165,15 @@ const handle[Action] = async (e) => {
118
165
  const res = await [handlerFunction]({ ...formData });
119
166
  setLoading(false);
120
167
  if (res?.code === 1) {
121
- navigate('/dashboard');
168
+ // success — navigate or show confirmation
169
+ navigate('/dashboard'); // use react-router useNavigate
122
170
  } else {
123
171
  setError(res?.message || 'Something went wrong. Please try again.');
124
172
  }
125
173
  };
126
174
  ```
127
175
 
128
- **Data fetch / load (get list, get details):**
176
+ **Data fetch / load pattern (get list, get details):**
129
177
  ```jsx
130
178
  const fetch[Resource] = async () => {
131
179
  setLoading(true);
@@ -138,10 +186,11 @@ const fetch[Resource] = async () => {
138
186
  setError(res?.message || 'Failed to load data. Please try again.');
139
187
  }
140
188
  };
141
- // Also add: useEffect(() => { fetch[Resource](); }, []);
142
189
  ```
190
+ Also add a `useEffect(() => { fetch[Resource](); }, [])` call to
191
+ load data on component mount if appropriate.
143
192
 
144
- **Create / Update (form submit):**
193
+ **Create / Update pattern (form submit):**
145
194
  ```jsx
146
195
  const handle[Action] = async (e) => {
147
196
  e?.preventDefault();
@@ -150,34 +199,72 @@ const handle[Action] = async (e) => {
150
199
  const res = await [handlerFunction](formData);
151
200
  setLoading(false);
152
201
  if (res?.code === 1) {
202
+ // success — show message or reset form
153
203
  setSuccessMsg(res?.message || '[Action] successful.');
154
- resetForm();
204
+ resetForm(); // only if a form reset function exists
155
205
  } else {
156
206
  setError(res?.message || 'Something went wrong. Please try again.');
157
207
  }
158
208
  };
159
209
  ```
160
210
 
161
- #### Loading feedback
211
+ #### 5c — Loading state feedback
212
+
213
+ Add a `disabled={loading}` prop to the submit button or action trigger.
214
+ Also add visual feedback text inside the button:
162
215
  ```jsx
163
216
  <button type="submit" disabled={loading}>
164
217
  {loading ? 'Please wait...' : '[Original Button Text]'}
165
218
  </button>
166
219
  ```
167
220
 
168
- #### Error display (above submit button)
221
+ #### 5d — Error display
222
+
223
+ Add an error display block just above the submit button:
169
224
  ```jsx
170
225
  {error && <p className={styles.apiError}>{error}</p>}
171
226
  ```
172
227
 
173
- #### Success display (for non-navigating actions)
228
+ Add to the page's `.module.css`:
229
+ ```css
230
+ .apiError {
231
+ color: #dc3545;
232
+ font-size: 0.875rem;
233
+ margin-bottom: 0.75rem;
234
+ padding: 0.5rem 0.75rem;
235
+ background-color: #fff5f5;
236
+ border: 1px solid #f5c6cb;
237
+ border-radius: 4px;
238
+ }
239
+ ```
240
+
241
+ #### 5e — Success feedback (for non-navigating actions)
242
+
243
+ If the action does not navigate away after success, add a success
244
+ message state and display:
245
+ ```jsx
246
+ const [successMsg, setSuccessMsg] = React.useState('');
247
+ ```
174
248
  ```jsx
175
249
  {successMsg && <p className={styles.successMsg}>{successMsg}</p>}
176
250
  ```
251
+ ```css
252
+ .successMsg {
253
+ color: #155724;
254
+ font-size: 0.875rem;
255
+ margin-bottom: 0.75rem;
256
+ padding: 0.5rem 0.75rem;
257
+ background-color: #d4edda;
258
+ border: 1px solid #c3e6cb;
259
+ border-radius: 4px;
260
+ }
261
+ ```
177
262
 
178
263
  ---
179
264
 
180
- ### Phase 6 — Show Integration Plan
265
+ ### Phase 6 — Build and Show Integration Plan
266
+
267
+ Display the integration plan before writing anything:
181
268
 
182
269
  ```
183
270
  ┌──────────────────────────────────────────────────────┐
@@ -190,40 +277,48 @@ const handle[Action] = async (e) => {
190
277
  │ INTEGRATIONS │
191
278
  │ │
192
279
  │ ① Login Form → webLogin() │
193
- │ Route : POST /login
194
- │ Handler : webLogin (already in apiHandler.js)
195
- │ State add: loading, error
196
- │ Pattern : auth/destructive
280
+ │ Route : POST /login
281
+ │ Handler : webLogin (already in apiHandler.js)
282
+ │ State add : loading, error
283
+ │ Pattern : auth/destructive
197
284
  │ On success: navigate('/dashboard') │
198
285
  │ │
199
286
  │ ② Delete Button → deleteUser() │
200
- │ Route : DELETE /users/:id
201
- │ Handler : deleteUser (NEW will add to │
202
- apiHandler.js)
203
- Pattern : destructive
287
+ │ Route : DELETE /users/:id
288
+ │ Handler : deleteUser (NEW will add to │
289
+ apiHandler.js)
290
+ State add : deleteLoading, deleteError
291
+ │ Pattern : destructive │
204
292
  │ On success: refresh user list │
205
293
  ├──────────────────────────────────────────────────────┤
206
- │ GAPS (no backend route yet)
207
- │ ③ Export CSV Button — no route exists yet
208
- │ Will add TODO placeholder
294
+ │ GAPS (no matching route yet)
295
+ │ ③ Export CSV Button — no backend route for this yet
296
+ │ Will add a TODO placeholder
209
297
  ├──────────────────────────────────────────────────────┤
210
298
  │ FILES TO MODIFY │
211
- │ → src/pages/[PageName]/index.jsx
212
- │ → src/pages/[PageName]/[PageName].module.css
213
- │ → src/api/apiHandler.js ([n] new function(s))
299
+ │ → src/pages/[PageName]/index.jsx
300
+ │ → src/pages/[PageName]/[PageName].module.css
301
+ │ → src/api/apiHandler.js (add deleteUser function)
214
302
  └──────────────────────────────────────────────────────┘
215
303
  ```
216
304
 
217
- Ask: "Apply this integration plan? (yes / no / adjust)"
305
+ Ask exactly this question:
306
+ "Apply this integration plan? (yes / no / adjust)"
307
+
308
+ - If yes → proceed to Phase 7
309
+ - If no → abort. Nothing is written.
310
+ - If adjust → ask what to change (different handler, different on-success
311
+ action, skip an integration point). Apply and re-display.
218
312
 
219
313
  ---
220
314
 
221
315
  ### Phase 7 — Apply Integration
222
316
 
223
- #### 7a — Update apiHandler.js (new functions only)
317
+ #### 7a — Update apiHandler.js (if new functions needed)
318
+
319
+ For each integration with `match_type == "new_handler"`:
320
+ Surgically append to `src/api/apiHandler.js`:
224
321
 
225
- For each `match_type == "new_handler"`:
226
- Append to `src/api/apiHandler.js`:
227
322
  ```jsx
228
323
  /**
229
324
  * [Route description from context.api_routes or inferred].
@@ -232,94 +327,100 @@ Append to `src/api/apiHandler.js`:
232
327
  * @returns {Promise<Object>} API response.
233
328
  */
234
329
  export async function [functionName](data) {
235
- const res = await axiosClient.[method]('[route_path]', data);
330
+ const res = await axiosClient.post('[route_path]', data);
236
331
  return res;
237
332
  }
238
333
  ```
239
- Use correct method: `.get`, `.post`, `.put`, `.patch`, `.delete`.
240
- For DELETE/GET with ID: `axiosClient.delete(\`/users/${data.id}\`)`
241
334
 
242
- For `match_type == "no_route"`:
335
+ Use the correct HTTP method — `axiosClient.get`, `.post`, `.put`,
336
+ `.patch`, `.delete` — matching the route method.
337
+
338
+ For DELETE or GET with ID: use template string for the path:
339
+ ```jsx
340
+ const res = await axiosClient.delete(`/users/${data.id}`);
341
+ ```
342
+
343
+ For gaps (`match_type == "no_route"`):
243
344
  ```jsx
244
345
  /**
245
- * TODO: Connect to backend route once created via /codeninja:api.
346
+ * TODO: Connect to backend route once created via @create-api.
347
+ *
348
+ * @param {Object} data - Request payload.
349
+ * @returns {Promise<Object>} API response.
246
350
  */
247
351
  export async function [functionName](data) {
352
+ // TODO: Replace with actual route when backend is ready.
353
+ // Suggested: POST /[suggested_path]
248
354
  console.warn('[functionName] is not yet connected to a backend route.');
249
355
  return { code: 0, message: 'API not connected yet.' };
250
356
  }
251
357
  ```
252
358
 
253
- #### 7b — Update the page file (surgical edits only)
359
+ #### 7b — Update the page file
360
+
361
+ Read the current page file. Apply all changes surgically:
254
362
 
255
- 1. Add imports for new apiHandler functions (only new ones):
363
+ 1. **Add imports** for apiHandler functions (only the new ones):
256
364
  ```jsx
257
365
  import { webLogin, deleteUser } from '../../api/apiHandler';
258
366
  ```
259
- Add `useNavigate` if any handler navigates:
367
+ Also add `useNavigate` from react-router-dom if any handler navigates:
260
368
  ```jsx
261
369
  import { useNavigate } from 'react-router-dom';
262
370
  ```
263
371
 
264
- 2. Add state declarations inside component:
372
+ 2. **Add state declarations** inside the component function:
265
373
  ```jsx
266
374
  const [loading, setLoading] = React.useState(false);
267
375
  const [error, setError] = React.useState(null);
268
- const navigate = useNavigate(); // if navigate is used
269
376
  ```
377
+ Add `const navigate = useNavigate();` if navigate is used.
270
378
 
271
- 3. Add handler functions just before the return statement.
272
- If a handler already exists add API call logic inside it, don't create duplicate.
379
+ 3. **Add or update handler functions** inside the component:
380
+ Insert each handler function just before the return statement.
381
+ If a handler already exists (from validation or prior code) →
382
+ add only the API call logic inside it, not a new function.
273
383
 
274
- 4. Wire form `onSubmit` / button `onClick`:
275
- - `<form onSubmit={handle[Action]}>`
276
- - `<button onClick={handle[Action]}>`
384
+ 4. **Wire the form's onSubmit / button's onClick**:
385
+ - If `<form onSubmit={existing}>` → rename existing handler and
386
+ call it inside the new handler (after the API call succeeds)
387
+ - If no onSubmit → add `onSubmit={handle[Action]}`
388
+ - If button has no onClick → add `onClick={handle[Action]}`
277
389
 
278
- 5. Add `disabled={loading}` and conditional button text to submit buttons.
390
+ 5. **Add loading state to buttons**:
391
+ Locate each submit button / action button. Add `disabled={loading}`
392
+ and the conditional button text as designed in Phase 5c.
279
393
 
280
- 6. Add error and success display elements adjacent to submit buttons.
394
+ 6. **Add error and success display elements**:
395
+ Place the error `<p>` above the submit button.
396
+ Place the success `<p>` below the submit button (for non-nav actions).
281
397
 
282
- 7. Add `useEffect` for data-fetching handlers (load on mount).
398
+ 7. **Add useEffect for data fetching** if applicable (Phase 5b).
283
399
 
284
- #### 7c Update page CSS module
285
- Add `.apiError` and `.successMsg` classes (if not already present):
286
- ```css
287
- .apiError {
288
- color: #dc3545;
289
- font-size: 0.875rem;
290
- margin-bottom: 0.75rem;
291
- padding: 0.5rem 0.75rem;
292
- background-color: #fff5f5;
293
- border: 1px solid #f5c6cb;
294
- border-radius: 4px;
295
- }
400
+ > **Multi-agent:** Delegate to `reactjs-frontend` via Task invocation for parallel execution.
401
+ > Read `.codeninja/tasks/` before applying API integration changes.
296
402
 
297
- .successMsg {
298
- color: #155724;
299
- font-size: 0.875rem;
300
- margin-bottom: 0.75rem;
301
- padding: 0.5rem 0.75rem;
302
- background-color: #d4edda;
303
- border: 1px solid #c3e6cb;
304
- border-radius: 4px;
305
- }
306
- ```
403
+ #### 7c — Update the page's CSS module
404
+
405
+ Add `.apiError` and `.successMsg` classes to the page's `.module.css`
406
+ if they are not already there. Do not overwrite existing definitions.
307
407
 
308
408
  ---
309
409
 
310
- ### Phase 8 — Finalize
410
+ ### Phase 8 — Write Context and Report
311
411
 
312
- **Step 1.** Call `context_write`:
412
+ Run task: `write-context` with:
313
413
  - Append to `context.services[<service_name>].integrated_pages`:
314
- `{ page, integrations: [{ form_purpose, handler, route }], timestamp: ISO now }`
414
+ `{ page, integrations: [list of { form_purpose, handler, route }], timestamp: ISO now }`
315
415
  - Set `last_command` = "integrate-api"
316
- - Append to `change_log`
416
+ - Append to top-level `change_log`:
417
+ `{ timestamp, command: "integrate-api", action: "Wired [n] API calls in [page]", affected_files: [...] }`
418
+ - After write-context → call MCP tool `context_clear_scratchpad` with keys: ["current_action"]
317
419
 
318
- **Step 2.** Call `context_clear_scratchpad` with keys: ["current_action"]
420
+ Display completion report:
319
421
 
320
- **Step 3.** Show completion report:
321
422
  ```
322
- /codeninja:integrate-api Complete
423
+ @integrate-api Complete
323
424
  ─────────────────────────────────────────
324
425
  Page : [page_name]
325
426
  Integrations : [n] connected, [n] placeholders
@@ -330,7 +431,23 @@ Integrations : [n] connected, [n] placeholders
330
431
  ─────────────────────────────────────────
331
432
  [If gaps exist:]
332
433
  ⚠ [n] action(s) have no backend route yet.
333
- Placeholders added. Run /codeninja:api to create backend routes,
334
- then re-run /codeninja:integrate-api to connect them.
434
+ Placeholders added run @create-api to scaffold the backend routes,
435
+ then re-run @integrate-api to connect them.
335
436
  ─────────────────────────────────────────
336
437
  ```
438
+
439
+ Run task: `show-final-summary`
440
+
441
+ ---
442
+
443
+ ## What This Workflow Does NOT Do
444
+
445
+ - Does not add or modify form validation — that is `@validate-page`'s job
446
+ - Does not create new pages or components
447
+ - Does not modify App.jsx routing
448
+ - Does not touch backend files (NodeJS service)
449
+ - Does not add authentication/session management beyond what apiHandler
450
+ already provides
451
+ - Does not add global state (Redux, Context API)
452
+ - Does not handle file uploads (beyond wiring the existing input to
453
+ an API call with FormData if the input type is "file")