Files
trackgo-be/.cursor/rules/read-write-controllers.mdc
T
shancheas f635ebeda0 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.
2026-08-26 13:44:13 +07:00

57 lines
2.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
description: Main modules use separate read and write controllers with list/detail, CRUD, status, bulk, and CSV import
globs: "src/modules/**/*.ts"
alwaysApply: false
---
# Read / Write Controllers
## Structure
Every **main** (CRUD) feature module under `src/modules/` MUST expose at least:
- `*-read.controller.ts`
- `*-write.controller.ts`
Same resource path and `@ApiTags`. Example: `@Controller('shipments')`.
Exempt: auth and similar non-CRUD modules (single controller is fine).
```typescript
@Module({
controllers: [ShipmentsReadController, ShipmentsWriteController],
providers: [ShipmentsService, ShipmentsRepository],
})
export class ShipmentsModule {}
```
Register static write paths (`import`, `bulk-delete`, `bulk-status`) **before** parameterized `:id` routes so they never collide.
## Read controller
1. `GET /` — list
2. `GET /:id` — detail
List requirements:
- Query filters for the resources own attributes **plus** `search` (case-insensitive match on the modules searchable text columns; AND with other filters)
- 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
1. `POST /` — create (status defaults to `draft` unless body sets a valid status)
2. `PATCH /:id` — update (**must not** change `status`; reject if `status` is present)
3. `DELETE /:id` — delete (hard delete unless the module documents otherwise)
4. `PATCH /:id/status` — body is **only** `{ status }`
5. `POST /bulk-delete` — `{ ids: string[] }`
6. `POST /bulk-status` — `{ ids: string[], status }`
7. `POST /import` — multipart CSV `file`; headers map to create fields; omitted status → `draft`; `created_by` / `updated_by` = current user; fail the batch on validation errors with row-level messages (do not echo raw invalid phones/dates beyond VO policy)
Set `created_at` / `updated_at` (`DateTime`) and `created_by` / `updated_by` (current user id) in the write path.
Document both controllers per `.cursor/rules/nestjs-swagger.mdc`.