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.
Files changed (111) hide show
  1. package/README.md +13 -1
  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 +219 -83
  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 +97 -21
  18. package/ide/antigravity/.agents/workflows/codeninja-audit.md +112 -16
  19. package/ide/antigravity/.agents/workflows/codeninja-db-create.md +135 -9
  20. package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +107 -9
  21. package/ide/antigravity/.agents/workflows/codeninja-db-index.md +100 -9
  22. package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +162 -9
  23. package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +102 -8
  24. package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +105 -11
  25. package/ide/antigravity/.agents/workflows/codeninja-debug.md +94 -10
  26. package/ide/antigravity/.agents/workflows/codeninja-design.md +61 -14
  27. package/ide/antigravity/.agents/workflows/codeninja-explain.md +59 -9
  28. package/ide/antigravity/.agents/workflows/codeninja-init.md +518 -21
  29. package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +451 -9
  30. package/ide/antigravity/.agents/workflows/codeninja-modularize.md +332 -9
  31. package/ide/antigravity/.agents/workflows/codeninja-optimize.md +124 -11
  32. package/ide/antigravity/.agents/workflows/codeninja-refactor.md +69 -16
  33. package/ide/antigravity/.agents/workflows/codeninja-review.md +85 -10
  34. package/ide/antigravity/.agents/workflows/codeninja-sync.md +957 -16
  35. package/ide/antigravity/.agents/workflows/codeninja-test.md +40 -13
  36. package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +546 -9
  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 +40 -38
  62. package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +47 -31
  63. package/ide/cursor/.cursor/rules/03-api-builder.mdc +30 -58
  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 +69 -270
  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 -87
  110. package/ide/cursor/.cursor/rules/05-reactjs.mdc +0 -83
  111. package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +0 -112
@@ -0,0 +1,13 @@
1
+ ---
2
+ type: task
3
+ name: ask-new-module-name
4
+ ---
5
+
6
+ # Task: ask-new-module-name
7
+
8
+ Ask: "Enter the new name for '[context.current_refactor.old_module_name]':"
9
+ - Validate: must not already exist in the service — error if conflict
10
+ - Use PascalCase (e.g., "UserOrders" not "userorders")
11
+ - Stores: `context.current_refactor.new_module_name`
12
+
13
+ Do not ask any other question in this task.
@@ -0,0 +1,13 @@
1
+ ---
2
+ type: task
3
+ name: ask-new-service-name
4
+ ---
5
+
6
+ # Task: ask-new-service-name
7
+
8
+ Ask: "Enter the new name for '[context.current_refactor.old_service_name]':"
9
+ - Validate: must not already exist in `context.services` — error if conflict
10
+ - Validate: lowercase, no spaces (suggest replacing spaces with hyphens)
11
+ - Stores: `context.current_refactor.new_service_name`
12
+
13
+ Do not ask any other question in this task.
@@ -0,0 +1,15 @@
1
+ ---
2
+ type: task
3
+ name: ask-old-module-name
4
+ ---
5
+
6
+ # Task: ask-old-module-name
7
+
8
+ Read the target service name from: `context.current_refactor.old_service_name` (set by ask-old-service-name).
9
+
10
+ Ask: "Enter the current module name to rename:"
11
+ - Show available modules from `context.services[<service>].modules`
12
+ - Validate: must exist in the service — error if not found
13
+ - Stores: `context.current_refactor.old_module_name`
14
+
15
+ Do not ask any other question in this task.
@@ -0,0 +1,13 @@
1
+ ---
2
+ type: task
3
+ name: ask-old-service-name
4
+ ---
5
+
6
+ # Task: ask-old-service-name
7
+
8
+ Ask: "Enter the current service name to rename:"
9
+ - Show available service names from `context.services` as options
10
+ - Validate: name must exist in `context.services` — error if not found
11
+ - Stores: `context.current_refactor.old_service_name`
12
+
13
+ Do not ask any other question in this task.
@@ -0,0 +1,26 @@
1
+ ---
2
+ type: task
3
+ name: ask-orm-type
4
+ ---
5
+
6
+ # Task: ask-orm-type
7
+
8
+ Condition: if `context.current_init.init_mode == "fast"` → skip this task,
9
+ set `context.db.orm = "none"` silently, return.
10
+
11
+ Ask: "How would you like to interact with the database?"
12
+
13
+ Options:
14
+ 1. Raw driver (default) — direct SQL with pg / mysql2 / mongoose; generates config/database.js
15
+ 2. Prisma ORM — schema-first ORM; generates prisma/schema.prisma + config/prisma.js
16
+
17
+ Guidance to show the user:
18
+ - Raw driver: full SQL control, better for complex queries and existing DBA workflows
19
+ - Prisma: type-safe queries, auto-generated client, faster development (pairs well with TypeScript)
20
+
21
+ If `context.db.orm` is already set from a previous service init, ask:
22
+ "Existing services use [current value]. Keep the same? (yes / change)"
23
+
24
+ Stores: `context.db.orm` ("none" | "prisma")
25
+
26
+ Do not ask any other question in this task.
@@ -0,0 +1,19 @@
1
+ ---
2
+ type: task
3
+ name: collect-seed-data
4
+ ---
5
+
6
+ # Task: collect-seed-data
7
+
8
+ Orchestrates seed row collection for `context.current_db.table_name`.
9
+
10
+ Step 1 — Run task: `ask-seed-rows-count`
11
+ - Stores: `context.current_db.seed_count`
12
+
13
+ Step 2 — Repeat `context.current_db.seed_count` times:
14
+ Run task: `ask-seed-row-values`
15
+ - Appends each completed row to: `context.current_db.seed_rows[]`
16
+
17
+ After all rows are collected, show preview:
18
+ "Seed data collected: [N] rows for [table_name]"
19
+ Return to calling workflow.
@@ -14,6 +14,48 @@ starts.
14
14
 
15
15
  ---
16
16
 
17
+ ## Language Branch
18
+
19
+ Read `context.current_init.language` (or `context.services[name].language`).
20
+
21
+ **TypeScript — generate `app.ts` + `server.ts`:**
22
+
23
+ `app.ts`:
24
+ ```typescript
25
+ import express, { Application } from 'express';
26
+ import cors from 'cors';
27
+ import helmet from 'helmet';
28
+ import dotenv from 'dotenv';
29
+
30
+ dotenv.config();
31
+
32
+ const app: Application = express();
33
+
34
+ app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(',') }));
35
+ app.use(helmet());
36
+ app.use(express.json());
37
+ app.use(express.urlencoded({ extended: true }));
38
+
39
+ export default app;
40
+ ```
41
+
42
+ `server.ts` (entry point):
43
+ ```typescript
44
+ import app from './app';
45
+ import { router as v1Router } from './modules/v1/route_manager';
46
+
47
+ app.use('/api/v1', v1Router);
48
+
49
+ const PORT = parseInt(process.env.PORT || '3000', 10);
50
+ app.listen(PORT, () => {
51
+ console.log(`[${process.env.PROJECT_NAME}] running on port ${PORT}`);
52
+ });
53
+ ```
54
+
55
+ **JavaScript — generate `app.js` (existing behavior — see below)**
56
+
57
+ ---
58
+
17
59
  ## Dependencies to Import
18
60
 
19
61
  - `dotenv` — called as `require('dotenv').config()` on the very first
@@ -15,6 +15,19 @@ config/database.js. The object is named `common` and exported directly.
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 `config/common.ts`:**
23
+ Same content as JS variant but with typed exports.
24
+ Use `export const GLOBALS = Object.freeze({ ... } as const);`
25
+ All function signatures typed.
26
+
27
+ **JavaScript — generate `config/common.js` (existing behavior — see below)**
28
+
29
+ ---
30
+
18
31
  ## Dependencies to Import
19
32
 
20
33
  - `./database` — imported as `con`. Used by all database functions.
@@ -15,6 +15,19 @@ using Object.freeze so no file can accidentally mutate it at runtime.
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 `config/constants.ts`:**
23
+ Same content as JS variant.
24
+ Use `export const` for all exported values.
25
+ Add type annotations where helpful: `export const PORT: number = parseInt(process.env.PORT || '3000', 10);`
26
+
27
+ **JavaScript — generate `config/constants.js` (existing behavior — see below)**
28
+
29
+ ---
30
+
18
31
  ## Dependencies
19
32
 
20
33
  No imports from within the service. Only reads from process.env which
@@ -15,6 +15,38 @@ the correct implementation.
15
15
 
16
16
  ---
17
17
 
18
+ ## ORM Branch
19
+
20
+ Read `context.db.orm` before generating anything.
21
+
22
+ **If `orm == "prisma"`:**
23
+ - Do NOT generate `config/database.js` or `config/database.ts`
24
+ - Instead: run task `generate-prisma-schema` then run task `generate-prisma-client`
25
+ - Update `.env` to use `DATABASE_URL` instead of individual DB_HOST/PORT/NAME/USER/PASS:
26
+ - PostgreSQL: `DATABASE_URL="postgresql://<user>:<password>@<host>:<port>/<db_name>?schema=public"`
27
+ - MySQL: `DATABASE_URL="mysql://<user>:<password>@<host>:<port>/<db_name>"`
28
+ - MongoDB: `DATABASE_URL="mongodb+srv://<user>:<password>@<cluster>/<db_name>?retryWrites=true&w=majority"`
29
+ - Skip the rest of this task after running those two tasks.
30
+
31
+ **If `orm == "none"`:**
32
+ - Continue with raw driver generation below (existing behavior).
33
+
34
+ ---
35
+
36
+ ## Language Branch (raw driver path only — Prisma path already handles JS/TS in generate-prisma-client)
37
+
38
+ Read `context.current_init.language` (or `context.services[name].language`).
39
+
40
+ **TypeScript — generate `config/database.ts`:**
41
+ Same pool/connection setup as JS but with typed imports.
42
+ PostgreSQL: `import { Pool, PoolConfig } from 'pg';`
43
+ MySQL: `import mysql from 'mysql2/promise';`
44
+ MongoDB: `import mongoose from 'mongoose';`
45
+
46
+ **JavaScript — generate `config/database.js` (existing behavior — see below)**
47
+
48
+ ---
49
+
18
50
  ## Dependencies to Import
19
51
 
20
52
  - `../logger/logging` — imported as `log`. Used for connection error
@@ -6,6 +6,34 @@ agent: nodejs-agent
6
6
 
7
7
  # File: utilities/encryption.js
8
8
 
9
+ ## SCOPE: Transport Encryption Only
10
+
11
+ `utilities/encryption.js` (or `.ts`) handles AES-256-CBC **transport encryption only**:
12
+ - Encrypting outgoing API response payloads
13
+ - Decrypting incoming encrypted request payloads
14
+ - Encrypting/decrypting session tokens for transmission
15
+
16
+ **This file does NOT handle passwords.** Password hashing is handled exclusively by
17
+ `utilities/hashing.js` (see task: generate-hashing). Never import encryption functions
18
+ for password storage. Never store an AES-encrypted password — passwords must be
19
+ bcrypt/argon2 hashed (one-way, irreversible).
20
+
21
+ ---
22
+
23
+ ## Language Branch
24
+
25
+ Read `context.current_init.language` (or `context.services[name].language`).
26
+
27
+ **TypeScript — generate `utilities/encryption.ts`:**
28
+ Same AES-256-CBC encrypt/decrypt functions as JS variant.
29
+ Use `import CryptoJS from 'crypto-js';` (or `import cryptlib from 'cryptlib';` for app client type).
30
+ All function signatures typed: `export function encrypt(data: unknown): string`
31
+ and `export function decrypt(ciphertext: string): unknown`.
32
+
33
+ **JavaScript — generate `utilities/encryption.js` (existing behavior — see below)**
34
+
35
+ ---
36
+
9
37
  ## Purpose
10
38
  Single source of truth for all encryption and decryption operations in the
11
39
  service. All other files that need to encrypt or decrypt call this module.
@@ -50,6 +50,13 @@ Validate after generation:
50
50
  - encryption_iv must equal the first 16 characters of encryption_key —
51
51
  re-derive if not
52
52
 
53
+ ### Language and Hashing Library
54
+ - `language` → "javascript" (TypeScript requires manual selection — never auto-picked in fast mode)
55
+ - `hashing_library` → "bcryptjs" (fast mode default — pure JS, no native build tools required)
56
+
57
+ ### ORM Default (nodejs only, if not already set)
58
+ - `context.db.orm` → "none" if not already set (raw driver — Prisma requires manual selection)
59
+
53
60
  ### Redis Config (nodejs only — skip for reactjs)
54
61
  - `context.current_init.redis_host` → `"localhost"`
55
62
  - `context.current_init.redis_port` → `6379`
@@ -0,0 +1,180 @@
1
+ ---
2
+ type: task
3
+ name: generate-hashing
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: utilities/hashing.js OR utilities/hashing.ts
8
+
9
+ ## Purpose
10
+ Single source of truth for all password hashing and verification in the service.
11
+ All code that needs to hash or verify a password calls this module.
12
+ No other file in the service imports bcryptjs or argon2 directly.
13
+ This file handles one-way password storage ONLY.
14
+
15
+ ## SCOPE BOUNDARY
16
+
17
+ NEVER use `encryption.js` / `decrypt` / AES / KEY / IV in this file.
18
+ This is not transport encryption — it is irreversible password hashing.
19
+ Do not import or reference `../utilities/encryption` from this file.
20
+
21
+ ---
22
+
23
+ ## Active library and language
24
+
25
+ Read `context.current_init.hashing_library` (or
26
+ `context.services[<name>].hashing_library`) — value is `"bcryptjs"` or
27
+ `"argon2"`.
28
+
29
+ Read `context.current_init.language` (or `context.services[<name>].language`)
30
+ — value is `"javascript"` or `"typescript"`.
31
+
32
+ Generate the matching variant below. Do not emit unused variants.
33
+
34
+ ---
35
+
36
+ ## JavaScript — bcryptjs variant
37
+
38
+ ```javascript
39
+ const bcrypt = require('bcryptjs');
40
+
41
+ const SALT_ROUNDS = 12;
42
+
43
+ /**
44
+ * Hashes a plaintext password using bcrypt.
45
+ *
46
+ * @param {string} plaintext - The raw password string to hash.
47
+ * @returns {Promise<string>} The bcrypt hash string.
48
+ */
49
+ async function hashPassword(plaintext) {
50
+ return bcrypt.hash(plaintext, SALT_ROUNDS);
51
+ }
52
+
53
+ /**
54
+ * Verifies a plaintext password against a stored bcrypt hash.
55
+ *
56
+ * @param {string} plaintext - The raw password to verify.
57
+ * @param {string} hash - The stored bcrypt hash.
58
+ * @returns {Promise<boolean>} True if the password matches the hash.
59
+ */
60
+ async function verifyPassword(plaintext, hash) {
61
+ return bcrypt.compare(plaintext, hash);
62
+ }
63
+
64
+ module.exports = { hashPassword, verifyPassword };
65
+ ```
66
+
67
+ ---
68
+
69
+ ## JavaScript — argon2 variant
70
+
71
+ ```javascript
72
+ const argon2 = require('argon2');
73
+
74
+ /**
75
+ * Hashes a plaintext password using argon2id.
76
+ *
77
+ * @param {string} plaintext - The raw password string to hash.
78
+ * @returns {Promise<string>} The argon2 hash string.
79
+ */
80
+ async function hashPassword(plaintext) {
81
+ return argon2.hash(plaintext, { type: argon2.argon2id });
82
+ }
83
+
84
+ /**
85
+ * Verifies a plaintext password against a stored argon2 hash.
86
+ *
87
+ * @param {string} plaintext - The raw password to verify.
88
+ * @param {string} hash - The stored argon2 hash.
89
+ * @returns {Promise<boolean>} True if the password matches the hash.
90
+ */
91
+ async function verifyPassword(plaintext, hash) {
92
+ return argon2.verify(hash, plaintext);
93
+ }
94
+
95
+ module.exports = { hashPassword, verifyPassword };
96
+ ```
97
+
98
+ ---
99
+
100
+ ## TypeScript — bcryptjs variant
101
+
102
+ ```typescript
103
+ import bcrypt from 'bcryptjs';
104
+
105
+ const SALT_ROUNDS = 12;
106
+
107
+ /**
108
+ * Hashes a plaintext password using bcrypt.
109
+ *
110
+ * @param {string} plaintext - The raw password string to hash.
111
+ * @returns {Promise<string>} The bcrypt hash string.
112
+ */
113
+ export async function hashPassword(plaintext: string): Promise<string> {
114
+ return bcrypt.hash(plaintext, SALT_ROUNDS);
115
+ }
116
+
117
+ /**
118
+ * Verifies a plaintext password against a stored bcrypt hash.
119
+ *
120
+ * @param {string} plaintext - The raw password to verify.
121
+ * @param {string} hash - The stored bcrypt hash.
122
+ * @returns {Promise<boolean>} True if the password matches the hash.
123
+ */
124
+ export async function verifyPassword(plaintext: string, hash: string): Promise<boolean> {
125
+ return bcrypt.compare(plaintext, hash);
126
+ }
127
+ ```
128
+
129
+ ---
130
+
131
+ ## TypeScript — argon2 variant
132
+
133
+ ```typescript
134
+ import argon2 from 'argon2';
135
+
136
+ /**
137
+ * Hashes a plaintext password using argon2id.
138
+ *
139
+ * @param {string} plaintext - The raw password string to hash.
140
+ * @returns {Promise<string>} The argon2 hash string.
141
+ */
142
+ export async function hashPassword(plaintext: string): Promise<string> {
143
+ return argon2.hash(plaintext, { type: argon2.argon2id });
144
+ }
145
+
146
+ /**
147
+ * Verifies a plaintext password against a stored argon2 hash.
148
+ *
149
+ * @param {string} plaintext - The raw password to verify.
150
+ * @param {string} hash - The stored argon2 hash.
151
+ * @returns {Promise<boolean>} True if the password matches the hash.
152
+ */
153
+ export async function verifyPassword(plaintext: string, hash: string): Promise<boolean> {
154
+ return argon2.verify(hash, plaintext);
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Export
161
+
162
+ JavaScript variants export via CommonJS:
163
+ ```
164
+ module.exports = { hashPassword, verifyPassword }
165
+ ```
166
+
167
+ TypeScript variants use named ES module exports (no default export).
168
+
169
+ Every file that imports this module destructures exactly what it needs:
170
+ `const { hashPassword, verifyPassword } = require('../utilities/hashing')`
171
+
172
+ ---
173
+
174
+ ## What This File Does NOT Do
175
+
176
+ - Does not read `req` or `res` — no Express objects
177
+ - Does not log — callers handle logging
178
+ - Does not import `encryption.js` or use AES, KEY, or IV
179
+ - Does not provide a `decrypt` or `unhash` function — hashing is irreversible
180
+ - Does not conditionally skip hashing — always hashes when called
@@ -17,6 +17,19 @@ delegated to `utilities/validator.js`.
17
17
 
18
18
  ---
19
19
 
20
+ ## Language Branch
21
+
22
+ Read `context.current_init.language` (or `context.services[name].language`).
23
+
24
+ **TypeScript — generate `headerValidator.ts`:**
25
+ All exports are typed middleware functions with signature `(req: Request, res: Response, next: NextFunction): void`.
26
+ Use `import { Request, Response, NextFunction } from 'express';` at the top.
27
+ All other logic identical to JS variant — same checks, same middleware order.
28
+
29
+ **JavaScript — generate `headerValidator.js` (existing behavior — see below)**
30
+
31
+ ---
32
+
20
33
  ## Dependencies to Import
21
34
 
22
35
  - `../config/constants` — GLOBALS object containing API_KEY and other
@@ -19,6 +19,26 @@ starting the service.
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 `utilities/ioRedis.ts`:**
27
+ ```typescript
28
+ import Redis from 'ioredis';
29
+
30
+ const redisClient = new Redis({
31
+ host: process.env.REDIS_HOST || 'localhost',
32
+ port: parseInt(process.env.REDIS_PORT || '6379', 10),
33
+ });
34
+
35
+ export default redisClient;
36
+ ```
37
+
38
+ **JavaScript — generate `utilities/ioRedis.js` (existing behavior — see below)**
39
+
40
+ ---
41
+
22
42
  ## Dependencies to Import
23
43
 
24
44
  - `ioredis` — imported as `IORedis` (capital letters). The Redis client
@@ -19,6 +19,18 @@ area. This makes it easy to find and add related messages together.
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 `languages/en.ts`:**
27
+ Same message key/value object as JS variant.
28
+ Use: `const messages: Record<string, string> = { ... }; export default messages;`
29
+
30
+ **JavaScript — generate `languages/en.js` (existing behavior — see below)**
31
+
32
+ ---
33
+
22
34
  ## Structure and Sections
23
35
 
24
36
  ### Section 1 — Validator Messages
@@ -16,6 +16,18 @@ than 10 days.
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 `logger/logging.ts`:**
24
+ Same custom file-based logger as JS variant with typed function signatures.
25
+ `export function log(message: string, level?: 'info' | 'error' | 'warn'): void`
26
+
27
+ **JavaScript — generate `logger/logging.js` (existing behavior — see below)**
28
+
29
+ ---
30
+
19
31
  ## Dependencies to Import
20
32
 
21
33
  - `fs` — Node.js built-in. Used for file existence checks, directory
@@ -19,6 +19,50 @@ name, primary table, and available columns.
19
19
 
20
20
  ---
21
21
 
22
+ ## ORM Branch
23
+
24
+ Read `context.db.orm` before generating the model file.
25
+
26
+ ### If `orm == "prisma"` — generate Prisma-based model
27
+
28
+ Import from the `config/prisma` singleton. Use Prisma Client API. Never use raw SQL.
29
+
30
+ Example model function (JavaScript):
31
+ ```javascript
32
+ const prisma = require('../../config/prisma');
33
+ const { hashPassword, verifyPassword } = require('../../utilities/hashing');
34
+
35
+ /**
36
+ * Registers a new user with hashed password.
37
+ *
38
+ * @param {Object} request - Decrypted request body.
39
+ * @param {number} user_id - Authenticated user ID (0 for public endpoint).
40
+ * @param {string} user_type - Authenticated user type.
41
+ * @returns {Promise<Object>} Standard response: { responsecode, responsemsg, responsedata }
42
+ */
43
+ async function registerUser(request, user_id, user_type) {
44
+ const hashedPassword = await hashPassword(request.password);
45
+ const user = await prisma.users.create({
46
+ data: { email: request.email, password: hashedPassword, status: 1 },
47
+ select: { id: true, email: true }
48
+ });
49
+ return { responsecode: 1, responsemsg: 'register_success', responsedata: user };
50
+ }
51
+
52
+ module.exports = { registerUser };
53
+ ```
54
+
55
+ Prisma model naming rules:
56
+ - `tbl_users` → `prisma.users` (strip `tbl_` prefix, keep lowercase in queries)
57
+ - Always use `select` to specify returned columns — never return all columns
58
+ - Passwords: always call `hashPassword()` / `verifyPassword()` from utilities/hashing
59
+
60
+ ### If `orm == "none"` — generate raw SQL model (existing behavior)
61
+
62
+ Continue with parameterized SQL queries as per the rest of this task file.
63
+
64
+ ---
65
+
22
66
  ## Dependencies to Import
23
67
 
24
68
  - `../../../config/database` — imported as `con`. Used for all DB
@@ -129,12 +173,36 @@ Every function generated by `@create-api` follows this pattern:
129
173
  error level with function name and error, then return the failure
130
174
  shape with keyword `rest_keywords_something_went_wrong`.
131
175
 
132
- ### Password handling
133
- When the function receives or stores passwords:
134
- - For storing: call `encrypt(password)` from utilities/encryption.js.
135
- Never store plaintext passwords.
136
- - For comparing: encrypt the incoming password and compare against the
137
- stored encrypted value. Never decrypt stored passwords for comparison.
176
+ ## Password Handling in Model Files
177
+
178
+ When a query involves a password column (login, register, change-password):
179
+
180
+ **On registration / password save (JavaScript):**
181
+ ```javascript
182
+ const { hashPassword } = require('../../utilities/hashing');
183
+ // ...
184
+ const hashedPassword = await hashPassword(request.password);
185
+ // Store hashedPassword in DB — NEVER store request.password directly
186
+ ```
187
+
188
+ **On login / password verify (JavaScript):**
189
+ ```javascript
190
+ const { verifyPassword } = require('../../utilities/hashing');
191
+ // ...
192
+ const isMatch = await verifyPassword(request.password, dbRow.password);
193
+ if (!isMatch) {
194
+ return { responsecode: 0, responsemsg: 'invalid_credentials', responsedata: [] };
195
+ }
196
+ ```
197
+
198
+ **TypeScript imports:**
199
+ ```typescript
200
+ import { hashPassword, verifyPassword } from '../../utilities/hashing';
201
+ ```
202
+
203
+ NEVER call `encrypt()` or `decrypt()` from `encryption.js` for password fields.
204
+ NEVER store the raw plaintext password.
205
+ NEVER store an AES-encrypted password — AES is reversible and not safe for password storage.
138
206
 
139
207
  ### Session generation (login/signup)
140
208
  When a function completes a successful login or signup:
@@ -15,6 +15,18 @@ instance is exported.
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/notification.ts`:**
23
+ Same email/FCM notification utilities as JS variant with typed function signatures.
24
+ All function parameters and returns explicitly typed.
25
+
26
+ **JavaScript — generate `utilities/notification.js` (existing behavior — see below)**
27
+
28
+ ---
29
+
18
30
  ## Dependencies to Import
19
31
 
20
32
  - `firebase-admin` — imported as `admin`. Used for FCM push