docs/specs/20260710-161530-agent-feature.mdadded---
spec: agent-feature
status: done
owner: feature-pipeline-agent
related-routes:
files:
- src/api/v2/systems/systems.routes.ts
- src/api/v2/systems/systems.controller.ts
- src/api/v2/systems/systems.validator.ts
- src/services/systems.service.ts
- src/api/v2/systems/systems.routes.ts
- src/api/v2/systems/systems.controller.ts
- src/services/systems.service.ts
- src/api/v2/systems/systems.routes.ts
- src/api/v2/systems/systems.controller.ts
- src/api/v2/systems/systems.validator.ts
- src/services/systems.service.ts
---
# agent-feature
## Goal
Add three read/create REST endpoints under /api/v2/systems for the existing
xyz."CommissioningSystem" table: POST /systems (create), GET /systems
(paginated list of non-deleted systems), and GET /systems/:commissioningSystemId
(single fetch). All DB access wires up to EXISTING stored procedures/functions
already in master; no new DDL, no new DB functions, and no new permissions —
reuse existing project permissions (e.g. PROJECT_EDIT for create, PROJECT_VIEW
for reads).
## Behavior changes
- POST /api/v2/systems
- GET /api/v2/systems
- GET /api/v2/systems/{commissioningSystemId}
## 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) endpoint for CommissioningSystem
- Delete / soft-delete endpoint for CommissioningSystem
- Filtering beyond project scope and soft-delete exclusion
- Any new Postgres DDL, tables, columns, procedures, or functions
- Any new permissions/authorities (reuse existing project permissions)
## 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 `CommissioningSystem` directly on the existing `Asset` resource
(`src/services/assets.service.ts` + `src/api/v2/projects/assets/*`): a
`CommissioningSystem` is the instance of a `SystemType` exactly as an `Asset`
is the instance of an `AssetType`. Wired to the (assumed pre-existing) DB
functions `fn_GetCommissioningSystemList($1,$2,$3)`,
`fn_GetCommissioningSystem($1,$2)` and `fn_InsertCommissioningSystem($1,$2,$3,$4)`,
matching the sibling naming convention. No new DDL/functions added.
- The spec asked for the endpoints at the **top-level** `/api/v2/systems` (files
under `src/api/v2/systems/`) rather than nested under
`/api/v2/projects/:projectId/...`, but still project-scoped and reusing
`PROJECT_VIEW`/`PROJECT_EDIT`. Since `hasRolesOrProjectAccess` reads
`req.params.projectId`, the project scope is supplied by the client
(`projectId` query param for the two reads, `projectId` body field for create)
and the validator copies it onto `req.params.projectId` before the auth
middleware runs. This reuses the existing middleware unchanged.
- Soft-delete exclusion ("non-deleted systems") is delegated to the DB list
function, consistent with the sibling list endpoints.
- Wiring outside the spec's `files:` list was required and applied: mounted the
router in `src/app.ts`, added the `CommissioningSystem` schema to
`src/swagger.components.schemas.json`, and added an e2e DB helper. See the
specialist report at the repo root.
- Build/tests were **not** run locally: project dependencies (`node_modules`)
are not installed in this environment and the instructions forbid installing a
toolchain. The CI/pipeline test suite will exercise them.