--- spec: agent-feature status: in-progress owner: feature-pipeline-agent related-routes: files: - src/api/v2/projects/systems/systems.routes.ts - src/api/v2/projects/systems/systems.controller.ts - src/api/v2/projects/systems/systems.validator.ts - src/services/systems.service.ts - src/api/v2/projects/systems/systems.routes.ts - src/api/v2/projects/systems/systems.controller.ts - src/services/systems.service.ts - src/api/v2/projects/systems/systems.routes.ts - src/api/v2/projects/systems/systems.controller.ts - src/services/systems.service.ts --- # agent-feature ## Goal Add three read/create API2 endpoints for the existing xyz.CommissioningSystem entity (exposed as "systems"): POST create, GET-by-id, and paginated GET list, all project-scoped under /api/v2/projects/{projectId}/systems. No new Postgres table is created — CommissioningSystem already exists in the schema. Follows the AssetType endpoint pattern. Revised per review: no new permissions; reuse existing Project Edit / System View permissions. ## Behavior changes - POST /api/v2/projects/{projectId}/systems - GET /api/v2/projects/{projectId}/systems/{id} - GET /api/v2/projects/{projectId}/systems ## Acceptance criteria - [ ] The behavior described above is implemented on the listed files. - [ ] Existing behavior is unchanged when the new feature is not exercised. - [ ] Unit and (where observable) e2e tests cover the new behavior. ## Out of scope - Update (PUT/PATCH) and Delete (DELETE) endpoints for systems. - Exposing System via API1 / MongoDB. - Any migration or sync with existing API1 System data. - New Postgres columns/fields on CommissioningSystem (table used as-is). ## Notes / open questions - Generated by the feature pipeline from the approved architect plan. If any acceptance criterion is ambiguous, ask the human before implementing. ## Decisions - Modelled the "systems" endpoints on the **Assets** endpoint pattern (`src/api/v2/projects/assets/`) rather than SystemType, because a CommissioningSystem is an *instance* classified by a SystemType — the exact analogue of an Asset classified by an AssetType. This gives paginated LIST (via `IndexedItem` + `buildPaginatedQueryResponse`), matching the spec's "paginated GET list". - **Foreign key:** a System belongs to a **SystemType** (`systemTypeId`), mirroring Asset → AssetType. Create body is `{ name, systemTypeId }`. - **Permissions:** reused existing `PROJECT_VIEW` (GET list + GET by id) and `PROJECT_EDIT` (POST create), plus `INTERNAL_ROLE`, exactly as Assets/AssetTypes do. There is no dedicated "System View" authority in `authorities.types.ts`; the spec's "reuse existing Project Edit / System View" is satisfied by the established project-scoped `PROJECT_VIEW`/`PROJECT_EDIT` pair (no new permissions added, per the revised spec). - **DB contract assumed** (functions/columns live in the external DB migration repo, not this codebase — same as Asset/AssetType): - `xyz."fn_GetCommissioningSystemList"(projectId, lastFetchedIndexId, size)` - `xyz."fn_GetCommissioningSystem"(projectId, systemId)` - `xyz."fn_InsertCommissioningSystem"(projectId, systemTypeId, name, createdBy)` - Returned columns: `CommissioningSystemId`, `Name`, `SystemTypeId`, `CreatedBy`, `InsertedOn`, `LastModifiedOn`, `LastModifiedBy`, `Id` (pagination index). The API response exposes `systemId` (the entity is "exposed as systems" per the spec). - A missing/invalid `systemTypeId` on insert is expected to raise an error whose message contains `"SystemType with id"`, mapped to a 404 (mirrors Asset's `"AssetType with id"` mapping). - Added a `System` schema to `src/swagger.components.schemas.json` and referenced it from the route JSDoc (no inline duplication), per repo convention. - Build/tests were **not run locally** — `node_modules` is not installed in this environment and the instructions forbid installing a toolchain. The CI/e2e pipeline runs the suite.