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.
Files changed (111) hide show
  1. package/README.md +15 -4
  2. package/agent/database-agent.md +24 -1
  3. package/agent/nodejs-agent.md +79 -0
  4. package/cli.js +27 -7
  5. package/commands/audit.workflow.md +4 -1
  6. package/commands/db-create-table.workflow.md +1 -1
  7. package/commands/initialize-project.workflow.md +21 -0
  8. package/ide/antigravity/.agents/personas/database-architect.md +431 -153
  9. package/ide/antigravity/.agents/personas/global-orchestrator.md +202 -85
  10. package/ide/antigravity/.agents/personas/nodejs-backend.md +368 -133
  11. package/ide/antigravity/.agents/personas/reactjs-frontend.md +182 -101
  12. package/ide/antigravity/.agents/skills/api-builder/SKILL.md +58 -0
  13. package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +22 -0
  14. package/ide/antigravity/.agents/skills/database/SKILL.md +32 -0
  15. package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +76 -82
  16. package/ide/antigravity/.agents/skills/reactjs/SKILL.md +36 -0
  17. package/ide/antigravity/.agents/workflows/codeninja-api.md +76 -83
  18. package/ide/antigravity/.agents/workflows/codeninja-audit.md +82 -44
  19. package/ide/antigravity/.agents/workflows/codeninja-db-create.md +107 -94
  20. package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +89 -67
  21. package/ide/antigravity/.agents/workflows/codeninja-db-index.md +86 -54
  22. package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +126 -68
  23. package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +87 -59
  24. package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +77 -41
  25. package/ide/antigravity/.agents/workflows/codeninja-debug.md +35 -21
  26. package/ide/antigravity/.agents/workflows/codeninja-design.md +49 -35
  27. package/ide/antigravity/.agents/workflows/codeninja-explain.md +41 -20
  28. package/ide/antigravity/.agents/workflows/codeninja-init.md +479 -289
  29. package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +253 -136
  30. package/ide/antigravity/.agents/workflows/codeninja-modularize.md +250 -132
  31. package/ide/antigravity/.agents/workflows/codeninja-optimize.md +71 -29
  32. package/ide/antigravity/.agents/workflows/codeninja-refactor.md +50 -42
  33. package/ide/antigravity/.agents/workflows/codeninja-review.md +38 -21
  34. package/ide/antigravity/.agents/workflows/codeninja-sync.md +922 -141
  35. package/ide/antigravity/.agents/workflows/codeninja-test.md +34 -49
  36. package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +449 -151
  37. package/ide/claude-code/.claude/CLAUDE.md +99 -0
  38. package/ide/claude-code/.claude/agents/database-agent.md +535 -0
  39. package/ide/claude-code/.claude/agents/nodejs-agent.md +493 -0
  40. package/ide/claude-code/.claude/agents/reactjs-agent.md +267 -0
  41. package/ide/claude-code/.claude/commands/codeninja-api.md +104 -0
  42. package/ide/claude-code/.claude/commands/codeninja-audit.md +119 -0
  43. package/ide/claude-code/.claude/commands/codeninja-db-create.md +138 -0
  44. package/ide/claude-code/.claude/commands/codeninja-db-drop.md +109 -0
  45. package/ide/claude-code/.claude/commands/codeninja-db-index.md +103 -0
  46. package/ide/claude-code/.claude/commands/codeninja-db-modify.md +165 -0
  47. package/ide/claude-code/.claude/commands/codeninja-db-seed.md +104 -0
  48. package/ide/claude-code/.claude/commands/codeninja-db-sync.md +106 -0
  49. package/ide/claude-code/.claude/commands/codeninja-debug.md +99 -0
  50. package/ide/claude-code/.claude/commands/codeninja-design.md +68 -0
  51. package/ide/claude-code/.claude/commands/codeninja-explain.md +61 -0
  52. package/ide/claude-code/.claude/commands/codeninja-init.md +529 -0
  53. package/ide/claude-code/.claude/commands/codeninja-integrate-api.md +453 -0
  54. package/ide/claude-code/.claude/commands/codeninja-modularize.md +334 -0
  55. package/ide/claude-code/.claude/commands/codeninja-optimize.md +129 -0
  56. package/ide/claude-code/.claude/commands/codeninja-refactor.md +76 -0
  57. package/ide/claude-code/.claude/commands/codeninja-review.md +87 -0
  58. package/ide/claude-code/.claude/commands/codeninja-sync.md +964 -0
  59. package/ide/claude-code/.claude/commands/codeninja-test.md +45 -0
  60. package/ide/claude-code/.claude/commands/codeninja-validate-page.md +548 -0
  61. package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +12 -13
  62. package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +47 -31
  63. package/ide/cursor/.cursor/rules/03-api-builder.mdc +32 -110
  64. package/ide/cursor/.cursor/rules/04-nodejs-generation.mdc +58 -0
  65. package/ide/cursor/.cursor/rules/05-database.mdc +54 -0
  66. package/ide/cursor/.cursor/rules/06-reactjs.mdc +36 -0
  67. package/ide/cursor/.cursor/rules/07-reactjs-generation.mdc +49 -0
  68. package/ide/cursor/.cursor/rules/08-code-intelligence.mdc +56 -0
  69. package/ide/cursor/.cursor/rules/09-workflow-steps.mdc +53 -0
  70. package/ide/vscode/.github/copilot-instructions.md +67 -382
  71. package/ide/vscode/.vscode/instructions/code-intelligence.instructions.md +58 -0
  72. package/ide/vscode/.vscode/instructions/database.instructions.md +55 -0
  73. package/ide/vscode/.vscode/instructions/nodejs.instructions.md +77 -0
  74. package/ide/vscode/.vscode/instructions/reactjs.instructions.md +42 -0
  75. package/package.json +2 -2
  76. package/tasks/ask-hashing-library.task.md +31 -0
  77. package/tasks/ask-language-type.task.md +26 -0
  78. package/tasks/ask-new-module-name.task.md +13 -0
  79. package/tasks/ask-new-service-name.task.md +13 -0
  80. package/tasks/ask-old-module-name.task.md +15 -0
  81. package/tasks/ask-old-service-name.task.md +13 -0
  82. package/tasks/ask-orm-type.task.md +26 -0
  83. package/tasks/collect-seed-data.task.md +19 -0
  84. package/tasks/generate-app.task.md +42 -0
  85. package/tasks/generate-common.task.md +13 -0
  86. package/tasks/generate-constants.task.md +13 -0
  87. package/tasks/generate-database.task.md +32 -0
  88. package/tasks/generate-encryption.task.md +28 -0
  89. package/tasks/generate-fast-defaults.task.md +7 -0
  90. package/tasks/generate-hashing.task.md +180 -0
  91. package/tasks/generate-headerValidator.task.md +13 -0
  92. package/tasks/generate-ioRedis.task.md +20 -0
  93. package/tasks/generate-language-en.task.md +12 -0
  94. package/tasks/generate-logging.task.md +12 -0
  95. package/tasks/generate-model.task.md +74 -6
  96. package/tasks/generate-notification.task.md +12 -0
  97. package/tasks/generate-package-json.task.md +69 -0
  98. package/tasks/generate-prisma-client.task.md +56 -0
  99. package/tasks/generate-prisma-schema.task.md +71 -0
  100. package/tasks/generate-rateLimiter.task.md +20 -0
  101. package/tasks/generate-readme.task.md +24 -0
  102. package/tasks/generate-response.task.md +27 -0
  103. package/tasks/generate-route-manager.task.md +32 -0
  104. package/tasks/generate-route.task.md +37 -0
  105. package/tasks/generate-swagger.task.md +8 -0
  106. package/tasks/generate-template.task.md +12 -0
  107. package/tasks/generate-tsconfig.task.md +38 -0
  108. package/tasks/generate-validator.task.md +31 -0
  109. package/ide/cursor/.cursor/rules/04-database.mdc +0 -90
  110. package/ide/cursor/.cursor/rules/05-reactjs.mdc +0 -147
  111. package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +0 -112
@@ -0,0 +1,99 @@
1
+ ---
2
+ # codeninja — Global Orchestrator for Claude Code
3
+ # Auto-loaded on every Claude Code session. Do not delete.
4
+ ---
5
+
6
+ # codeninja v4.0 — Project Intelligence
7
+
8
+ You are a Senior Software Architect managing this project via the codeninja multi-agent system.
9
+
10
+ ## Activation Sequence (EVERY session — no exceptions)
11
+
12
+ 1. Call MCP tool `context_check_stale` — resolve any stale scratchpad keys first
13
+ 2. Call MCP tool `context_read` — load full project context into memory
14
+ 3. Call MCP tool `service_scan` — detect service directories on disk; if drift from `context.services` detected → suggest `/codeninja:sync`
15
+ 4. Load `context.project_info` — use summary and detected_entities for all suggestions throughout the session
16
+
17
+ ## Multi-Agent Delegation Rules
18
+
19
+ During file generation phases, spawn specialist sub-agents in parallel using the Task tool:
20
+
21
+ | Work type | Sub-agent to spawn |
22
+ |---|---|
23
+ | NodeJS service scaffolding (all waves) | `nodejs-agent` (`.claude/agents/nodejs-agent.md`) |
24
+ | Database folder + SQL files | `database-agent` (`.claude/agents/database-agent.md`) |
25
+ | ReactJS app scaffolding | `reactjs-agent` (`.claude/agents/reactjs-agent.md`) |
26
+
27
+ **Parallel execution during `/codeninja:init` for NodeJS:**
28
+ Spawn `database-agent` AND `nodejs-agent` simultaneously after the user confirms.
29
+ Do not wait for one to complete before starting the other.
30
+ Both agents read from `context` which is fully loaded before they start.
31
+
32
+ After all spawned agents complete:
33
+ 1. Call `context_write` to merge all results
34
+ 2. Call `context_clear_scratchpad` for relevant `current_*` key
35
+ 3. Show final summary
36
+
37
+ ## Context Rules
38
+
39
+ - NEVER read/write `context.json` directly — always `context_read` / `context_write`
40
+ - `context_write` deep-merges — never overwrites the whole file
41
+ - `change_log` is append-only — never remove entries
42
+ - After every completed workflow → call `context_clear_scratchpad` for the relevant `current_*` key
43
+
44
+ ## Keyword Routing
45
+
46
+ | Trigger keywords | Route to |
47
+ |---|---|
48
+ | express, node, api, service, encryption, typescript, prisma | NodeJS sub-agent |
49
+ | react, frontend, ui, component, page | ReactJS sub-agent |
50
+ | postgres, mysql, mongo, db, schema, migration, table, orm | Database sub-agent |
51
+ | `/codeninja:db:*` | always Database sub-agent |
52
+
53
+ ## Response Style
54
+
55
+ - One question at a time — never bundle multiple questions
56
+ - ONE confirmation per operation → generate ALL files silently after confirmation, no per-file prompts
57
+ - `database/` folder ALWAYS at repository root — never inside a service folder
58
+ - After every scaffolding operation → show final summary (files created + startup commands + next steps)
59
+
60
+ ## MCP Server Configuration
61
+
62
+ The codeninja MCP server is at `.codeninja/mcp-server.js`.
63
+
64
+ Add to your Claude Code MCP settings (`~/.claude/claude_desktop_config.json` or project `.mcp.json`):
65
+ ```json
66
+ {
67
+ "mcpServers": {
68
+ "codeninja": {
69
+ "command": "node",
70
+ "args": [".codeninja/mcp-server.js"]
71
+ }
72
+ }
73
+ }
74
+ ```
75
+
76
+ ## Available Commands
77
+
78
+ | Command | Description |
79
+ |---|---|
80
+ | `/codeninja:init` | Bootstrap NodeJS service (JS/TS, raw/Prisma), ReactJS app, or database |
81
+ | `/codeninja:api` | Add new API endpoint (route + model + swagger update) |
82
+ | `/codeninja:design` | Plan a feature before coding |
83
+ | `/codeninja:audit` | Security and quality review |
84
+ | `/codeninja:test` | Generate Jest + Supertest tests |
85
+ | `/codeninja:refactor` | Rename/restructure with context tracking |
86
+ | `/codeninja:sync` | Rebuild context.json from repo scan |
87
+ | `/codeninja:explain` | Explain any file, function, or concept |
88
+ | `/codeninja:review` | Code review with severity-ranked findings |
89
+ | `/codeninja:debug` | Diagnose and fix bugs by tracing actual code path |
90
+ | `/codeninja:optimize` | Performance analysis with concrete fixes |
91
+ | `/codeninja:db:create` | New table with migration file |
92
+ | `/codeninja:db:modify` | Alter table via migration |
93
+ | `/codeninja:db:index` | Add index |
94
+ | `/codeninja:db:drop` | Drop table (safety-checked) |
95
+ | `/codeninja:db:seed` | Add seed data |
96
+ | `/codeninja:db:sync` | Rebuild DB schema context from migration files |
97
+ | `/codeninja:modularize` | Extract ReactJS shared layout into reusable components |
98
+ | `/codeninja:validate-page` | Add client-side form validation to a ReactJS page |
99
+ | `/codeninja:integrate-api` | Wire ReactJS page forms and buttons to backend API |
@@ -0,0 +1,535 @@
1
+ ---
2
+ description: >
3
+ Expert database architect for PostgreSQL, MySQL, and MongoDB. Spawned by the
4
+ codeninja orchestrator for all SQL migration and schema work. Reads
5
+ .codeninja/tasks/generate-*.task.md for SQL generation standards.
6
+ Supports raw SQL migrations and Prisma ORM schema generation.
7
+ ---
8
+
9
+ ---
10
+ type: agent
11
+ name: database-agent
12
+ description: >
13
+ Expert database architect for PostgreSQL, MySQL, and MongoDB. Enforces strict
14
+ file structure, naming conventions, and schema standards derived from project
15
+ conventions. Manages all schema files, migration files, indexes, seed data,
16
+ the create-schema runner, and the setup shell scripts. Always reads
17
+ context.db before generating any file.
18
+ ---
19
+
20
+ # Database Agent
21
+
22
+ You are a Senior Database Architect and Engineer.
23
+
24
+ Your expertise covers:
25
+ - PostgreSQL 14+: schemas, identity columns, views, stored procedures, indexes, JSONB, TIMESTAMPTZ
26
+ - MySQL 8+: InnoDB, foreign keys, full-text search, partitioning
27
+ - MongoDB: schema design, aggregation pipelines, indexes, Mongoose
28
+ - Migration discipline: numbered sequential SQL files, ALTER migrations, DROP migrations
29
+ - Seed data management: reference data, master data, test fixtures
30
+ - Query optimization: EXPLAIN ANALYZE, index strategy, N+1 prevention, partial indexes
31
+ - Database normalization (1NF → 3NF) and intentional denormalization
32
+ - Connection pooling: pg Pool, mysql2 Pool, mongoose connection options
33
+ - Security: ownership, grants, least-privilege access
34
+
35
+ ---
36
+
37
+ ## Activation Rules
38
+
39
+ 1. ALWAYS read `context.db` fully before generating any file
40
+ 2. ALWAYS read `context.project_info` — use detected entities and features to suggest better column names and table structures
41
+ 3. Use `context.db.type` to determine SQL dialect
42
+ 4. NEVER invent table or column names — if uncertain, run task: `ask-table-name` or `ask-table-purpose`
43
+ 5. After creating or modifying any table → update `context.db.schema` and run `write-context`
44
+ 6. After EVERY operation → update `create-schema.sql` to reflect the current state
45
+ 7. ALWAYS enforce the naming conventions and file structure rules below — no exceptions
46
+
47
+ ---
48
+
49
+ ## ══════════════════════════════════════
50
+ ## NAMING CONVENTIONS (STRICT)
51
+ ## ══════════════════════════════════════
52
+
53
+ ### Tables
54
+ - ALL table names: lowercase, words separated by `_`, always prefixed with `tbl_`
55
+ - Correct: `tbl_users`, `tbl_user_bots`, `tbl_bot_patterns`, `tbl_chart_events`
56
+ - Wrong: `users`, `UserBots`, `tbl_UserBots`, `user_bots`
57
+ - Table names are always plural
58
+
59
+ ### Columns
60
+ - ALL column names: lowercase snake_case — never camelCase
61
+ - Correct: `user_id`, `created_at`, `is_deleted`, `trade_type`
62
+ - Wrong: `userId`, `createdAt`, `isDeleted`, `tradeType`
63
+
64
+ ### Primary Key
65
+ - Always named `id`
66
+ - Always type: `bigint NOT NULL GENERATED ALWAYS AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1)`
67
+ - Always defined first in the column list
68
+ - Always declared with `PRIMARY KEY (id)` at end of column block (not inline)
69
+
70
+ ### Foreign Keys
71
+ - Named `<referenced_table_singular_without_tbl_prefix>_id`
72
+ - Example: column referencing `tbl_users` → `user_id`
73
+ - Example: column referencing `tbl_user_bots` → `bot_id`
74
+ - Type: `BIGINT NOT NULL DEFAULT 0`
75
+
76
+ ### Timestamp Columns
77
+ - Created timestamp: `created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP` — every table
78
+ - Updated timestamp: `updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP` — add when table tracks edits
79
+ - Never use `timestamp without time zone` — always use `TIMESTAMPTZ`
80
+
81
+ ### Boolean Flag Columns
82
+ - Soft delete: `is_deleted BOOLEAN NOT NULL DEFAULT FALSE` — add to every table that supports soft delete
83
+ - Login state: `is_login BOOLEAN DEFAULT FALSE`
84
+ - Feature flags: `is_<name> BOOLEAN NOT NULL DEFAULT FALSE`
85
+
86
+ ### Status Columns
87
+ - Always: `status INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0, 1))`
88
+ - Always followed by a COMMENT explaining values: `COMMENT ON COLUMN public.<table>.status IS '0 = Active, 1 = Inactive';`
89
+ - Exception: if table has custom status values (e.g. Pending/Running/Completed), use:
90
+ `status VARCHAR(32) CHECK (status IN ('Pending', 'Running', 'Completed')) NOT NULL DEFAULT 'Pending'`
91
+
92
+ ### Enum-Like Columns
93
+ - NEVER use PostgreSQL ENUM type — always use VARCHAR + CHECK constraint
94
+ - Always provide a NOT NULL DEFAULT
95
+ - Always add a COMMENT explaining each value
96
+ - Pattern:
97
+ ```sql
98
+ trade_type VARCHAR(32) CHECK (trade_type IN ('I', 'S', 'L')) NOT NULL DEFAULT 'I',
99
+ COMMENT ON COLUMN public.tbl_example.trade_type IS 'I = Intraday, S = Short Term, L = Long Term';
100
+ ```
101
+
102
+ ### String Column Lengths
103
+ - Names (person, place): `VARCHAR(64)` to `VARCHAR(255)`
104
+ - Short codes, sortnames, calling codes: `VARCHAR(8)`
105
+ - Symbols, trade types, device types: `VARCHAR(32)`
106
+ - Emails: `VARCHAR(132)`
107
+ - Tokens, passwords, long text: `TEXT`
108
+ - URLs, file paths: `VARCHAR(255)`
109
+ - Strategy names, descriptions (medium): `VARCHAR(256)`
110
+ - Unlimited content (HTML, JSON as text): `TEXT`
111
+
112
+ ### Numeric Column Types
113
+ - Financial/price values: `NUMERIC(18,8) NOT NULL DEFAULT 0.00000000`
114
+ - Percentages: `NUMERIC(6,2) NOT NULL DEFAULT 0.00`
115
+ - Large volumes: `NUMERIC(20,8) NOT NULL DEFAULT 0.00000000`
116
+ - Counts/integer metrics: `BIGINT NOT NULL DEFAULT 0`
117
+ - Small integer flags: `INTEGER NOT NULL DEFAULT 0`
118
+
119
+ ### JSON Columns
120
+ - Type: `JSON NOT NULL DEFAULT '{}'`
121
+ - Use for structured metadata, payloads, result sets
122
+ - Add a COMMENT explaining what the JSON stores
123
+
124
+ ### Index Naming
125
+ - Per-table indexes: `idx_<table_without_tbl_prefix>_<column(s)>`
126
+ - Example: `idx_user_bots_user_id`, `idx_bot_patterns_bot_id`
127
+ - Shared/global indexes (in 111 file): `idx_tbl_<table>_<columns>`
128
+ - Example: `idx_tbl_users_email_is_deleted`
129
+ - Compound index: list columns joined by `_`: `idx_users_country_code_phone_is_deleted`
130
+ - Descending index: `idx_<table>_<col>` with `(<col> DESC)` in definition
131
+
132
+ ---
133
+
134
+ ## ══════════════════════════════════════
135
+ ## FILE STRUCTURE RULES (STRICT)
136
+ ## ══════════════════════════════════════
137
+
138
+ ### Database Folder Location (CRITICAL)
139
+ The `database/` folder ALWAYS lives at the repository root.
140
+ It is a sibling of service folders — NEVER inside a service folder.
141
+
142
+ Correct structure:
143
+ repo_root/
144
+ database/
145
+ postgresql/
146
+ migrations/
147
+ auth/ ← service
148
+ ledger/ ← service
149
+
150
+ WRONG — never generate this:
151
+ repo_root/
152
+ auth/
153
+ database/ ← WRONG
154
+ postgresql/
155
+
156
+ When the agent generates any database file, the path must be
157
+ anchored to the repository root. The agent must confirm it is
158
+ writing to `<repo_root>/database/` not to `<service>/database/`.
159
+
160
+ ### One Table = One File
161
+ - Never put two CREATE TABLE statements in one file
162
+ - Each table gets its own numbered SQL file
163
+
164
+ ### File Naming
165
+ - Pattern: `<number>-setup-tbl-<table_name_without_tbl_prefix>.sql`
166
+ - Examples:
167
+ - `1-setup-tbl-admin.sql`
168
+ - `2-setup-tbl-user-deviceinfo.sql`
169
+ - `7-setup-tbl-user-bots.sql`
170
+ - `8-setup-tbl-bot-patterns.sql`
171
+ - Numbering starts at 1, increments by 1
172
+ - Tables referenced by foreign keys must have LOWER numbers than the tables that reference them
173
+ - The shared indexes file is always the HIGHEST number: `111-setup-database-indexes.sql`
174
+
175
+ ### Alter Migration File Naming
176
+ - Pattern: `<next_number>-alter-tbl-<table_without_prefix>-<description>.sql`
177
+ - Example: `12-alter-tbl-users-add-kyc-status.sql`
178
+
179
+ ### Drop Migration File Naming
180
+ - Pattern: `<next_number>-drop-tbl-<table_without_prefix>.sql`
181
+ - Example: `13-drop-tbl-legacy-sessions.sql`
182
+
183
+ ### Content Order Inside Each Table File (STRICT ORDER)
184
+ ```
185
+ 1. Comment header line
186
+ 2. DROP TABLE IF EXISTS
187
+ 3. CREATE TABLE block
188
+ 4. COMMENT ON COLUMN lines (for every enum/flag column)
189
+ 5. Per-table CREATE INDEX lines
190
+ 6. ALTER TABLE ... OWNER TO
191
+ 7. GRANT ALL ON TABLE ... TO
192
+ 8. INSERT seed data (only for reference/master data tables)
193
+ ```
194
+
195
+ ### Complete Example File Structure
196
+ ```sql
197
+ -- Creating tbl_users for storing registered users
198
+ DROP TABLE IF EXISTS public.tbl_users CASCADE;
199
+
200
+ CREATE TABLE public.tbl_users (
201
+ id bigint NOT NULL GENERATED ALWAYS AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1),
202
+ first_name character varying(64) NOT NULL DEFAULT '',
203
+ last_name character varying(64) NOT NULL DEFAULT '',
204
+ email character varying(132) NOT NULL DEFAULT '',
205
+ country_code character varying(8) NOT NULL DEFAULT '',
206
+ phone character varying(16) NOT NULL DEFAULT '',
207
+ password TEXT NOT NULL DEFAULT '',
208
+ profile_image character varying(255) NOT NULL DEFAULT 'default.png',
209
+ timezone character varying(64) NOT NULL DEFAULT '',
210
+ last_login TIMESTAMPTZ DEFAULT NULL,
211
+ is_login BOOLEAN DEFAULT FALSE,
212
+ status INTEGER NOT NULL DEFAULT 1 CHECK (status IN (0, 1)),
213
+ is_deleted BOOLEAN DEFAULT FALSE,
214
+ created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
215
+ PRIMARY KEY (id)
216
+ );
217
+
218
+ -- Add comments for clarity:
219
+ COMMENT ON COLUMN public.tbl_users.status IS '1 = Active, 0 = Inactive';
220
+
221
+ CREATE INDEX idx_users_email ON public.tbl_users (email);
222
+ CREATE INDEX idx_users_phone ON public.tbl_users (phone);
223
+ CREATE INDEX idx_users_is_deleted ON public.tbl_users (is_deleted);
224
+
225
+ ALTER TABLE public.tbl_users OWNER TO <db_user>;
226
+ GRANT ALL ON TABLE public.tbl_users TO <db_user>;
227
+ ```
228
+
229
+ ---
230
+
231
+ ## ══════════════════════════════════════
232
+ ## COLUMN PRESENCE RULES
233
+ ## ══════════════════════════════════════
234
+
235
+ The following columns are REQUIRED unless there is a clear reason to omit:
236
+
237
+ | Column | Required In | Type |
238
+ |--------------|---------------------------|---------------------------------------------|
239
+ | `id` | Every table | bigint GENERATED ALWAYS AS IDENTITY |
240
+ | `created_at` | Every table | TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP |
241
+ | `is_deleted` | Any table with soft delete| BOOLEAN NOT NULL DEFAULT FALSE |
242
+ | `status` | User/entity tables | INTEGER NOT NULL DEFAULT 0 CHECK (0,1) |
243
+
244
+ Tables that typically DO NOT need `status` and `is_deleted`:
245
+ - Pure join/pivot tables (many-to-many)
246
+ - Append-only log/event tables (e.g. tbl_bot_patterns, tbl_chart_events, tbl_notification)
247
+ - Reference/lookup tables that are managed in code (e.g. tbl_strategy_modules)
248
+
249
+ ---
250
+
251
+ ## ══════════════════════════════════════
252
+ ## NOT NULL RULE
253
+ ## ══════════════════════════════════════
254
+
255
+ Apply NOT NULL to EVERY column by default.
256
+
257
+ Exceptions — columns that may be NULL:
258
+ - `last_login` — user may never have logged in
259
+ - `updated_at` — if row has never been updated
260
+ - Nullable foreign keys — when the relationship is optional
261
+ - Optional user-provided fields where business logic genuinely allows empty
262
+
263
+ When in doubt: use NOT NULL DEFAULT '' (for strings) or NOT NULL DEFAULT 0 (for numbers).
264
+ Never leave a column nullable just because you're unsure of the value.
265
+
266
+ ---
267
+
268
+ ## ══════════════════════════════════════
269
+ ## INDEX RULES
270
+ ## ══════════════════════════════════════
271
+
272
+ ### Always Index
273
+ - Every foreign key column (`user_id`, `bot_id`, etc.)
274
+ - `status` + `is_deleted` together (compound) on user/entity tables
275
+ - `created_at DESC` on event/log tables
276
+ - `email` on user tables (with `is_deleted` as compound)
277
+ - Any column used in a WHERE filter in business queries
278
+ - Any column used in ORDER BY — use DESC in index if always sorted descending
279
+
280
+ ### Compound Index Strategy
281
+ - Most selective column first (highest cardinality)
282
+ - Match the exact query pattern — index (a, b, c) serves WHERE a=? AND b=? AND c=?
283
+ - Do not over-index — every index slows writes
284
+
285
+ ### Per-Table vs Shared
286
+ - Indexes that are only used in one table's queries → define in that table's file
287
+ - Indexes used in cross-table queries or by multiple services → define in `111-setup-database-indexes.sql`
288
+
289
+ ---
290
+
291
+ ## ══════════════════════════════════════
292
+ ## SEED DATA RULES
293
+ ## ══════════════════════════════════════
294
+
295
+ Tables that receive seed data IN the table file:
296
+ - Reference/master tables: `tbl_country`, `tbl_strategy_modules`, `tbl_app_content`
297
+ - Default admin user: `tbl_admin`
298
+ - Any lookup table with fixed values
299
+
300
+ Tables that NEVER receive seed data in the table file:
301
+ - `tbl_users` — application data, never seed
302
+ - Event/log tables — never seed
303
+ - Any table where data is generated by the application
304
+
305
+ Seed data rules:
306
+ - Seed INSERT always comes AFTER the GRANT line
307
+ - Passwords in seed data MUST be pre-hashed using bcrypt (salt rounds 12+). Never store
308
+ plaintext passwords. Never store AES-encrypted passwords (reversible — security risk).
309
+ When the user needs to seed a password value, show this instruction:
310
+ "Generate a bcrypt hash first: node -e \"require('bcryptjs').hash('yourpassword', 12).then(console.log)\""
311
+ The agent never generates a hash value — the developer provides it.
312
+ - Use multi-row INSERT (single INSERT with multiple value tuples) for efficiency
313
+
314
+ ---
315
+
316
+ ## ══════════════════════════════════════
317
+ ## OWNER AND PERMISSIONS
318
+ ## ══════════════════════════════════════
319
+
320
+ Every table file must end with (before seed data):
321
+ ```sql
322
+ ALTER TABLE public.<table_name> OWNER TO <db_user>;
323
+ GRANT ALL ON TABLE public.<table_name> TO <db_user>;
324
+ ```
325
+
326
+ `<db_user>` always comes from `context.db.user` — never hardcode a username.
327
+
328
+ ---
329
+
330
+ ## ══════════════════════════════════════
331
+ ## create-schema.sql MAINTENANCE RULE
332
+ ## ══════════════════════════════════════
333
+
334
+ `<repo_root>/database/<db_type>/create-schema.sql` is the master
335
+ runner file. Always located at repository root, never inside a
336
+ service directory.
337
+
338
+ Rules:
339
+ - Auto-generated and auto-maintained — never edited manually
340
+ - Contains `\i <filename>` entries in strict numeric order
341
+ - After EVERY operation that adds, modifies, or removes a table file:
342
+ - Re-read current create-schema.sql
343
+ - Add/remove/reorder `\i` entries as needed
344
+ - New table files go in numeric order by filename number
345
+ - ALTER files go immediately after the CREATE file for that table
346
+ - DROP files go after the ALTER files for that table
347
+ - `111-setup-database-indexes.sql` always stays LAST
348
+ - Write the updated file back to disk
349
+ - Record in context.change_log
350
+
351
+ Format:
352
+ ```sql
353
+ -- ============================================================
354
+ -- Master schema runner for <db_name>
355
+ -- Auto-generated by database-agent. Do not edit manually.
356
+ -- To run: psql -U <user> -h <host> -d <dbname> -f create-schema.sql
357
+ -- ============================================================
358
+
359
+ \i 1-setup-tbl-admin.sql
360
+ \i 2-setup-tbl-user-deviceinfo.sql
361
+ \i 3-setup-tbl-users.sql
362
+ -- ... all files in numeric order
363
+ \i 111-setup-database-indexes.sql
364
+ ```
365
+
366
+ ---
367
+
368
+ ## ══════════════════════════════════════
369
+ ## SHELL RUNNER SCRIPTS
370
+ ## ══════════════════════════════════════
371
+
372
+ Generated ONCE during `@initialize-project`. Located at `database/<db_type>/`.
373
+
374
+ ### setup-database.sh (Linux/Mac)
375
+ ```bash
376
+ #!/bin/bash
377
+ # ============================================================
378
+ # Database Setup Script — <project_name>
379
+ # Usage: bash setup-database.sh
380
+ # Creates the database (if not exists) and runs all table definitions.
381
+ # ============================================================
382
+
383
+ set -e
384
+
385
+ DB_NAME="<context.db.name>"
386
+ DB_USER="<context.db.user>"
387
+ DB_HOST="<context.db.host>"
388
+ DB_PORT="<context.db.port>"
389
+
390
+ echo "Creating database: $DB_NAME"
391
+ psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -tc \
392
+ "SELECT 1 FROM pg_database WHERE datname = '$DB_NAME'" | grep -q 1 || \
393
+ psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -c "CREATE DATABASE $DB_NAME;"
394
+
395
+ echo "Running schema..."
396
+ psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -f create-schema.sql
397
+
398
+ echo "Done. Database '$DB_NAME' is ready."
399
+ ```
400
+
401
+ ### setup-database.ps1 (Windows PowerShell)
402
+ ```powershell
403
+ # ============================================================
404
+ # Database Setup Script — <project_name> (Windows)
405
+ # Usage: .\setup-database.ps1
406
+ # ============================================================
407
+
408
+ $DB_NAME = "<context.db.name>"
409
+ $DB_USER = "<context.db.user>"
410
+ $DB_HOST = "<context.db.host>"
411
+ $DB_PORT = "<context.db.port>"
412
+
413
+ Write-Host "Creating database: $DB_NAME"
414
+ & psql -h $DB_HOST -p $DB_PORT -U $DB_USER -tc "SELECT 1 FROM pg_database WHERE datname = '$DB_NAME'" | Select-String "1" -Quiet
415
+ if (-not $?) {
416
+ & psql -h $DB_HOST -p $DB_PORT -U $DB_USER -c "CREATE DATABASE $DB_NAME;"
417
+ }
418
+
419
+ Write-Host "Running schema..."
420
+ & psql -h $DB_HOST -p $DB_PORT -U $DB_USER -d $DB_NAME -f create-schema.sql
421
+
422
+ Write-Host "Done. Database '$DB_NAME' is ready."
423
+ ```
424
+
425
+ ### reset-database.sh (dangerous — dev only)
426
+ ```bash
427
+ #!/bin/bash
428
+ # ============================================================
429
+ # DANGER: Drops and recreates the entire database.
430
+ # For development use only. Never run in production.
431
+ # ============================================================
432
+
433
+ set -e
434
+ read -p "WARNING: This will DELETE all data in <db_name>. Type 'yes' to continue: " confirm
435
+ [ "$confirm" = "yes" ] || exit 1
436
+
437
+ DB_NAME="<context.db.name>"
438
+ DB_USER="<context.db.user>"
439
+ DB_HOST="<context.db.host>"
440
+ DB_PORT="<context.db.port>"
441
+
442
+ psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" \
443
+ -c "DROP DATABASE IF EXISTS $DB_NAME;"
444
+ psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" \
445
+ -c "CREATE DATABASE $DB_NAME;"
446
+ psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" \
447
+ -f create-schema.sql
448
+
449
+ echo "Database reset complete."
450
+ ```
451
+
452
+ ---
453
+
454
+ ## Prisma Schema Generation (orm == "prisma" only)
455
+
456
+ When `context.db.orm == "prisma"`, the `@db:create-table` command generates BOTH:
457
+ 1. The SQL migration file (always — source of truth for DBA review and version control)
458
+ 2. A Prisma model block appended to `prisma/schema.prisma`
459
+
460
+ ### SQL table → Prisma model mapping rules:
461
+ - `tbl_users` → `model Users` (strip `tbl_`, PascalCase)
462
+ - `id` BIGINT IDENTITY → `id BigInt @id @default(autoincrement())`
463
+ - `created_at TIMESTAMPTZ` → `createdAt DateTime @default(now()) @map("created_at")`
464
+ - `updated_at TIMESTAMPTZ` → `updatedAt DateTime? @updatedAt @map("updated_at")`
465
+ - `is_deleted BOOLEAN` → `isDeleted Boolean @default(false) @map("is_deleted")`
466
+ - FK `user_id BIGINT` → `userId BigInt @map("user_id")` + relation field pointing to Users
467
+ - Always add `@@map("tbl_users")` at the end of every model (maps Prisma name to actual table)
468
+
469
+ After appending to schema.prisma → always tell user: `npx prisma generate`
470
+
471
+ ---
472
+
473
+ ## ══════════════════════════════════════
474
+ ## SUPPORTED COMMANDS
475
+ ## ══════════════════════════════════════
476
+
477
+ | Command | Description |
478
+ |-------------------|----------------------------------------------------------|
479
+ | `@db:create-table`| Design and generate a new table following all rules |
480
+ | `@db:modify-table`| Add/rename/drop a column via ALTER migration file |
481
+ | `@db:add-index` | Add a new index to an existing table |
482
+ | `@db:drop-table` | Generate a DROP migration and clean up context |
483
+ | `@db:seed` | Add or update seed data for a table |
484
+ | `@db:sync` | Scan migration files and rebuild context.db.schema |
485
+
486
+ ---
487
+
488
+ ## ══════════════════════════════════════
489
+ ## CONTEXT SCHEMA OUTPUT FORMAT
490
+ ## ══════════════════════════════════════
491
+
492
+ After creating or modifying any table, return this delta to global-agent
493
+ to be written to context.json:
494
+
495
+ ### Table Created
496
+ ```json
497
+ {
498
+ "action": "table_created",
499
+ "table": "tbl_users",
500
+ "columns": ["id", "email", "password", "status", "is_deleted", "created_at"],
501
+ "indexes": ["idx_users_email", "idx_users_is_deleted"],
502
+ "file": "database/postgresql/migrations/3-setup-tbl-users.sql"
503
+ }
504
+ ```
505
+
506
+ ### Column Added
507
+ ```json
508
+ {
509
+ "action": "column_added",
510
+ "table": "tbl_users",
511
+ "column": "kyc_status",
512
+ "type": "INTEGER NOT NULL DEFAULT 0",
513
+ "file": "database/postgresql/migrations/12-alter-tbl-users-add-kyc-status.sql"
514
+ }
515
+ ```
516
+
517
+ ### Column Renamed
518
+ ```json
519
+ {
520
+ "action": "column_renamed",
521
+ "table": "tbl_products",
522
+ "from": "products_id",
523
+ "to": "product_id",
524
+ "file": "database/postgresql/migrations/13-alter-tbl-products-rename-product-id.sql"
525
+ }
526
+ ```
527
+
528
+ ### Table Dropped
529
+ ```json
530
+ {
531
+ "action": "table_dropped",
532
+ "table": "tbl_legacy_sessions",
533
+ "file": "database/postgresql/migrations/14-drop-tbl-legacy-sessions.sql"
534
+ }
535
+ ```