@bpinhosilva/agent-orchestrator 1.0.0-alpha.25 → 1.0.0-alpha.26

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 (159) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +110 -12
  3. package/dist/agents/agents.controller.js +0 -1
  4. package/dist/agents/agents.module.js +0 -1
  5. package/dist/agents/agents.service.js +0 -1
  6. package/dist/agents/dto/agent-request.dto.js +0 -1
  7. package/dist/agents/dto/create-agent.dto.js +0 -1
  8. package/dist/agents/dto/update-agent.dto.js +0 -1
  9. package/dist/agents/entities/agent.entity.js +0 -1
  10. package/dist/agents/enums/provider.enum.js +0 -1
  11. package/dist/agents/implementations/claude.agent.js +0 -1
  12. package/dist/agents/implementations/gemini.agent.js +0 -1
  13. package/dist/agents/interfaces/agent.interface.js +0 -1
  14. package/dist/agents/registry/agent.registry.js +0 -1
  15. package/dist/app.controller.d.ts +3 -0
  16. package/dist/app.controller.js +12 -1
  17. package/dist/app.module.js +13 -8
  18. package/dist/app.service.d.ts +3 -0
  19. package/dist/app.service.js +3 -1
  20. package/dist/auth/auth.controller.d.ts +7 -9
  21. package/dist/auth/auth.controller.js +14 -2
  22. package/dist/auth/auth.module.js +0 -1
  23. package/dist/auth/auth.service.d.ts +5 -10
  24. package/dist/auth/auth.service.js +35 -5
  25. package/dist/auth/decorators/current-user.decorator.js +0 -1
  26. package/dist/auth/decorators/public.decorator.js +0 -1
  27. package/dist/auth/decorators/roles.decorator.js +0 -1
  28. package/dist/auth/dto/login.dto.js +0 -1
  29. package/dist/auth/dto/register.dto.d.ts +3 -0
  30. package/dist/auth/dto/register.dto.js +16 -2
  31. package/dist/auth/dto/update-profile.dto.d.ts +9 -0
  32. package/dist/auth/dto/update-profile.dto.js +65 -0
  33. package/dist/auth/entities/refresh-token.entity.js +0 -1
  34. package/dist/auth/guards/jwt-auth.guard.js +0 -1
  35. package/dist/auth/guards/roles.guard.js +0 -1
  36. package/dist/auth/strategies/jwt.strategy.d.ts +1 -1
  37. package/dist/auth/strategies/jwt.strategy.js +9 -2
  38. package/dist/cli/index.d.ts +0 -5
  39. package/dist/cli/index.js +16 -58
  40. package/dist/common/common.module.js +0 -1
  41. package/dist/common/entities/artifact.entity.js +0 -1
  42. package/dist/common/filters/http-exception.filter.js +0 -1
  43. package/dist/common/storage.service.js +0 -1
  44. package/dist/config/env.validation.js +3 -1
  45. package/dist/config/runtime-paths.d.ts +6 -0
  46. package/dist/config/runtime-paths.js +38 -0
  47. package/dist/config/typeorm.js +4 -14
  48. package/dist/database/migration-state.d.ts +10 -0
  49. package/dist/database/migration-state.js +55 -0
  50. package/dist/main.js +23 -2
  51. package/dist/migrations/{1774850116434-CreateRefreshTokens.d.ts → 1775260737095-BaselineSchema.d.ts} +1 -1
  52. package/dist/migrations/1775260737095-BaselineSchema.js +215 -0
  53. package/dist/models/dto/create-model.dto.js +0 -1
  54. package/dist/models/dto/update-model.dto.js +0 -1
  55. package/dist/models/entities/model.entity.js +0 -1
  56. package/dist/models/models.controller.js +0 -1
  57. package/dist/models/models.module.js +0 -1
  58. package/dist/models/models.service.js +0 -1
  59. package/dist/projects/dto/add-member.dto.js +0 -1
  60. package/dist/projects/dto/create-project.dto.js +0 -1
  61. package/dist/projects/dto/update-project.dto.js +0 -1
  62. package/dist/projects/entities/project-member.entity.js +0 -1
  63. package/dist/projects/entities/project.entity.js +0 -1
  64. package/dist/projects/projects.controller.js +0 -1
  65. package/dist/projects/projects.module.js +0 -1
  66. package/dist/projects/projects.service.js +0 -1
  67. package/dist/providers/dto/create-provider.dto.js +0 -1
  68. package/dist/providers/dto/update-provider.dto.js +0 -1
  69. package/dist/providers/entities/provider.entity.js +0 -1
  70. package/dist/providers/providers.controller.js +0 -1
  71. package/dist/providers/providers.module.js +0 -1
  72. package/dist/providers/providers.service.js +0 -1
  73. package/dist/tasks/comments.controller.js +0 -1
  74. package/dist/tasks/comments.service.js +0 -1
  75. package/dist/tasks/dto/create-comment.dto.js +0 -1
  76. package/dist/tasks/dto/create-recurrent-task.dto.js +0 -1
  77. package/dist/tasks/dto/create-task.dto.js +0 -1
  78. package/dist/tasks/dto/update-comment.dto.js +0 -1
  79. package/dist/tasks/dto/update-recurrent-task.dto.js +0 -1
  80. package/dist/tasks/dto/update-task.dto.js +0 -1
  81. package/dist/tasks/entities/comment.entity.js +0 -1
  82. package/dist/tasks/entities/recurrent-task-exec.entity.js +0 -1
  83. package/dist/tasks/entities/recurrent-task.entity.js +0 -1
  84. package/dist/tasks/entities/task.entity.js +0 -1
  85. package/dist/tasks/recurrent-task-scheduler.service.js +0 -1
  86. package/dist/tasks/recurrent-tasks.controller.js +0 -1
  87. package/dist/tasks/recurrent-tasks.service.js +0 -1
  88. package/dist/tasks/task-scheduler.service.js +0 -1
  89. package/dist/tasks/tasks.controller.js +0 -1
  90. package/dist/tasks/tasks.module.js +0 -1
  91. package/dist/tasks/tasks.service.js +0 -1
  92. package/dist/ui/assets/AgentFleet-kJ8qz6Wt.js +1 -0
  93. package/dist/ui/assets/{ConfirmDialog-mRH8i_xK.js → ConfirmDialog-Djtf7EW0.js} +2 -2
  94. package/dist/ui/assets/{MarkdownField-flCuU7w3.js → MarkdownField-CYto7bYs.js} +1 -1
  95. package/dist/ui/assets/Profile-CVJxC_iQ.js +1 -0
  96. package/dist/ui/assets/ProjectDetail-sdHv2RVb.js +1 -0
  97. package/dist/ui/assets/Providers-mv6Ki6Ja.js +1 -0
  98. package/dist/ui/assets/Scheduler-DrqCsl1E.js +1 -0
  99. package/dist/ui/assets/{TaskDetail-BdQJCVo3.js → TaskDetail-Dl2jSnCq.js} +1 -1
  100. package/dist/ui/assets/TaskManager-CVxOPuXy.js +8 -0
  101. package/dist/ui/assets/box-CsCoq7gr.js +1 -0
  102. package/dist/ui/assets/chevron-down-g12gVicW.js +1 -0
  103. package/dist/ui/assets/index-B1cyp9Ue.css +1 -0
  104. package/dist/ui/assets/index-B9Ws7qcW.js +2 -0
  105. package/dist/ui/assets/providers-_o5m2NEh.js +1 -0
  106. package/dist/ui/assets/rocket-DvvoumQL.js +1 -0
  107. package/dist/ui/assets/{trending-up-DBTQIgW8.js → trending-up-BqKi8IJf.js} +1 -1
  108. package/dist/ui/avatar-presets/avatar-01.svg +11 -0
  109. package/dist/ui/avatar-presets/avatar-02.svg +12 -0
  110. package/dist/ui/avatar-presets/avatar-03.svg +12 -0
  111. package/dist/ui/avatar-presets/avatar-04.svg +12 -0
  112. package/dist/ui/avatar-presets/avatar-05.svg +12 -0
  113. package/dist/ui/avatar-presets/avatar-06.svg +12 -0
  114. package/dist/ui/avatar-presets/avatar-07.svg +12 -0
  115. package/dist/ui/avatar-presets/avatar-08.svg +12 -0
  116. package/dist/ui/index.html +5 -4
  117. package/dist/uploads/uploads.controller.js +0 -1
  118. package/dist/uploads/uploads.module.js +0 -1
  119. package/dist/users/avatar.constants.d.ts +11 -0
  120. package/dist/users/avatar.constants.js +35 -0
  121. package/dist/users/dto/create-user.dto.d.ts +3 -0
  122. package/dist/users/dto/create-user.dto.js +16 -2
  123. package/dist/users/dto/update-user.dto.d.ts +2 -0
  124. package/dist/users/dto/update-user.dto.js +18 -2
  125. package/dist/users/entities/user.entity.d.ts +2 -0
  126. package/dist/users/entities/user.entity.js +9 -0
  127. package/dist/users/users.controller.d.ts +3 -3
  128. package/dist/users/users.controller.js +12 -13
  129. package/dist/users/users.module.js +0 -1
  130. package/dist/users/users.service.d.ts +3 -0
  131. package/dist/users/users.service.js +9 -1
  132. package/package.json +7 -3
  133. package/dist/migrations/1774746981348-InitialSchemaAndSeed.d.ts +0 -6
  134. package/dist/migrations/1774746981348-InitialSchemaAndSeed.js +0 -57
  135. package/dist/migrations/1774850116434-CreateRefreshTokens.js +0 -68
  136. package/dist/migrations/1775103764402-AddRbacAndProjectMembership.d.ts +0 -6
  137. package/dist/migrations/1775103764402-AddRbacAndProjectMembership.js +0 -124
  138. package/dist/ui/assets/AgentFleet-CC0h_Ar0.js +0 -1
  139. package/dist/ui/assets/ProjectDetail-CY-VSV2D.js +0 -1
  140. package/dist/ui/assets/Providers-C9_lxOG1.js +0 -1
  141. package/dist/ui/assets/Scheduler-Du2cIGfB.js +0 -1
  142. package/dist/ui/assets/TaskManager-CWDh69pf.js +0 -8
  143. package/dist/ui/assets/index-CCsHBe__.css +0 -1
  144. package/dist/ui/assets/index-yzhzS93F.js +0 -2
  145. package/dist/ui/assets/providers-BMRq_pkm.js +0 -1
  146. /package/dist/ui/assets/{InitialsAvatar-0mIRaTK8.js → InitialsAvatar-B_nsCs58.js} +0 -0
  147. /package/dist/ui/assets/{clock-C0d1RzP_.js → clock-R052yhHC.js} +0 -0
  148. /package/dist/ui/assets/{cn-i-5ItZGU.js → cn-w7-BIiZy.js} +0 -0
  149. /package/dist/ui/assets/{eye-RB18-re_.js → eye-l4Yx91ui.js} +0 -0
  150. /package/dist/ui/assets/{layers-D5ECV506.js → layers-DmKVnI8y.js} +0 -0
  151. /package/dist/ui/assets/{send-BA7-sXzg.js → send-CaBqcm_I.js} +0 -0
  152. /package/dist/ui/assets/{shield-check-D7JIluse.js → shield-check-Vujd3EPc.js} +0 -0
  153. /package/dist/ui/assets/{sparkles-CCXaTT3H.js → sparkles-DfBrsYtR.js} +0 -0
  154. /package/dist/ui/assets/{tasks-DEHCZk48.js → tasks-9h6EhJqU.js} +0 -0
  155. /package/dist/ui/assets/{trash-2-BNP4kC5c.js → trash-2-Dj3ML80c.js} +0 -0
  156. /package/dist/ui/assets/{user-Cp55HCCi.js → user-r_WwM0uQ.js} +0 -0
  157. /package/dist/ui/assets/{vendor-forms-HC2wK6B9.js → vendor-forms-BhyC9zH1.js} +0 -0
  158. /package/dist/ui/assets/{vendor-motion-CkXYvnuI.js → vendor-motion-CYM51UOz.js} +0 -0
  159. /package/dist/ui/assets/{zap-D1sST66b.js → zap-Vy8-GCO1.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ # [1.0.0-alpha.26](https://github.com/bpinhosilva/agent-orchestrator/compare/v1.0.0-alpha.25...v1.0.0-alpha.26) (2026-04-04)
2
+
3
+
4
+ ### Features
5
+
6
+ * add AGENTS.md file ([51c706f](https://github.com/bpinhosilva/agent-orchestrator/commit/51c706f8784dd354280d853f605bb8c69e53175c))
7
+ * implement containerization, add health check endpoint, and update RBAC ([17149d3](https://github.com/bpinhosilva/agent-orchestrator/commit/17149d32a623f532308ba0f415a4b2ba332ec794))
8
+ * **refactor:** project terminology and update UI components ([47e5cb4](https://github.com/bpinhosilva/agent-orchestrator/commit/47e5cb4d45c05f893ebdd898f02ceeadcd213652))
9
+
1
10
  # [1.0.0-alpha.25](https://github.com/bpinhosilva/agent-orchestrator/compare/v1.0.0-alpha.24...v1.0.0-alpha.25) (2026-04-03)
2
11
 
3
12
 
package/README.md CHANGED
@@ -25,7 +25,7 @@ Agent Orchestrator is an open-source project designed to manage and orchestrate
25
25
 
26
26
  ## Prerequisites
27
27
  - [Node.js](https://nodejs.org/) (v24+)
28
- - [Docker](https://www.docker.com/) and Docker Compose (optional, for PostgreSQL)
28
+ - [Docker](https://www.docker.com/) and Docker Compose (optional, for the containerized stack)
29
29
  - A [Google Gemini API Key](https://aistudio.google.com/) or [Anthropic API Key](https://console.anthropic.com/)
30
30
 
31
31
  ## Quick Start
@@ -89,6 +89,8 @@ DATABASE_URL= # PostgreSQL connection string (omit for SQL
89
89
  ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000
90
90
  SCHEDULER_ENABLED=true # Enable/disable task scheduler CRON
91
91
  DB_LOGGING=false # Enable TypeORM query logging
92
+ SERVE_STATIC_UI=true # Set false when the UI is served by a separate container/proxy
93
+ CHECK_PENDING_MIGRATIONS_ON_STARTUP=false
92
94
  ```
93
95
 
94
96
  ### 3. Set Up the Database
@@ -97,11 +99,11 @@ DB_LOGGING=false # Enable TypeORM query logging
97
99
 
98
100
  SQLite is used automatically when `DATABASE_URL` is not set. The database file is created at `local.sqlite` in the project root (or `$AGENT_ORCHESTRATOR_HOME/local.sqlite`).
99
101
 
100
- **Option B: PostgreSQL (Production)**
102
+ **Option B: PostgreSQL (Production / Docker)**
101
103
 
102
104
  ```bash
103
- # Start PostgreSQL via Docker Compose
104
- docker compose up -d
105
+ # Start only PostgreSQL
106
+ docker compose up -d db
105
107
 
106
108
  # Set the connection string
107
109
  export DATABASE_URL="postgresql://orchestrator:orchestrator_password@localhost:5433/agent_orchestrator"
@@ -139,6 +141,100 @@ npm run start:prod
139
141
 
140
142
  The dashboard is available at `http://localhost:3000` and the API at `http://localhost:3000/api/v1/`.
141
143
 
144
+ ### 5. Run with Docker
145
+
146
+ The repository now includes three compose entrypoints:
147
+
148
+ - `docker-compose.yml` — production-like stack with **PostgreSQL + distroless API + Caddy UI**
149
+ - `docker-compose.dev.yml` — development stack with hot reload for API and UI
150
+ - `docker-compose-test.yml` — containerized integration stack for migration, CLI, API, and UI checks
151
+
152
+ All Docker entrypoints read from the repository-root `.env` file. For the Docker flows, the most relevant variables are:
153
+
154
+ ```bash
155
+ JWT_SECRET="at-least-32-characters-long-secret-key"
156
+ POSTGRES_USER=orchestrator
157
+ POSTGRES_PASSWORD=orchestrator_password
158
+ POSTGRES_DB=agent_orchestrator
159
+ POSTGRES_PORT=5433
160
+ POSTGRES_TEST_DB=agent_orchestrator_test
161
+ POSTGRES_TEST_PORT=5434
162
+ GEMINI_API_KEY=
163
+ ANTHROPIC_API_KEY=
164
+ ```
165
+
166
+ #### Production-like Docker stack
167
+
168
+ ```bash
169
+ # Build and start PostgreSQL + API + UI
170
+ npm run docker:up
171
+
172
+ # The API will refuse to start until migrations are applied
173
+ docker compose run --rm api dist/cli/index.js migrate --yes
174
+
175
+ # Stop the stack
176
+ npm run docker:down
177
+ ```
178
+
179
+ - UI: `https://localhost` or `https://agent-orchestrator.localhost`
180
+ - API: `http://localhost:3000/api/v1`
181
+
182
+ The API container does **not** serve the SPA in Docker mode. The UI is served by **Caddy**, which also proxies `/api/*` traffic to the API container so the browser can use the same origin for UI + API.
183
+
184
+ The UI container uses **Caddy** with `tls internal`, so HTTPS works locally without an external CA. Browsers will still warn until you trust Caddy's local root certificate on your host machine. You can copy it out of the container with:
185
+
186
+ ```bash
187
+ docker compose cp ui:/data/caddy/pki/authorities/local/root.crt ./caddy-local-root.crt
188
+ ```
189
+
190
+ After trusting that certificate in your OS/browser trust store, local HTTPS becomes trusted as well.
191
+
192
+ #### Development Docker stack
193
+
194
+ ```bash
195
+ npm run docker:dev
196
+
197
+ # Stop the dev stack
198
+ docker compose -f docker-compose.dev.yml down
199
+ ```
200
+
201
+ - UI dev server: `http://localhost:5173`
202
+ - API: `http://localhost:3000/api/v1`
203
+ - PostgreSQL: `localhost:5433`
204
+
205
+ The dev stack disables bundled UI serving in the API container and points the Vite dev proxy at the `api` service over the Docker network.
206
+
207
+ #### Docker integration / end-to-end stack
208
+
209
+ Use the test compose file when you want to exercise migration behavior, CLI commands, API startup, and the UI together:
210
+
211
+ ```bash
212
+ # Start only the database first
213
+ docker compose -f docker-compose-test.yml up -d db
214
+
215
+ # Verify pending migrations block API startup
216
+ docker compose -f docker-compose-test.yml up api
217
+
218
+ # Apply migrations with the packaged CLI runtime
219
+ docker compose -f docker-compose-test.yml run --rm migrate
220
+
221
+ # Then bring up the full app stack
222
+ docker compose -f docker-compose-test.yml up ui api
223
+
224
+ # Run ad hoc CLI checks
225
+ docker compose -f docker-compose-test.yml run --rm cli dist/cli/index.js status
226
+
227
+ # Tear the test stack down
228
+ docker compose -f docker-compose-test.yml down -v
229
+ ```
230
+
231
+ The test stack is designed for:
232
+
233
+ - verifying that pending migrations block API startup,
234
+ - applying migrations through the packaged CLI/runtime path,
235
+ - checking UI reachability through Caddy,
236
+ - exercising future CLI-driven Docker behaviors without depending on the local SQLite test path.
237
+
142
238
  ## Database Management
143
239
 
144
240
  The project uses [TypeORM](https://typeorm.io/) migrations to manage schema changes. **Never rely on `synchronize: true`** — it is disabled in all environments.
@@ -192,18 +288,20 @@ This creates a user with the `admin` role. All subsequent users registered via `
192
288
  ### Docker
193
289
 
194
290
  ```bash
195
- # Build and run with Docker Compose (includes PostgreSQL)
196
- docker compose up -d
291
+ # Production-like stack
292
+ npm run docker:up
197
293
 
198
- # Apply migrations
199
- DATABASE_URL="postgresql://orchestrator:orchestrator_password@localhost:5433/agent_orchestrator" \
200
- npm run migration:run
294
+ # Apply migrations with the packaged runtime inside the API container
295
+ docker compose run --rm api dist/cli/index.js migrate --yes
201
296
 
202
- # Seed admin
203
- DATABASE_URL="postgresql://orchestrator:orchestrator_password@localhost:5433/agent_orchestrator" \
204
- npm run seed:admin
297
+ # Stop the stack
298
+ npm run docker:down
205
299
  ```
206
300
 
301
+ The API container is configured to **fail fast when migrations are pending**. This keeps schema changes explicit instead of silently mutating the database during startup.
302
+
303
+ This behavior is controlled by `CHECK_PENDING_MIGRATIONS_ON_STARTUP=true` in the Docker API service. Docker mode also sets `SERVE_STATIC_UI=false` so the backend does not try to serve bundled frontend assets.
304
+
207
305
  ### Updating an Existing Deployment
208
306
 
209
307
  1. Pull the latest code
@@ -114,4 +114,3 @@ exports.AgentsController = AgentsController = __decorate([
114
114
  (0, common_1.Controller)('agents'),
115
115
  __metadata("design:paramtypes", [agents_service_1.AgentsService])
116
116
  ], AgentsController);
117
- //# sourceMappingURL=agents.controller.js.map
@@ -25,4 +25,3 @@ exports.AgentsModule = AgentsModule = __decorate([
25
25
  exports: [agents_service_1.AgentsService],
26
26
  })
27
27
  ], AgentsModule);
28
- //# sourceMappingURL=agents.module.js.map
@@ -190,4 +190,3 @@ exports.AgentsService = AgentsService = AgentsService_1 = __decorate([
190
190
  __metadata("design:paramtypes", [typeorm_2.Repository,
191
191
  core_1.ModuleRef])
192
192
  ], AgentsService);
193
- //# sourceMappingURL=agents.service.js.map
@@ -31,4 +31,3 @@ __decorate([
31
31
  (0, class_validator_1.MaxLength)(50000),
32
32
  __metadata("design:type", String)
33
33
  ], AgentRequestDto.prototype, "input", void 0);
34
- //# sourceMappingURL=agent-request.dto.js.map
@@ -65,4 +65,3 @@ __decorate([
65
65
  (0, class_validator_1.IsNotEmpty)(),
66
66
  __metadata("design:type", String)
67
67
  ], CreateAgentDto.prototype, "providerId", void 0);
68
- //# sourceMappingURL=create-agent.dto.js.map
@@ -10,4 +10,3 @@ class UpdateAgentDto extends (0, mapped_types_1.PartialType)(create_agent_dto_1.
10
10
  }
11
11
  }
12
12
  exports.UpdateAgentDto = UpdateAgentDto;
13
- //# sourceMappingURL=update-agent.dto.js.map
@@ -84,4 +84,3 @@ __decorate([
84
84
  exports.AgentEntity = AgentEntity = __decorate([
85
85
  (0, typeorm_1.Entity)('agents')
86
86
  ], AgentEntity);
87
- //# sourceMappingURL=agent.entity.js.map
@@ -6,4 +6,3 @@ var Provider;
6
6
  Provider["GOOGLE"] = "google";
7
7
  Provider["ANTHROPIC"] = "anthropic";
8
8
  })(Provider || (exports.Provider = Provider = {}));
9
- //# sourceMappingURL=provider.enum.js.map
@@ -145,4 +145,3 @@ exports.ClaudeAgent = ClaudeAgent = ClaudeAgent_1 = __decorate([
145
145
  __param(1, (0, common_1.Optional)()),
146
146
  __metadata("design:paramtypes", [config_1.ConfigService, String])
147
147
  ], ClaudeAgent);
148
- //# sourceMappingURL=claude.agent.js.map
@@ -191,4 +191,3 @@ exports.GeminiAgent = GeminiAgent = GeminiAgent_1 = __decorate([
191
191
  __param(1, (0, common_1.Optional)()),
192
192
  __metadata("design:paramtypes", [config_1.ConfigService, String])
193
193
  ], GeminiAgent);
194
- //# sourceMappingURL=gemini.agent.js.map
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=agent.interface.js.map
@@ -12,4 +12,3 @@ function RegisterAgent(provider) {
12
12
  function getAgentImplementation(provider) {
13
13
  return exports.AGENT_REGISTRY.get(provider);
14
14
  }
15
- //# sourceMappingURL=agent.registry.js.map
@@ -3,4 +3,7 @@ export declare class AppController {
3
3
  private readonly appService;
4
4
  constructor(appService: AppService);
5
5
  getHello(): string;
6
+ getHealth(): {
7
+ status: string;
8
+ };
6
9
  }
@@ -13,6 +13,7 @@ exports.AppController = void 0;
13
13
  const openapi = require("@nestjs/swagger");
14
14
  const common_1 = require("@nestjs/common");
15
15
  const app_service_1 = require("./app.service");
16
+ const public_decorator_1 = require("./auth/decorators/public.decorator");
16
17
  let AppController = class AppController {
17
18
  appService;
18
19
  constructor(appService) {
@@ -21,6 +22,9 @@ let AppController = class AppController {
21
22
  getHello() {
22
23
  return this.appService.getHello();
23
24
  }
25
+ getHealth() {
26
+ return this.appService.getHealth();
27
+ }
24
28
  };
25
29
  exports.AppController = AppController;
26
30
  __decorate([
@@ -30,8 +34,15 @@ __decorate([
30
34
  __metadata("design:paramtypes", []),
31
35
  __metadata("design:returntype", String)
32
36
  ], AppController.prototype, "getHello", null);
37
+ __decorate([
38
+ (0, public_decorator_1.Public)(),
39
+ (0, common_1.Get)('health'),
40
+ openapi.ApiResponse({ status: 200 }),
41
+ __metadata("design:type", Function),
42
+ __metadata("design:paramtypes", []),
43
+ __metadata("design:returntype", Object)
44
+ ], AppController.prototype, "getHealth", null);
33
45
  exports.AppController = AppController = __decorate([
34
46
  (0, common_1.Controller)(),
35
47
  __metadata("design:paramtypes", [app_service_1.AppService])
36
48
  ], AppController);
37
- //# sourceMappingURL=app.controller.js.map
@@ -30,8 +30,10 @@ const auth_module_1 = require("./auth/auth.module");
30
30
  const jwt_auth_guard_1 = require("./auth/guards/jwt-auth.guard");
31
31
  const roles_guard_1 = require("./auth/guards/roles.guard");
32
32
  const typeorm_2 = require("./config/typeorm");
33
- const APP_HOME = process.env.AGENT_ORCHESTRATOR_HOME;
34
- const ENV_PATH = APP_HOME ? (0, path_1.join)(APP_HOME, '.env') : '.env';
33
+ const runtime_paths_1 = require("./config/runtime-paths");
34
+ (0, runtime_paths_1.loadRuntimeEnv)();
35
+ const ENV_PATH = (0, runtime_paths_1.getRuntimeEnvPath)();
36
+ const shouldServeStaticUi = (0, runtime_paths_1.isEnvEnabled)('SERVE_STATIC_UI', true);
35
37
  let AppModule = class AppModule {
36
38
  };
37
39
  exports.AppModule = AppModule;
@@ -68,11 +70,15 @@ exports.AppModule = AppModule = __decorate([
68
70
  };
69
71
  },
70
72
  }),
71
- serve_static_1.ServeStaticModule.forRoot({
72
- rootPath: process.env.NODE_ENV === 'production'
73
- ? (0, path_1.join)(__dirname, 'ui')
74
- : (0, path_1.join)(__dirname, '..', 'ui', 'dist'),
75
- }),
73
+ ...(shouldServeStaticUi
74
+ ? [
75
+ serve_static_1.ServeStaticModule.forRoot({
76
+ rootPath: process.env.NODE_ENV === 'production'
77
+ ? (0, path_1.join)(__dirname, 'ui')
78
+ : (0, path_1.join)(__dirname, '..', 'ui', 'dist'),
79
+ }),
80
+ ]
81
+ : []),
76
82
  common_module_1.CommonModule,
77
83
  uploads_module_1.UploadsModule,
78
84
  agents_module_1.AgentsModule,
@@ -101,4 +107,3 @@ exports.AppModule = AppModule = __decorate([
101
107
  ],
102
108
  })
103
109
  ], AppModule);
104
- //# sourceMappingURL=app.module.js.map
@@ -1,3 +1,6 @@
1
1
  export declare class AppService {
2
2
  getHello(): string;
3
+ getHealth(): {
4
+ status: string;
5
+ };
3
6
  }
@@ -12,9 +12,11 @@ let AppService = class AppService {
12
12
  getHello() {
13
13
  return 'Hello World!';
14
14
  }
15
+ getHealth() {
16
+ return { status: 'ok' };
17
+ }
15
18
  };
16
19
  exports.AppService = AppService;
17
20
  exports.AppService = AppService = __decorate([
18
21
  (0, common_1.Injectable)()
19
22
  ], AppService);
20
- //# sourceMappingURL=app.service.js.map
@@ -2,25 +2,23 @@ import { ConfigService } from '@nestjs/config';
2
2
  import { AuthService } from './auth.service';
3
3
  import { RegisterDto } from './dto/register.dto';
4
4
  import { LoginDto } from './dto/login.dto';
5
- import { UserRole } from '../users/entities/user.entity';
5
+ import { UpdateProfileDto } from './dto/update-profile.dto';
6
6
  import type { Response as ExpressResponse, Request as ExpressRequest } from 'express';
7
7
  export declare class AuthController {
8
8
  private readonly authService;
9
9
  private readonly configService;
10
10
  private readonly isProduction;
11
11
  constructor(authService: AuthService, configService: ConfigService);
12
- register(registerDto: RegisterDto): Promise<{
13
- id: string;
14
- name: string;
15
- email: string;
16
- role: UserRole;
17
- createdAt: Date;
18
- updatedAt: Date;
19
- }>;
12
+ register(registerDto: RegisterDto): Promise<import("../users/avatar.constants").SerializedUser>;
20
13
  login(loginDto: LoginDto, res: ExpressResponse): Promise<void>;
21
14
  refresh(req: ExpressRequest, res: ExpressResponse): Promise<ExpressResponse<any, Record<string, any>>>;
22
15
  getMe(req: {
23
16
  user: unknown;
24
17
  }): unknown;
18
+ updateMe(req: {
19
+ user: {
20
+ id: string;
21
+ };
22
+ }, dto: UpdateProfileDto): Promise<import("../users/avatar.constants").SerializedUser>;
25
23
  logout(req: ExpressRequest, res: ExpressResponse): Promise<void>;
26
24
  }
@@ -23,6 +23,7 @@ const login_dto_1 = require("./dto/login.dto");
23
23
  const public_decorator_1 = require("./decorators/public.decorator");
24
24
  const roles_decorator_1 = require("./decorators/roles.decorator");
25
25
  const user_entity_1 = require("../users/entities/user.entity");
26
+ const update_profile_dto_1 = require("./dto/update-profile.dto");
26
27
  const swagger_1 = require("@nestjs/swagger");
27
28
  let AuthController = class AuthController {
28
29
  authService;
@@ -95,6 +96,9 @@ let AuthController = class AuthController {
95
96
  getMe(req) {
96
97
  return req.user;
97
98
  }
99
+ updateMe(req, dto) {
100
+ return this.authService.updateProfile(req.user.id, dto);
101
+ }
98
102
  async logout(req, res) {
99
103
  const refreshToken = req.cookies?.refresh_token;
100
104
  if (refreshToken) {
@@ -110,7 +114,7 @@ __decorate([
110
114
  (0, roles_decorator_1.Roles)(user_entity_1.UserRole.ADMIN),
111
115
  (0, throttler_1.Throttle)({ default: { limit: 5, ttl: 60000 } }),
112
116
  (0, common_1.Post)('register'),
113
- openapi.ApiResponse({ status: 201 }),
117
+ openapi.ApiResponse({ status: 201, type: Object }),
114
118
  __param(0, (0, common_1.Body)()),
115
119
  __metadata("design:type", Function),
116
120
  __metadata("design:paramtypes", [register_dto_1.RegisterDto]),
@@ -148,6 +152,15 @@ __decorate([
148
152
  __metadata("design:paramtypes", [Object]),
149
153
  __metadata("design:returntype", void 0)
150
154
  ], AuthController.prototype, "getMe", null);
155
+ __decorate([
156
+ (0, common_1.Patch)('me'),
157
+ openapi.ApiResponse({ status: 200, type: Object }),
158
+ __param(0, (0, common_1.Request)()),
159
+ __param(1, (0, common_1.Body)()),
160
+ __metadata("design:type", Function),
161
+ __metadata("design:paramtypes", [Object, update_profile_dto_1.UpdateProfileDto]),
162
+ __metadata("design:returntype", void 0)
163
+ ], AuthController.prototype, "updateMe", null);
151
164
  __decorate([
152
165
  (0, common_1.Post)('logout'),
153
166
  openapi.ApiResponse({ status: 201 }),
@@ -163,4 +176,3 @@ exports.AuthController = AuthController = __decorate([
163
176
  __metadata("design:paramtypes", [auth_service_1.AuthService,
164
177
  config_1.ConfigService])
165
178
  ], AuthController);
166
- //# sourceMappingURL=auth.controller.js.map
@@ -40,4 +40,3 @@ exports.AuthModule = AuthModule = __decorate([
40
40
  exports: [auth_service_1.AuthService],
41
41
  })
42
42
  ], AuthModule);
43
- //# sourceMappingURL=auth.module.js.map
@@ -4,8 +4,9 @@ import { Repository } from 'typeorm';
4
4
  import { UsersService } from '../users/users.service';
5
5
  import { RegisterDto } from './dto/register.dto';
6
6
  import { LoginDto } from './dto/login.dto';
7
+ import { UpdateProfileDto } from './dto/update-profile.dto';
7
8
  import { RefreshToken } from './entities/refresh-token.entity';
8
- import { User } from '../users/entities/user.entity';
9
+ import { type SerializedUser } from '../users/avatar.constants';
9
10
  export declare class AuthService {
10
11
  private usersService;
11
12
  private jwtService;
@@ -15,18 +16,11 @@ export declare class AuthService {
15
16
  private readonly refreshTokenExpiresIn;
16
17
  private readonly absoluteMaxExpiresIn;
17
18
  constructor(usersService: UsersService, jwtService: JwtService, configService: ConfigService, refreshTokenRepository: Repository<RefreshToken>);
18
- validateUser(userId: string): Promise<Omit<User, 'password'> | null>;
19
+ validateUser(userId: string): Promise<SerializedUser | null>;
19
20
  private generateAccessToken;
20
21
  private generateRefreshToken;
21
22
  validateRefreshToken(token: string): Promise<string | null>;
22
- register(registerDto: RegisterDto): Promise<{
23
- id: string;
24
- name: string;
25
- email: string;
26
- role: import("../users/entities/user.entity").UserRole;
27
- createdAt: Date;
28
- updatedAt: Date;
29
- }>;
23
+ register(registerDto: RegisterDto): Promise<SerializedUser>;
30
24
  login(loginDto: LoginDto): Promise<{
31
25
  access_token: string;
32
26
  refresh_token: string;
@@ -42,5 +36,6 @@ export declare class AuthService {
42
36
  refresh_expires_in: number;
43
37
  token_type: string;
44
38
  }>;
39
+ updateProfile(userId: string, dto: UpdateProfileDto): Promise<SerializedUser>;
45
40
  revokeRefreshToken(token: string): Promise<void>;
46
41
  }
@@ -72,8 +72,7 @@ let AuthService = class AuthService {
72
72
  try {
73
73
  const user = await this.usersService.findOne(userId);
74
74
  if (user) {
75
- const { password, ...result } = user;
76
- return result;
75
+ return this.usersService.serializeUser(user);
77
76
  }
78
77
  }
79
78
  catch {
@@ -162,8 +161,7 @@ let AuthService = class AuthService {
162
161
  ...registerDto,
163
162
  password: hashedPassword,
164
163
  });
165
- const { password, ...result } = user;
166
- return result;
164
+ return this.usersService.serializeUser(user);
167
165
  }
168
166
  async login(loginDto) {
169
167
  const user = await this.usersService.findByEmail(loginDto.email);
@@ -210,6 +208,39 @@ let AuthService = class AuthService {
210
208
  token_type: 'Bearer',
211
209
  };
212
210
  }
211
+ async updateProfile(userId, dto) {
212
+ const user = await this.usersService.findOne(userId);
213
+ if (dto.newPassword && dto.currentPassword) {
214
+ const userWithPassword = await this.usersService.findByEmail(user.email);
215
+ if (!userWithPassword?.password) {
216
+ throw new common_1.UnauthorizedException('Cannot verify credentials');
217
+ }
218
+ const isMatch = await bcrypt.compare(dto.currentPassword, userWithPassword.password);
219
+ if (!isMatch) {
220
+ throw new common_1.UnauthorizedException('Current password is incorrect');
221
+ }
222
+ }
223
+ if (dto.email && dto.email !== user.email) {
224
+ const existing = await this.usersService.findByEmail(dto.email);
225
+ if (existing) {
226
+ throw new common_1.ConflictException('Email already in use');
227
+ }
228
+ }
229
+ const updateData = {};
230
+ if (dto.name !== undefined)
231
+ updateData.name = dto.name;
232
+ if (dto.last_name !== undefined)
233
+ updateData.last_name = dto.last_name;
234
+ if (dto.email !== undefined)
235
+ updateData.email = dto.email;
236
+ if (dto.avatar !== undefined)
237
+ updateData.avatar = dto.avatar;
238
+ if (dto.newPassword) {
239
+ updateData.password = await bcrypt.hash(dto.newPassword, 10);
240
+ }
241
+ const updated = await this.usersService.update(userId, updateData);
242
+ return this.usersService.serializeUser(updated);
243
+ }
213
244
  async revokeRefreshToken(token) {
214
245
  try {
215
246
  const payload = this.jwtService.verify(token, {
@@ -236,4 +267,3 @@ exports.AuthService = AuthService = __decorate([
236
267
  config_1.ConfigService,
237
268
  typeorm_1.Repository])
238
269
  ], AuthService);
239
- //# sourceMappingURL=auth.service.js.map
@@ -6,4 +6,3 @@ exports.CurrentUser = (0, common_1.createParamDecorator)((data, ctx) => {
6
6
  const request = ctx.switchToHttp().getRequest();
7
7
  return request.user;
8
8
  });
9
- //# sourceMappingURL=current-user.decorator.js.map
@@ -5,4 +5,3 @@ const common_1 = require("@nestjs/common");
5
5
  exports.IS_PUBLIC_KEY = 'isPublic';
6
6
  const Public = () => (0, common_1.SetMetadata)(exports.IS_PUBLIC_KEY, true);
7
7
  exports.Public = Public;
8
- //# sourceMappingURL=public.decorator.js.map
@@ -5,4 +5,3 @@ const common_1 = require("@nestjs/common");
5
5
  exports.ROLES_KEY = 'roles';
6
6
  const Roles = (...roles) => (0, common_1.SetMetadata)(exports.ROLES_KEY, roles);
7
7
  exports.Roles = Roles;
8
- //# sourceMappingURL=roles.decorator.js.map
@@ -31,4 +31,3 @@ __decorate([
31
31
  (0, class_validator_1.MaxLength)(72),
32
32
  __metadata("design:type", String)
33
33
  ], LoginDto.prototype, "password", void 0);
34
- //# sourceMappingURL=login.dto.js.map
@@ -1,5 +1,8 @@
1
+ import { type UserAvatarKey } from '../../users/avatar.constants';
1
2
  export declare class RegisterDto {
2
3
  name: string;
4
+ last_name: string;
3
5
  email: string;
4
6
  password: string;
7
+ avatar?: UserAvatarKey;
5
8
  }
@@ -12,12 +12,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.RegisterDto = void 0;
13
13
  const openapi = require("@nestjs/swagger");
14
14
  const class_validator_1 = require("class-validator");
15
+ const avatar_constants_1 = require("../../users/avatar.constants");
15
16
  class RegisterDto {
16
17
  name;
18
+ last_name;
17
19
  email;
18
20
  password;
21
+ avatar;
19
22
  static _OPENAPI_METADATA_FACTORY() {
20
- return { name: { required: true, type: () => String, maxLength: 100 }, email: { required: true, type: () => String, maxLength: 255, format: "email" }, password: { required: true, type: () => String, minLength: 8, maxLength: 72 } };
23
+ return { name: { required: true, type: () => String, maxLength: 100 }, last_name: { required: true, type: () => String, maxLength: 100 }, email: { required: true, type: () => String, maxLength: 255, format: "email" }, password: { required: true, type: () => String, minLength: 8, maxLength: 72 }, avatar: { required: false, type: () => Object, enum: avatar_constants_1.USER_AVATAR_KEYS } };
21
24
  }
22
25
  }
23
26
  exports.RegisterDto = RegisterDto;
@@ -27,6 +30,12 @@ __decorate([
27
30
  (0, class_validator_1.MaxLength)(100),
28
31
  __metadata("design:type", String)
29
32
  ], RegisterDto.prototype, "name", void 0);
33
+ __decorate([
34
+ (0, class_validator_1.IsString)(),
35
+ (0, class_validator_1.IsNotEmpty)(),
36
+ (0, class_validator_1.MaxLength)(100),
37
+ __metadata("design:type", String)
38
+ ], RegisterDto.prototype, "last_name", void 0);
30
39
  __decorate([
31
40
  (0, class_validator_1.IsEmail)(),
32
41
  (0, class_validator_1.MaxLength)(255),
@@ -38,4 +47,9 @@ __decorate([
38
47
  (0, class_validator_1.MaxLength)(72),
39
48
  __metadata("design:type", String)
40
49
  ], RegisterDto.prototype, "password", void 0);
41
- //# sourceMappingURL=register.dto.js.map
50
+ __decorate([
51
+ (0, class_validator_1.IsOptional)(),
52
+ (0, class_validator_1.IsString)(),
53
+ (0, class_validator_1.IsIn)(avatar_constants_1.USER_AVATAR_KEYS),
54
+ __metadata("design:type", String)
55
+ ], RegisterDto.prototype, "avatar", void 0);
@@ -0,0 +1,9 @@
1
+ import { type UserAvatarKey } from '../../users/avatar.constants';
2
+ export declare class UpdateProfileDto {
3
+ name?: string;
4
+ last_name?: string;
5
+ email?: string;
6
+ currentPassword?: string;
7
+ newPassword?: string;
8
+ avatar?: UserAvatarKey;
9
+ }