codeninja 2.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 (140) hide show
  1. package/.gitattributes +11 -0
  2. package/README.md +293 -0
  3. package/agent/database-agent.md +504 -0
  4. package/agent/designs/README.md +10 -0
  5. package/agent/global-agent.md +236 -0
  6. package/agent/nodejs-agent.md +406 -0
  7. package/agent/reactjs-agent.md +260 -0
  8. package/cli.js +352 -0
  9. package/commands/audit.workflow.md +111 -0
  10. package/commands/create-api.workflow.md +99 -0
  11. package/commands/db-add-index.workflow.md +97 -0
  12. package/commands/db-create-table.workflow.md +132 -0
  13. package/commands/db-drop-table.workflow.md +103 -0
  14. package/commands/db-modify-table.workflow.md +159 -0
  15. package/commands/db-seed.workflow.md +99 -0
  16. package/commands/db-sync.workflow.md +100 -0
  17. package/commands/design.workflow.md +66 -0
  18. package/commands/initialize-project.workflow.md +500 -0
  19. package/commands/integrate-api.workflow.md +448 -0
  20. package/commands/modularize.workflow.md +329 -0
  21. package/commands/refactor.workflow.md +70 -0
  22. package/commands/sync.workflow.md +962 -0
  23. package/commands/test.workflow.md +40 -0
  24. package/commands/validate-page.workflow.md +543 -0
  25. package/mcp-server.js +842 -0
  26. package/package.json +24 -0
  27. package/tasks/README.md +283 -0
  28. package/tasks/add-health-route.task.md +103 -0
  29. package/tasks/ask-api-integration-scope.task.md +34 -0
  30. package/tasks/ask-api-key.task.md +23 -0
  31. package/tasks/ask-api-version.task.md +28 -0
  32. package/tasks/ask-client-type.task.md +24 -0
  33. package/tasks/ask-column-enum-values.task.md +51 -0
  34. package/tasks/ask-column-is-enum.task.md +39 -0
  35. package/tasks/ask-column-name.task.md +39 -0
  36. package/tasks/ask-column-position.task.md +39 -0
  37. package/tasks/ask-column-type.task.md +59 -0
  38. package/tasks/ask-database-config.task.md +66 -0
  39. package/tasks/ask-database-host.task.md +16 -0
  40. package/tasks/ask-database-name.task.md +18 -0
  41. package/tasks/ask-database-port.task.md +23 -0
  42. package/tasks/ask-database-type.task.md +30 -0
  43. package/tasks/ask-database-user.task.md +14 -0
  44. package/tasks/ask-design-description.task.md +16 -0
  45. package/tasks/ask-design-target.task.md +24 -0
  46. package/tasks/ask-encrypted-transport.task.md +25 -0
  47. package/tasks/ask-encryption-iv.task.md +23 -0
  48. package/tasks/ask-encryption-key.task.md +23 -0
  49. package/tasks/ask-feature-name.task.md +20 -0
  50. package/tasks/ask-http-method.task.md +21 -0
  51. package/tasks/ask-index-columns.task.md +46 -0
  52. package/tasks/ask-index-file-placement.task.md +33 -0
  53. package/tasks/ask-index-sort-order.task.md +37 -0
  54. package/tasks/ask-index-type.task.md +42 -0
  55. package/tasks/ask-init-mode.task.md +28 -0
  56. package/tasks/ask-linked-service.task.md +57 -0
  57. package/tasks/ask-modify-operation.task.md +36 -0
  58. package/tasks/ask-modularize-scope.task.md +31 -0
  59. package/tasks/ask-module-name.task.md +30 -0
  60. package/tasks/ask-new-column-name.task.md +21 -0
  61. package/tasks/ask-new-table-name.task.md +22 -0
  62. package/tasks/ask-old-column-name.task.md +22 -0
  63. package/tasks/ask-package-author.task.md +16 -0
  64. package/tasks/ask-package-name.task.md +23 -0
  65. package/tasks/ask-page-path.task.md +40 -0
  66. package/tasks/ask-primary-table.task.md +30 -0
  67. package/tasks/ask-project-figma.task.md +71 -0
  68. package/tasks/ask-project-info-doc.task.md +57 -0
  69. package/tasks/ask-project-scope-of-work.task.md +57 -0
  70. package/tasks/ask-project-type.task.md +24 -0
  71. package/tasks/ask-react-target-service.task.md +32 -0
  72. package/tasks/ask-redis-config.task.md +42 -0
  73. package/tasks/ask-redis-host.task.md +16 -0
  74. package/tasks/ask-redis-port.task.md +18 -0
  75. package/tasks/ask-refactor-type.task.md +26 -0
  76. package/tasks/ask-requires-auth.task.md +22 -0
  77. package/tasks/ask-response-mode.task.md +38 -0
  78. package/tasks/ask-route-description.task.md +20 -0
  79. package/tasks/ask-route-path.task.md +29 -0
  80. package/tasks/ask-seed-row-values.task.md +42 -0
  81. package/tasks/ask-seed-rows-count.task.md +22 -0
  82. package/tasks/ask-service-description.task.md +16 -0
  83. package/tasks/ask-service-name.task.md +27 -0
  84. package/tasks/ask-service-port.task.md +24 -0
  85. package/tasks/ask-supported-languages.task.md +40 -0
  86. package/tasks/ask-table-file-number.task.md +36 -0
  87. package/tasks/ask-table-indexes.task.md +47 -0
  88. package/tasks/ask-table-name.task.md +32 -0
  89. package/tasks/ask-table-needs-soft-delete.task.md +29 -0
  90. package/tasks/ask-table-needs-status.task.md +30 -0
  91. package/tasks/ask-table-purpose.task.md +28 -0
  92. package/tasks/ask-table-seed-data.task.md +44 -0
  93. package/tasks/ask-target-service.task.md +32 -0
  94. package/tasks/ask-test-type.task.md +20 -0
  95. package/tasks/ask-validation-library.task.md +38 -0
  96. package/tasks/detect-repository-state.task.md +92 -0
  97. package/tasks/generate-app.task.md +146 -0
  98. package/tasks/generate-common.task.md +330 -0
  99. package/tasks/generate-constants.task.md +123 -0
  100. package/tasks/generate-database.task.md +168 -0
  101. package/tasks/generate-docker-compose.task.md +298 -0
  102. package/tasks/generate-dockerfile.task.md +126 -0
  103. package/tasks/generate-dockerignore.task.md +123 -0
  104. package/tasks/generate-enc-dec-html.task.md +127 -0
  105. package/tasks/generate-enc-dec-php.task.md +145 -0
  106. package/tasks/generate-encryption.task.md +159 -0
  107. package/tasks/generate-fast-defaults.task.md +68 -0
  108. package/tasks/generate-gitignore.task.md +79 -0
  109. package/tasks/generate-headerValidator.task.md +377 -0
  110. package/tasks/generate-ide-configs.task.md +114 -0
  111. package/tasks/generate-ioRedis.task.md +120 -0
  112. package/tasks/generate-language-en.task.md +155 -0
  113. package/tasks/generate-logging.task.md +257 -0
  114. package/tasks/generate-model.task.md +180 -0
  115. package/tasks/generate-notification.task.md +251 -0
  116. package/tasks/generate-package-json.task.md +114 -0
  117. package/tasks/generate-rateLimiter.task.md +125 -0
  118. package/tasks/generate-react-api-client.task.md +169 -0
  119. package/tasks/generate-react-api-handler.task.md +102 -0
  120. package/tasks/generate-react-app-jsx.task.md +56 -0
  121. package/tasks/generate-react-dockerfile.task.md +175 -0
  122. package/tasks/generate-react-env.task.md +58 -0
  123. package/tasks/generate-react-gitignore.task.md +49 -0
  124. package/tasks/generate-react-htaccess.task.md +54 -0
  125. package/tasks/generate-react-index-html.task.md +53 -0
  126. package/tasks/generate-react-index-jsx.task.md +51 -0
  127. package/tasks/generate-react-package-json.task.md +77 -0
  128. package/tasks/generate-react-welcome-page.task.md +71 -0
  129. package/tasks/generate-readme.task.md +160 -0
  130. package/tasks/generate-response.task.md +202 -0
  131. package/tasks/generate-route-manager.task.md +173 -0
  132. package/tasks/generate-route.task.md +203 -0
  133. package/tasks/generate-swagger.task.md +290 -0
  134. package/tasks/generate-tbl-user-deviceinfo.task.md +75 -0
  135. package/tasks/generate-template.task.md +129 -0
  136. package/tasks/generate-validator.task.md +122 -0
  137. package/tasks/show-db-table-summary.task.md +66 -0
  138. package/tasks/show-final-summary.task.md +108 -0
  139. package/tasks/show-init-summary.task.md +257 -0
  140. package/tasks/write-context.task.md +314 -0
@@ -0,0 +1,168 @@
1
+ ---
2
+ type: task
3
+ name: generate-database
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: config/database.js
8
+
9
+ ## Purpose
10
+ Establishes and exports the database connection for the service. All
11
+ model files import this module to run queries. The implementation differs
12
+ based on `context.db.type` — one file is generated per project, not one
13
+ per database type. The agent reads the db type from context and generates
14
+ the correct implementation.
15
+
16
+ ---
17
+
18
+ ## Dependencies to Import
19
+
20
+ - `../logger/logging` — imported as `log`. Used for connection error
21
+ logging and query error logging.
22
+
23
+ Additionally, one database driver is imported based on `context.db.type`:
24
+ - If `postgresql` → import `{ Pool }` from `pg`
25
+ - If `mysql` → import `mysql2/promise` and create a pool using
26
+ `mysql2.createPool()`
27
+ - If `mongodb` → import `mongoose`
28
+
29
+ Never import more than one driver. Only the driver matching
30
+ `context.db.type` is imported.
31
+
32
+ ---
33
+
34
+ ## Implementation by Database Type
35
+
36
+ ---
37
+
38
+ ### PostgreSQL (context.db.type == "postgresql")
39
+
40
+ **Pool creation**:
41
+ Create a `new Pool` instance with these configuration keys all read
42
+ from process.env:
43
+ - `user` from `process.env.DATABASE_USER`
44
+ - `host` from `process.env.DATABASE_HOST`
45
+ - `database` from `process.env.DATABASE_NAME`
46
+ - `password` from `process.env.DATABASE_PASSWORD`
47
+ - `port` from `process.env.DATABASE_PORT`
48
+ - `ssl` set to `{ rejectUnauthorized: false }` — required for most
49
+ hosted PostgreSQL providers including AWS RDS and Supabase.
50
+
51
+ **Pool error handler**:
52
+ Register a listener on the pool's `error` event using `pool.on('error',
53
+ callback)`. The callback receives the error object. Inside the callback:
54
+ log at critical level with the message "Error establishing PostgreSQL
55
+ connection" and the error object. Then call `process.exit(-1)`.
56
+ This handles unexpected errors on idle clients in the pool — without
57
+ this handler, such errors would be unhandled rejections and crash the
58
+ process silently.
59
+
60
+ **logFormattedQuery(queryText, params)**:
61
+ Internal helper function. Not exported.
62
+ Purpose: reconstructs the SQL query string with parameter placeholders
63
+ replaced by their actual values, for use in error logs only. Never used
64
+ to actually execute queries — parameterized queries are always used for
65
+ execution.
66
+ Takes `queryText` (the SQL string with `$1`, `$2` placeholders) and
67
+ `params` (the values array).
68
+ Uses a regex replace on the pattern `\$(\d+)` to find each placeholder.
69
+ For each match, read the corresponding value from params at index
70
+ `(matched_number - 1)`.
71
+ Format the value:
72
+ - If null or undefined → replace with the string `NULL`
73
+ - If a string → wrap in single quotes: `'value'`
74
+ - Any other type → use the value as-is (numbers, booleans)
75
+ Returns the reconstructed query string. Used only in error log messages.
76
+
77
+ **query(text, params)**:
78
+ Async function. The primary export used by all model files.
79
+ Parameters:
80
+ - `text` — the SQL query string with `$1`, `$2` parameter placeholders
81
+ - `params` — array of values. Defaults to empty array if not provided.
82
+
83
+ Flow:
84
+ 1. Call `pool.query(text, params)` inside a try/catch.
85
+ 2. On success — return the result object directly. The result has
86
+ `rows` (array of row objects) and `rowCount` (number of affected
87
+ rows) which callers destructure as needed.
88
+ 3. On error — log at error level with the message "DATABASE QUERY ERROR",
89
+ including the formatted query from `logFormattedQuery(text, params)`
90
+ and the error object. Then re-throw the error. Model functions are
91
+ responsible for catching query errors.
92
+
93
+ **Export**:
94
+ ```
95
+ module.exports = { query, pool }
96
+ ```
97
+ `pool` is exported for use in transaction scenarios where the caller
98
+ needs to acquire a client directly and manage BEGIN/COMMIT/ROLLBACK
99
+ manually.
100
+
101
+ ---
102
+
103
+ ### MySQL (context.db.type == "mysql")
104
+
105
+ **Pool creation**:
106
+ Call `mysql2.createPool()` with these configuration keys all from
107
+ process.env:
108
+ - `host` from `process.env.DATABASE_HOST`
109
+ - `user` from `process.env.DATABASE_USER`
110
+ - `password` from `process.env.DATABASE_PASSWORD`
111
+ - `database` from `process.env.DATABASE_NAME`
112
+ - `port` from `process.env.DATABASE_PORT`
113
+ - `waitForConnections: true`
114
+ - `connectionLimit: 10`
115
+ - `queueLimit: 0`
116
+
117
+ **logFormattedQuery(queryText, params)**:
118
+ Same purpose as PostgreSQL version but uses `?` placeholders instead
119
+ of `$1` style. Replace each `?` in sequence with its corresponding
120
+ param value, applying the same null/string/other formatting rules.
121
+
122
+ **query(text, params)**:
123
+ Same async pattern as PostgreSQL. Call `pool.execute(text, params)`.
124
+ Returns `[rows, fields]` — destructure and return `{ rows, rowCount:
125
+ rows.length }` to give callers a consistent interface matching the
126
+ PostgreSQL result shape.
127
+ On error — same log pattern and re-throw.
128
+
129
+ **Export**:
130
+ ```
131
+ module.exports = { query, pool }
132
+ ```
133
+
134
+ ---
135
+
136
+ ### MongoDB (context.db.type == "mongodb")
137
+
138
+ **Connection**:
139
+ Call `mongoose.connect()` with the connection string constructed from
140
+ process.env values:
141
+ `mongodb://${process.env.DATABASE_USER}:${process.env.DATABASE_PASSWORD}
142
+ @${process.env.DATABASE_HOST}:${process.env.DATABASE_PORT}/
143
+ ${process.env.DATABASE_NAME}`
144
+ Options: `{ useNewUrlParser: true, useUnifiedTopology: true }`
145
+
146
+ Wrap in an async immediately-invoked function. On connection success —
147
+ log at info level. On error — log at critical level and call
148
+ `process.exit(-1)`.
149
+
150
+ **Export**:
151
+ ```
152
+ module.exports = mongoose
153
+ ```
154
+ Model files import mongoose directly and define their own schemas.
155
+ No `query` wrapper is needed for MongoDB — each model uses mongoose
156
+ model methods directly.
157
+
158
+ ---
159
+
160
+ ## What This File Does NOT Do
161
+
162
+ - Does not hardcode any connection values — all from process.env
163
+ - Does not define any data models or schemas — those live in
164
+ module _model.js files
165
+ - Does not retry failed connections — process exits on critical
166
+ connection failure
167
+ - Does not export raw connection strings — only the pool or
168
+ connection object
@@ -0,0 +1,298 @@
1
+ ---
2
+ type: task
3
+ name: generate-docker-compose
4
+ agent: global-agent
5
+ ---
6
+
7
+ # File: docker-compose.yml
8
+
9
+ ## Purpose
10
+ Orchestrates all services in the project (NodeJS APIs, ReactJS frontends,
11
+ databases, Redis) in a unified Docker environment. Generated once per
12
+ repository and updated as new services are added.
13
+
14
+ ---
15
+
16
+ ## Generation Logic
17
+
18
+ ### When to Generate
19
+ - First `@initialize-project` in the repo (no docker-compose.yml exists)
20
+ - Any subsequent `@initialize-project` that adds a new service
21
+
22
+ ### When to Update
23
+ - New service initialized → add service definition
24
+ - Service port changed → update ports mapping
25
+ - Database type changed → update db service definition
26
+
27
+ ---
28
+
29
+ ## Template Structure
30
+
31
+ ```yaml
32
+ version: '3.8'
33
+
34
+ services:
35
+ # Database service (if context.db.type exists)
36
+ {db_service_name}:
37
+ image: {db_image}
38
+ container_name: {project_name}-{db_type}
39
+ environment:
40
+ {db_env_vars}
41
+ ports:
42
+ - "{db_port}:{db_internal_port}"
43
+ volumes:
44
+ - {db_data_volume}:/var/lib/{db_volume_path}
45
+ - ./database/{db_type}/migrations:/docker-entrypoint-initdb.d:ro
46
+ networks:
47
+ - {project_name}-network
48
+ healthcheck:
49
+ test: {db_healthcheck}
50
+ interval: 10s
51
+ timeout: 5s
52
+ retries: 5
53
+
54
+ # Redis service (always included for NodeJS services)
55
+ redis:
56
+ image: redis:7-alpine
57
+ container_name: {project_name}-redis
58
+ ports:
59
+ - "6379:6379"
60
+ volumes:
61
+ - redis-data:/data
62
+ networks:
63
+ - {project_name}-network
64
+ command: redis-server --appendonly yes
65
+ healthcheck:
66
+ test: ["CMD", "redis-cli", "ping"]
67
+ interval: 10s
68
+ timeout: 3s
69
+ retries: 5
70
+
71
+ # NodeJS services (one per service in context.services where type == nodejs)
72
+ {service_name}:
73
+ build:
74
+ context: ./{service_name}
75
+ dockerfile: Dockerfile
76
+ container_name: {project_name}-{service_name}
77
+ environment:
78
+ - NODE_ENV=production
79
+ - DB_HOST={db_service_name}
80
+ - DB_PORT={db_internal_port}
81
+ - DB_NAME=${DB_NAME}
82
+ - DB_USER=${DB_USER}
83
+ - DB_PASS=${DB_PASS}
84
+ - REDIS_HOST=redis
85
+ - REDIS_PORT=6379
86
+ - KEY=${KEY}
87
+ - IV=${IV}
88
+ - API_KEY=${API_KEY}
89
+ ports:
90
+ - "{service_port}:{service_port}"
91
+ volumes:
92
+ - ./{service_name}/logger/logs:/app/logger/logs
93
+ - ./{service_name}/pem:/app/pem
94
+ - ./{service_name}/images:/app/images
95
+ depends_on:
96
+ {db_service_name}:
97
+ condition: service_healthy
98
+ redis:
99
+ condition: service_healthy
100
+ networks:
101
+ - {project_name}-network
102
+ restart: unless-stopped
103
+
104
+ # ReactJS services (one per service in context.services where type == reactjs)
105
+ {frontend_service_name}:
106
+ build:
107
+ context: ./{frontend_service_name}
108
+ dockerfile: Dockerfile
109
+ container_name: {project_name}-{frontend_service_name}
110
+ environment:
111
+ - REACT_APP_BASE_URL=http://{linked_service_name}:{linked_service_port}/api/v1/
112
+ - REACT_APP_API_KEY=${REACT_APP_API_KEY}
113
+ - REACT_APP_KEY=${REACT_APP_KEY}
114
+ - REACT_APP_IV=${REACT_APP_IV}
115
+ ports:
116
+ - "{frontend_port}:80"
117
+ depends_on:
118
+ - {linked_service_name}
119
+ networks:
120
+ - {project_name}-network
121
+ restart: unless-stopped
122
+
123
+ networks:
124
+ {project_name}-network:
125
+ driver: bridge
126
+
127
+ volumes:
128
+ {db_data_volume}:
129
+ redis-data:
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Variable Substitution Rules
135
+
136
+ ### Project-level
137
+ - `{project_name}` → `context.project_name` (lowercase, hyphens)
138
+
139
+ ### Database service
140
+ - `{db_service_name}` → `postgres` | `mysql` | `mongo`
141
+ - `{db_image}` → `postgres:15-alpine` | `mysql:8` | `mongo:7`
142
+ - `{db_type}` → `context.db.type`
143
+ - `{db_port}` → `context.db.port`
144
+ - `{db_internal_port}` → 5432 (postgres) | 3306 (mysql) | 27017 (mongo)
145
+ - `{db_data_volume}` → `postgres-data` | `mysql-data` | `mongo-data`
146
+ - `{db_volume_path}` → `postgresql/data` | `mysql` | `mongodb`
147
+
148
+ ### Database environment variables
149
+ **PostgreSQL:**
150
+ ```yaml
151
+ POSTGRES_DB: ${DB_NAME}
152
+ POSTGRES_USER: ${DB_USER}
153
+ POSTGRES_PASSWORD: ${DB_PASS}
154
+ ```
155
+
156
+ **MySQL:**
157
+ ```yaml
158
+ MYSQL_DATABASE: ${DB_NAME}
159
+ MYSQL_USER: ${DB_USER}
160
+ MYSQL_PASSWORD: ${DB_PASS}
161
+ MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
162
+ ```
163
+
164
+ **MongoDB:**
165
+ ```yaml
166
+ MONGO_INITDB_ROOT_USERNAME: ${DB_USER}
167
+ MONGO_INITDB_ROOT_PASSWORD: ${DB_PASS}
168
+ MONGO_INITDB_DATABASE: ${DB_NAME}
169
+ ```
170
+
171
+ ### Database health checks
172
+ **PostgreSQL:**
173
+ ```yaml
174
+ test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
175
+ ```
176
+
177
+ **MySQL:**
178
+ ```yaml
179
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u${DB_USER}", "-p${DB_PASS}"]
180
+ ```
181
+
182
+ **MongoDB:**
183
+ ```yaml
184
+ test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
185
+ ```
186
+
187
+ ### NodeJS services
188
+ For each service in `context.services` where `type == "nodejs"`:
189
+ - `{service_name}` → service key from context.services
190
+ - `{service_port}` → `context.services[<service_name>].port`
191
+
192
+ ### ReactJS services
193
+ For each service in `context.services` where `type == "reactjs"`:
194
+ - `{frontend_service_name}` → service key
195
+ - `{frontend_port}` → `context.services[<service_name>].port`
196
+ - `{linked_service_name}` → `context.services[<service_name>].linked_service`
197
+ - `{linked_service_port}` → `context.services[<linked_service>].port`
198
+
199
+ ---
200
+
201
+ ## File Location
202
+
203
+ Write to: `<repository_root>/docker-compose.yml`
204
+
205
+ ---
206
+
207
+ ## Companion File: .env.docker
208
+
209
+ Also generate `.env.docker` at repository root:
210
+
211
+ ```env
212
+ # Database credentials
213
+ DB_NAME={context.db.name}
214
+ DB_USER={context.db.user}
215
+ DB_PASS=your_secure_password_here
216
+ DB_ROOT_PASS=your_root_password_here
217
+
218
+ # Service keys (from first NodeJS service)
219
+ KEY={encryption_key}
220
+ IV={encryption_iv}
221
+ API_KEY={api_key}
222
+
223
+ # ReactJS keys (inherited from linked service)
224
+ REACT_APP_API_KEY={api_key}
225
+ REACT_APP_KEY={encryption_key}
226
+ REACT_APP_IV={encryption_iv}
227
+ ```
228
+
229
+ And `.env.docker.example` with blanked values.
230
+
231
+ ---
232
+
233
+ ## Update Strategy
234
+
235
+ ### If docker-compose.yml already exists:
236
+ 1. Read existing file
237
+ 2. Parse services section
238
+ 3. Add new service definition for the newly initialized service
239
+ 4. Update networks and volumes if needed
240
+ 5. Write back to disk
241
+
242
+ ### If this is the first service:
243
+ Generate the complete file with all sections.
244
+
245
+ ---
246
+
247
+ ## Dependencies
248
+
249
+ - Requires at least one service in `context.services`
250
+ - Requires `context.db` to be populated (for NodeJS/database projects)
251
+ - Can be generated after all service Dockerfiles are created
252
+
253
+ ---
254
+
255
+ ## Usage Commands (added to README)
256
+
257
+ ```bash
258
+ # Start all services
259
+ docker-compose --env-file .env.docker up -d
260
+
261
+ # Start specific service
262
+ docker-compose --env-file .env.docker up -d auth
263
+
264
+ # View logs
265
+ docker-compose logs -f auth
266
+
267
+ # Stop all services
268
+ docker-compose down
269
+
270
+ # Rebuild after code changes
271
+ docker-compose build auth
272
+ docker-compose up -d auth
273
+
274
+ # Full reset (removes volumes)
275
+ docker-compose down -v
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Security Notes
281
+
282
+ - `.env.docker` should be in `.gitignore` (secrets never committed)
283
+ - `.env.docker.example` is committed (structure without values)
284
+ - Database passwords must be strong in production
285
+ - Service-to-service communication happens on internal network only
286
+ - External access only through exposed ports
287
+
288
+ ---
289
+
290
+ ## Production Considerations
291
+
292
+ For production deployment, this compose file should be:
293
+ 1. Split into `docker-compose.yml` (base) + `docker-compose.prod.yml` (overrides)
294
+ 2. Use Docker secrets instead of environment variables
295
+ 3. Add resource limits (CPU, memory)
296
+ 4. Add logging drivers
297
+ 5. Use external volumes for data persistence
298
+ 6. Add traefik/nginx for reverse proxy and SSL
@@ -0,0 +1,126 @@
1
+ ---
2
+ type: task
3
+ name: generate-dockerfile
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: Dockerfile
8
+
9
+ ## Purpose
10
+ Generates a multi-stage production-ready Dockerfile for the NodeJS service.
11
+ Uses Alpine Linux for minimal image size and includes only production
12
+ dependencies in the final image.
13
+
14
+ ---
15
+
16
+ ## Template
17
+
18
+ ```dockerfile
19
+ # Stage 1: Build dependencies
20
+ FROM node:18-alpine AS builder
21
+
22
+ WORKDIR /app
23
+
24
+ # Copy package files
25
+ COPY package*.json ./
26
+
27
+ # Install all dependencies (including devDependencies for build if needed)
28
+ RUN npm ci
29
+
30
+ # Copy application code
31
+ COPY . .
32
+
33
+ # Stage 2: Production image
34
+ FROM node:18-alpine
35
+
36
+ # Install dumb-init for proper signal handling
37
+ RUN apk add --no-cache dumb-init
38
+
39
+ # Create app user for security (don't run as root)
40
+ RUN addgroup -g 1001 -S nodejs && \
41
+ adduser -S nodejs -u 1001
42
+
43
+ WORKDIR /app
44
+
45
+ # Copy package files
46
+ COPY package*.json ./
47
+
48
+ # Install only production dependencies
49
+ RUN npm ci --only=production && npm cache clean --force
50
+
51
+ # Copy built application from builder stage
52
+ COPY --from=builder --chown=nodejs:nodejs /app .
53
+
54
+ # Create necessary directories with proper permissions
55
+ RUN mkdir -p logger/logs pem images && \
56
+ chown -R nodejs:nodejs logger/logs pem images
57
+
58
+ # Switch to non-root user
59
+ USER nodejs
60
+
61
+ # Expose the service port
62
+ EXPOSE {port}
63
+
64
+ # Health check
65
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
66
+ CMD node -e "require('http').get('http://localhost:{port}/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
67
+
68
+ # Use dumb-init to handle signals properly
69
+ ENTRYPOINT ["dumb-init", "--"]
70
+
71
+ # Start the application
72
+ CMD ["node", "app.js"]
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Variable Substitutions
78
+
79
+ Replace these placeholders with context values:
80
+ - `{port}` → `context.current_init.port` or `context.services[<service_name>].port`
81
+
82
+ ---
83
+
84
+ ## File Location
85
+
86
+ Write to: `<service_name>/Dockerfile`
87
+
88
+ ---
89
+
90
+ ## Dependencies
91
+
92
+ - Requires `package.json` to exist (Wave 1)
93
+ - Requires `app.js` to exist (Wave 5)
94
+ - Can be generated in Wave 6 (post-completion)
95
+
96
+ ---
97
+
98
+ ## What This Dockerfile Does
99
+
100
+ 1. **Multi-stage build** — reduces final image size by 40-60%
101
+ 2. **Alpine Linux** — minimal base image (~5MB vs ~150MB for full node)
102
+ 3. **Non-root user** — security best practice
103
+ 4. **dumb-init** — proper signal handling for graceful shutdowns
104
+ 5. **Health check** — container orchestration support
105
+ 6. **Production dependencies only** — no devDependencies in final image
106
+ 7. **Layer caching** — package.json copied before app code for faster rebuilds
107
+
108
+ ---
109
+
110
+ ## Security Features
111
+
112
+ - Runs as non-root user (nodejs:nodejs with UID 1001)
113
+ - No unnecessary packages installed
114
+ - Proper file permissions for writable directories
115
+ - Health check endpoint at `/health` (assumes route exists)
116
+
117
+ ---
118
+
119
+ ## Notes
120
+
121
+ - The health check assumes a `/health` route exists on the service.
122
+ If not present, the nodejs-agent should generate a basic health
123
+ route in the default module during initialization.
124
+ - Image size will be approximately 120-150MB depending on dependencies
125
+ - Build time is optimized through layer caching — changing app code
126
+ does not invalidate the npm install layer
@@ -0,0 +1,123 @@
1
+ ---
2
+ type: task
3
+ name: generate-dockerignore
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: .dockerignore
8
+
9
+ ## Purpose
10
+ Excludes unnecessary files and directories from the Docker build context,
11
+ reducing build time and final image size. Mirrors .gitignore but with
12
+ additional Docker-specific exclusions.
13
+
14
+ ---
15
+
16
+ ## Template
17
+
18
+ ```
19
+ # Dependencies
20
+ node_modules/
21
+ npm-debug.log
22
+ yarn-error.log
23
+ package-lock.json
24
+
25
+ # Environment files (will be provided at runtime)
26
+ .env
27
+ .env.*
28
+ !.env.example
29
+
30
+ # Logs
31
+ logger/logs/
32
+ *.log
33
+
34
+ # Development files
35
+ .vscode/
36
+ .idea/
37
+ .cursor/
38
+ *.swp
39
+ *.swo
40
+ *~
41
+
42
+ # Testing
43
+ coverage/
44
+ .nyc_output/
45
+ *.test.js
46
+ *.spec.js
47
+ __tests__/
48
+
49
+ # Documentation
50
+ README.md
51
+ docs/
52
+ *.md
53
+ !package.json
54
+
55
+ # Git
56
+ .git/
57
+ .gitignore
58
+ .gitattributes
59
+
60
+ # Docker
61
+ Dockerfile
62
+ .dockerignore
63
+ docker-compose*.yml
64
+
65
+ # OS files
66
+ .DS_Store
67
+ Thumbs.db
68
+ .cache/
69
+
70
+ # Build artifacts
71
+ dist/
72
+ build/
73
+
74
+ # IDE configs
75
+ .codeninja/
76
+
77
+ # Demo files
78
+ enc_dec.html
79
+ enc_dec.php
80
+
81
+ # Temporary files
82
+ tmp/
83
+ temp/
84
+ *.tmp
85
+ ```
86
+
87
+ ---
88
+
89
+ ## File Location
90
+
91
+ Write to: `<service_name>/.dockerignore`
92
+
93
+ ---
94
+
95
+ ## Dependencies
96
+
97
+ None — can be generated in Wave 1 alongside .gitignore
98
+
99
+ ---
100
+
101
+ ## What This File Does
102
+
103
+ 1. **Excludes node_modules** — will be installed fresh in container
104
+ 2. **Excludes .env** — environment variables passed at runtime
105
+ 3. **Excludes logs** — logs are written at runtime, not baked into image
106
+ 4. **Excludes development files** — IDE configs, test files, docs
107
+ 5. **Excludes .codeninja** — agent system not needed in production
108
+
109
+ ---
110
+
111
+ ## Security Benefits
112
+
113
+ - `.env` files never accidentally copied into image
114
+ - Development-only secrets (.cursor, .vscode configs) excluded
115
+ - Smaller attack surface (fewer files in image)
116
+
117
+ ---
118
+
119
+ ## Performance Benefits
120
+
121
+ - Faster builds (smaller context sent to Docker daemon)
122
+ - Better layer caching (changes to excluded files don't invalidate layers)
123
+ - Smaller final image size