codeninja 3.1.0 → 4.0.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 +13 -1
- 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 +219 -83
- 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 +97 -21
- package/ide/antigravity/.agents/workflows/codeninja-audit.md +112 -16
- package/ide/antigravity/.agents/workflows/codeninja-db-create.md +135 -9
- package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +107 -9
- package/ide/antigravity/.agents/workflows/codeninja-db-index.md +100 -9
- package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +162 -9
- package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +102 -8
- package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +105 -11
- package/ide/antigravity/.agents/workflows/codeninja-debug.md +94 -10
- package/ide/antigravity/.agents/workflows/codeninja-design.md +61 -14
- package/ide/antigravity/.agents/workflows/codeninja-explain.md +59 -9
- package/ide/antigravity/.agents/workflows/codeninja-init.md +518 -21
- package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +451 -9
- package/ide/antigravity/.agents/workflows/codeninja-modularize.md +332 -9
- package/ide/antigravity/.agents/workflows/codeninja-optimize.md +124 -11
- package/ide/antigravity/.agents/workflows/codeninja-refactor.md +69 -16
- package/ide/antigravity/.agents/workflows/codeninja-review.md +85 -10
- package/ide/antigravity/.agents/workflows/codeninja-sync.md +957 -16
- package/ide/antigravity/.agents/workflows/codeninja-test.md +40 -13
- package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +546 -9
- 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 +40 -38
- package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +47 -31
- package/ide/cursor/.cursor/rules/03-api-builder.mdc +30 -58
- 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 +69 -270
- 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 -87
- package/ide/cursor/.cursor/rules/05-reactjs.mdc +0 -83
- package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +0 -112
|
@@ -81,6 +81,75 @@ Include based on context values:
|
|
|
81
81
|
|
|
82
82
|
---
|
|
83
83
|
|
|
84
|
+
## Hashing Library Dependencies
|
|
85
|
+
|
|
86
|
+
Read `context.current_init.hashing_library` (or `context.services[name].hashing_library`).
|
|
87
|
+
|
|
88
|
+
If `hashing_library == "bcryptjs"`:
|
|
89
|
+
Add to `dependencies`:
|
|
90
|
+
```json
|
|
91
|
+
"bcryptjs": "^2.4.3"
|
|
92
|
+
```
|
|
93
|
+
If TypeScript (`language == "typescript"`), also add to `devDependencies`:
|
|
94
|
+
```json
|
|
95
|
+
"@types/bcryptjs": "^2.4.4"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If `hashing_library == "argon2"`:
|
|
99
|
+
Add to `dependencies`:
|
|
100
|
+
```json
|
|
101
|
+
"argon2": "^0.31.0"
|
|
102
|
+
```
|
|
103
|
+
(argon2 ships its own TypeScript types — no @types package needed)
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## ORM Dependencies
|
|
108
|
+
|
|
109
|
+
Read `context.db.orm`.
|
|
110
|
+
|
|
111
|
+
If `orm == "prisma"`:
|
|
112
|
+
Add to `dependencies`:
|
|
113
|
+
```json
|
|
114
|
+
"@prisma/client": "^5.0.0"
|
|
115
|
+
```
|
|
116
|
+
Add to `devDependencies`:
|
|
117
|
+
```json
|
|
118
|
+
"prisma": "^5.0.0"
|
|
119
|
+
```
|
|
120
|
+
Add to `scripts`:
|
|
121
|
+
```json
|
|
122
|
+
"postinstall": "prisma generate"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## TypeScript Package.json Additions
|
|
128
|
+
|
|
129
|
+
When `context.current_init.language == "typescript"`:
|
|
130
|
+
|
|
131
|
+
Replace the default `"start": "node app.js"` with these scripts:
|
|
132
|
+
```json
|
|
133
|
+
"dev": "nodemon --exec ts-node app.ts",
|
|
134
|
+
"build": "tsc",
|
|
135
|
+
"start": "node dist/app.js",
|
|
136
|
+
"start:dev": "ts-node app.ts"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Add to `devDependencies`:
|
|
140
|
+
```json
|
|
141
|
+
"typescript": "^5.4.0",
|
|
142
|
+
"ts-node": "^10.9.2",
|
|
143
|
+
"nodemon": "^3.1.0",
|
|
144
|
+
"@types/node": "^20.14.0",
|
|
145
|
+
"@types/express": "^4.17.21",
|
|
146
|
+
"@types/cors": "^2.8.17"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Note: If `hashing_library == "bcryptjs"`, also add `"@types/bcryptjs": "^2.4.4"` to devDependencies (already covered in Hashing Library Dependencies section — do not duplicate).
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
84
153
|
## Dev Dependencies (always included)
|
|
85
154
|
```json
|
|
86
155
|
"devDependencies": {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: task
|
|
3
|
+
name: generate-prisma-client
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Task: generate-prisma-client
|
|
7
|
+
|
|
8
|
+
Condition: only run if `context.db.orm == "prisma"`. Otherwise skip entirely.
|
|
9
|
+
|
|
10
|
+
Read: `context.current_init.language`
|
|
11
|
+
|
|
12
|
+
Generate: `<service_name>/config/prisma.js` OR `<service_name>/config/prisma.ts`
|
|
13
|
+
|
|
14
|
+
This file is the shared PrismaClient singleton. Model files import from here — never
|
|
15
|
+
instantiate PrismaClient directly in model files (creates multiple connection pools).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## JavaScript variant
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
const { PrismaClient } = require('@prisma/client');
|
|
23
|
+
|
|
24
|
+
const prisma = new PrismaClient({
|
|
25
|
+
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
module.exports = prisma;
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## TypeScript variant
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { PrismaClient } from '@prisma/client';
|
|
37
|
+
|
|
38
|
+
const prisma = new PrismaClient({
|
|
39
|
+
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export default prisma;
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Import rule (enforce in all model files)
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
// CORRECT — import the singleton
|
|
51
|
+
const prisma = require('../../config/prisma');
|
|
52
|
+
|
|
53
|
+
// WRONG — never instantiate directly in model files
|
|
54
|
+
const { PrismaClient } = require('@prisma/client');
|
|
55
|
+
const prisma = new PrismaClient(); // creates a new connection pool per instantiation
|
|
56
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: task
|
|
3
|
+
name: generate-prisma-schema
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Task: generate-prisma-schema
|
|
7
|
+
|
|
8
|
+
Condition: only run if `context.db.orm == "prisma"`. Otherwise skip entirely.
|
|
9
|
+
|
|
10
|
+
Read: `context.db.type`, `context.db.name`
|
|
11
|
+
|
|
12
|
+
Generate: `<service_name>/prisma/schema.prisma`
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## PostgreSQL
|
|
17
|
+
|
|
18
|
+
```prisma
|
|
19
|
+
generator client {
|
|
20
|
+
provider = "prisma-client-js"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
datasource db {
|
|
24
|
+
provider = "postgresql"
|
|
25
|
+
url = env("DATABASE_URL")
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Models are added by the @db:create-table command.
|
|
29
|
+
// Each tbl_* table maps to a PascalCase Prisma model.
|
|
30
|
+
// Example: tbl_users → model Users { ... } with @@map("tbl_users")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## MySQL
|
|
36
|
+
|
|
37
|
+
```prisma
|
|
38
|
+
generator client {
|
|
39
|
+
provider = "prisma-client-js"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
datasource db {
|
|
43
|
+
provider = "mysql"
|
|
44
|
+
url = env("DATABASE_URL")
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Models are added by the @db:create-table command.
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## MongoDB
|
|
53
|
+
|
|
54
|
+
```prisma
|
|
55
|
+
generator client {
|
|
56
|
+
provider = "prisma-client-js"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
datasource db {
|
|
60
|
+
provider = "mongodb"
|
|
61
|
+
url = env("DATABASE_URL")
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Models are added by the @db:create-table command.
|
|
65
|
+
// Note: MongoDB requires a replica set URL for Prisma.
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
After generating, inform the user:
|
|
71
|
+
"Run `npx prisma generate` after adding models to regenerate the Prisma client."
|
|
@@ -16,6 +16,26 @@ as all other responses in the service.
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
+
## Language Branch
|
|
20
|
+
|
|
21
|
+
Read `context.current_init.language` (or `context.services[name].language`).
|
|
22
|
+
|
|
23
|
+
**TypeScript — generate `middleware/rateLimiter.ts`:**
|
|
24
|
+
```typescript
|
|
25
|
+
import rateLimit from 'express-rate-limit';
|
|
26
|
+
|
|
27
|
+
export const rateLimiter = rateLimit({
|
|
28
|
+
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS || '900000', 10),
|
|
29
|
+
max: parseInt(process.env.RATE_LIMIT_MAX || '100', 10),
|
|
30
|
+
standardHeaders: true,
|
|
31
|
+
legacyHeaders: false,
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**JavaScript — generate `middleware/rateLimiter.js` (existing behavior — see below)**
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
19
39
|
## Dependencies to Import
|
|
20
40
|
|
|
21
41
|
- `express-rate-limit` — the rate limiting library. Imported as
|
|
@@ -14,6 +14,30 @@ from context to produce a readme specific to this service.
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
+
## TypeScript README additions
|
|
18
|
+
|
|
19
|
+
When `language == "typescript"`, add these commands to the generated README under a `## Development` heading:
|
|
20
|
+
|
|
21
|
+
```markdown
|
|
22
|
+
## Development
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm run dev # Start with ts-node (hot reload, no build)
|
|
26
|
+
npm run build # Compile TypeScript to dist/
|
|
27
|
+
npm start # Run compiled output (production)
|
|
28
|
+
npm test # Run Jest tests
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**First-time TypeScript setup:**
|
|
32
|
+
```bash
|
|
33
|
+
npm install
|
|
34
|
+
npm run build
|
|
35
|
+
npm start
|
|
36
|
+
```
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
17
41
|
## Sections to Include
|
|
18
42
|
|
|
19
43
|
---
|
|
@@ -15,6 +15,33 @@ response shape in one place.
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
+
## Language Branch
|
|
19
|
+
|
|
20
|
+
Read `context.current_init.language` (or `context.services[name].language`).
|
|
21
|
+
|
|
22
|
+
**TypeScript — generate `response.ts`:**
|
|
23
|
+
```typescript
|
|
24
|
+
import { Request, Response } from 'express';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Sends a standardized API response, encrypting if transport is encrypted.
|
|
28
|
+
*
|
|
29
|
+
* @param {Request} req - Express request object.
|
|
30
|
+
* @param {Response} res - Express response object.
|
|
31
|
+
* @param {number} code - Response code: 1 = success, 0 = error, -1 = session expired.
|
|
32
|
+
* @param {string} messageKey - Localization key for the message.
|
|
33
|
+
* @param {unknown[]} data - Response data array.
|
|
34
|
+
* @returns {Response} The Express response.
|
|
35
|
+
*/
|
|
36
|
+
export function sendResponse(req: Request, res: Response, code: number, messageKey: string, data: unknown[]): Response {
|
|
37
|
+
// implementation same as JS variant
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**JavaScript — generate `response.js` (existing behavior — see below)**
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
18
45
|
## Dependencies to Import
|
|
19
46
|
|
|
20
47
|
- `../utilities/encryption` — imports `encrypt` only
|
|
@@ -15,6 +15,38 @@ new module means adding exactly one line to this file.
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
+
## Language Branch
|
|
19
|
+
|
|
20
|
+
Read `context.current_init.language` (or `context.services[name].language`).
|
|
21
|
+
|
|
22
|
+
**TypeScript — generate `route_manager.ts`:**
|
|
23
|
+
```typescript
|
|
24
|
+
import { Router } from 'express';
|
|
25
|
+
import { rateLimiter } from '../../middleware/rateLimiter';
|
|
26
|
+
import {
|
|
27
|
+
extractLanguage,
|
|
28
|
+
validateApiKey,
|
|
29
|
+
validateAuthToken,
|
|
30
|
+
decryptRequest
|
|
31
|
+
} from '../../middleware/headerValidator';
|
|
32
|
+
import <ModuleName>Router from './<ModuleName>/route';
|
|
33
|
+
|
|
34
|
+
const router = Router();
|
|
35
|
+
|
|
36
|
+
router.use(rateLimiter);
|
|
37
|
+
router.use(extractLanguage);
|
|
38
|
+
router.use(validateApiKey);
|
|
39
|
+
// router.use(validateAuthToken); // uncomment for protected routes
|
|
40
|
+
router.use(decryptRequest);
|
|
41
|
+
router.use('/<path>', <ModuleName>Router);
|
|
42
|
+
|
|
43
|
+
export { router };
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**JavaScript — generate `route_manager.js` (existing behavior — see below)**
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
18
50
|
## Dependencies to Import
|
|
19
51
|
|
|
20
52
|
- `express` — for `express.Router()`.
|
|
@@ -19,6 +19,43 @@ primary table, and auth requirements for the new route being added.
|
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
+
## Language Branch
|
|
23
|
+
|
|
24
|
+
Read `context.current_init.language` (or `context.services[name].language`).
|
|
25
|
+
|
|
26
|
+
**TypeScript — generate `route.ts`:**
|
|
27
|
+
```typescript
|
|
28
|
+
import { Router, Request, Response } from 'express';
|
|
29
|
+
import Validator from 'validatorjs';
|
|
30
|
+
import { sendResponse } from '../../utilities/response';
|
|
31
|
+
import * as Model from './<module>_model';
|
|
32
|
+
|
|
33
|
+
const router = Router();
|
|
34
|
+
|
|
35
|
+
// POST /<path> — <endpoint description>
|
|
36
|
+
router.post('/<path>', async (req: Request, res: Response) => {
|
|
37
|
+
const rules: Record<string, string> = {
|
|
38
|
+
field: 'required|string'
|
|
39
|
+
};
|
|
40
|
+
const validation = new Validator(req.body, rules);
|
|
41
|
+
if (validation.fails()) {
|
|
42
|
+
return sendResponse(req, res, 0, 'validation_error', validation.errors.all());
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const result = await Model.functionName(req.body, 0, '');
|
|
46
|
+
return sendResponse(req, res, result.responsecode, result.responsemsg, result.responsedata);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
return sendResponse(req, res, 0, 'server_error', []);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export default router;
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**JavaScript — generate `route.js` (existing behavior — see below)**
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
22
59
|
## Dependencies to Import
|
|
23
60
|
|
|
24
61
|
- `express` — for `express.Router()`
|
|
@@ -17,6 +17,14 @@ returns.
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
+
## Language Branch
|
|
21
|
+
|
|
22
|
+
TypeScript services generate the same `swagger_doc.json` file as JavaScript services.
|
|
23
|
+
The swagger document is always JSON — no TypeScript syntax is involved.
|
|
24
|
+
No branching needed for this task — generate identically for both languages.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
20
28
|
## Generation Modes
|
|
21
29
|
|
|
22
30
|
This task is called in two different situations. The agent reads the
|
|
@@ -16,6 +16,18 @@ fully responsive, and styled for modern email clients.
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
+
## Language Branch
|
|
20
|
+
|
|
21
|
+
Read `context.current_init.language` (or `context.services[name].language`).
|
|
22
|
+
|
|
23
|
+
**TypeScript — generate `config/template.ts`:**
|
|
24
|
+
Same email/notification template content as JS variant.
|
|
25
|
+
Use `export const` and add string type annotations where applicable.
|
|
26
|
+
|
|
27
|
+
**JavaScript — generate `config/template.js` (existing behavior — see below)**
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
19
31
|
## Dependencies to Import
|
|
20
32
|
|
|
21
33
|
- `./constants` — imported as `GLOBALS`. Used for APP_NAME, LOGO,
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: task
|
|
3
|
+
name: generate-tsconfig
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Task: generate-tsconfig
|
|
7
|
+
|
|
8
|
+
Condition: only run if `context.current_init.language == "typescript"`. Otherwise skip entirely.
|
|
9
|
+
|
|
10
|
+
Generate: `<service_name>/tsconfig.json`
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"compilerOptions": {
|
|
15
|
+
"target": "ES2020",
|
|
16
|
+
"module": "commonjs",
|
|
17
|
+
"lib": ["ES2020"],
|
|
18
|
+
"outDir": "./dist",
|
|
19
|
+
"rootDir": "./",
|
|
20
|
+
"strict": true,
|
|
21
|
+
"esModuleInterop": true,
|
|
22
|
+
"skipLibCheck": true,
|
|
23
|
+
"forceConsistentCasingInFileNames": true,
|
|
24
|
+
"resolveJsonModule": true,
|
|
25
|
+
"declaration": true,
|
|
26
|
+
"declarationMap": true,
|
|
27
|
+
"sourceMap": true
|
|
28
|
+
},
|
|
29
|
+
"include": [
|
|
30
|
+
"./**/*.ts"
|
|
31
|
+
],
|
|
32
|
+
"exclude": [
|
|
33
|
+
"node_modules",
|
|
34
|
+
"dist",
|
|
35
|
+
"**/*.test.ts"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
```
|
|
@@ -15,6 +15,37 @@ invalid input without throwing.
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
+
## Language Branch
|
|
19
|
+
|
|
20
|
+
Read `context.current_init.language` (or `context.services[name].language`).
|
|
21
|
+
|
|
22
|
+
**TypeScript — generate `utilities/validator.ts`:**
|
|
23
|
+
```typescript
|
|
24
|
+
import Validator from 'validatorjs';
|
|
25
|
+
import { Request, Response, NextFunction } from 'express';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Validates request body against validatorjs rules; calls next() if valid, sends 400 if not.
|
|
29
|
+
*
|
|
30
|
+
* @param {Record<string, string>} rules - Validatorjs rule object.
|
|
31
|
+
* @returns Express middleware function.
|
|
32
|
+
*/
|
|
33
|
+
export function checkValidationRules(rules: Record<string, string>) {
|
|
34
|
+
return (req: Request, res: Response, next: NextFunction): void => {
|
|
35
|
+
const validation = new Validator(req.body, rules);
|
|
36
|
+
if (validation.fails()) {
|
|
37
|
+
res.status(400).json({ status: 0, message: 'Validation failed', data: validation.errors.all() });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
next();
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**JavaScript — generate `utilities/validator.js` (existing behavior — see below)**
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
18
49
|
## Dependencies to Import
|
|
19
50
|
|
|
20
51
|
- `validatorjs` — imported as `Validator` (capital V). This is the
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: codeninja database standards — loaded for SQL migration files and database work
|
|
3
|
-
globs: ["**/database/**", "**/*.sql", "**/migrations/**"]
|
|
4
|
-
alwaysApply: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# codeninja — Database Architect
|
|
8
|
-
|
|
9
|
-
## Before Any SQL Generation
|
|
10
|
-
Call `migration_next_number` MCP tool. NEVER invent table or column names.
|
|
11
|
-
Load `context.db` fully. `database/` folder ALWAYS at repository root.
|
|
12
|
-
|
|
13
|
-
## Naming (strict — no exceptions)
|
|
14
|
-
| Element | Rule | Example |
|
|
15
|
-
|---------|------|---------|
|
|
16
|
-
| Table | `tbl_` prefix, lowercase, plural | `tbl_users` |
|
|
17
|
-
| Column | lowercase snake_case | `user_id`, `created_at` |
|
|
18
|
-
| PK | `id` bigint identity, first | always |
|
|
19
|
-
| FK | `<table_singular_no_prefix>_id` | `user_id` → `tbl_users` |
|
|
20
|
-
| Index (per-table) | `idx_<table_no_prefix>_<cols>` | `idx_users_email` |
|
|
21
|
-
| Index (global) | `idx_tbl_<table>_<cols>` | `idx_tbl_users_email_is_deleted` |
|
|
22
|
-
| Create file | `<N>-setup-tbl-<n>.sql` | `3-setup-tbl-users.sql` |
|
|
23
|
-
| Alter file | `<N>-alter-tbl-<n>-<desc>.sql` | `12-alter-tbl-users-add-kyc.sql` |
|
|
24
|
-
| Drop file | `<N>-drop-tbl-<n>.sql` | `13-drop-tbl-sessions.sql` |
|
|
25
|
-
| Shared indexes | `111-setup-database-indexes.sql` | always last |
|
|
26
|
-
|
|
27
|
-
## Primary Key (exact format)
|
|
28
|
-
```sql
|
|
29
|
-
id bigint NOT NULL GENERATED ALWAYS AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1),
|
|
30
|
-
```
|
|
31
|
-
`PRIMARY KEY (id)` at END of column block — never inline.
|
|
32
|
-
|
|
33
|
-
## Column Types
|
|
34
|
-
| Use | Type |
|
|
35
|
-
|-----|------|
|
|
36
|
-
| FK | `BIGINT NOT NULL DEFAULT 0` |
|
|
37
|
-
| Names | `VARCHAR(64)`–`VARCHAR(255)` |
|
|
38
|
-
| Short codes | `VARCHAR(8)`–`VARCHAR(32)` |
|
|
39
|
-
| Email | `VARCHAR(132)` |
|
|
40
|
-
| Token/password | `TEXT` |
|
|
41
|
-
| Timestamp | `TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP` |
|
|
42
|
-
| Status flag | `INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0, 1))` |
|
|
43
|
-
| Soft delete | `BOOLEAN NOT NULL DEFAULT FALSE` |
|
|
44
|
-
| Price | `NUMERIC(18,8) NOT NULL DEFAULT 0.00000000` |
|
|
45
|
-
| JSON | `JSON NOT NULL DEFAULT '{}'` |
|
|
46
|
-
|
|
47
|
-
NEVER use PostgreSQL ENUM — always `VARCHAR + CHECK constraint`.
|
|
48
|
-
Apply `NOT NULL` to every column by default.
|
|
49
|
-
|
|
50
|
-
## SQL File Content Order (strict)
|
|
51
|
-
```
|
|
52
|
-
1. -- Comment: Creating <table> for <purpose>
|
|
53
|
-
2. DROP TABLE IF EXISTS public.<table> CASCADE;
|
|
54
|
-
3. CREATE TABLE block (id first, timestamps last)
|
|
55
|
-
4. COMMENT ON COLUMN for every enum/flag column
|
|
56
|
-
5. Per-table CREATE INDEX statements
|
|
57
|
-
6. ALTER TABLE public.<table> OWNER TO <context.db.user>;
|
|
58
|
-
7. GRANT ALL ON TABLE public.<table> TO <context.db.user>;
|
|
59
|
-
8. INSERT seed data (reference tables only)
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Required Columns
|
|
63
|
-
| Column | Every table | Entity tables | Log tables |
|
|
64
|
-
|--------|------------|---------------|------------|
|
|
65
|
-
| `id` | ✓ | ✓ | ✓ |
|
|
66
|
-
| `created_at` | ✓ | ✓ | ✓ |
|
|
67
|
-
| `status` | — | ✓ | — |
|
|
68
|
-
| `is_deleted` | — | ✓ | — |
|
|
69
|
-
|
|
70
|
-
## Index Rules — Always Index
|
|
71
|
-
- Every FK column
|
|
72
|
-
- `(status, is_deleted)` compound on entity tables
|
|
73
|
-
- `created_at DESC` on log/event tables
|
|
74
|
-
- `email` compound with `is_deleted` on user tables
|
|
75
|
-
- Any WHERE or ORDER BY column in business queries
|
|
76
|
-
|
|
77
|
-
## create-schema.sql
|
|
78
|
-
Lives at `<repo_root>/database/<db_type>/create-schema.sql`. Auto-generated, never hand-edited.
|
|
79
|
-
After every table operation: update `\i` entries in numeric order.
|
|
80
|
-
`111-setup-database-indexes.sql` always last.
|
|
81
|
-
|
|
82
|
-
## Permissions (end of every file)
|
|
83
|
-
```sql
|
|
84
|
-
ALTER TABLE public.<table> OWNER TO <context.db.user>;
|
|
85
|
-
GRANT ALL ON TABLE public.<table> TO <context.db.user>;
|
|
86
|
-
```
|
|
87
|
-
Always from `context.db.user` — never hardcode username.
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: codeninja ReactJS standards — loaded for React app files
|
|
3
|
-
globs: ["**/src/**", "**/public/**", "**/*.jsx", "**/*.css", "**/apiClient*", "**/apiHandler*"]
|
|
4
|
-
alwaysApply: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# codeninja — ReactJS Frontend
|
|
8
|
-
|
|
9
|
-
## Backend Linking (enforced before any generation)
|
|
10
|
-
```
|
|
11
|
-
context.current_init.linked_service → backend service name
|
|
12
|
-
context.services[linked].port → REACT_APP_BASE_URL
|
|
13
|
-
context.services[linked].encryption_key → REACT_APP_KEY
|
|
14
|
-
context.services[linked].encryption_iv → REACT_APP_IV
|
|
15
|
-
context.services[linked].api_key → REACT_APP_API_KEY
|
|
16
|
-
```
|
|
17
|
-
These 4 values are ALWAYS inherited. NEVER ask the user. NEVER hardcode.
|
|
18
|
-
|
|
19
|
-
## File Structure
|
|
20
|
-
```
|
|
21
|
-
<service>/
|
|
22
|
-
public/
|
|
23
|
-
assets/css/style.css ← global styles
|
|
24
|
-
index.html ← single HTML shell
|
|
25
|
-
.htaccess ← Apache SPA rewrite
|
|
26
|
-
src/
|
|
27
|
-
api/
|
|
28
|
-
apiClient.js ← Axios + encrypt/decrypt interceptors
|
|
29
|
-
apiHandler.js ← one export per API endpoint
|
|
30
|
-
components/ ← shared reusable components
|
|
31
|
-
pages/Welcome/
|
|
32
|
-
index.jsx
|
|
33
|
-
Welcome.module.css
|
|
34
|
-
App.jsx ← React Router root
|
|
35
|
-
index.jsx ← ReactDOM.createRoot
|
|
36
|
-
.env ← gitignored
|
|
37
|
-
.env.example ← committed, values blank
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## apiClient.js — 4 Responsibilities
|
|
41
|
-
1. Static headers: `api-key`, `Accept-Language`, `Content-Type: text/plain`
|
|
42
|
-
2. Request: encrypt body via AES-256-CBC; attach encrypted `token` from `localStorage('wa_token')` if present
|
|
43
|
-
3. Response success: decrypt body; parse JSON; if `status === -1` → `logOutRedirectCall()`; if decrypt fails → return raw
|
|
44
|
-
4. Response error: `ERR_NETWORK` or `401` → `logOutRedirectCall()` + `showErrorMessage()`
|
|
45
|
-
|
|
46
|
-
KEY/IV: `CryptoJS.enc.Hex.parse(process.env.REACT_APP_KEY/IV)`.
|
|
47
|
-
`logOutRedirectCall` and `showErrorMessage` imported from `../pages/common/Utils`.
|
|
48
|
-
|
|
49
|
-
## apiHandler.js — Pattern
|
|
50
|
-
```javascript
|
|
51
|
-
export const functionName = async (data) => {
|
|
52
|
-
const res = await axiosClient.post('/path', data);
|
|
53
|
-
return res.data;
|
|
54
|
-
};
|
|
55
|
-
```
|
|
56
|
-
- One async function per endpoint — no try/catch, no decryption
|
|
57
|
-
- Session saving in handler, not in UI components
|
|
58
|
-
- Functions match routes in `context.api_routes` for linked service
|
|
59
|
-
|
|
60
|
-
## Code Style
|
|
61
|
-
- Functional components only — no class components
|
|
62
|
-
- JSDoc above every exported function and component
|
|
63
|
-
- No inline styles — `.module.css` per page, `global.css` shared
|
|
64
|
-
- No `console.log` — use `showMessage` / `showErrorMessage`
|
|
65
|
-
- No hardcoded API paths — all calls through `apiHandler.js`
|
|
66
|
-
|
|
67
|
-
## .env Contents
|
|
68
|
-
```
|
|
69
|
-
REACT_APP_BASE_URL=http://localhost:<linked_port>/api/v1/
|
|
70
|
-
REACT_APP_API_KEY=<inherited>
|
|
71
|
-
REACT_APP_KEY=<inherited>
|
|
72
|
-
REACT_APP_IV=<inherited>
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## @modularize
|
|
76
|
-
Scan pages, find repeated layout blocks, extract to `src/components/<Name>/`.
|
|
77
|
-
Rewrite pages to use component. Never change data-fetching or state.
|
|
78
|
-
|
|
79
|
-
## @validate-page
|
|
80
|
-
Client-side only. Per-field error messages below inputs. Preferred library from user.
|
|
81
|
-
|
|
82
|
-
## @integrate-api
|
|
83
|
-
Add handler in `apiHandler.js`. Wire buttons/forms. Add loading, error, success states.
|