--- spec: agent-feature status: done owner: feature-pipeline-agent related-routes: files: - src/api/v2/projects/assettypes/asset.types.routes.ts - src/api/v2/projects/assettypes/asset.types.controller.ts - src/api/v2/projects/assettypes/asset.types.validator.ts - src/services/asset.types.service.ts - src/api/v2/projects/assettypes/asset.types.routes.ts - src/api/v2/projects/assettypes/asset.types.controller.ts - src/services/asset.types.service.ts - src/api/v2/projects/assettypes/asset.types.routes.ts - src/api/v2/projects/assettypes/asset.types.controller.ts - src/services/asset.types.service.ts --- # agent-feature ## Goal Add API2 create-and-read endpoints for AssetType scoped to a project: POST to create an AssetType, GET by id, and GET list. No update/delete in this version. AssetType already exists as a project-scoped Postgres table; this adds the procedure/function DB surface and the API2 runtime layer. ## 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) endpoint for AssetType. - Delete endpoint for AssetType. - Role-based access control beyond authenticated project membership. - Pagination/filtering/sorting on the list endpoint (flat list only in v1). - Duplicate-name rejection at the API level. ## 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 new resource on the freshest sibling, `commissioning/systemTypes` (PAPI-3524), which is the closest create+read analogue in the repo. Stripped the update/delete surface per "Out of scope". - New resource lives under `src/api/v2/projects/assettypes/` and is mounted at `/api/v2/projects/:projectId/asset-types` in `api.v2.routes.ts`. - `AssetType` shape: `assetTypeId`, `name` (required), `description` (optional, nullable), `createdBy`, `insertedOn`, `lastModifiedOn`, `lastModifiedBy` — mirroring `SystemType` audit columns. `name` + optional `description` are the only client-supplied fields on create. - Service calls the assumed DB surface `xyz."fn_GetAssetTypeList"`, `xyz."fn_GetAssetType"`, `xyz."fn_InsertAssetType"`, mirroring the SystemType function naming. These DB functions must exist via migration for the e2e tests to pass (see open questions). - No duplicate-name rejection at the API level and no pagination/filtering, per "Out of scope". Authorization mirrors SystemType: `PROJECT_VIEW` for reads, `PROJECT_EDIT` for create, both allowing `INTERNAL_ROLE`. - Swagger `AssetType` schema added to `src/swagger.components.schemas.json` and referenced via `$ref` from the route JSDoc (never inlined).