3.1 KiB
Service Layer Rules
Generated NestJS services must follow these rules so that update operations work correctly with React Admin and Prisma.
Update Payload Sanitization
React Admin (and many REST clients) always send id in PATCH/PUT request bodies.
Example payload from React Admin:
{
"id": "003",
"name": "Pump"
}
Some entities use a different primary key (e.g. code). The API response includes id (mapped from the PK) for React Admin compatibility, but the Prisma model may have no id field—only code. If the service passes the incoming DTO directly to Prisma:
// WRONG — causes runtime error
prisma.equipmentType.update({
where: { code },
data: dto // dto contains "id", which is not a Prisma field
});
Prisma throws because id (and possibly other non-updatable fields) are not on the model or must not be written in data.
Rules
-
Update payload must be sanitized before passing to the ORM. Do not pass the raw request body as
datatoprisma.*.update(). -
Remove
idfrom the update payload. React Admin sendsidfor identity; it must not be written to the database as a column (unless the entity actually has anidcolumn and it is intended to be immutable on update). -
Remove the primary key field from the update payload. The primary key is used in
where; it must not appear indata. For example, removecodefromdatawhen updating bycode. -
Remove readonly attributes (e.g. created timestamps, server-generated fields) if they are present in the DTO, so they are not passed to Prisma
data.
Example Implementation
Destructure identity and primary key (and any other non-updatable fields) out of the DTO, then pass only the rest as data:
Entity with primary key code (e.g. EquipmentType):
update(code: string, dto: UpdateEquipmentTypeDto) {
const { id, code: _pk, ...data } = dto as any;
return this.prisma.equipmentType.update({
where: { code },
data,
});
}
Or, if the DTO type does not include id or code, explicitly omit only the fields that must not be written:
update(code: string, dto: UpdateEquipmentTypeDto) {
const { id, code: _pk, ...data } = dto as Record<string, unknown>;
return this.prisma.equipmentType.update({
where: { code },
data,
});
}
Entity with primary key id (e.g. Equipment):
update(id: string, dto: UpdateEquipmentDto) {
const { id: _pk, ...data } = dto as any;
return this.prisma.equipment.update({
where: { id },
data,
});
}
This way, id (and the PK) are never passed into data, and Prisma does not receive unknown or read-only fields.
Summary
| Rule | Action |
|---|---|
| Sanitize update payload | Before prisma.*.update(), strip non-data fields from the DTO. |
Remove id |
Do not pass id in data unless the entity has an updatable id (rare). |
| Remove primary key | Use PK only in where; omit from data. |
| Remove readonly fields | Omit created_at, server-only fields, etc. from data. |