codeninja 3.2.0 → 4.0.1
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 +15 -4
- package/agent/database-agent.md +24 -1
- package/agent/nodejs-agent.md +79 -0
- package/cli.js +27 -7
- package/commands/audit.workflow.md +4 -1
- package/commands/db-create-table.workflow.md +1 -1
- package/commands/initialize-project.workflow.md +21 -0
- package/ide/antigravity/.agents/personas/database-architect.md +431 -153
- package/ide/antigravity/.agents/personas/global-orchestrator.md +202 -85
- package/ide/antigravity/.agents/personas/nodejs-backend.md +368 -133
- package/ide/antigravity/.agents/personas/reactjs-frontend.md +182 -101
- package/ide/antigravity/.agents/skills/api-builder/SKILL.md +58 -0
- package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +22 -0
- package/ide/antigravity/.agents/skills/database/SKILL.md +32 -0
- package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +76 -82
- package/ide/antigravity/.agents/skills/reactjs/SKILL.md +36 -0
- package/ide/antigravity/.agents/workflows/codeninja-api.md +76 -83
- package/ide/antigravity/.agents/workflows/codeninja-audit.md +82 -44
- package/ide/antigravity/.agents/workflows/codeninja-db-create.md +107 -94
- package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +89 -67
- package/ide/antigravity/.agents/workflows/codeninja-db-index.md +86 -54
- package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +126 -68
- package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +87 -59
- package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +77 -41
- package/ide/antigravity/.agents/workflows/codeninja-debug.md +35 -21
- package/ide/antigravity/.agents/workflows/codeninja-design.md +49 -35
- package/ide/antigravity/.agents/workflows/codeninja-explain.md +41 -20
- package/ide/antigravity/.agents/workflows/codeninja-init.md +479 -289
- package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +253 -136
- package/ide/antigravity/.agents/workflows/codeninja-modularize.md +250 -132
- package/ide/antigravity/.agents/workflows/codeninja-optimize.md +71 -29
- package/ide/antigravity/.agents/workflows/codeninja-refactor.md +50 -42
- package/ide/antigravity/.agents/workflows/codeninja-review.md +38 -21
- package/ide/antigravity/.agents/workflows/codeninja-sync.md +922 -141
- package/ide/antigravity/.agents/workflows/codeninja-test.md +34 -49
- package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +449 -151
- package/ide/claude-code/.claude/CLAUDE.md +99 -0
- package/ide/claude-code/.claude/agents/database-agent.md +535 -0
- package/ide/claude-code/.claude/agents/nodejs-agent.md +493 -0
- package/ide/claude-code/.claude/agents/reactjs-agent.md +267 -0
- package/ide/claude-code/.claude/commands/codeninja-api.md +104 -0
- package/ide/claude-code/.claude/commands/codeninja-audit.md +119 -0
- package/ide/claude-code/.claude/commands/codeninja-db-create.md +138 -0
- package/ide/claude-code/.claude/commands/codeninja-db-drop.md +109 -0
- package/ide/claude-code/.claude/commands/codeninja-db-index.md +103 -0
- package/ide/claude-code/.claude/commands/codeninja-db-modify.md +165 -0
- package/ide/claude-code/.claude/commands/codeninja-db-seed.md +104 -0
- package/ide/claude-code/.claude/commands/codeninja-db-sync.md +106 -0
- package/ide/claude-code/.claude/commands/codeninja-debug.md +99 -0
- package/ide/claude-code/.claude/commands/codeninja-design.md +68 -0
- package/ide/claude-code/.claude/commands/codeninja-explain.md +61 -0
- package/ide/claude-code/.claude/commands/codeninja-init.md +529 -0
- package/ide/claude-code/.claude/commands/codeninja-integrate-api.md +453 -0
- package/ide/claude-code/.claude/commands/codeninja-modularize.md +334 -0
- package/ide/claude-code/.claude/commands/codeninja-optimize.md +129 -0
- package/ide/claude-code/.claude/commands/codeninja-refactor.md +76 -0
- package/ide/claude-code/.claude/commands/codeninja-review.md +87 -0
- package/ide/claude-code/.claude/commands/codeninja-sync.md +964 -0
- package/ide/claude-code/.claude/commands/codeninja-test.md +45 -0
- package/ide/claude-code/.claude/commands/codeninja-validate-page.md +548 -0
- package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +12 -13
- package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +47 -31
- package/ide/cursor/.cursor/rules/03-api-builder.mdc +32 -110
- package/ide/cursor/.cursor/rules/04-nodejs-generation.mdc +58 -0
- package/ide/cursor/.cursor/rules/05-database.mdc +54 -0
- package/ide/cursor/.cursor/rules/06-reactjs.mdc +36 -0
- package/ide/cursor/.cursor/rules/07-reactjs-generation.mdc +49 -0
- package/ide/cursor/.cursor/rules/08-code-intelligence.mdc +56 -0
- package/ide/cursor/.cursor/rules/09-workflow-steps.mdc +53 -0
- package/ide/vscode/.github/copilot-instructions.md +67 -382
- package/ide/vscode/.vscode/instructions/code-intelligence.instructions.md +58 -0
- package/ide/vscode/.vscode/instructions/database.instructions.md +55 -0
- package/ide/vscode/.vscode/instructions/nodejs.instructions.md +77 -0
- package/ide/vscode/.vscode/instructions/reactjs.instructions.md +42 -0
- package/package.json +2 -2
- package/tasks/ask-hashing-library.task.md +31 -0
- package/tasks/ask-language-type.task.md +26 -0
- package/tasks/ask-new-module-name.task.md +13 -0
- package/tasks/ask-new-service-name.task.md +13 -0
- package/tasks/ask-old-module-name.task.md +15 -0
- package/tasks/ask-old-service-name.task.md +13 -0
- package/tasks/ask-orm-type.task.md +26 -0
- package/tasks/collect-seed-data.task.md +19 -0
- package/tasks/generate-app.task.md +42 -0
- package/tasks/generate-common.task.md +13 -0
- package/tasks/generate-constants.task.md +13 -0
- package/tasks/generate-database.task.md +32 -0
- package/tasks/generate-encryption.task.md +28 -0
- package/tasks/generate-fast-defaults.task.md +7 -0
- package/tasks/generate-hashing.task.md +180 -0
- package/tasks/generate-headerValidator.task.md +13 -0
- package/tasks/generate-ioRedis.task.md +20 -0
- package/tasks/generate-language-en.task.md +12 -0
- package/tasks/generate-logging.task.md +12 -0
- package/tasks/generate-model.task.md +74 -6
- package/tasks/generate-notification.task.md +12 -0
- package/tasks/generate-package-json.task.md +69 -0
- package/tasks/generate-prisma-client.task.md +56 -0
- package/tasks/generate-prisma-schema.task.md +71 -0
- package/tasks/generate-rateLimiter.task.md +20 -0
- package/tasks/generate-readme.task.md +24 -0
- package/tasks/generate-response.task.md +27 -0
- package/tasks/generate-route-manager.task.md +32 -0
- package/tasks/generate-route.task.md +37 -0
- package/tasks/generate-swagger.task.md +8 -0
- package/tasks/generate-template.task.md +12 -0
- package/tasks/generate-tsconfig.task.md +38 -0
- package/tasks/generate-validator.task.md +31 -0
- package/ide/cursor/.cursor/rules/04-database.mdc +0 -90
- package/ide/cursor/.cursor/rules/05-reactjs.mdc +0 -147
- package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +0 -112
|
@@ -1,124 +1,137 @@
|
|
|
1
|
+
This workflow runs when user invokes /codeninja:db:create
|
|
2
|
+
|
|
1
3
|
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
description:
|
|
4
|
+
type: workflow
|
|
5
|
+
name: db-create-table
|
|
6
|
+
command: "@db:create-table"
|
|
7
|
+
description: >
|
|
8
|
+
Design and generate a new database table following all project conventions.
|
|
9
|
+
Collects table purpose, name, columns one at a time, then generates the
|
|
10
|
+
numbered SQL file, updates create-schema.sql, and records in context.
|
|
6
11
|
---
|
|
7
12
|
|
|
8
|
-
#
|
|
13
|
+
# Workflow: @db:create-table
|
|
9
14
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
3. Call `migration_next_number` MCP tool — get next sequential migration number
|
|
15
|
+
## Goal
|
|
16
|
+
Generate a complete, convention-compliant SQL table file. Every generated
|
|
17
|
+
file must pass ALL rules defined in database-agent.md.
|
|
14
18
|
|
|
15
|
-
##
|
|
19
|
+
## Rules
|
|
20
|
+
- Ask ONE question at a time — never bundle column definitions
|
|
21
|
+
- Always enforce tbl_ prefix and snake_case naming
|
|
22
|
+
- Never create a table file without updating create-schema.sql
|
|
23
|
+
- Always record in context.db.schema after generation
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
---
|
|
18
26
|
|
|
19
|
-
|
|
20
|
-
|
|
27
|
+
## Step-by-Step Execution
|
|
28
|
+
|
|
29
|
+
### Phase 1 — Table Identity
|
|
30
|
+
1. Run task: `ask-table-purpose`
|
|
31
|
+
- Stores: `context.current_db.table_purpose`
|
|
32
|
+
- Used by agent to suggest column names and structure
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
- Enforce
|
|
24
|
-
-
|
|
34
|
+
2. Run task: `ask-table-name`
|
|
35
|
+
- Enforce: lowercase, snake_case, must start with `tbl_`
|
|
36
|
+
- Stores: `context.current_db.table_name`
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
38
|
+
3. Run task: `ask-table-file-number`
|
|
39
|
+
- Agent reads existing files in `database/<db_type>/migrations/`
|
|
40
|
+
- Suggests next available number
|
|
41
|
+
- Stores: `context.current_db.file_number`
|
|
29
42
|
|
|
30
43
|
---
|
|
31
44
|
|
|
32
45
|
### Phase 2 — Standard Columns Decision
|
|
46
|
+
4. Run task: `ask-table-needs-status`
|
|
47
|
+
- Ask: "Does this table need status and is_deleted columns?"
|
|
48
|
+
- Agent guidance: suggest YES for user/entity tables, NO for event/log tables
|
|
49
|
+
- Stores: `context.current_db.needs_status`
|
|
33
50
|
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
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`
|
|
51
|
+
5. Run task: `ask-table-needs-soft-delete`
|
|
52
|
+
- Ask: "Does this table support soft delete (is_deleted)?"
|
|
53
|
+
- Auto-suggest: YES if needs_status is YES
|
|
54
|
+
- Stores: `context.current_db.needs_soft_delete`
|
|
41
55
|
|
|
42
56
|
---
|
|
43
57
|
|
|
44
58
|
### Phase 3 — Column Collection (repeat until done)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
- Enforce: snake_case, lowercase
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
-
|
|
53
|
-
- `
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
- `
|
|
61
|
-
- `*
|
|
62
|
-
- `
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
6. Run task: `ask-column-name`
|
|
60
|
+
- Show columns collected so far
|
|
61
|
+
- Ask: "Enter the next column name (or type 'done' to finish)"
|
|
62
|
+
- Enforce: snake_case, lowercase
|
|
63
|
+
- Stores: appends to `context.current_db.columns[]`
|
|
64
|
+
|
|
65
|
+
7. Run task: `ask-column-type`
|
|
66
|
+
- Show suggested type based on column name pattern:
|
|
67
|
+
- `*_id` → BIGINT NOT NULL DEFAULT 0
|
|
68
|
+
- When a column name ends in `_id`:
|
|
69
|
+
- Cross-reference context.db.schema.tables for a table whose name
|
|
70
|
+
matches the prefix (e.g. user_id → tbl_users)
|
|
71
|
+
- If found → suggest: "This looks like a foreign key to tbl_users.
|
|
72
|
+
Add FK constraint? (yes/no)"
|
|
73
|
+
- If yes → add REFERENCES clause to the column definition
|
|
74
|
+
- `is_*` → BOOLEAN NOT NULL DEFAULT FALSE
|
|
75
|
+
- `*_at` → TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
76
|
+
- `status` → INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0,1))
|
|
77
|
+
- `*_count` → BIGINT NOT NULL DEFAULT 0
|
|
78
|
+
- `*_price`, `*_amount` → NUMERIC(18,8) NOT NULL DEFAULT 0.00000000
|
|
79
|
+
- `email` → VARCHAR(132) NOT NULL DEFAULT ''
|
|
80
|
+
- `phone` → VARCHAR(16) NOT NULL DEFAULT ''
|
|
81
|
+
- `password` → TEXT NOT NULL DEFAULT ''
|
|
82
|
+
- `*_image`, `*_url` → VARCHAR(255) NOT NULL DEFAULT ''
|
|
83
|
+
- `payload`, `metadata`, `*_result` → JSON NOT NULL DEFAULT '{}'
|
|
84
|
+
- default → VARCHAR(255) NOT NULL DEFAULT ''
|
|
85
|
+
- Stores: in current column entry
|
|
86
|
+
|
|
87
|
+
8. Run task: `ask-column-is-enum`
|
|
88
|
+
- Ask: "Does this column have a fixed set of allowed values? (enum-like)"
|
|
89
|
+
- If yes → run task: `ask-column-enum-values`
|
|
90
|
+
- Stores: check constraint and comment text
|
|
91
|
+
|
|
92
|
+
9. Return to step 6 until user types 'done'
|
|
69
93
|
|
|
70
94
|
---
|
|
71
95
|
|
|
72
96
|
### Phase 4 — Index Decision
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- Every `*_id` (
|
|
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
|
|
97
|
+
10. Run task: `ask-table-indexes`
|
|
98
|
+
- Agent auto-suggests indexes based on collected columns:
|
|
99
|
+
- Every `*_id` (foreign key) column → suggest index
|
|
100
|
+
- `status + is_deleted` compound → suggest if both exist
|
|
101
|
+
- `created_at DESC` → suggest for event/log tables
|
|
102
|
+
- Ask user to confirm suggested indexes or add custom ones
|
|
79
103
|
|
|
80
104
|
---
|
|
81
105
|
|
|
82
106
|
### Phase 5 — Seed Data
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
- If yes →
|
|
87
|
-
-
|
|
107
|
+
11. Run task: `ask-table-seed-data`
|
|
108
|
+
- Ask: "Does this table need seed/initial data?"
|
|
109
|
+
- Guidance: suggest YES only for reference/master data tables
|
|
110
|
+
- If yes → run task: `collect-seed-data`
|
|
111
|
+
- Stores: `context.current_db.seed_rows[]`
|
|
88
112
|
|
|
89
113
|
---
|
|
90
114
|
|
|
91
115
|
### Phase 6 — Summary and Generate
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
-
|
|
95
|
-
- Ask: "Generate this table? (yes / no / change a value)"
|
|
96
|
-
- If change → re-run specific
|
|
97
|
-
- If no → abort
|
|
98
|
-
- If yes → proceed
|
|
99
|
-
|
|
100
|
-
**
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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.
|
|
116
|
+
12. Run task: `show-db-table-summary`
|
|
117
|
+
- Display complete table definition as it will be generated
|
|
118
|
+
- Show: table name, file number, all columns with types, indexes, seed data
|
|
119
|
+
- Ask: "Generate this table? (yes / no / change a value)"
|
|
120
|
+
- If change → re-run specific task → return to this step
|
|
121
|
+
- If no → abort, nothing created
|
|
122
|
+
- If yes → proceed
|
|
123
|
+
|
|
124
|
+
> **Multi-agent:** Delegate to `database-architect` via Task invocation for parallel execution.
|
|
125
|
+
> Read `.codeninja/tasks/generate-prisma-schema.task.md` and relevant task files before generating each file.
|
|
126
|
+
|
|
127
|
+
13. Delegate to `database-agent`:
|
|
128
|
+
- Generate: `<repo_root>/database/<db_type>/migrations/<number>-setup-tbl-<name>.sql`
|
|
129
|
+
- Update: `<repo_root>/database/<db_type>/create-schema.sql`
|
|
130
|
+
- If any indexes belong in shared file → update: `111-setup-database-indexes.sql`
|
|
131
|
+
|
|
132
|
+
14. Run task: `write-context`
|
|
133
|
+
- Append table to `context.db.schema.tables`
|
|
134
|
+
- Append to `context.db.schema.change_log`
|
|
135
|
+
- Clear `context.current_db`
|
|
136
|
+
|
|
137
|
+
15. Run task: `show-final-summary`
|
|
@@ -1,87 +1,109 @@
|
|
|
1
|
+
This workflow runs when user invokes /codeninja:db:drop
|
|
2
|
+
|
|
1
3
|
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
description:
|
|
4
|
+
type: workflow
|
|
5
|
+
name: db-drop-table
|
|
6
|
+
command: "@db:drop-table"
|
|
7
|
+
description: >
|
|
8
|
+
Generate a DROP TABLE migration file for an existing table. Removes the
|
|
9
|
+
table from context, updates create-schema.sql, and records the drop in
|
|
10
|
+
change_log. Never deletes the original setup file — history is preserved.
|
|
6
11
|
---
|
|
7
12
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
## Before Running
|
|
11
|
-
1. Call `context_read` — load `context.db.schema`
|
|
12
|
-
2. Call `context_check_stale`
|
|
13
|
+
# Workflow: @db:drop-table
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## Goal
|
|
16
|
+
Safely generate a DROP TABLE migration. The original setup file is preserved
|
|
17
|
+
for history. The schema runner will execute the drop when run.
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
19
|
+
## Rules
|
|
20
|
+
- NEVER delete the original <number>-setup-tbl-<n>.sql file
|
|
21
|
+
- ALWAYS generate a new numbered drop migration file
|
|
22
|
+
- ALWAYS warn the user about irreversibility
|
|
23
|
+
- Records in change_log with full before-state for rollback reference
|
|
20
24
|
|
|
21
25
|
---
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
## Step-by-Step Execution
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
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)
|
|
29
|
+
### Phase 1 — Target
|
|
30
|
+
1. Run task: `ask-table-name`
|
|
31
|
+
- List tables from `context.db.schema.tables`
|
|
32
|
+
- Stores: `context.current_db.table_name`
|
|
35
33
|
|
|
36
|
-
|
|
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.
|
|
34
|
+
---
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
### Phase 2 — Impact Analysis
|
|
37
|
+
2. Agent scans `context`:
|
|
38
|
+
- Check `context.api_routes` for any routes that reference this table as `primary_table`
|
|
39
|
+
- Check `context.services` for any modules using this table
|
|
40
|
+
- Check `context.db.schema.tables` for any other tables with FK columns pointing here
|
|
41
|
+
|
|
42
|
+
3. If references found:
|
|
43
|
+
- Display warning:
|
|
44
|
+
```
|
|
45
|
+
⚠ WARNING: This table is referenced by:
|
|
46
|
+
- [service]/modules/[Module] (primary_table)
|
|
47
|
+
- tbl_<other_table>.user_id → tbl_users (FK dependency)
|
|
48
|
+
|
|
49
|
+
Dropping this table will break these references.
|
|
50
|
+
Make sure to update or remove dependent code first.
|
|
51
|
+
```
|
|
52
|
+
- Ask: "Do you still want to proceed? (yes / no)"
|
|
53
|
+
- If no → abort
|
|
54
|
+
|
|
55
|
+
4. Final confirmation:
|
|
56
|
+
- Ask exactly: "Type the table name to confirm the drop."
|
|
57
|
+
- Must match exactly — if wrong → abort
|
|
58
|
+
- Stores: confirmation
|
|
45
59
|
|
|
46
60
|
---
|
|
47
61
|
|
|
48
62
|
### Phase 3 — File Numbering
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
63
|
+
5. Run task: `ask-table-file-number`
|
|
64
|
+
- Suggest: next available number
|
|
65
|
+
- Stores: `context.current_db.file_number`
|
|
52
66
|
|
|
53
67
|
---
|
|
54
68
|
|
|
55
69
|
### Phase 4 — Generate
|
|
56
70
|
|
|
57
|
-
**
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
--
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
71
|
+
> **Multi-agent:** Delegate to `database-architect` via Task invocation for parallel execution.
|
|
72
|
+
> Read `.codeninja/tasks/` before generating the drop migration file.
|
|
73
|
+
|
|
74
|
+
6. Delegate to `database-agent`:
|
|
75
|
+
- Generate: `<repo_root>/database/<db_type>/migrations/<number>-drop-tbl-<n>.sql`
|
|
76
|
+
|
|
77
|
+
File contents:
|
|
78
|
+
```sql
|
|
79
|
+
-- Drop tbl_<table_name>
|
|
80
|
+
-- Migration: <number>-drop-tbl-<n>.sql
|
|
81
|
+
-- Generated: <ISO date>
|
|
82
|
+
-- WARNING: This migration is irreversible in production.
|
|
83
|
+
-- Original table definition: <original_setup_file>
|
|
84
|
+
|
|
85
|
+
BEGIN;
|
|
86
|
+
|
|
87
|
+
DROP TABLE IF EXISTS public.<table_name> CASCADE;
|
|
88
|
+
|
|
89
|
+
COMMIT;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- Update: `database/<db_type>/create-schema.sql`
|
|
93
|
+
- Keep the original `\i <setup_file>` entry
|
|
94
|
+
- Add the drop file entry AFTER it
|
|
95
|
+
|
|
96
|
+
7. Run task: `write-context`
|
|
97
|
+
- Move table from `context.db.schema.tables` → save columns snapshot
|
|
98
|
+
- Append to `context.db.schema.change_log`:
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"type": "table_dropped",
|
|
102
|
+
"table": "<table_name>",
|
|
103
|
+
"snapshot": { "<full column list saved here>" },
|
|
104
|
+
"file": "<drop_file_path>"
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
- Clear `context.current_db`
|
|
108
|
+
|
|
109
|
+
8. Run task: `show-final-summary`
|
|
@@ -1,70 +1,102 @@
|
|
|
1
|
+
This workflow runs when user invokes /codeninja:db:index
|
|
2
|
+
|
|
1
3
|
---
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
description:
|
|
4
|
+
type: workflow
|
|
5
|
+
name: db-add-index
|
|
6
|
+
command: "@db:add-index"
|
|
7
|
+
description: >
|
|
8
|
+
Add a new index to an existing table. Determines whether the index belongs
|
|
9
|
+
in the table's own file (new tables) or in 111-setup-database-indexes.sql
|
|
10
|
+
(shared/cross-service indexes). Updates context and create-schema.sql.
|
|
6
11
|
---
|
|
7
12
|
|
|
8
|
-
#
|
|
13
|
+
# Workflow: @db:add-index
|
|
14
|
+
|
|
15
|
+
## Goal
|
|
16
|
+
Generate a properly named CREATE INDEX statement and place it in the correct
|
|
17
|
+
file. Follow all index naming conventions from database-agent.md.
|
|
9
18
|
|
|
10
|
-
|
|
11
|
-
1. Call `context_read` — load `context.db.schema`
|
|
12
|
-
2. Call `context_check_stale`
|
|
19
|
+
---
|
|
13
20
|
|
|
14
|
-
##
|
|
21
|
+
## Step-by-Step Execution
|
|
15
22
|
|
|
16
23
|
### Phase 1 — Target Table
|
|
24
|
+
1. Run task: `ask-table-name`
|
|
25
|
+
- List tables from `context.db.schema.tables`
|
|
26
|
+
- Stores: `context.current_db.table_name`
|
|
17
27
|
|
|
18
|
-
|
|
19
|
-
- Store: `context.current_db.table_name`
|
|
28
|
+
---
|
|
20
29
|
|
|
21
30
|
### Phase 2 — Index Columns
|
|
31
|
+
2. Run task: `ask-index-columns`
|
|
32
|
+
- Ask: "Which column(s) should this index cover?"
|
|
33
|
+
- List available columns from `context.db.schema.tables[<table>].columns`
|
|
34
|
+
- Allow selecting one or multiple columns (compound index)
|
|
35
|
+
- Stores: `context.current_db.index_columns[]`
|
|
36
|
+
|
|
37
|
+
3. Run task: `ask-index-sort-order`
|
|
38
|
+
- Ask: "Should any column in this index be sorted descending?"
|
|
39
|
+
- Common case: `created_at DESC`, `time DESC`
|
|
40
|
+
- If yes → ask which column(s) should be DESC
|
|
41
|
+
- Stores: `context.current_db.index_desc_columns[]`
|
|
42
|
+
|
|
43
|
+
4. Run task: `ask-index-type`
|
|
44
|
+
- Ask: "Is this a standard index or a partial index?"
|
|
45
|
+
- Options:
|
|
46
|
+
1. Standard index (covers all rows)
|
|
47
|
+
2. Partial index (only indexes rows matching a condition)
|
|
48
|
+
- If partial → ask: "Enter the WHERE condition."
|
|
49
|
+
Example: `WHERE is_deleted = FALSE`
|
|
50
|
+
- Stores: `context.current_db.index_where_clause`
|
|
22
51
|
|
|
23
|
-
|
|
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`
|
|
52
|
+
---
|
|
36
53
|
|
|
37
54
|
### Phase 3 — File Placement
|
|
55
|
+
5. Run task: `ask-index-file-placement`
|
|
56
|
+
- Ask: "Where should this index be defined?"
|
|
57
|
+
- Options:
|
|
58
|
+
1. In the table's own setup file (for new/just-created tables)
|
|
59
|
+
2. In 111-setup-database-indexes.sql (for existing tables, shared use)
|
|
60
|
+
- Auto-suggest option 2 if table already has a setup file in migrations
|
|
61
|
+
- Stores: `context.current_db.index_file`
|
|
38
62
|
|
|
39
|
-
|
|
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`
|
|
63
|
+
---
|
|
43
64
|
|
|
44
65
|
### Phase 4 — Generate
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- In
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
6. Agent auto-generates the index name following convention:
|
|
67
|
+
- In table file: `idx_<table_without_tbl_prefix>_<columns_joined>`
|
|
68
|
+
- In shared file: `idx_tbl_<table_without_tbl_prefix>_<columns_joined>`
|
|
69
|
+
- Show name to user: "Index will be named: <n> — OK? (yes / rename)"
|
|
70
|
+
|
|
71
|
+
7. Confirm: "Generate this index? (yes / no)"
|
|
72
|
+
|
|
73
|
+
> **Multi-agent:** Delegate to `database-architect` via Task invocation for parallel execution.
|
|
74
|
+
> Read `.codeninja/tasks/` before generating the index.
|
|
75
|
+
|
|
76
|
+
8. Delegate to `database-agent`:
|
|
77
|
+
- If table file placement → append to `<repo_root>/database/<db_type>/migrations/<table_file>.sql`
|
|
78
|
+
- If shared file → append to `<repo_root>/database/<db_type>/migrations/111-setup-database-indexes.sql`
|
|
79
|
+
|
|
80
|
+
Generated SQL:
|
|
81
|
+
```sql
|
|
82
|
+
-- Standard
|
|
83
|
+
CREATE INDEX <index_name> ON public.<table_name> (<col> [DESC], ...);
|
|
84
|
+
|
|
85
|
+
-- Partial
|
|
86
|
+
CREATE INDEX <index_name> ON public.<table_name> (<col> [DESC], ...)
|
|
87
|
+
WHERE <where_clause>;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
With standard header comment:
|
|
91
|
+
```sql
|
|
92
|
+
--
|
|
93
|
+
-- Name: <index_name>; Type: INDEX; Schema: public
|
|
94
|
+
--
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
9. Run task: `write-context`
|
|
98
|
+
- Append index name to `context.db.schema.tables[<table>].indexes`
|
|
99
|
+
- Append to `context.db.schema.change_log`
|
|
100
|
+
- Clear `context.current_db`
|
|
101
|
+
|
|
102
|
+
10. Run task: `show-final-summary`
|