docs/specs/20260703-102519-agent-feature.mdadded---
spec: agent-feature
status: in-progress
owner: feature-pipeline-agent
related-routes:
files:
- routes
- controller
- validator
- service
- routes
- controller
- service
- routes
- controller
- service
---
# agent-feature
## Goal
Add three API2 endpoints for AssetType (create, get-one, list) scoped to a
project. AssetType already exists in the xyz schema; this feature adds
read/write stored procedures and functions plus API2 runtime code. No new
tables are introduced. Uniqueness of Name and Code within a project is
enforced. Note: the existing AssetType table has no "Code" column — see risks.
## Behavior changes
- POST /api/v2/projects/{projectId}/asset-types
- GET /api/v2/projects/{projectId}/asset-types/{assetTypeId}
- GET /api/v2/projects/{projectId}/asset-types
## 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) AssetType endpoint
- Delete AssetType endpoint
- Tenant-level scoping of AssetTypes
- Role-based access control beyond authentication (any authenticated user is authorized)
- Pagination / filtering / sorting on the list endpoint (flat list for v1)
- Backfilling Code for pre-existing AssetType rows (raised as a risk)
## 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 entire API2 surface on the sibling `SystemType` feature
(`src/api/v2/projects/commissioning/systemTypes/*`, `src/services/system.types.service.ts`),
which is the closest existing analogue (project-scoped type resource backed by
`fn_*` functions + `usp_*` procedures).
- Mounted the router directly under `/:projectId/asset-types` (not under
`commissioning`) to match the endpoint paths in the spec's Behavior section.
- Implemented only create / get-one / list; update and delete are explicitly out
of scope, so no PUT/PATCH/DELETE routes, controllers or `fn_Update*`/`usp_Delete*`
wiring were added.
- Both `name` and `code` are required non-blank strings on create, and each maps
a distinct DB unique-constraint violation to a `409 ResourceConflictError`
(`AssetType_ProjectShardId_Name_key` → name conflict,
`AssetType_ProjectShardId_Code_key` → code conflict). Constraint names mirror
the `SystemType_ProjectShardId_Name_key` convention — verify they match the
DB-side migration.
- Assumed the DB read/write functions `xyz."fn_GetAssetTypeList"`,
`xyz."fn_GetAssetType"`, and `xyz."fn_InsertAssetType"($projectId,$name,$code,$createdBy)`
exist (or land alongside this change). These are DB-side artefacts outside the
api2 repo. See risks re: the missing `Code` column.
- Authorization mirrors SystemType: read requires `PROJECT_VIEW` or `INTERNAL_ROLE`,
create requires `PROJECT_EDIT` or `INTERNAL_ROLE`.