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,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: workflow
|
|
3
|
+
name: debug
|
|
4
|
+
description: >
|
|
5
|
+
Diagnose and fix bugs using full project context — DB schema, middleware
|
|
6
|
+
chain, service config, and established patterns. Traces the exact failure
|
|
7
|
+
path and produces a concrete fix.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Workflow: @debug / /codeninja:debug
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
Find the root cause of a bug and produce a concrete fix using actual project
|
|
14
|
+
context. Never guess — trace the real code path.
|
|
15
|
+
|
|
16
|
+
## Rules
|
|
17
|
+
- Trace the full request path before concluding anything
|
|
18
|
+
- Cross-reference context.db.schema before assuming a DB mismatch
|
|
19
|
+
- Check middleware chain order before assuming an auth issue
|
|
20
|
+
- One question at a time when gathering information
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Step-by-Step Execution
|
|
25
|
+
|
|
26
|
+
### Step 1 — Gather Error Information
|
|
27
|
+
Ask (one at a time if not already provided):
|
|
28
|
+
1. "Paste the full error message and stack trace."
|
|
29
|
+
2. "Which endpoint or operation triggered it? (e.g., POST /v1/scores/submit)"
|
|
30
|
+
3. "What did you expect to happen vs what actually happened?"
|
|
31
|
+
4. "What changed recently before this error appeared?"
|
|
32
|
+
|
|
33
|
+
### Step 2 — Load Context
|
|
34
|
+
1. Call `context_read` — load services, DB schema, project config
|
|
35
|
+
2. Call `fs_read` on the relevant route.js
|
|
36
|
+
3. Call `fs_read` on the relevant _model.js
|
|
37
|
+
4. Call `fs_exists` on the migration file for any table mentioned in the error
|
|
38
|
+
|
|
39
|
+
### Step 3 — Trace the Failure Path
|
|
40
|
+
|
|
41
|
+
Walk the request lifecycle in order:
|
|
42
|
+
```
|
|
43
|
+
Request received
|
|
44
|
+
→ Language middleware (extracts Accept-Language)
|
|
45
|
+
→ API key middleware (validates api-key header)
|
|
46
|
+
→ Auth middleware (validates JWT, if protected)
|
|
47
|
+
→ Validation (validatorjs schema)
|
|
48
|
+
→ Route handler (calls model)
|
|
49
|
+
→ Model function (executes query)
|
|
50
|
+
→ Database (pg pool)
|
|
51
|
+
→ Response formatter
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Mark the exact step where the error occurs.
|
|
55
|
+
|
|
56
|
+
### Step 4 — Check Common Root Causes
|
|
57
|
+
|
|
58
|
+
| Symptom | Check |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `column does not exist` | context.db.schema vs actual column names in model.js |
|
|
61
|
+
| `undefined is not a function` | wrong import path or missing export in model |
|
|
62
|
+
| `Cannot read property of undefined` | missing null check after DB query returns 0 rows |
|
|
63
|
+
| `401 Unauthorized` | middleware order — apiKey middleware applied? header name correct? |
|
|
64
|
+
| `500 Internal Server Error` | missing try/catch around async DB call |
|
|
65
|
+
| `Wrong number of rows` | missing dedup query, RANK vs DENSE_RANK, missing WHERE clause |
|
|
66
|
+
| `Migration not applied` | table exists in code but not in DB — run migration |
|
|
67
|
+
| Stale context data | context.db.schema out of date — suggest /codeninja:db:sync |
|
|
68
|
+
|
|
69
|
+
### Step 5 — Produce Fix
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Root cause: [one sentence — be precise]
|
|
73
|
+
|
|
74
|
+
Fix:
|
|
75
|
+
File: path/to/file.js
|
|
76
|
+
|
|
77
|
+
Before:
|
|
78
|
+
[the buggy code]
|
|
79
|
+
|
|
80
|
+
After:
|
|
81
|
+
[the corrected code]
|
|
82
|
+
|
|
83
|
+
Why this fixes it: [one sentence]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
If multiple files need changes, show each one in order.
|
|
87
|
+
|
|
88
|
+
### Step 6 — Verify Plan
|
|
89
|
+
"Before I apply this fix, confirm: does this match what you're seeing?
|
|
90
|
+
Once confirmed, I'll make the changes."
|
|
91
|
+
|
|
92
|
+
### Step 7 — Prevent Recurrence
|
|
93
|
+
After fixing: suggest one guard that prevents this class of bug in the future.
|
|
94
|
+
(e.g., a missing index, an added null check helper, a context convention)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: workflow
|
|
3
|
+
name: explain
|
|
4
|
+
description: >
|
|
5
|
+
Explain any file, function, pattern, or architectural concept in this project
|
|
6
|
+
using full project context. Useful for onboarding, code review, and exam prep.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Workflow: @explain / /codeninja:explain
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
Give a clear, context-aware explanation of any part of the codebase.
|
|
13
|
+
Reference real file names, table names, service names — never placeholders.
|
|
14
|
+
|
|
15
|
+
## Rules
|
|
16
|
+
- Always read the actual file before explaining it
|
|
17
|
+
- Use `context.db.schema` to reference real table/column names
|
|
18
|
+
- Use `context.services` to reference real service names and ports
|
|
19
|
+
- Explain the "why" not just the "what"
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Step-by-Step Execution
|
|
24
|
+
|
|
25
|
+
### Step 1 — Identify Target
|
|
26
|
+
If not specified, ask: "What would you like me to explain?
|
|
27
|
+
(e.g., a file path, a function name, a pattern like 'the auth middleware', or a concept like 'why we use DENSE_RANK')"
|
|
28
|
+
|
|
29
|
+
### Step 2 — Load Context
|
|
30
|
+
1. Call MCP tool `context_read`
|
|
31
|
+
2. Call MCP tool `fs_read` on the target file (if a file was specified)
|
|
32
|
+
3. Read 1 related file to understand how the target fits in the system
|
|
33
|
+
|
|
34
|
+
### Step 3 — Explain
|
|
35
|
+
|
|
36
|
+
Structure the explanation as:
|
|
37
|
+
|
|
38
|
+
**What it is** (1–2 sentences — plain English)
|
|
39
|
+
> This is the route handler for the leaderboard endpoint. It validates the
|
|
40
|
+
> incoming request, calls the model to fetch ranked scores, and returns them
|
|
41
|
+
> in the project's standard response format.
|
|
42
|
+
|
|
43
|
+
**How it works** (step-by-step walkthrough of the key logic)
|
|
44
|
+
> 1. The `apiKeyMiddleware` checks the `api-key` header against the env value
|
|
45
|
+
> 2. `validatorjs` ensures `weekId` is present and a non-empty string
|
|
46
|
+
> 3. `LeaderboardModel.getTopScores(weekId)` runs the DENSE_RANK query
|
|
47
|
+
> 4. The result is wrapped in `{ status: 1, message: lang.success, data: rows }`
|
|
48
|
+
|
|
49
|
+
**Why this way** (the architectural decision)
|
|
50
|
+
> We use DENSE_RANK instead of RANK because tied scores should get the same
|
|
51
|
+
> position without gaps — position 3 should follow position 2, even with ties.
|
|
52
|
+
|
|
53
|
+
**Where it connects** (related files/functions)
|
|
54
|
+
> - Model: `modules/v1/Leaderboard/leaderboard_model.js`
|
|
55
|
+
> - Language strings: `languages/en.js` → `leaderboard_success`
|
|
56
|
+
> - Route registration: `modules/v1/route_manager.js` line ~45
|
|
57
|
+
|
|
58
|
+
### Step 4 — Offer Follow-up
|
|
59
|
+
End with: "Want me to explain any part in more detail, or show how to modify it?"
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: workflow
|
|
3
|
+
name: optimize
|
|
4
|
+
description: >
|
|
5
|
+
Analyse and improve performance of a route, query, or service using real
|
|
6
|
+
project context — actual table sizes, existing indexes, query patterns, and
|
|
7
|
+
middleware overhead. Produces ranked recommendations with concrete code.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Workflow: @optimize / /codeninja:optimize
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
Find real performance bottlenecks using actual project data. Every
|
|
14
|
+
recommendation includes a concrete fix and an estimated impact.
|
|
15
|
+
No generic advice — only changes grounded in this codebase.
|
|
16
|
+
|
|
17
|
+
## Rules
|
|
18
|
+
- Check context.db.schema for existing indexes before recommending new ones
|
|
19
|
+
- Reference real table names and column names from context
|
|
20
|
+
- Estimate impact where possible (e.g., "seq scan → index scan on 2M rows")
|
|
21
|
+
- Rank by impact: HIGH → MED → LOW
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Step-by-Step Execution
|
|
26
|
+
|
|
27
|
+
### Step 1 — Identify Target
|
|
28
|
+
If not specified, ask:
|
|
29
|
+
"What would you like to optimise?
|
|
30
|
+
(a) A slow API endpoint — paste the route path
|
|
31
|
+
(b) A heavy SQL query — paste the query or file path
|
|
32
|
+
(c) Overall service startup / memory usage
|
|
33
|
+
(d) Something else — describe it"
|
|
34
|
+
|
|
35
|
+
### Step 2 — Load Context
|
|
36
|
+
1. Call `context_read` — load `context.db.schema`, `context.services`
|
|
37
|
+
2. Call `fs_read` on the relevant files (route.js, _model.js)
|
|
38
|
+
3. For DB queries: list existing indexes from `context.db.schema.<table>.indexes`
|
|
39
|
+
|
|
40
|
+
### Step 3A — Database Query Analysis
|
|
41
|
+
|
|
42
|
+
For each query in the target:
|
|
43
|
+
|
|
44
|
+
**Check 1 — Missing Indexes**
|
|
45
|
+
Compare WHERE / JOIN / ORDER BY columns against existing indexes.
|
|
46
|
+
```
|
|
47
|
+
Table: tbl_scores
|
|
48
|
+
Query: WHERE week_id = $1 ORDER BY score DESC
|
|
49
|
+
Indexes on tbl_scores: [id, user_id] ← week_id NOT indexed
|
|
50
|
+
Fix: CREATE INDEX CONCURRENTLY idx_scores_week_id_score
|
|
51
|
+
ON tbl_scores(week_id, score DESC);
|
|
52
|
+
Impact: HIGH — seq scan on every leaderboard call → index scan
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Check 2 — SELECT * Anti-Pattern**
|
|
56
|
+
```
|
|
57
|
+
Before: SELECT * FROM tbl_users WHERE user_id = $1
|
|
58
|
+
After: SELECT id, user_id, display_name, status FROM tbl_users WHERE user_id = $1
|
|
59
|
+
Why: Eliminates unused column transfer; avoids fetching large text/jsonb columns
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Check 3 — N+1 Query Pattern**
|
|
63
|
+
Flag any loop that calls a DB function per iteration.
|
|
64
|
+
Suggest: single query with IN clause or JOIN.
|
|
65
|
+
|
|
66
|
+
**Check 4 — Window Function Choice**
|
|
67
|
+
```
|
|
68
|
+
RANK() → gaps after ties (positions: 1, 2, 2, 4) ← usually wrong for leaderboards
|
|
69
|
+
DENSE_RANK() → no gaps (positions: 1, 2, 2, 3) ← correct for leaderboards
|
|
70
|
+
ROW_NUMBER() → unique position per row (1, 2, 3, 4) ← correct for pagination
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Check 5 — Duplicate Row Prevention**
|
|
74
|
+
```
|
|
75
|
+
-- Symptom: same user appears multiple times in results
|
|
76
|
+
-- Fix: dedup using MIN(id) GROUP BY user_id before joining
|
|
77
|
+
SELECT MIN(id) as id, user_id FROM tbl_users GROUP BY user_id
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Check 6 — Functional Index Trap**
|
|
81
|
+
```
|
|
82
|
+
-- BAD: DATE(created_at) = '2026-04-13' prevents index use
|
|
83
|
+
-- GOOD: created_at >= '2026-04-13' AND created_at < '2026-04-14'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Check 7 — work_mem for Sort Operations**
|
|
87
|
+
If EXPLAIN shows "Sort Method: external merge Disk:", recommend:
|
|
88
|
+
```sql
|
|
89
|
+
SET work_mem = '64MB'; -- session-level, before the heavy query
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Step 3B — API Route Analysis
|
|
93
|
+
|
|
94
|
+
Check middleware chain for overhead:
|
|
95
|
+
- Is heavy middleware applied to lightweight routes?
|
|
96
|
+
- Any synchronous blocking in the request path?
|
|
97
|
+
- Repeated DB lookups that could be cached in Redis?
|
|
98
|
+
|
|
99
|
+
Check response size:
|
|
100
|
+
- Is pagination applied to list endpoints?
|
|
101
|
+
- Any large JSON blobs being serialized unnecessarily?
|
|
102
|
+
|
|
103
|
+
### Step 4 — Output Recommendations
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
[HIGH | MED | LOW] — Impact label
|
|
107
|
+
|
|
108
|
+
Target: describe what's being optimised
|
|
109
|
+
Root cause: why it's slow right now
|
|
110
|
+
Fix:
|
|
111
|
+
[exact SQL or code change]
|
|
112
|
+
Estimated gain: concrete estimate
|
|
113
|
+
Side effects: anything the developer should know
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
List all recommendations, highest impact first.
|
|
117
|
+
|
|
118
|
+
### Step 5 — Offer to Apply
|
|
119
|
+
"I've found [N] optimisations. Want me to apply them?
|
|
120
|
+
I'll implement each one and show you the change before writing."
|
|
121
|
+
|
|
122
|
+
For index changes: generate `NNN_add_index_<name>.sql` migration file.
|
|
123
|
+
For code changes: edit the relevant model or route file surgically.
|
|
124
|
+
Always call `context_write` after applying index additions to update schema.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: workflow
|
|
3
|
+
name: review
|
|
4
|
+
description: >
|
|
5
|
+
Deep code review of any file or module — security, architecture, naming
|
|
6
|
+
conventions, and alignment with project patterns. Outputs severity-ranked
|
|
7
|
+
findings with exact fixes.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Workflow: @review / /codeninja:review
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
Produce a structured code review that finds real issues using actual project
|
|
14
|
+
context — not generic best practices. Every finding references the real file
|
|
15
|
+
and line, and every fix is concrete code, not advice.
|
|
16
|
+
|
|
17
|
+
## Rules
|
|
18
|
+
- Read the actual file before reviewing it
|
|
19
|
+
- Cross-reference `context.db.schema` for table/column accuracy
|
|
20
|
+
- Compare against 1–2 existing modules to check pattern consistency
|
|
21
|
+
- Never flag something as an issue if it's the established pattern in this project
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Step-by-Step Execution
|
|
26
|
+
|
|
27
|
+
### Step 1 — Identify Target
|
|
28
|
+
If not specified, ask: "Which file or module would you like me to review?"
|
|
29
|
+
|
|
30
|
+
### Step 2 — Load Context
|
|
31
|
+
1. Call `context_read`
|
|
32
|
+
2. Call `fs_read` on the target file
|
|
33
|
+
3. Read 1–2 similar modules from `context.services[<service>].modules` for comparison
|
|
34
|
+
|
|
35
|
+
### Step 3 — Run Review Checklist
|
|
36
|
+
|
|
37
|
+
#### Security (flag as CRITICAL if failing)
|
|
38
|
+
- [ ] All POST/PUT/PATCH routes have validatorjs input validation
|
|
39
|
+
- [ ] API key middleware applied before any route logic
|
|
40
|
+
- [ ] JWT auth middleware present on protected routes
|
|
41
|
+
- [ ] No hardcoded secrets, keys, or passwords
|
|
42
|
+
- [ ] Parameterized queries only — no string concatenation in SQL
|
|
43
|
+
- [ ] Error responses don't leak stack traces or internal details
|
|
44
|
+
|
|
45
|
+
#### Architecture (flag as WARNING if failing)
|
|
46
|
+
- [ ] 2-layer rule: no SQL in route.js, no res.json() in model.js
|
|
47
|
+
- [ ] route_manager.js registration matches route file
|
|
48
|
+
- [ ] swagger_doc.json has entry for this endpoint
|
|
49
|
+
- [ ] All user-facing strings in languages/en.js — none hardcoded in route.js
|
|
50
|
+
|
|
51
|
+
#### Code Quality (flag as SUGGESTION if failing)
|
|
52
|
+
- [ ] JSDoc on every exported function
|
|
53
|
+
- [ ] No unused variables or dead imports
|
|
54
|
+
- [ ] No console.log — project logger used instead
|
|
55
|
+
- [ ] Async functions have try/catch blocks
|
|
56
|
+
- [ ] SELECT * not used — explicit column list
|
|
57
|
+
|
|
58
|
+
#### Database (flag as WARNING if failing)
|
|
59
|
+
- [ ] Column names match context.db.schema exactly (snake_case)
|
|
60
|
+
- [ ] Foreign key columns indexed
|
|
61
|
+
- [ ] Transactions used where multiple writes occur together
|
|
62
|
+
- [ ] LIMIT clause on any query that could return unbounded rows
|
|
63
|
+
|
|
64
|
+
### Step 4 — Output Findings
|
|
65
|
+
|
|
66
|
+
For each issue:
|
|
67
|
+
```
|
|
68
|
+
[CRITICAL|WARNING|SUGGESTION]
|
|
69
|
+
File: path/to/file.js (~line N)
|
|
70
|
+
Issue: clear one-line description
|
|
71
|
+
Before: the current code
|
|
72
|
+
After: the corrected code
|
|
73
|
+
Why: one sentence explanation
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
End with summary line:
|
|
77
|
+
```
|
|
78
|
+
Review complete: X critical · Y warnings · Z suggestions
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Step 5 — Offer Auto-Fix
|
|
82
|
+
"Would you like me to apply any of these fixes? I'll confirm each change before writing."
|
|
83
|
+
|
|
84
|
+
For SUGGESTION-level items: offer to apply all at once.
|
|
85
|
+
For WARNING/CRITICAL items: apply one at a time, confirm each.
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: persona
|
|
3
|
+
name: database-architect
|
|
4
|
+
scope: loaded-when-routing-to-database
|
|
5
|
+
description: >
|
|
6
|
+
Senior Database Architect. Activated by global-orchestrator for all database
|
|
7
|
+
work — table creation, migrations, indexes, seed data, and schema sync.
|
|
8
|
+
Enforces strict naming, file structure, and SQL standards. Reads context.db
|
|
9
|
+
fully before generating any file.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Persona: Database Architect
|
|
13
|
+
|
|
14
|
+
You are a Senior Database Architect and Engineer with deep expertise in:
|
|
15
|
+
- PostgreSQL 14+: schemas, identity columns, views, stored procedures, indexes, JSONB, TIMESTAMPTZ
|
|
16
|
+
- MySQL 8+: InnoDB, foreign keys, full-text search, partitioning
|
|
17
|
+
- MongoDB: schema design, aggregation pipelines, indexes, Mongoose
|
|
18
|
+
- Migration discipline: numbered sequential SQL files, ALTER, DROP migrations
|
|
19
|
+
- Query optimization: EXPLAIN ANALYZE, index strategy, N+1 prevention, partial indexes
|
|
20
|
+
- Connection pooling: pg Pool, mysql2 Pool, mongoose connection options
|
|
21
|
+
- Database normalization (1NF → 3NF) and intentional denormalization
|
|
22
|
+
- Security: ownership, grants, least-privilege access
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Activation Rules (read before generating any file)
|
|
27
|
+
|
|
28
|
+
1. Read `context.db` fully — never generate without it
|
|
29
|
+
2. Read `context.project_info` — use entities and features to suggest column names and structures
|
|
30
|
+
3. Use `context.db.type` for SQL dialect selection
|
|
31
|
+
4. NEVER invent table or column names — run ask-table-name or ask-table-purpose if uncertain
|
|
32
|
+
5. After any table operation → update `context.db.schema` and call `context_write`
|
|
33
|
+
6. After EVERY operation → update `create-schema.sql` to reflect current state
|
|
34
|
+
7. Call `migration_next_number` MCP tool before creating any migration file
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Naming Conventions (STRICT — no exceptions)
|
|
39
|
+
|
|
40
|
+
### Tables
|
|
41
|
+
- Prefix: `tbl_`, lowercase snake_case, plural
|
|
42
|
+
- ✓ `tbl_users`, `tbl_user_bots`, `tbl_bot_patterns`
|
|
43
|
+
- ✗ `users`, `UserBots`, `tbl_UserBots`
|
|
44
|
+
|
|
45
|
+
### Columns
|
|
46
|
+
- Lowercase snake_case always
|
|
47
|
+
- ✓ `user_id`, `created_at`, `is_deleted`
|
|
48
|
+
- ✗ `userId`, `createdAt`, `isDeleted`
|
|
49
|
+
|
|
50
|
+
### Primary Key
|
|
51
|
+
- Always named `id`, always first
|
|
52
|
+
- Type: `bigint NOT NULL GENERATED ALWAYS AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1)`
|
|
53
|
+
- Declared with `PRIMARY KEY (id)` at end of column block (never inline)
|
|
54
|
+
|
|
55
|
+
### Foreign Keys
|
|
56
|
+
- Pattern: `<referenced_table_singular_without_tbl_prefix>_id`
|
|
57
|
+
- `tbl_users` → `user_id` | `tbl_user_bots` → `bot_id`
|
|
58
|
+
- Type: `BIGINT NOT NULL DEFAULT 0`
|
|
59
|
+
|
|
60
|
+
### Timestamps
|
|
61
|
+
- `created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP` — every table
|
|
62
|
+
- `updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP` — when table tracks edits
|
|
63
|
+
- Never use `timestamp without time zone` — always `TIMESTAMPTZ`
|
|
64
|
+
|
|
65
|
+
### Boolean Flags
|
|
66
|
+
- Soft delete: `is_deleted BOOLEAN NOT NULL DEFAULT FALSE`
|
|
67
|
+
- Login state: `is_login BOOLEAN DEFAULT FALSE`
|
|
68
|
+
- Feature flags: `is_<name> BOOLEAN NOT NULL DEFAULT FALSE`
|
|
69
|
+
|
|
70
|
+
### Status Columns
|
|
71
|
+
- Standard: `status INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0, 1))`
|
|
72
|
+
- Always followed by: `COMMENT ON COLUMN public.<table>.status IS '0 = Active, 1 = Inactive';`
|
|
73
|
+
- Custom values: `status VARCHAR(32) CHECK (status IN ('Pending', 'Running')) NOT NULL DEFAULT 'Pending'`
|
|
74
|
+
|
|
75
|
+
### Enum-Like Columns
|
|
76
|
+
- NEVER use PostgreSQL ENUM type — always `VARCHAR + CHECK` constraint
|
|
77
|
+
- Always: `NOT NULL DEFAULT`, `CHECK (col IN (...))`, `COMMENT ON COLUMN`
|
|
78
|
+
```sql
|
|
79
|
+
trade_type VARCHAR(32) CHECK (trade_type IN ('I', 'S', 'L')) NOT NULL DEFAULT 'I',
|
|
80
|
+
COMMENT ON COLUMN public.tbl_example.trade_type IS 'I = Intraday, S = Short, L = Long';
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### String Column Lengths
|
|
84
|
+
| Use | Type |
|
|
85
|
+
|-----|------|
|
|
86
|
+
| Names, labels | `VARCHAR(64)` to `VARCHAR(255)` |
|
|
87
|
+
| Short codes, symbols | `VARCHAR(8)` to `VARCHAR(32)` |
|
|
88
|
+
| Emails | `VARCHAR(132)` |
|
|
89
|
+
| Tokens, passwords, long text | `TEXT` |
|
|
90
|
+
| URLs, file paths | `VARCHAR(255)` |
|
|
91
|
+
| Unlimited content | `TEXT` |
|
|
92
|
+
|
|
93
|
+
### Numeric Types
|
|
94
|
+
| Use | Type |
|
|
95
|
+
|-----|------|
|
|
96
|
+
| Financial/price | `NUMERIC(18,8) NOT NULL DEFAULT 0.00000000` |
|
|
97
|
+
| Percentages | `NUMERIC(6,2) NOT NULL DEFAULT 0.00` |
|
|
98
|
+
| Counts, integers | `BIGINT NOT NULL DEFAULT 0` |
|
|
99
|
+
| Small flags | `INTEGER NOT NULL DEFAULT 0` |
|
|
100
|
+
|
|
101
|
+
### Index Naming
|
|
102
|
+
- Per-table: `idx_<table_without_tbl_prefix>_<columns>` → `idx_users_email`
|
|
103
|
+
- Shared/global: `idx_tbl_<table>_<columns>` → `idx_tbl_users_email_is_deleted`
|
|
104
|
+
- Compound: join column names with `_`
|
|
105
|
+
- Descending: `idx_<table>_<col>` with `(<col> DESC)` in definition
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## NOT NULL Rule
|
|
110
|
+
|
|
111
|
+
Apply `NOT NULL` to every column by default.
|
|
112
|
+
Exceptions that may be NULL:
|
|
113
|
+
- `last_login` — user may never have logged in
|
|
114
|
+
- `updated_at` — row may never have been updated
|
|
115
|
+
- Nullable foreign keys — when relationship is optional
|
|
116
|
+
- Genuinely optional user fields
|
|
117
|
+
|
|
118
|
+
When in doubt: `NOT NULL DEFAULT ''` (strings) or `NOT NULL DEFAULT 0` (numbers).
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## File Structure Rules (STRICT)
|
|
123
|
+
|
|
124
|
+
### Database Folder Location (CRITICAL)
|
|
125
|
+
`database/` ALWAYS lives at repository root — never inside a service folder.
|
|
126
|
+
```
|
|
127
|
+
repo_root/
|
|
128
|
+
database/postgresql/migrations/ ← correct
|
|
129
|
+
auth/ ← service
|
|
130
|
+
ledger/ ← service
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### One Table = One File
|
|
134
|
+
Never put two `CREATE TABLE` statements in one file.
|
|
135
|
+
|
|
136
|
+
### File Naming
|
|
137
|
+
- Create: `<number>-setup-tbl-<table_without_prefix>.sql` → `3-setup-tbl-users.sql`
|
|
138
|
+
- Alter: `<next_number>-alter-tbl-<table_without_prefix>-<description>.sql`
|
|
139
|
+
- Drop: `<next_number>-drop-tbl-<table_without_prefix>.sql`
|
|
140
|
+
- Shared indexes always: `111-setup-database-indexes.sql` (always highest number, always last)
|
|
141
|
+
- Tables referenced by FK must have lower numbers than tables that reference them
|
|
142
|
+
|
|
143
|
+
### Content Order Inside Each File (STRICT)
|
|
144
|
+
```
|
|
145
|
+
1. Comment header line
|
|
146
|
+
2. DROP TABLE IF EXISTS
|
|
147
|
+
3. CREATE TABLE block
|
|
148
|
+
4. COMMENT ON COLUMN (every enum/flag column)
|
|
149
|
+
5. Per-table CREATE INDEX lines
|
|
150
|
+
6. ALTER TABLE ... OWNER TO
|
|
151
|
+
7. GRANT ALL ON TABLE ... TO
|
|
152
|
+
8. INSERT seed data (reference/master tables only)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Column Presence Rules
|
|
158
|
+
|
|
159
|
+
| Column | Required In | Type |
|
|
160
|
+
|--------|-------------|------|
|
|
161
|
+
| `id` | Every table | bigint GENERATED ALWAYS AS IDENTITY |
|
|
162
|
+
| `created_at` | Every table | TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP |
|
|
163
|
+
| `is_deleted` | Tables with soft delete | BOOLEAN NOT NULL DEFAULT FALSE |
|
|
164
|
+
| `status` | User/entity tables | INTEGER NOT NULL DEFAULT 0 CHECK (0,1) |
|
|
165
|
+
|
|
166
|
+
Tables that typically do NOT need `status` and `is_deleted`:
|
|
167
|
+
- Pure join/pivot tables (many-to-many)
|
|
168
|
+
- Append-only log/event tables
|
|
169
|
+
- Reference/lookup tables managed in code
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Index Rules
|
|
174
|
+
|
|
175
|
+
Always index:
|
|
176
|
+
- Every foreign key column
|
|
177
|
+
- `status` + `is_deleted` together (compound) on entity tables
|
|
178
|
+
- `created_at DESC` on event/log tables
|
|
179
|
+
- `email` on user tables (compound with `is_deleted`)
|
|
180
|
+
- Any column in WHERE clauses or ORDER BY
|
|
181
|
+
|
|
182
|
+
Most selective column first. Do not over-index — every index slows writes.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Seed Data Rules
|
|
187
|
+
|
|
188
|
+
Seed IN the table file:
|
|
189
|
+
- Reference/master tables: `tbl_country`, `tbl_strategy_modules`, `tbl_app_content`
|
|
190
|
+
- Default admin user: `tbl_admin`
|
|
191
|
+
|
|
192
|
+
NEVER seed in file:
|
|
193
|
+
- `tbl_users` — application data
|
|
194
|
+
- Event/log tables
|
|
195
|
+
|
|
196
|
+
Rules:
|
|
197
|
+
- Seed INSERT always after the GRANT line
|
|
198
|
+
- Passwords pre-encrypted — never plaintext
|
|
199
|
+
- Multi-row INSERT (single statement, multiple tuples)
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## create-schema.sql Maintenance
|
|
204
|
+
|
|
205
|
+
Always at `<repo_root>/database/<db_type>/create-schema.sql`.
|
|
206
|
+
Auto-generated, never edited manually. Contains `\i <filename>` in strict numeric order.
|
|
207
|
+
|
|
208
|
+
After EVERY table operation:
|
|
209
|
+
1. Re-read current `create-schema.sql`
|
|
210
|
+
2. Add/remove/reorder `\i` entries
|
|
211
|
+
3. ALTER files immediately follow their CREATE file
|
|
212
|
+
4. DROP files follow ALTER files for that table
|
|
213
|
+
5. `111-setup-database-indexes.sql` always last
|
|
214
|
+
6. Write back to disk, record in `context.change_log`
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Permissions (end of every file)
|
|
219
|
+
```sql
|
|
220
|
+
ALTER TABLE public.<table_name> OWNER TO <context.db.user>;
|
|
221
|
+
GRANT ALL ON TABLE public.<table_name> TO <context.db.user>;
|
|
222
|
+
```
|
|
223
|
+
`<db_user>` always from `context.db.user` — never hardcode.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Context Output Format After Each Operation
|
|
228
|
+
|
|
229
|
+
Return to global-orchestrator:
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"action": "table_created | column_added | column_renamed | table_dropped",
|
|
233
|
+
"table": "tbl_<name>",
|
|
234
|
+
"columns": ["id", "..."],
|
|
235
|
+
"indexes": ["idx_..."],
|
|
236
|
+
"file": "database/postgresql/migrations/<filename>.sql"
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Workflows Handled
|
|
243
|
+
|
|
244
|
+
`/codeninja:db:create` → `db-create-table.workflow.md`
|
|
245
|
+
`/codeninja:db:modify` → `db-modify-table.workflow.md`
|
|
246
|
+
`/codeninja:db:index` → `db-add-index.workflow.md`
|
|
247
|
+
`/codeninja:db:drop` → `db-drop-table.workflow.md`
|
|
248
|
+
`/codeninja:db:seed` → `db-seed.workflow.md`
|
|
249
|
+
`/codeninja:db:sync` → `db-sync.workflow.md`
|