Enhance branch management with foreign key relation handling
- Updated `BranchesModule` to include foreign key relations in list and write responses, ensuring they are represented as nested objects using `pickRelation`. - Introduced new `relation-response.mdc` file to define guidelines for embedding foreign key relations. - Modified `BranchesRepository` to support fetching related `division`, `createdByUser`, and `updatedByUser` data. - Updated DTOs and service methods to reflect changes in response structure, removing direct foreign key IDs. - Added unit tests to validate the new relation handling in branches service and repository. - Enhanced e2e tests to verify the correct structure of branch responses with nested relations.
This commit is contained in:
@@ -38,6 +38,7 @@ List requirements:
|
||||
- Shared pagination query (`page`/`limit` or `offset`/`limit`) via `PaginationQueryDto`
|
||||
- Handler **must** use `@Pagination()` and return `{ data, total }` — never build `meta` here (see `.cursor/rules/pagination-response.mdc`)
|
||||
- Service `visibleFields` whitelist: default **all non-secret** attributes; modules may narrow. Project in the **service**, not the controller
|
||||
- FK relations in list/detail (and write responses that reuse the mapper) MUST be nested objects via `pickRelation` — see `.cursor/rules/relation-response.mdc`
|
||||
- List query must be extendable (e.g. `extendListQuery(qb, filters)` on the repository/service) so joins/extra predicates can be added without forking list
|
||||
|
||||
## Write controller
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
description: List/detail (and write responses that reuse the mapper) embed FK relations as objects via pickRelation
|
||||
globs: "src/modules/**/*.ts,src/common/http/response/**/*.ts"
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
# Relation Response Objects
|
||||
|
||||
List, detail, and write handlers that reuse the same mapper MUST embed foreign keys as nested objects, not bare ids.
|
||||
|
||||
## Field lists
|
||||
|
||||
- Default catalog fields: `DEFAULT_RELATION_FIELDS` (`id`, `code`, `name`) from `src/common/http/response/`
|
||||
- Override per entity with a module/local constant (users: `USER_RELATION_FIELDS` = `id`, `username`)
|
||||
- Use `pickRelation(source, fields)` only — do not hand-roll partial copies
|
||||
|
||||
## Mapping
|
||||
|
||||
- Request DTOs still accept `*Id` (`divisionId`); the response key is the relation name (`division`, not `divisionId`)
|
||||
- Null FK → `null` (not omitted)
|
||||
- Never expose secrets (`passwordHash`, tokens) in relation objects
|
||||
- Load relations in the repository (joins or batch-load); map with `pickRelation` in the service
|
||||
|
||||
```typescript
|
||||
// BAD
|
||||
return { divisionId: branch.divisionId, createdBy: branch.createdBy }
|
||||
|
||||
// GOOD
|
||||
return {
|
||||
division: pickRelation(branch.division, DEFAULT_RELATION_FIELDS),
|
||||
createdBy: pickRelation(branch.createdByUser, USER_RELATION_FIELDS),
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user