codeninja 2.0.0 → 3.1.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/README.md +122 -251
- package/agent/global-agent.md +8 -0
- package/cli.js +248 -223
- package/commands/debug.workflow.md +94 -0
- package/commands/explain.workflow.md +59 -0
- package/commands/optimize.workflow.md +124 -0
- package/commands/review.workflow.md +85 -0
- package/ide/antigravity/.agents/personas/database-architect.md +249 -0
- package/ide/antigravity/.agents/personas/global-orchestrator.md +125 -0
- package/ide/antigravity/.agents/personas/nodejs-backend.md +250 -0
- package/ide/antigravity/.agents/personas/reactjs-frontend.md +179 -0
- package/ide/antigravity/.agents/skills/api-builder/SKILL.md +179 -0
- package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +184 -0
- package/ide/antigravity/.agents/skills/database/SKILL.md +165 -0
- package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +111 -0
- package/ide/antigravity/.agents/skills/reactjs/SKILL.md +211 -0
- package/ide/antigravity/.agents/workflows/codeninja-api.md +28 -0
- package/ide/antigravity/.agents/workflows/codeninja-audit.md +23 -0
- package/ide/antigravity/.agents/workflows/codeninja-db-create.md +11 -0
- package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +11 -0
- package/ide/antigravity/.agents/workflows/codeninja-db-index.md +11 -0
- package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +11 -0
- package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +10 -0
- package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +12 -0
- package/ide/antigravity/.agents/workflows/codeninja-debug.md +12 -0
- package/ide/antigravity/.agents/workflows/codeninja-design.md +21 -0
- package/ide/antigravity/.agents/workflows/codeninja-explain.md +11 -0
- package/ide/antigravity/.agents/workflows/codeninja-init.md +29 -0
- package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +11 -0
- package/ide/antigravity/.agents/workflows/codeninja-modularize.md +11 -0
- package/ide/antigravity/.agents/workflows/codeninja-optimize.md +13 -0
- package/ide/antigravity/.agents/workflows/codeninja-refactor.md +23 -0
- package/ide/antigravity/.agents/workflows/codeninja-review.md +12 -0
- package/ide/antigravity/.agents/workflows/codeninja-sync.md +23 -0
- package/ide/antigravity/.agents/workflows/codeninja-test.md +19 -0
- package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +11 -0
- package/ide/cursor/.cursor/mcp.json +8 -0
- package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +60 -0
- package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +38 -0
- package/ide/cursor/.cursor/rules/03-api-builder.mdc +74 -0
- package/ide/cursor/.cursor/rules/04-database.mdc +87 -0
- package/ide/cursor/.cursor/rules/05-reactjs.mdc +83 -0
- package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +112 -0
- package/ide/vscode/.github/copilot-instructions.md +285 -0
- package/ide/vscode/.vscode/mcp.json +9 -0
- package/package.json +24 -23
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: api-builder
|
|
3
|
+
scope: nodejs-commands
|
|
4
|
+
loaded-for:
|
|
5
|
+
- /codeninja:api
|
|
6
|
+
- /codeninja:init (nodejs type)
|
|
7
|
+
- /codeninja:audit
|
|
8
|
+
- /codeninja:test
|
|
9
|
+
- /codeninja:refactor
|
|
10
|
+
- /codeninja:sync
|
|
11
|
+
description: >
|
|
12
|
+
All technical standards for Node.js/Express API development. Defines the
|
|
13
|
+
2-layer architecture, 5-step SOP, response contract, middleware chain order,
|
|
14
|
+
localizify rules, code style, and file generation standards.
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Skill: API Builder
|
|
18
|
+
|
|
19
|
+
Technical standards for every NodeJS Express endpoint in this project.
|
|
20
|
+
These rules apply to every file generated by the nodejs-backend persona.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## The 2-Layer Architecture (enforced without exception)
|
|
25
|
+
|
|
26
|
+
Every API module lives in `modules/<version>/<ModuleName>/`:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
modules/v1/<ModuleName>/
|
|
30
|
+
├── route.js ← HTTP layer ONLY
|
|
31
|
+
└── <module>_model.js ← DB layer ONLY
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**`route.js` responsibilities:**
|
|
35
|
+
- Import and apply middleware
|
|
36
|
+
- Define validatorjs schema
|
|
37
|
+
- Call model function
|
|
38
|
+
- Format and send `res.json()` response
|
|
39
|
+
- Handle error boundary (try/catch)
|
|
40
|
+
|
|
41
|
+
**`<module>_model.js` responsibilities:**
|
|
42
|
+
- Execute parameterized SQL queries via shared pg pool
|
|
43
|
+
- Implement business logic
|
|
44
|
+
- Return raw data objects — never `res.json()`
|
|
45
|
+
- Never import Express or touch the response object
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 5-Step SOP for Every New Endpoint
|
|
50
|
+
|
|
51
|
+
Execute in this exact order — no skipping:
|
|
52
|
+
|
|
53
|
+
1. **ROUTING** — append to `modules/<version>/route_manager.js`
|
|
54
|
+
- Never rewrite this file — surgical append only
|
|
55
|
+
- Use `file_insert_after` MCP tool
|
|
56
|
+
|
|
57
|
+
2. **VALIDATION** — validatorjs schema in `route.js`
|
|
58
|
+
- Reference existing patterns in the service
|
|
59
|
+
- Never invent validation rules — match what already exists
|
|
60
|
+
|
|
61
|
+
3. **CONTROLLER** — model call + error boundary in `route.js`
|
|
62
|
+
- Single try/catch wrapping the model call
|
|
63
|
+
- Call `sendResponse` from `utilities/response.js`
|
|
64
|
+
|
|
65
|
+
4. **MODEL** — parameterized query in `<module>_model.js`
|
|
66
|
+
- pg pool from `config/database.js`
|
|
67
|
+
- Parameterized queries only — `$1`, `$2` placeholders
|
|
68
|
+
- Never string concatenation in SQL
|
|
69
|
+
|
|
70
|
+
5. **LOCALIZE** — strings in `languages/en.js`
|
|
71
|
+
- Never hardcode user-facing strings in route.js or model.js
|
|
72
|
+
- Use `file_contains` to check if key already exists before adding
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Middleware Chain Order (always this order — never change)
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
Language extraction (headerValidator.js)
|
|
80
|
+
→ API key validation (headerValidator.js)
|
|
81
|
+
→ JWT authentication (headerValidator.js — protected routes only)
|
|
82
|
+
→ Rate limiting (rateLimiter.js)
|
|
83
|
+
→ Input validation (inline in route.js)
|
|
84
|
+
→ Route handler
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Response Contract
|
|
90
|
+
|
|
91
|
+
All endpoints return the same shape:
|
|
92
|
+
```javascript
|
|
93
|
+
// Success
|
|
94
|
+
{ status: 1, message: lang.success_key, data: result }
|
|
95
|
+
|
|
96
|
+
// Error
|
|
97
|
+
{ status: 0, message: lang.error_key }
|
|
98
|
+
|
|
99
|
+
// Auth / session expired (triggers frontend logout)
|
|
100
|
+
{ status: -1, message: lang.session_expired }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Use `sendResponse(req, res, status, message, data)` from `utilities/response.js`.
|
|
104
|
+
Never call `res.json()` directly — always use `sendResponse`.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Localizify Rules
|
|
109
|
+
|
|
110
|
+
- `headerValidator.js` and `response.js` are the ONLY files that may import localizify or call `t()`
|
|
111
|
+
- All other files use `sendResponse()`, `getMessage()`, or `req.t("keyword")`
|
|
112
|
+
- Never call `setLocale` from model files — race condition under concurrent requests
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Swagger Maintenance Rules
|
|
117
|
+
|
|
118
|
+
- `document/v1/swagger_doc.json` is patched — never fully rewritten
|
|
119
|
+
- When adding a new endpoint: add only the new path key to `paths` object
|
|
120
|
+
- Use `file_insert_after` MCP tool for surgical patch
|
|
121
|
+
- Always update the `info.version` timestamp when patching
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## route_manager.js Maintenance Rules
|
|
126
|
+
|
|
127
|
+
- Append-only — never rewrite the entire file
|
|
128
|
+
- New module import goes at top of imports section
|
|
129
|
+
- New router.use() goes at end of routes section
|
|
130
|
+
- Use `file_insert_after` MCP tool
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Testing Standards (Jest + Supertest)
|
|
135
|
+
|
|
136
|
+
Test file location: `tests/v1/<ModuleName>.test.js`
|
|
137
|
+
|
|
138
|
+
Structure:
|
|
139
|
+
```javascript
|
|
140
|
+
describe('<ModuleName> API', () => {
|
|
141
|
+
describe('POST /<path>', () => {
|
|
142
|
+
it('should return 200 with valid payload', async () => { ... })
|
|
143
|
+
it('should return 400 with missing required field', async () => { ... })
|
|
144
|
+
it('should return 401 with invalid api-key', async () => { ... })
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- Test the happy path first, then each validation failure
|
|
150
|
+
- Test missing required fields, wrong types, out-of-range values
|
|
151
|
+
- Test auth failure separately
|
|
152
|
+
- Never test implementation details — test behavior via HTTP
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## JSDoc Standards (enforced on every function)
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
/**
|
|
160
|
+
* One-sentence description. Active voice. Present tense.
|
|
161
|
+
*
|
|
162
|
+
* @param {type} name - Description of what it expects.
|
|
163
|
+
* @returns {Promise<Object>} Description of what it returns.
|
|
164
|
+
*/
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Special cases:
|
|
168
|
+
- Middleware: `@middleware` tag, no `@returns`
|
|
169
|
+
- Async: `@returns {Promise<T>}`
|
|
170
|
+
- Optional: `@param {string} [lang='en'] - Language code`
|
|
171
|
+
|
|
172
|
+
Route-level comment (above route definition, not JSDoc):
|
|
173
|
+
```javascript
|
|
174
|
+
// POST /login — Authenticates user credentials and returns a session token.
|
|
175
|
+
router.post('/login', async (req, res) => {
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
No inline `//` comments inside function bodies.
|
|
179
|
+
No file-level headers at top of files.
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: code-intelligence
|
|
3
|
+
scope: analysis-commands
|
|
4
|
+
loaded-for:
|
|
5
|
+
- /codeninja:explain
|
|
6
|
+
- /codeninja:review
|
|
7
|
+
- /codeninja:debug
|
|
8
|
+
- /codeninja:optimize
|
|
9
|
+
- /codeninja:audit
|
|
10
|
+
description: >
|
|
11
|
+
Analysis and intelligence standards for explain, review, debug, optimize,
|
|
12
|
+
and audit commands. Defines how to read code with full project context,
|
|
13
|
+
how to report findings, and how to produce concrete fixes.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Skill: Code Intelligence
|
|
17
|
+
|
|
18
|
+
Standards for all analysis commands. Every finding is grounded in actual
|
|
19
|
+
project files and real context values — never generic advice.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Before Any Analysis
|
|
24
|
+
|
|
25
|
+
1. Call `context_read` — load full context (services, DB schema, project info)
|
|
26
|
+
2. Call `fs_read` on the target file(s)
|
|
27
|
+
3. Read 1–2 sibling files to understand the expected pattern in this project
|
|
28
|
+
4. Reference real table names, column names, and service names from context — never placeholders
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## /codeninja:explain — Response Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
What it is (1–2 sentences, plain English)
|
|
36
|
+
How it works (step-by-step key logic — not boilerplate)
|
|
37
|
+
Why this way (architectural reason specific to this project)
|
|
38
|
+
Where it connects (related files, functions, context entries)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Rules:
|
|
42
|
+
- Use real file names, real column names, real service names from context
|
|
43
|
+
- Explain the "why" — the decision behind the pattern, not just what it does
|
|
44
|
+
- Reference `context.project_info` to tie the explanation to the project's domain
|
|
45
|
+
- End with: "Want me to explain any part in more detail, or show how to modify it?"
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## /codeninja:review — Checklist and Output Format
|
|
50
|
+
|
|
51
|
+
### Security (CRITICAL if failing)
|
|
52
|
+
- [ ] All POST/PUT/PATCH routes have validatorjs input validation
|
|
53
|
+
- [ ] API key middleware applied before any route logic
|
|
54
|
+
- [ ] JWT auth middleware on protected routes
|
|
55
|
+
- [ ] No hardcoded secrets, keys, or passwords in any file
|
|
56
|
+
- [ ] Parameterized queries only — no string concatenation in SQL
|
|
57
|
+
- [ ] Error responses don't leak stack traces or internal details
|
|
58
|
+
|
|
59
|
+
### Architecture (WARNING if failing)
|
|
60
|
+
- [ ] 2-layer rule: no SQL in route.js, no res.json() in _model.js
|
|
61
|
+
- [ ] route_manager.js registration matches the route file
|
|
62
|
+
- [ ] swagger_doc.json has entry for this endpoint
|
|
63
|
+
- [ ] All user-facing strings in languages/en.js — none hardcoded in route.js
|
|
64
|
+
|
|
65
|
+
### Code Quality (SUGGESTION if failing)
|
|
66
|
+
- [ ] JSDoc on every exported function
|
|
67
|
+
- [ ] No unused variables or dead imports
|
|
68
|
+
- [ ] No console.log — project logger used
|
|
69
|
+
- [ ] Async functions have try/catch
|
|
70
|
+
- [ ] No SELECT * — explicit column list
|
|
71
|
+
|
|
72
|
+
### Database (WARNING if failing)
|
|
73
|
+
- [ ] Column names match context.db.schema exactly (snake_case)
|
|
74
|
+
- [ ] Foreign key columns indexed in context.db.schema
|
|
75
|
+
- [ ] Transactions used where multiple writes happen together
|
|
76
|
+
- [ ] LIMIT on any unbounded query
|
|
77
|
+
|
|
78
|
+
### Output format per finding:
|
|
79
|
+
```
|
|
80
|
+
[CRITICAL | WARNING | SUGGESTION]
|
|
81
|
+
File: path/to/file.js (~line N)
|
|
82
|
+
Issue: one-line description
|
|
83
|
+
Before: current code
|
|
84
|
+
After: corrected code
|
|
85
|
+
Why: one sentence
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
End: `Review complete: X critical · Y warnings · Z suggestions`
|
|
89
|
+
Offer to apply each fix — confirm before writing.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## /codeninja:debug — Diagnosis Process
|
|
94
|
+
|
|
95
|
+
### Information to gather (one at a time if missing)
|
|
96
|
+
1. Full error message + stack trace
|
|
97
|
+
2. Which endpoint or operation triggered it
|
|
98
|
+
3. Expected vs actual behaviour
|
|
99
|
+
4. Recent changes before the error appeared
|
|
100
|
+
|
|
101
|
+
### Request lifecycle trace
|
|
102
|
+
```
|
|
103
|
+
Request received
|
|
104
|
+
→ Language middleware
|
|
105
|
+
→ API key middleware
|
|
106
|
+
→ Auth middleware (if protected)
|
|
107
|
+
→ Validation (validatorjs)
|
|
108
|
+
→ Route handler
|
|
109
|
+
→ Model function
|
|
110
|
+
→ Database (pg pool)
|
|
111
|
+
→ Response formatter
|
|
112
|
+
```
|
|
113
|
+
Mark the exact step where the failure occurs.
|
|
114
|
+
|
|
115
|
+
### Common root causes
|
|
116
|
+
| Symptom | Check |
|
|
117
|
+
|---------|-------|
|
|
118
|
+
| `column does not exist` | context.db.schema vs code column names |
|
|
119
|
+
| `undefined is not a function` | wrong import or missing export |
|
|
120
|
+
| `Cannot read property of undefined` | missing null check after 0-row query |
|
|
121
|
+
| `401 Unauthorized` | middleware order, header name spelling |
|
|
122
|
+
| `500 Internal Server Error` | missing try/catch on async DB call |
|
|
123
|
+
| Wrong row count | missing dedup, RANK vs DENSE_RANK, missing WHERE |
|
|
124
|
+
| Migration not applied | table in code but not in DB — run migration |
|
|
125
|
+
| Stale context | context.db.schema outdated — suggest /codeninja:db:sync |
|
|
126
|
+
|
|
127
|
+
### Fix output format:
|
|
128
|
+
```
|
|
129
|
+
Root cause: [one sentence — be precise]
|
|
130
|
+
|
|
131
|
+
File: path/to/file.js
|
|
132
|
+
Before: [buggy code]
|
|
133
|
+
After: [corrected code]
|
|
134
|
+
Why: [one sentence]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Confirm with user before applying. After fix: suggest one guard to prevent recurrence.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## /codeninja:optimize — Analysis Framework
|
|
142
|
+
|
|
143
|
+
### DB query analysis (check all)
|
|
144
|
+
1. **Missing indexes** — compare WHERE/JOIN/ORDER BY cols vs `context.db.schema.<table>.indexes`
|
|
145
|
+
2. **SELECT *** — suggest explicit column list
|
|
146
|
+
3. **N+1** — loop calling DB per iteration → suggest JOIN or IN clause
|
|
147
|
+
4. **No LIMIT** — unbounded queries must have pagination
|
|
148
|
+
5. **RANK() vs DENSE_RANK()** — flag RANK() on leaderboard queries (gaps after ties)
|
|
149
|
+
6. **DATE() in WHERE** — `DATE(col) = '...'` prevents index use → use range filter
|
|
150
|
+
7. **Duplicate rows** — missing dedup → `MIN(id) GROUP BY`
|
|
151
|
+
8. **Sort spilling to disk** — EXPLAIN shows "external merge Disk" → suggest `work_mem = '64MB'`
|
|
152
|
+
|
|
153
|
+
### API route analysis
|
|
154
|
+
- Repeated DB calls that could be Redis-cached
|
|
155
|
+
- Synchronous blocking in request path
|
|
156
|
+
- Large response payloads without pagination
|
|
157
|
+
|
|
158
|
+
### Output format per recommendation:
|
|
159
|
+
```
|
|
160
|
+
[HIGH | MED | LOW]
|
|
161
|
+
Target: what is slow
|
|
162
|
+
Cause: why it is slow
|
|
163
|
+
Fix: exact SQL or code change
|
|
164
|
+
Gain: concrete estimate (e.g. "seq scan → index scan, ~400x on 2M rows")
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
List highest impact first.
|
|
168
|
+
For index additions: generate `<N>-add-index-<desc>.sql` migration file via `migration_next_number`.
|
|
169
|
+
Always call `context_write` after applying index changes.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## /codeninja:audit — Full Service Audit
|
|
174
|
+
|
|
175
|
+
Runs the full review checklist above PLUS:
|
|
176
|
+
- Middleware chain order (use `analyze_middleware_order` MCP tool)
|
|
177
|
+
- Encryption library consistency (use `analyze_encryption_library` MCP tool)
|
|
178
|
+
- Language key completeness (use `analyze_language_keys` MCP tool)
|
|
179
|
+
- Dependency health (use `analyze_dependencies` MCP tool)
|
|
180
|
+
- .env completeness (use `analyze_env_file` MCP tool)
|
|
181
|
+
- context.db.schema alignment with actual code table/column references
|
|
182
|
+
|
|
183
|
+
Output: severity-ranked report grouped by category.
|
|
184
|
+
Offer to auto-fix SUGGESTION items. Fix WARNING/CRITICAL one at a time with confirmation.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: database
|
|
3
|
+
scope: database-commands
|
|
4
|
+
loaded-for:
|
|
5
|
+
- /codeninja:db:create
|
|
6
|
+
- /codeninja:db:modify
|
|
7
|
+
- /codeninja:db:index
|
|
8
|
+
- /codeninja:db:drop
|
|
9
|
+
- /codeninja:db:seed
|
|
10
|
+
- /codeninja:db:sync
|
|
11
|
+
- /codeninja:init (database type)
|
|
12
|
+
- /codeninja:optimize (DB queries)
|
|
13
|
+
description: >
|
|
14
|
+
All database standards: naming conventions, migration file rules, index
|
|
15
|
+
strategy, column rules, SQL content order, create-schema.sql maintenance,
|
|
16
|
+
and seed data rules. The database-architect persona uses this skill for
|
|
17
|
+
every SQL file it generates.
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# Skill: Database
|
|
21
|
+
|
|
22
|
+
Technical standards for every SQL file and migration in this project.
|
|
23
|
+
Apply without exception.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Before Generating Any File
|
|
28
|
+
|
|
29
|
+
1. Call `context_read` — load `context.db` fully
|
|
30
|
+
2. Call `context.project_info` — use entities/features to suggest columns
|
|
31
|
+
3. Call `migration_next_number` MCP tool — get the next sequential number
|
|
32
|
+
4. NEVER invent table or column names
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Naming Quick Reference
|
|
37
|
+
|
|
38
|
+
| Element | Rule | Example |
|
|
39
|
+
|---------|------|---------|
|
|
40
|
+
| Table | `tbl_` prefix, lowercase, plural | `tbl_users` |
|
|
41
|
+
| Column | lowercase snake_case | `user_id`, `created_at` |
|
|
42
|
+
| PK | `id`, bigint identity, first column | always |
|
|
43
|
+
| FK | `<table_singular_no_prefix>_id` | `user_id` refs `tbl_users` |
|
|
44
|
+
| Index (per-table) | `idx_<table_no_prefix>_<cols>` | `idx_users_email` |
|
|
45
|
+
| Index (global) | `idx_tbl_<table>_<cols>` | `idx_tbl_users_email_is_deleted` |
|
|
46
|
+
| Migration (create) | `<N>-setup-tbl-<name>.sql` | `3-setup-tbl-users.sql` |
|
|
47
|
+
| Migration (alter) | `<N>-alter-tbl-<name>-<desc>.sql` | `12-alter-tbl-users-add-kyc.sql` |
|
|
48
|
+
| Migration (drop) | `<N>-drop-tbl-<name>.sql` | `13-drop-tbl-sessions.sql` |
|
|
49
|
+
| Shared indexes | `111-setup-database-indexes.sql` | always last, always 111 |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Column Type Reference
|
|
54
|
+
|
|
55
|
+
| Use Case | PostgreSQL Type |
|
|
56
|
+
|----------|----------------|
|
|
57
|
+
| Primary key | `bigint NOT NULL GENERATED ALWAYS AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1)` |
|
|
58
|
+
| Foreign key | `BIGINT NOT NULL DEFAULT 0` |
|
|
59
|
+
| Names, labels | `VARCHAR(64)` to `VARCHAR(255)` |
|
|
60
|
+
| Short codes, symbols | `VARCHAR(8)` to `VARCHAR(32)` |
|
|
61
|
+
| Emails | `VARCHAR(132)` |
|
|
62
|
+
| Tokens, passwords | `TEXT` |
|
|
63
|
+
| URLs, paths | `VARCHAR(255)` |
|
|
64
|
+
| Timestamps | `TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP` |
|
|
65
|
+
| Status/flag | `INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0, 1))` |
|
|
66
|
+
| Soft delete | `BOOLEAN NOT NULL DEFAULT FALSE` |
|
|
67
|
+
| Price/financial | `NUMERIC(18,8) NOT NULL DEFAULT 0.00000000` |
|
|
68
|
+
| Percentage | `NUMERIC(6,2) NOT NULL DEFAULT 0.00` |
|
|
69
|
+
| Count/integer | `BIGINT NOT NULL DEFAULT 0` |
|
|
70
|
+
| JSON data | `JSON NOT NULL DEFAULT '{}'` |
|
|
71
|
+
|
|
72
|
+
**NEVER use PostgreSQL ENUM** — always `VARCHAR + CHECK constraint`.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Required Columns by Table Type
|
|
77
|
+
|
|
78
|
+
| Column | Every table | Entity tables | Log/event tables |
|
|
79
|
+
|--------|------------|---------------|-----------------|
|
|
80
|
+
| `id` | ✓ | ✓ | ✓ |
|
|
81
|
+
| `created_at` | ✓ | ✓ | ✓ |
|
|
82
|
+
| `status` | — | ✓ | — |
|
|
83
|
+
| `is_deleted` | — | ✓ (soft delete) | — |
|
|
84
|
+
| `updated_at` | — | ✓ (tracked edits) | — |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## SQL File Content Order (STRICT)
|
|
89
|
+
|
|
90
|
+
```sql
|
|
91
|
+
-- 1. Comment: Creating <table> for <purpose>
|
|
92
|
+
-- 2. DROP TABLE IF EXISTS public.<table> CASCADE;
|
|
93
|
+
-- 3. CREATE TABLE block (id first, timestamps last)
|
|
94
|
+
-- 4. COMMENT ON COLUMN for every enum/flag column
|
|
95
|
+
-- 5. Per-table CREATE INDEX statements
|
|
96
|
+
-- 6. ALTER TABLE public.<table> OWNER TO <db_user>;
|
|
97
|
+
-- 7. GRANT ALL ON TABLE public.<table> TO <db_user>;
|
|
98
|
+
-- 8. INSERT seed data (reference tables only)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Primary Key Block (exact format)
|
|
104
|
+
|
|
105
|
+
```sql
|
|
106
|
+
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1),
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Primary key constraint at END of column list:
|
|
110
|
+
```sql
|
|
111
|
+
PRIMARY KEY (id)
|
|
112
|
+
```
|
|
113
|
+
Never declare `PRIMARY KEY` inline on the `id` column.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Index Strategy
|
|
118
|
+
|
|
119
|
+
Always index:
|
|
120
|
+
- Every FK column (`user_id`, `bot_id`, etc.)
|
|
121
|
+
- `(status, is_deleted)` compound on entity tables
|
|
122
|
+
- `created_at DESC` on log/event tables
|
|
123
|
+
- `email` compound with `is_deleted` on user tables
|
|
124
|
+
- Any column used in WHERE or ORDER BY in business queries
|
|
125
|
+
|
|
126
|
+
Compound index — most selective column first.
|
|
127
|
+
Descending index — use `(<col> DESC)` when always sorted descending.
|
|
128
|
+
|
|
129
|
+
Per-table indexes go in the table file.
|
|
130
|
+
Cross-table / multi-service indexes go in `111-setup-database-indexes.sql`.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## create-schema.sql Rules
|
|
135
|
+
|
|
136
|
+
- Lives at `<repo_root>/database/<db_type>/create-schema.sql`
|
|
137
|
+
- Auto-generated — never edited manually
|
|
138
|
+
- Contains `\i <filename>` in strict numeric order
|
|
139
|
+
- `111-setup-database-indexes.sql` always last
|
|
140
|
+
|
|
141
|
+
After EVERY table operation — update this file:
|
|
142
|
+
1. `fs_read` the current file
|
|
143
|
+
2. Insert/remove/reorder `\i` entries
|
|
144
|
+
3. ALTER files immediately after CREATE for that table
|
|
145
|
+
4. DROP files after ALTER files for that table
|
|
146
|
+
5. Write back via `fs_read` + `file_insert_after` MCP tool
|
|
147
|
+
6. Log to `context.change_log`
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Query Optimisation Patterns
|
|
152
|
+
|
|
153
|
+
When asked to optimise a query (via `/codeninja:optimize`):
|
|
154
|
+
|
|
155
|
+
1. Check `context.db.schema.<table>.indexes` against WHERE/JOIN/ORDER BY columns
|
|
156
|
+
2. Flag seq scans → suggest `CREATE INDEX CONCURRENTLY`
|
|
157
|
+
3. Flag `SELECT *` → suggest explicit column list
|
|
158
|
+
4. Flag N+1 patterns → suggest JOIN or IN clause
|
|
159
|
+
5. Flag missing `LIMIT` on unbounded queries
|
|
160
|
+
6. Flag `RANK()` with gaps → suggest `DENSE_RANK()` for leaderboards
|
|
161
|
+
7. Flag `DATE(col)` in WHERE → suggest range filter to preserve index use
|
|
162
|
+
8. Flag duplicate rows → suggest dedup with `MIN(id) GROUP BY`
|
|
163
|
+
9. Suggest `work_mem = '64MB'` session-level if sort spilling to disk
|
|
164
|
+
|
|
165
|
+
Always provide: before/after query, estimated improvement, migration file if new index.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: mcp-and-context
|
|
3
|
+
scope: always-loaded
|
|
4
|
+
description: >
|
|
5
|
+
MCP tool usage rules and context management protocol. Loaded on every
|
|
6
|
+
session. Governs how every persona reads, writes, and protects context.json.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Skill: MCP and Context Management
|
|
10
|
+
|
|
11
|
+
This skill governs all interaction with the codeninja MCP server and
|
|
12
|
+
context.json. Every persona must follow these rules without exception.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Available MCP Tools
|
|
17
|
+
|
|
18
|
+
| Tool | Purpose | When to use |
|
|
19
|
+
|------|---------|-------------|
|
|
20
|
+
| `context_read` | Load full project context | First thing on every activation |
|
|
21
|
+
| `context_write` | Persist changes (deep-merge) | After every completed operation |
|
|
22
|
+
| `context_clear_scratchpad` | Clear a current_* key | After writing context |
|
|
23
|
+
| `context_check_stale` | Detect unresolved scratchpad | Step 0 of activation |
|
|
24
|
+
| `service_scan` | Discover all services on disk | Step 2 of activation |
|
|
25
|
+
| `migration_next_number` | Get next sequential migration number | Before creating any migration file |
|
|
26
|
+
| `fs_read` | Read a file from disk | Before modifying any existing file |
|
|
27
|
+
| `fs_list` | List directory contents | When scanning structure |
|
|
28
|
+
| `fs_exists` | Check if file/directory exists | Before conditional operations |
|
|
29
|
+
| `file_insert_after` | Surgical file insertion | Appending to route_manager.js, etc. |
|
|
30
|
+
| `file_contains` | Check if string exists in file | Before appending to avoid duplicates |
|
|
31
|
+
| `run_drift_check` | Compare context vs disk | During @sync workflow |
|
|
32
|
+
| `lint_file` | Lint a generated file | After generating JS/SQL files |
|
|
33
|
+
| `npm_check_package` | Look up npm package info | When verifying dependencies |
|
|
34
|
+
| `npm_install` | Install a package | When adding new dependencies |
|
|
35
|
+
| `validate_redis_connection` | Test Redis connectivity | During service init |
|
|
36
|
+
| `validate_postgres_connection` | Test DB connectivity | During service init |
|
|
37
|
+
| `analyze_middleware_order` | Check middleware chain | During @audit |
|
|
38
|
+
| `analyze_encryption_library` | Verify encryption setup | During @audit |
|
|
39
|
+
| `analyze_language_keys` | Check i18n completeness | During @audit |
|
|
40
|
+
| `analyze_dependencies` | Scan package.json | During @audit / @sync |
|
|
41
|
+
| `analyze_env_file` | Check .env completeness | During @audit |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Absolute Rules
|
|
46
|
+
|
|
47
|
+
- NEVER read `context.json` directly with `fs_read` — always use `context_read`
|
|
48
|
+
- NEVER write `context.json` directly — always use `context_write`
|
|
49
|
+
- `context_write` deep-merges — it never overwrites the whole file
|
|
50
|
+
- `change_log` is append-only — never delete entries
|
|
51
|
+
- NEVER assume a stored value — always read from loaded context object
|
|
52
|
+
- `context_version` is managed automatically — if `context_read` returns a
|
|
53
|
+
higher version than expected, the file was modified externally — re-read before acting
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Context Schema Reference
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"context_version": 0,
|
|
62
|
+
"project_name": "",
|
|
63
|
+
"project_info": {
|
|
64
|
+
"summary": "",
|
|
65
|
+
"detected_entities": [],
|
|
66
|
+
"features": [],
|
|
67
|
+
"from_doc": { "project_name": "", "domain": "", "purpose": "", "features": [], "entities": [], "tech_preferences": [] },
|
|
68
|
+
"from_sow": { "integrations": [] },
|
|
69
|
+
"from_figma": { "screens": [] }
|
|
70
|
+
},
|
|
71
|
+
"db": {
|
|
72
|
+
"type": "",
|
|
73
|
+
"name": "",
|
|
74
|
+
"host": "",
|
|
75
|
+
"port": 0,
|
|
76
|
+
"user": "",
|
|
77
|
+
"schema": {}
|
|
78
|
+
},
|
|
79
|
+
"services": {},
|
|
80
|
+
"api_routes": [],
|
|
81
|
+
"change_log": []
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Scratchpad Keys (current_* pattern)
|
|
88
|
+
|
|
89
|
+
Temporary keys written during multi-step workflows:
|
|
90
|
+
|
|
91
|
+
| Key | Used by |
|
|
92
|
+
|-----|---------|
|
|
93
|
+
| `current_init` | initialize-project workflow |
|
|
94
|
+
| `current_api` | create-api workflow |
|
|
95
|
+
| `current_table` | db-create-table workflow |
|
|
96
|
+
| `current_modify` | db-modify-table workflow |
|
|
97
|
+
| `current_index` | db-add-index workflow |
|
|
98
|
+
| `current_design` | design workflow |
|
|
99
|
+
|
|
100
|
+
After `context_write` with final results → always call `context_clear_scratchpad`
|
|
101
|
+
for the relevant key. This prevents stale data from persisting across sessions.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Stale Scratchpad Recovery
|
|
106
|
+
|
|
107
|
+
When `context_check_stale` returns stale keys:
|
|
108
|
+
1. Show the user what was in progress
|
|
109
|
+
2. Ask: "Resume this operation or discard it?"
|
|
110
|
+
3. If resume → re-read the scratchpad and continue from where it left off
|
|
111
|
+
4. If discard → call `context_clear_scratchpad` and start fresh
|