codeninja 2.0.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.
Files changed (46) hide show
  1. package/README.md +122 -251
  2. package/agent/global-agent.md +8 -0
  3. package/cli.js +248 -223
  4. package/commands/debug.workflow.md +94 -0
  5. package/commands/explain.workflow.md +59 -0
  6. package/commands/optimize.workflow.md +124 -0
  7. package/commands/review.workflow.md +85 -0
  8. package/ide/antigravity/.agents/personas/database-architect.md +249 -0
  9. package/ide/antigravity/.agents/personas/global-orchestrator.md +144 -0
  10. package/ide/antigravity/.agents/personas/nodejs-backend.md +250 -0
  11. package/ide/antigravity/.agents/personas/reactjs-frontend.md +179 -0
  12. package/ide/antigravity/.agents/skills/api-builder/SKILL.md +179 -0
  13. package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +184 -0
  14. package/ide/antigravity/.agents/skills/database/SKILL.md +165 -0
  15. package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +111 -0
  16. package/ide/antigravity/.agents/skills/reactjs/SKILL.md +211 -0
  17. package/ide/antigravity/.agents/workflows/codeninja-api.md +111 -0
  18. package/ide/antigravity/.agents/workflows/codeninja-audit.md +81 -0
  19. package/ide/antigravity/.agents/workflows/codeninja-db-create.md +124 -0
  20. package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +87 -0
  21. package/ide/antigravity/.agents/workflows/codeninja-db-index.md +70 -0
  22. package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +106 -0
  23. package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +76 -0
  24. package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +70 -0
  25. package/ide/antigravity/.agents/workflows/codeninja-debug.md +82 -0
  26. package/ide/antigravity/.agents/workflows/codeninja-design.md +54 -0
  27. package/ide/antigravity/.agents/workflows/codeninja-explain.md +40 -0
  28. package/ide/antigravity/.agents/workflows/codeninja-init.md +336 -0
  29. package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +336 -0
  30. package/ide/antigravity/.agents/workflows/codeninja-modularize.md +216 -0
  31. package/ide/antigravity/.agents/workflows/codeninja-optimize.md +84 -0
  32. package/ide/antigravity/.agents/workflows/codeninja-refactor.md +68 -0
  33. package/ide/antigravity/.agents/workflows/codeninja-review.md +70 -0
  34. package/ide/antigravity/.agents/workflows/codeninja-sync.md +183 -0
  35. package/ide/antigravity/.agents/workflows/codeninja-test.md +61 -0
  36. package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +250 -0
  37. package/ide/cursor/.cursor/mcp.json +8 -0
  38. package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +63 -0
  39. package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +38 -0
  40. package/ide/cursor/.cursor/rules/03-api-builder.mdc +124 -0
  41. package/ide/cursor/.cursor/rules/04-database.mdc +90 -0
  42. package/ide/cursor/.cursor/rules/05-reactjs.mdc +147 -0
  43. package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +112 -0
  44. package/ide/vscode/.github/copilot-instructions.md +399 -0
  45. package/ide/vscode/.vscode/mcp.json +9 -0
  46. package/package.json +24 -23
@@ -0,0 +1,211 @@
1
+ ---
2
+ skill: reactjs
3
+ scope: reactjs-commands
4
+ loaded-for:
5
+ - /codeninja:init (reactjs type)
6
+ - @modularize
7
+ - @validate-page
8
+ - @integrate-api
9
+ description: >
10
+ All technical standards for ReactJS frontend development — file structure,
11
+ apiClient/apiHandler patterns, encryption inheritance, routing standards,
12
+ and component conventions. The reactjs-frontend persona uses this skill.
13
+ ---
14
+
15
+ # Skill: ReactJS Frontend
16
+
17
+ Technical standards for every ReactJS file in this project.
18
+
19
+ ---
20
+
21
+ ## Backend Linking (enforced before any generation)
22
+
23
+ ```
24
+ context.current_init.linked_service → backend service name
25
+ context.services[linked].port → REACT_APP_BASE_URL port
26
+ context.services[linked].encryption_key → REACT_APP_KEY
27
+ context.services[linked].encryption_iv → REACT_APP_IV
28
+ context.services[linked].api_key → REACT_APP_API_KEY
29
+ ```
30
+
31
+ These 4 values are inherited — NEVER ask the user for them.
32
+ NEVER hardcode any key, IV, or API key value.
33
+
34
+ ---
35
+
36
+ ## apiClient.js — Exact Specification
37
+
38
+ ```javascript
39
+ // src/api/apiClient.js
40
+ // Axios instance — all cross-cutting concerns live here
41
+
42
+ import axios from 'axios';
43
+ import CryptoJS from 'crypto-js';
44
+ import { logOutRedirectCall, showErrorMessage } from '../pages/common/Utils';
45
+
46
+ const KEY = CryptoJS.enc.Hex.parse(process.env.REACT_APP_KEY);
47
+ const IV = CryptoJS.enc.Hex.parse(process.env.REACT_APP_IV);
48
+
49
+ const axiosClient = axios.create({
50
+ baseURL: process.env.REACT_APP_BASE_URL,
51
+ headers: {
52
+ 'api-key': process.env.REACT_APP_API_KEY,
53
+ 'Content-Type': 'text/plain',
54
+ },
55
+ });
56
+
57
+ // Request interceptor: encrypt body, attach token
58
+ axiosClient.interceptors.request.use((config) => {
59
+ const token = localStorage.getItem('wa_token');
60
+ if (token) {
61
+ config.headers['token'] = CryptoJS.AES.encrypt(token, KEY, { iv: IV }).toString();
62
+ }
63
+ if (config.data) {
64
+ config.data = CryptoJS.AES.encrypt(JSON.stringify(config.data), KEY, { iv: IV }).toString();
65
+ }
66
+ return config;
67
+ });
68
+
69
+ // Response interceptor: decrypt body
70
+ axiosClient.interceptors.response.use(
71
+ (response) => {
72
+ try {
73
+ const bytes = CryptoJS.AES.decrypt(response.data, KEY, { iv: IV });
74
+ const parsed = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
75
+ if (parsed.status === -1) { logOutRedirectCall(); }
76
+ return { ...response, data: parsed };
77
+ } catch {
78
+ return response;
79
+ }
80
+ },
81
+ (error) => {
82
+ if (!error.response || error.response.status === 401) {
83
+ logOutRedirectCall();
84
+ showErrorMessage('Session expired. Please log in again.');
85
+ }
86
+ return Promise.reject(error);
87
+ }
88
+ );
89
+
90
+ export default axiosClient;
91
+ ```
92
+
93
+ ---
94
+
95
+ ## apiHandler.js — Pattern
96
+
97
+ ```javascript
98
+ // src/api/apiHandler.js
99
+ import axiosClient from './apiClient';
100
+ import { saveWebSession } from '../pages/common/Utils';
101
+
102
+ // POST /login — authenticate user
103
+ export const webLogin = async ({ email, password }) => {
104
+ const payload = { email, password, device_type: 'web', device_token: '' };
105
+ const res = await axiosClient.post('/login', payload);
106
+ if (res.data.status === 1) saveWebSession(res.data.data);
107
+ return res.data;
108
+ };
109
+
110
+ // POST /<path> — description
111
+ export const <functionName> = async (data) => {
112
+ const res = await axiosClient.post('/<path>', data);
113
+ return res.data;
114
+ };
115
+ ```
116
+
117
+ Rules:
118
+ - One function per endpoint
119
+ - No try/catch here — interceptors handle errors
120
+ - No decryption here — interceptors handle it
121
+ - Session saving happens in the handler, not in UI components
122
+ - Generate handlers matching `context.api_routes` for the linked service
123
+
124
+ ---
125
+
126
+ ## Component Standards
127
+
128
+ - Functional components only — no class components
129
+ - JSDoc above every exported function and component
130
+ - No inline styles — `.module.css` per page, `global.css` for shared
131
+ - No `console.log` — use `showMessage` / `showErrorMessage`
132
+ - No hardcoded API paths — all calls through `apiHandler.js`
133
+
134
+ ---
135
+
136
+ ## Welcome Page Standard
137
+
138
+ ```jsx
139
+ // src/pages/Welcome/index.jsx
140
+ import React from 'react';
141
+ import styles from './Welcome.module.css';
142
+
143
+ /**
144
+ * Default landing page displayed after app initialisation.
145
+ * @returns {JSX.Element} Welcome screen with project name.
146
+ */
147
+ const Welcome = () => (
148
+ <div className={styles.container}>
149
+ <h1>{process.env.REACT_APP_PROJECT_NAME || '<project_name>'}</h1>
150
+ <p>Welcome. Your application is ready.</p>
151
+ </div>
152
+ );
153
+
154
+ export default Welcome;
155
+ ```
156
+
157
+ ---
158
+
159
+ ## App.jsx Standard
160
+
161
+ ```jsx
162
+ import { BrowserRouter, Routes, Route } from 'react-router-dom';
163
+ import Welcome from './pages/Welcome';
164
+
165
+ function App() {
166
+ return (
167
+ <BrowserRouter>
168
+ <Routes>
169
+ <Route path="/" element={<Welcome />} />
170
+ {/* Additional routes added as project grows */}
171
+ </Routes>
172
+ </BrowserRouter>
173
+ );
174
+ }
175
+
176
+ export default App;
177
+ ```
178
+
179
+ ---
180
+
181
+ ## @modularize Workflow
182
+
183
+ 1. Scan all pages in `src/pages/`
184
+ 2. Identify repeated layout blocks (header, footer, sidebar, nav)
185
+ 3. Show user: "Found repeated blocks in X pages. Extract to components?"
186
+ 4. For each block → create `src/components/<BlockName>/index.jsx` + `.module.css`
187
+ 5. Rewrite each page to import and use the component
188
+ 6. Never change the page's data-fetching logic or state — layout only
189
+
190
+ ---
191
+
192
+ ## @validate-page Workflow
193
+
194
+ 1. Ask: which page to add validation to
195
+ 2. Read the page file
196
+ 3. Ask: preferred validation library (validatorjs / Yup / custom)
197
+ 4. Add validation on form submit — check required fields, types, formats
198
+ 5. Display error messages per field below the input
199
+ 6. Never add validation that requires a backend call — client-side only
200
+
201
+ ---
202
+
203
+ ## @integrate-api Workflow
204
+
205
+ 1. Ask: which page to wire up
206
+ 2. Read the page file and `src/api/apiHandler.js`
207
+ 3. Identify buttons/forms in the page that need API calls
208
+ 4. Add the appropriate handler function in `apiHandler.js` if not present
209
+ 5. Wire form submit and button clicks to handler functions
210
+ 6. Add loading state (boolean), error state (string), success state
211
+ 7. Show loading spinner during API call, error message on failure, success feedback on completion
@@ -0,0 +1,111 @@
1
+ ---
2
+ slash_command: /codeninja:api
3
+ personas: [global-orchestrator, nodejs-backend]
4
+ skills: [mcp-and-context, api-builder]
5
+ description: Add a new API module (route.js + model.js) to an existing NodeJS service.
6
+ ---
7
+
8
+ # /codeninja:api
9
+
10
+ ## Before Running
11
+ 1. Call `context_check_stale`
12
+ 2. Call `context_read` — load `context.services` and `context.db.schema`
13
+ 3. Read 1–2 existing modules in the target service to understand current patterns
14
+
15
+ ## Execution — Full Step-by-Step
16
+
17
+ ### Phase 0 — Existing Pattern Review
18
+ Before asking any questions, read existing modules in `context.services[<service_name>].modules`
19
+ and scan 1–2 existing `route.js` and `_model.js` files from the service.
20
+
21
+ Identify:
22
+ - Naming conventions (camelCase vs PascalCase)
23
+ - Common validation patterns
24
+ - Auth patterns (all protected? mixed?)
25
+ - Response patterns beyond standard contract
26
+
27
+ Surface: "I've reviewed [n] existing modules. I'll follow the same structure." Then proceed.
28
+
29
+ ---
30
+
31
+ ### Phase 1 — Target Service
32
+
33
+ **Step 1.** Ask: "Which service?" (list from `context.services`)
34
+ - Store: `context.current_api.service_name`
35
+
36
+ **Step 2.** Ask: "API version?" (default: v1)
37
+ - Store: `context.current_api.version`
38
+
39
+ ---
40
+
41
+ ### Phase 2 — Module Identity
42
+
43
+ **Step 3.** Ask: "Module name?" (e.g. Products, Orders, Invoice)
44
+ - Store: `context.current_api.module_name`
45
+
46
+ **Step 4.** Ask: "HTTP method?" (GET / POST / PUT / PATCH / DELETE)
47
+ - Store: `context.current_api.method`
48
+
49
+ **Step 5.** Ask: "Route path?" (e.g. /products, /products/:id)
50
+ - Store: `context.current_api.route_path`
51
+
52
+ **Step 6.** Ask: "Route description?" (one sentence)
53
+ - Store: `context.current_api.description`
54
+
55
+ ---
56
+
57
+ ### Phase 3 — Database Binding
58
+
59
+ **Step 7.** Ask: "Which table does this route primarily use?"
60
+ - Show available tables from `context.db.schema.tables`
61
+ - Store: `context.current_api.primary_table`
62
+
63
+ **Step 8.** Ask: "Does this route require authentication?" (yes / no)
64
+ - Store: `context.current_api.requires_auth`
65
+
66
+ ---
67
+
68
+ ### Phase 4 — Confirm and Generate
69
+
70
+ **Step 9.** Confirm: "Generate [METHOD] [path] in [service]/modules/[version]/[Module]? (yes/no)"
71
+
72
+ **Step 10.** Delegate to nodejs-agent — generate ALL files simultaneously:
73
+
74
+ - `modules/<version>/<ModuleName>/route.js`
75
+ - Full validation schema using `validatorjs`
76
+ - All middleware applied in correct order
77
+ - Calls model function, returns via `sendResponse`
78
+ - JSDoc on every handler
79
+
80
+ - `modules/<version>/<ModuleName>/<module>_model.js`
81
+ - Parameterized queries only — no string concatenation
82
+ - References actual column names from `context.db.schema`
83
+ - Returns exactly `{ responsecode, responsemsg, responsedata }`
84
+ - No `res.json()` anywhere in this file
85
+
86
+ - Append to `modules/<version>/route_manager.js`
87
+ - Use `file_insert_after` MCP tool — NEVER rewrite this file
88
+ - Surgical insert of `router.use('/<path>', require('./<Module>/route'))` only
89
+ - Use `file_contains` first to avoid duplicate registration
90
+
91
+ - Patch `document/<version>/swagger_doc.json`
92
+ - Use `file_insert_after` MCP tool — NEVER rewrite this file
93
+ - Add new path key to the `paths` object only
94
+
95
+ ---
96
+
97
+ ### Phase 5 — Finalize
98
+
99
+ **Step 11.** Call `context_write`:
100
+ - Append to `context.api_routes`
101
+ - Update `context.services[<service>].modules`
102
+ - Set `last_command` = "create-api"
103
+ - Append to `change_log`
104
+
105
+ **Step 12.** Call `context_clear_scratchpad` with keys: ["current_api"]
106
+
107
+ **Step 13.** Show final summary:
108
+ - Files created/modified
109
+ - Route registered in route_manager
110
+ - Swagger patched
111
+ - Offer next steps: /codeninja:design, /codeninja:db:create
@@ -0,0 +1,81 @@
1
+ ---
2
+ slash_command: /codeninja:audit
3
+ personas: [global-orchestrator, nodejs-backend]
4
+ skills: [mcp-and-context, api-builder, code-intelligence]
5
+ description: Deep security and quality review of an existing NodeJS service.
6
+ ---
7
+
8
+ # /codeninja:audit
9
+
10
+ ## Before Running
11
+ 1. Call `context_read`
12
+ 2. Call `context_check_stale`
13
+
14
+ ## Execution — Full Step-by-Step
15
+
16
+ **Step 1.** Ask: "Which service to audit?" (list from `context.services`)
17
+
18
+ **Step 2.** Delegate to nodejs-agent. Run all checks:
19
+
20
+ ### Security Checks
21
+ - [ ] API key validation middleware on ALL routes?
22
+ - [ ] Input validation on all POST/PUT/PATCH routes?
23
+ - [ ] SQL injection prevention (parameterized queries only)?
24
+ - [ ] Sensitive values only from env vars (no hardcoded keys/passwords)?
25
+ - [ ] `.env` in `.gitignore`?
26
+ - [ ] Real AES-256-CBC encryption (not base64)?
27
+ - [ ] `utilities/encryption.js` is the ONLY file importing crypto-js or cryptlib?
28
+ - [ ] `res.json()` never called directly in route.js or model files?
29
+ - [ ] Validator package never imported directly in route files?
30
+ - [ ] SMTP credentials only in .env — never hardcoded in notification.js or template.js?
31
+ - [ ] Firebase service account file in `pem/` and in `.gitignore`?
32
+ - [ ] `GLOBALS` object frozen using `Object.freeze()`?
33
+
34
+ ### Code Quality Checks
35
+ - [ ] Only services called from controllers (no DB queries in controllers)?
36
+ - [ ] Models contain only DB queries and business logic?
37
+ - [ ] Global error handler present and used?
38
+ - [ ] All routes call `checkValidationRules` from `utilities/validator.js`?
39
+ - [ ] No separate `_validator.js` files per module?
40
+ - [ ] `rateLimiter` is FIRST middleware in `route_manager.js`?
41
+ - [ ] `extractLanguage` runs BEFORE `validateApiKey` in `route_manager.js`?
42
+ - [ ] `decryptRequest` is LAST middleware in the chain?
43
+ - [ ] No route handlers defined directly in `route_manager.js`?
44
+ - [ ] `asyncHandler` wraps every middleware in `route_manager.js`?
45
+ - [ ] All model functions return exactly `{ responsecode, responsemsg, responsedata }`?
46
+ - [ ] No `req/res` objects in any model file?
47
+ - [ ] Passwords encrypted via `utilities/encryption.js` before storage?
48
+ - [ ] Session tokens generated only via `common.generateSessionCode()`?
49
+
50
+ ### Consistency Checks
51
+ - [ ] All routes documented in `swagger_doc.json`?
52
+ - [ ] Response format consistent (success, message, data, timestamp)?
53
+ - [ ] snake_case for DB, camelCase for JS?
54
+ - [ ] Port matches `context.services[<n>].port`?
55
+ - [ ] DB config matches `context.db`?
56
+ - [ ] All message keywords in `sendResponse` calls exist in `languages/en.js`?
57
+ - [ ] All language files have the same keys as `en.js`?
58
+ - [ ] No two services share the same port in context.services?
59
+ - [ ] All encryption keys exactly 32 chars in context.services?
60
+ - [ ] All encryption IVs exactly 16 chars in context.services?
61
+
62
+ ### Context Alignment
63
+ - [ ] All routes present in `context.api_routes`?
64
+ - [ ] All DB tables referenced match `context.db.schema`?
65
+ - [ ] All `router.use()` lines in route_manager.js have a corresponding entry in context.services modules?
66
+ - [ ] All context.services modules have a corresponding `router.use()` in route_manager.js?
67
+ - [ ] All swagger_doc.json paths have a corresponding entry in context.api_routes?
68
+
69
+ **Step 3.** Present audit report:
70
+ ```
71
+ AUDIT REPORT — <service_name>
72
+ ══════════════════════════════════════
73
+ 🔴 CRITICAL (must fix)
74
+ 🟡 WARNING (should fix)
75
+ 🟢 INFO (nice to have)
76
+ ══════════════════════════════════════
77
+ [list findings with file + line context]
78
+ ```
79
+
80
+ **Step 4.** Ask: "Auto-fix critical issues? (yes/no)"
81
+ If yes → delegate to nodejs-agent for fixes → call `context_write` after.
@@ -0,0 +1,124 @@
1
+ ---
2
+ slash_command: /codeninja:db:create
3
+ personas: [global-orchestrator, database-architect]
4
+ skills: [mcp-and-context, database]
5
+ description: Design and generate a new database table with migration file.
6
+ ---
7
+
8
+ # /codeninja:db:create
9
+
10
+ ## Before Running
11
+ 1. Call `context_read` — load `context.db` fully
12
+ 2. Call `context_check_stale`
13
+ 3. Call `migration_next_number` MCP tool — get next sequential migration number
14
+
15
+ ## Execution — Full Step-by-Step
16
+
17
+ ### Phase 1 — Table Identity
18
+
19
+ **Step 1.** Ask: "What is this table for?" (free text — used by agent for suggestions)
20
+ - Store: `context.current_db.table_purpose`
21
+
22
+ **Step 2.** Ask: "Table name?" (must start with `tbl_`, snake_case, lowercase)
23
+ - Enforce prefix and casing
24
+ - Store: `context.current_db.table_name`
25
+
26
+ **Step 3.** Ask: "Migration file number?" (agent reads migrations/ and suggests next)
27
+ - Call `migration_next_number` to get suggestion
28
+ - Store: `context.current_db.file_number`
29
+
30
+ ---
31
+
32
+ ### Phase 2 — Standard Columns Decision
33
+
34
+ **Step 4.** Ask: "Does this table need `status` and `is_deleted` columns?"
35
+ - Suggest YES for user/entity tables, NO for event/log tables
36
+ - Store: `context.current_db.needs_status`
37
+
38
+ **Step 5.** Ask: "Does this table support soft delete (`is_deleted`)?"
39
+ - Auto-suggest YES if needs_status is YES
40
+ - Store: `context.current_db.needs_soft_delete`
41
+
42
+ ---
43
+
44
+ ### Phase 3 — Column Collection (repeat until done)
45
+
46
+ **Step 6.** Ask: "Enter next column name (or type 'done' to finish):"
47
+ - Show columns collected so far
48
+ - Enforce: snake_case, lowercase
49
+ - Append to: `context.current_db.columns[]`
50
+
51
+ **Step 7.** Ask: "Column type?" — show type suggestion based on name pattern:
52
+ - `*_id` → BIGINT NOT NULL DEFAULT 0 (also check for FK — ask if foreign key)
53
+ - `is_*` → BOOLEAN NOT NULL DEFAULT FALSE
54
+ - `*_at` → TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
55
+ - `status` → INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0,1))
56
+ - `*_count` → BIGINT NOT NULL DEFAULT 0
57
+ - `*_price`, `*_amount` → NUMERIC(18,8) NOT NULL DEFAULT 0.00000000
58
+ - `email` → VARCHAR(132) NOT NULL DEFAULT ''
59
+ - `phone` → VARCHAR(16) NOT NULL DEFAULT ''
60
+ - `password` → TEXT NOT NULL DEFAULT ''
61
+ - `*_image`, `*_url` → VARCHAR(255) NOT NULL DEFAULT ''
62
+ - `payload`, `metadata`, `*_result` → JSON NOT NULL DEFAULT '{}'
63
+ - default → VARCHAR(255) NOT NULL DEFAULT ''
64
+
65
+ **Step 8.** Ask: "Does this column have a fixed set of allowed values? (enum-like)"
66
+ - If yes → ask for the allowed values and generate a CHECK constraint + COMMENT
67
+
68
+ **Step 9.** Return to Step 6 until user types 'done'
69
+
70
+ ---
71
+
72
+ ### Phase 4 — Index Decision
73
+
74
+ **Step 10.** Agent auto-suggests indexes based on collected columns:
75
+ - Every `*_id` (FK) column → suggest index
76
+ - `status + is_deleted` compound → suggest if both exist
77
+ - `created_at DESC` → suggest for event/log tables
78
+ Ask user to confirm suggested indexes or add custom ones.
79
+
80
+ ---
81
+
82
+ ### Phase 5 — Seed Data
83
+
84
+ **Step 11.** Ask: "Does this table need initial/seed data?"
85
+ - Guide: suggest YES only for reference/master data tables
86
+ - If yes → collect row values column by column, repeat per row
87
+ - Store: `context.current_db.seed_rows[]`
88
+
89
+ ---
90
+
91
+ ### Phase 6 — Summary and Generate
92
+
93
+ **Step 12.** Show complete table definition:
94
+ - Table name, file number, all columns with types, indexes, seed rows
95
+ - Ask: "Generate this table? (yes / no / change a value)"
96
+ - If change → re-run specific step → return to summary
97
+ - If no → abort
98
+ - If yes → proceed
99
+
100
+ **Step 13.** Delegate to database-agent:
101
+ - Generate: `<repo_root>/database/<db_type>/migrations/<number>-setup-tbl-<n>.sql`
102
+ - File header comment
103
+ - `BEGIN;`
104
+ - Standard system columns: `id BIGSERIAL PRIMARY KEY`
105
+ - All collected columns in order
106
+ - `status INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0,1))` if needs_status
107
+ - `is_deleted BOOLEAN NOT NULL DEFAULT FALSE` if needs_soft_delete
108
+ - `created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP`
109
+ - All CHECK constraints and COMMENTs for enum columns
110
+ - All per-table CREATE INDEX statements
111
+ - GRANT SELECT, INSERT, UPDATE, DELETE to `<db_user>`
112
+ - Seed data INSERT if collected
113
+ - `COMMIT;`
114
+ - Update: `<repo_root>/database/<db_type>/create-schema.sql` (add `\i` entry in order)
115
+ - If any indexes belong in shared file → update `111-setup-database-indexes.sql`
116
+
117
+ **Step 14.** Call `context_write`:
118
+ - Append table to `context.db.schema.tables`
119
+ - Append to `context.db.schema.change_log`
120
+ - Clear `context.current_db`
121
+
122
+ **Step 15.** Call `context_clear_scratchpad` with keys: ["current_db"]
123
+
124
+ **Step 16.** Show final summary with file path and next steps.
@@ -0,0 +1,87 @@
1
+ ---
2
+ slash_command: /codeninja:db:drop
3
+ personas: [global-orchestrator, database-architect]
4
+ skills: [mcp-and-context, database]
5
+ description: Generate a DROP TABLE migration. Never deletes the original setup file.
6
+ ---
7
+
8
+ # /codeninja:db:drop
9
+
10
+ ## Before Running
11
+ 1. Call `context_read` — load `context.db.schema`
12
+ 2. Call `context_check_stale`
13
+
14
+ ## Execution — Full Step-by-Step
15
+
16
+ ### Phase 1 — Target
17
+
18
+ **Step 1.** Ask: "Which table to drop?" (list from `context.db.schema.tables`)
19
+ - Store: `context.current_db.table_name`
20
+
21
+ ---
22
+
23
+ ### Phase 2 — Impact Analysis
24
+
25
+ **Step 2.** Agent scans context:
26
+ - Check `context.api_routes` for routes referencing this table as `primary_table`
27
+ - Check `context.services` for modules using this table
28
+ - Check `context.db.schema.tables` for FK columns pointing to this table
29
+
30
+ **Step 3.** If references found, display warning:
31
+ ```
32
+ ⚠ WARNING: This table is referenced by:
33
+ - [service]/modules/[Module] (primary_table)
34
+ - tbl_<other_table>.<col> → <this_table> (FK dependency)
35
+
36
+ Dropping this table will break these references.
37
+ Make sure to update or remove dependent code first.
38
+ ```
39
+ Ask: "Do you still want to proceed? (yes / no)"
40
+ If no → abort.
41
+
42
+ **Step 4.** Final confirmation:
43
+ Ask: "Type the table name to confirm the drop."
44
+ Must match exactly — if wrong → abort.
45
+
46
+ ---
47
+
48
+ ### Phase 3 — File Numbering
49
+
50
+ **Step 5.** Ask: "Migration file number?" (suggest next available)
51
+ - Store: `context.current_db.file_number`
52
+
53
+ ---
54
+
55
+ ### Phase 4 — Generate
56
+
57
+ **Step 6.** Delegate to database-agent:
58
+ Generate: `<repo_root>/database/<db_type>/migrations/<number>-drop-tbl-<n>.sql`
59
+
60
+ ```sql
61
+ -- Drop tbl_<table_name>
62
+ -- Migration: <number>-drop-tbl-<n>.sql
63
+ -- Generated: <ISO date>
64
+ -- WARNING: This migration is irreversible in production.
65
+ -- Original table definition: <original_setup_file>
66
+
67
+ BEGIN;
68
+
69
+ DROP TABLE IF EXISTS public.<table_name> CASCADE;
70
+
71
+ COMMIT;
72
+ ```
73
+
74
+ Update `create-schema.sql`:
75
+ - Keep the original `\i <setup_file>` entry
76
+ - Add the drop file entry AFTER it (never remove original)
77
+
78
+ **Step 7.** Call `context_write`:
79
+ - Snapshot full column list before removing from active tables
80
+ - Append to `context.db.schema.change_log`:
81
+ `{ type: "table_dropped", table: "<n>", snapshot: { full column list }, file: "<path>" }`
82
+ - Remove table from `context.db.schema.tables`
83
+ - Clear `context.current_db`
84
+
85
+ **Step 8.** Call `context_clear_scratchpad` with keys: ["current_db"]
86
+
87
+ **Step 9.** Show final summary.
@@ -0,0 +1,70 @@
1
+ ---
2
+ slash_command: /codeninja:db:index
3
+ personas: [global-orchestrator, database-architect]
4
+ skills: [mcp-and-context, database]
5
+ description: Add a new index to an existing table.
6
+ ---
7
+
8
+ # /codeninja:db:index
9
+
10
+ ## Before Running
11
+ 1. Call `context_read` — load `context.db.schema`
12
+ 2. Call `context_check_stale`
13
+
14
+ ## Execution — Full Step-by-Step
15
+
16
+ ### Phase 1 — Target Table
17
+
18
+ **Step 1.** Ask: "Which table?" (list from `context.db.schema.tables`)
19
+ - Store: `context.current_db.table_name`
20
+
21
+ ### Phase 2 — Index Columns
22
+
23
+ **Step 2.** Ask: "Which column(s) for this index?"
24
+ - List available columns from `context.db.schema.tables[<table>].columns`
25
+ - Allow one or multiple (compound index)
26
+ - Store: `context.current_db.index_columns[]`
27
+
28
+ **Step 3.** Ask: "Should any column be sorted DESC?" (common: `created_at DESC`, `time DESC`)
29
+ - If yes → ask which column(s)
30
+ - Store: `context.current_db.index_desc_columns[]`
31
+
32
+ **Step 4.** Ask: "Standard or partial index?"
33
+ - Standard: covers all rows
34
+ - Partial: only rows matching a WHERE condition — if partial, ask for WHERE clause
35
+ - Store: `context.current_db.index_where_clause`
36
+
37
+ ### Phase 3 — File Placement
38
+
39
+ **Step 5.** Ask: "Where should this index be defined?"
40
+ 1. In the table's own setup file (for new/just-created tables)
41
+ 2. In `111-setup-database-indexes.sql` (for existing tables — auto-suggested)
42
+ - Store: `context.current_db.index_file`
43
+
44
+ ### Phase 4 — Generate
45
+
46
+ **Step 6.** Agent auto-generates index name:
47
+ - In table file: `idx_<table_without_tbl_prefix>_<columns_joined>`
48
+ - In shared file: `idx_tbl_<table_without_tbl_prefix>_<columns_joined>`
49
+ - Show: "Index will be named: <name> — OK? (yes / rename)"
50
+
51
+ **Step 7.** Confirm: "Generate this index? (yes / no)"
52
+
53
+ **Step 8.** Delegate to database-agent:
54
+ ```sql
55
+ --
56
+ -- Name: <index_name>; Type: INDEX; Schema: public
57
+ --
58
+ CREATE INDEX <index_name> ON public.<table_name> (<col> [DESC], ...)
59
+ [WHERE <where_clause>];
60
+ ```
61
+ Append to correct file (table setup file OR `111-setup-database-indexes.sql`).
62
+
63
+ **Step 9.** Call `context_write`:
64
+ - Append index to `context.db.schema.tables[<table>].indexes`
65
+ - Append to `context.db.schema.change_log`
66
+ - Clear `context.current_db`
67
+
68
+ **Step 10.** Call `context_clear_scratchpad` with keys: ["current_db"]
69
+
70
+ **Step 11.** Show final summary.