| 1 | # Common Patterns |
| 2 | |
| 3 | ## Unified Response Format |
| 4 | |
| 5 | All API responses are wrapped by `ResponseInterceptor` into: |
| 6 | |
| 7 | ```typescript |
| 8 | { |
| 9 | data: T // Business data |
| 10 | code: number // 0 = success, 10000+ = business error |
| 11 | message: string |
| 12 | } |
| 13 | ``` |
| 14 | |
| 15 | Do not define custom response wrappers. Use `AppException + ResponseCode` for business errors, and standard `HttpException` only for protocol-level errors. |
| 16 | |
| 17 | ## Repository Pattern |
| 18 | |
| 19 | Based on `BaseRepository` (`libs/mongodb/src/repositories/base.repository.ts`): |
| 20 | |
| 21 | ```typescript |
| 22 | // Public methods (exposed to Service) |
| 23 | getById(id: string): Promise<LeanDoc<T> | null> |
| 24 | create(data: Partial<T>): Promise<LeanDoc<T>> |
| 25 | createMany(data: Partial<T>[]): Promise<LeanDoc<T>[]> |
| 26 | updateById(id: string, update: UpdateQuery<T>): Promise<LeanDoc<T> | null> |
| 27 | deleteById(id: string): Promise<LeanDoc<T> | null> |
| 28 | |
| 29 | // Protected methods (used within Repository subclasses) |
| 30 | findOne(filter: FilterQuery<T>): Promise<LeanDoc<T> | null> |
| 31 | find(filter: FilterQuery<T>): Promise<LeanDoc<T>[]> |
| 32 | findWithPagination(params: PaginationParams<T>): Promise<[LeanDoc<T>[], number]> |
| 33 | count(filter: FilterQuery<T>): Promise<number> |
| 34 | exists(filter: FilterQuery<T>): Promise<boolean> |
| 35 | ``` |
| 36 | |
| 37 | Subclass repositories expose domain-specific public methods following naming conventions: |
| 38 | - `getByXxx` / `listByXxx` / `countByXxx` / `listWithPagination` |
| 39 | - See `project-standards.md` for full naming rules. |
| 40 | |
| 41 | ## Skeleton Projects |
| 42 | |
| 43 | When implementing new functionality: |
| 44 | 1. Search for battle-tested skeleton projects |
| 45 | 2. Use parallel agents to evaluate options: |
| 46 | - Security assessment |
| 47 | - Extensibility analysis |
| 48 | - Relevance scoring |
| 49 | - Implementation planning |
| 50 | 3. Clone best match as foundation |
| 51 | 4. Iterate within proven structure |
| 52 |