Files
KIS-TOiR/backend/service-rules.md
2026-03-15 17:29:37 +03:00

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

  1. Update payload must be sanitized before passing to the ORM. Do not pass the raw request body as data to prisma.*.update().

  2. Remove id from the update payload. React Admin sends id for identity; it must not be written to the database as a column (unless the entity actually has an id column and it is intended to be immutable on update).

  3. Remove the primary key field from the update payload. The primary key is used in where; it must not appear in data. For example, remove code from data when updating by code.

  4. 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.