Навчанне Claude Code вашага Monorepo для NestJS: маршрутызацыя, правіла та навыкі
Навучыце Claude Code працаваць з NestJS манорепа: CLAUDE.md, правілы, навыкі і правыя на адпрацоўкі коду, якія керуюць тым, куды кладзіцца код у правы сервіс, і старавацца, каб ён паследаваў стандарты команды.
Крыніцы: Claude Code for NestJS Monorepos: A Practical Setup Guide
Якщо запрацавіць неканфігураванага AI-асистента з запитам, такім як «дадзіць статус, видны для спаканта, да броніраванню» у вялікам NestJS манорепа, рэзультат будзе прыгадным: змены паляцуюць у неправім мікросервісе, паведамленне пра адзію — гэта жорсткая строка, а доступ контролюецца за дапамою user.role === 'admin'. Модэль не выканаляеся ў TypeScript; яна толькі здагадваецца пра рашэнні, якія ваша каманда прыняла давно і ніколі не запісала, дзе яны можна прачытаць. Шэры рукаводства паказвае, як заменіць гэтыя здагадкі на контекст, кантролюемы версіямі, выкарыстоўваючы чатыры элемента, якія праспекуе Claude Code: CLAUDE.md, правілы, навыкі і настройкі дазволаў. До канца вы будете мяць структуру, яю можна будзе зафіксаваць у вашым репазітарые, так што кожны інжынер і кожная сесія AI будуць працаваць па адных і тых жа стандартах.
Якщо вам трэбая загальная практычная адказка пра напісанне самага файла з інструкцыямі, адзірніце нашу інструкцыю па стварэнні эфектыўнага CLAUDE.md. У гэтай статыце акцэнтаванае увага на тых змяненнях, якія выступаюць, калі база коду — это бэкенд NestJS з калькама служб.
Короткая версія
Для чытальнікаў, якія хочуць практычны список пераканаў прымусова:
- З’явіце Claude Code (напрыклад, за дапамогою
npm install -g @anthropic-ai/claude-code) і автентыфікуйцеся аднойчы, запускаючыclaude. - Створыце карэнтны файл
.claude/CLAUDE.md, у яком будуць паспісаныя, калькая служба адпаведнае дадзеныя, порядак обробкі запытанняў і формат адпаведзення, якое вяртае кожны эндпаінт. - Дадзіце каталог
.claude/rules/, у яком будуць зафіксаваныя забараненні: без запытанняў у ціклах, без пераканаў на адпаведнасць іменам ролей, без вялікіх імпортаў.
.claude/skills/, якая будзе міць пасляпэўныя крокі роботы і шаблоны коду для задач, якія вы адрабатваеце раз за разам, напрыклад, стварэння канцаўкі..claude/settings.json, каб заздалегідь санкцыонаваць безпечныя команды і заблокаваць шкодзівыя..claude/, так ўбыткі налашоўкаў будзе можна аддаляць і перагледваць, як код.Чаму монорепа NestJS плутае AI-асистэнтов
У большым кодавом базе NestJS правільнасць коду часта залежыць ад стандартоў, якія не паказвае жадны адзін файл. Дзесяткі модуляў, сотні DTO-ў, спецыяльныя захоўнікі, інтерсэптары, фільтры выключэнняў і адаптары HTTP створаюць справжню неяснасць. Калі нічога не рашае гэтую неяснасць, модель вяртаецца да здравым гэнерычным стандартам, а гэнерычныя стандарты рэдка калі падходзяць конкретнай командзе.
Тыповыя сімптамы неналашоўванай структуры:
- Метод службы вяртаецца безпосередна да базы дадзеных, а не через шар слою рэпазітарыяў.
- Паведамленні пра аберанняя ўжоўтаюцься як стрынг-літэралы, а не як элементы з файла сталяных значэнняў
ErrorMessages. - У падпапцы
operator-serviceствараецца новы файл, хоць логіка бронів належыць падпапцыapi-service. - Автарызацыя рэалізуецца за дапамою
user.role === 'admin', а не за дапамоюPermissionCodes. - Для вывару інфармацыі пад час дэбагавання викорыстоўваецца
console.log, а не структураваны логгер. - Імпорты здзійснююцца через паходы
../../common/utils, замест таго каб викорыстаць псевданім шляхуsrc/.
Асновная прычына — нехватка внутрошняй спецыялізаванай інформацыі
Ніхто з гэтых не ўз’яўляецца з багамі модэлю. Пад час сесіі асистент ведае толькі тыя файлы, якія ён ачыў. У ёнага немае можлівасці дазнацца, што каманда намераваўшыся выдаліла RolesGuard, што параметр synchronize у TypeORM павінен застацца false, або што сервісы взаімаюцца толькі через адаптары HTTP. Гэтыя знанні знаходзяцца ў галавах інжынераў і ў старых тэпах прашынкаў.
Расьледжэнне — гэта запісаць гэтыя знанні ў файлы, якія завантажае інструмент, і прысваяць кожны тип знанняяпатрэбнам механізму:
CLAUDE.mdмістіць інфармацыю пра архітектуру, власнікаў сервісаў і стандарты. Ён автаматычна завантажаецца на пачатку кожной сесіі.- Правілы містяць забораны і незменныя элементы, якія павінны кантролюваць кожны фрагмент створанага коду.
Структура рэпазітарыя, якую прымет гід
Дапамагае стварыць конкрэтную структуру пры напісанні будзь-якай настройкі. У прыкладным бэкендзе є чатыры сервісы і адна дырэктарыя .claude/ у корані рэпазітарыя:
my-backend/
├── .claude/ # Everything Claude needs to operate well
│ ├── CLAUDE.md # Root-level instructions (always loaded)
│ ├── rules/ # Enforced coding constraints
│ ├── skills/ # Custom slash commands with deep context
│ └── settings.json # Command permissions
├── services/
│ ├── api-service/ # NestJS consumer API (port 5001)
│ ├── operator-service/ # NestJS operator/vendor API (port 5002)
│ ├── chat-service/ # Express + Socket.IO (JavaScript, port 5005)
│ └── job-service/ # Scheduled jobs, no HTTP server
├── db/migration/ # Flyway migrations per schema
└── package.json # Root: only husky + lint-staged
Кожны сервіс — это самостоятельная аплікацыя з саею package.json, tsconfig.json і рэзультатамі кампаўлявання. Заўважыце, што адны з іх, chat-service, — это просты JavaScript на Express і Socket.IO, а job-service ўзагалі не мае сервера HTTP. Гэтая рознороднасць — самэ тое, чаго асистент не можа вывячыць з аднаго файлу.
У кожным сервісе NestJS модулі функцыйяў маюць аднаковую трываршчатую структуру:
src/modules/booking/
├── booking.module.ts
├── controllers/ # HTTP routing only, no logic
├── services/ # Business logic and orchestration
├── repositories/ # TypeORM queries only
└── dtos/ # Request/response shapes, validation
Кантролеры пераказваюць запыткі HTTP і нічога больш, сэрвісы мясточыць логіку бізнесу і ўпорядакоўванне, а рэпазітарыямі мясточыць запыткі TypeORM. Якщо асистэнту ніколі не было сказана пра такое раздзеленне, ён з радасцю яго спутае: сэрвіс, які выдае запыткі, або кантролер, який безпасэродна вызывае рэпазітарыю. Запісваўчы шары, можна дасягнуць ўрахоўвання гэтых меж.
Шаг 1: інсталяцыя і аутентыкацыя
Інсталяцыя адбываецца за дапамою адного глобальнага пакета, пасля чаго трэба адзін раз зайсці ў браузеры:
npm install -g @anthropic-ai/claude-code
claude # opens a browser for one-time OAuth
Пасля аутентыкацыі claude можна запускать з будзь-якай дырэктарыі. Кожны разработчык інсталюе і заходзіць у систему на сваёй машыне; не існуе спільнага ключа каманды для распадзелу. Варыянты інсталяцыі зменяюцца з часам, таму, якщо шлях npm больш не ўважаецца рэкамендаваным, пераканайцеся ў актуальной документацыі Claude Code.
Адзін аспект мае ўплыв эўчыльна для манорепо. Канфігурацыя проекта выбіраецца адносна корню репазітарыя, таму інструкцыі ў каталозе .claude/ працуюць усюды, дзе вы запускаеце сесію. Калі ваша работа адбываецца толькі ў однай службе, запускайте Claude з усероўні ціяго каталога службы, напрыклад services/api-service/, каб пошукі і команды працавалі з правым пакетам.
Шаг 2: напісаць дакумент CLAUDE.md
CLAUDE.md — гэта файл з найбольшым уплывам, таму што гэта контекст, які асистент чытае перш за ўсё. Напісайце яго так, як бы вы інформавалі старшага інжынера ў першы дзень: прыпускайце загальную кампетэнцію, адказвайце толькі на пытанні, спецыфічныя для вашай системы. У манорепо логічна наявнасць двух рэўлёў:
- Корневы файл
.claude/CLAUDE.md, які містыць інформацыю пра власніка службы, спакульярныя правіла та процес обработкі запыткаў.
services/{service}/CLAUDE.md для кожнага сервісу — гэта дакумент з інструкцыямі па шаблонамах модуляў, аутантыкацыі і деталямі впрыску залежнасцей, якія паслужаюць толькі для таго сервісу.Корневы файл: прымкніце рашэнне ў паўнай власнасці на сервіс, а не проста здогадку
Найдрожэйшыя памылкі ў репазітарыі з калькома сервісамі — гэта размешчанне коду не там, дзе трэба, адтуды ён праходзіць локальную пераглядку, а пазней выявляецца як нарушэнне правіл. Корневы файл запобегае гэтаму за дапамогою табелі маршрутаў і чыткага списку забраных шаблонав. Ёсць прыклад таго, калі можа выглядаць гэты файл:
## Monorepo StructureFour services under `services/`, each independently runnable.
Run all commands from inside the service directory.| Service | Port | Stack | Purpose |
| ------------------ | ---- | ------------------------ | -------------------- |
| `api-service` | 5001 | NestJS + TypeScript | Consumer-facing API |
| `operator-service` | 5002 | NestJS + TypeScript | Operator/vendor mgmt |
| `chat-service` | 5005 | Express + Socket.IO + JS | Real-time messaging |
| `job-service` | — | Node.js + TypeScript | Scheduled jobs |## Which Service Owns What- **operator-service** — if the data describes _what an experience is_:
package definitions, pricing, taxes, availability, operator accounts.
- **api-service** — if the data describes _a consumer's interaction_:
bookings, users, auth, trip planning, payments, notifications.| Task involves... | Service |
| ---------------------------------- | ---------------------------------- |
| Package categories, pricing, slots | operator-service |
| Booking status, user profiles | api-service |
| Stripe payments (consumer side) | api-service |
| Cross-service booking flow | Start in api-service → IMS adapter |## Global Request Pipeline (in order)1. `TraceContextMiddleware` — sets `correlationId` in `AsyncLocalStorage`
2. `ValidationPipe` — whitelist mode, flattens DTO errors
3. `LoggerInterceptor` — logs request/response
4. `TransformInterceptor` — wraps return value in the standard shape
5. Exception filters (`HttpExceptionFilter`, `TypeOrmExceptionFilter`, …)## Standard Response ShapeControllers return `{ data, meta }`; `TransformInterceptor` wraps it:
return { data: { items }, meta: { path: request.path } };
// → { success: true, data: { items }, meta: { path }, error: null }## Cross-Service Communicationapi-service NEVER touches operator-service's database. All reads/writes go
through HTTP adapters in `src/common/adapters/` (they handle OAuth refresh and
trace propagation). Need operator data? Call the adapter, never the DB.## What Claude Must Never Do- Use `console.log` → use `logMessage()` from `src/common/utils/logger`
- Check `user.role` → use `PermissionCodes` + `@Permissions()`
- Query the DB inside a loop → use bulk queries (`IN`, `JOIN`)
- Use relative `../../` imports → use the `src/` alias
- Set TypeORM `synchronize: true` → Flyway manages all schema changes
Некалькі частакаў гэтага файла заслуговуюць на адзінакавую увагу. Раздел прыналежнасці супакаваны як тэст (“Чы гэтыя данні описваюць сама працэс, чы ўзаемадзеянне спожывача з яйм?”), а не як список каталогаў, што дазволяе асистэнту класіфікаваць запыткі, якіх ён ніколі не бачыў. Раздел паэтапнай обробкі пераказвае спіс мідлвэра, пайпаў, інтэрцептораў і фільтраў у порядку ўжыцця, тады код, які ствараецца, не дуплікуе тое, што вже робіць TransformInterceptor. Раздел межы служб проста зазначае, што api-service ніколі не чыпае базу дадзеных аператара і павінен праходзіць через адаптары ў каталозе src/common/adapters/.
Што адразняе корыстны CLAUDE.md ад слабкага:
- Правіла адміністрування кращыя за структуры файлаў. Правіло на кшталт "Даныя, якія апісваюць, што такое певны досвід, должны знаходзіцца ў аператарскай службе" усувае неодназначнасці без неабяжных запытанняў.
- Указаць формат адпаведзі. Без гэтага кантролеры самастоятельна упаковваюць сваія адпаведзі, і структура пакета становіцца хаотычной.
- Чыткая прызначэння таго, што заборанае. Фраза "Ніколі не вжывайце
console.log" лёгкая для выпалення, чым "Вжывайце наш логгер". - Фіксаваць намеровыя адключэння. Якщо вы адключылі
RolesGuardчыстаўце функцыюsynchronize, трэба гэта зазначыць і паспяшыць прычыну. Аднойчы не зробіўшы гэтага, асистент можа знову ўвести іх, таму што яны выглядаюць як стандартны выбар у NestJS.
Файлы на рэвэлі службы: глыбіна, якая патрэбная толькі адной службе
Даклэ, дзеянні, які маюць значэнне толькі ўнутрь адной службы, пакладаюцца ў сабеў файл той службы. Для api-service гэта стосуецца шароўкавання, аутентыкацыі, токэнаў DI і фонавых заданняў:
## Module Architecture — never mix layerscontrollers/ HTTP routing only — call service, return data
services/ Business logic — orchestrate repos, no direct DB calls
repositories/ TypeORM queries only — accept EntityManager for transactions## Authentication- `JwtAuthGuard` validates Bearer tokens, attaches `UserRequest`
- `PermissionsGuard` reads `@Permissions([PermissionCodes.X])`
- Never use RolesGuard or check role names — removed intentionally## Dependency InjectionRegister services by interface token, and inject by token, not class:
{ provide: SERVICE_INTERFACE.BOOKING_SERVICE, useClass: BookingService }## Background JobsBullMQ + Redis. Processors live in `src/modules/{module}/processors/`.
Enqueue via the module's service — never from a controller.
Два моменты тут лёгка паспяць неправільна без керавання. Па-першае, прадастальнікі рэгіструюцца і вводзяцца через токэны інтарфейса, такія як SERVICE_INTERFACE.BOOKING_SERVICE, а не па класу, таму канстрактар, які генеруецца і вводзіць BookingService безпосередна, будзе скомпілявацца, але спяшыць патэрн команды. Па-другое, заданні BullMQ дадаюцца у чергу толькі з службы модуля, ніколі не з кантролера, а працоўнікі знаходзяцца пад src/modules/{module}/processors/. Якщо не пакладаць гэтыя факты ў корневы файл, яны не будуць выкарыстоўваны ў контэксте пад час работы з chat-service.
Шаг 3: дадаць правілы для тых речаў, якія ніколі не должны выйсці
У файле CLAUDE.md описваецца, як працюе система, а правілы — чаго не павінен мяць створаны код. Корыстным ментальным моделю ёсць настройка ESLint, спрямованая на выхід датчынкі AI. Правілы — это файлы у формате Markdown, які знаходзяцца ў каталозе .claude/rules/.
Просты спосаб прымэчкі, куда ўпаўсці тое чы іншае:
- Архітектура, структура модуляў, адпаведальнасць за сервісы, стандарты і паказанні команд належаць у
CLAUDE.md. - Стрымкія забораны, шаблоны, якія ніколі не павінны выдацца, а таксама канстанты безпекі чы працоўныя характэрыстыкі належаць у каталозе
rules/.
Памятайце, што правілы — это інструкцыі, якія завантажаюцца ў контэкст моделі, а не статычны аналізатор. Яны значна зменшаюць верагатывасць наяўнасці правалянняў, але для справжна важных канстант вам все рава трэба падтрымваць іх за дапамогою правілаў lint, тэстаў чы пераканальніка CI.
Правіла: без запытанняў типу N+1
N+1 запыткі лёгкая напісаць, але іх лёгкая працязначыць пад пераглядам, таму што кожны адзінны рядок выглядае нявіннаўскі. Правілу ў .claude/rules/database-queries.md будзе лепша, якщо ён пакажае як забраны шаблон, так і альтэрнатыўны варіант. Забраная версія выдае адзін запытак на кожную броніраванне:
// Wrong — N queries
for (const b of bookings) {
b.user = await this.userRepo.findOne(b.userId);
}
Альтэрнатыўны варіант заваношвае ўсіх выкарыстоўвачаў у адзін запытак за дапамогою оператара In з TypeORM, а пасля прыўязвае іх у памяці за дапамогою Map, ключамі якога є ідэнтыфікаторы:
// Correct — one query
const users = await this.userRepo.find({ where: { id: In(userIds) } });
const userMap = new Map(users.map((u) => [u.id, u]));
bookings.forEach((b) => {
b.user = userMap.get(b.userId);
});
Працэйскі плюс заключаецца ў тым, што запытак для большай колькасці дадзеных напісваецца ў момент гэнеравання, таму багі з працэйскай ефектывасцю ніколі не дасягаюць pull request-а. Не забудзіце спачатку скарыстацца userIds з броніраванняў, а таксама рассмотрзіце можлівасць ўсунуць дуплікаты, калі многа броніраванняў адналічваюць аднаго выкарыстоўвача.
Правіла: правыя на выкарыстоўванне, ніколи назвы ролей
Другое правіла, .claude/rules/permissions.md, забараняе такі спецыяльныя пераказванні ролей:
// Wrong
if (user.roles.includes('admin')) { ... }
У заместэ таго канцэнтры прызначэнняявляюць пераказаныя імі правыя на дзеянне і дазваляюць механізмам адбавы прыменяць іх:
// Correct
@Permissions([PermissionCodes.MANAGE_BOOKINGS])
@UseGuards(JwtAuthGuard, PermissionsGuard)
Аргументы для такога рашэння таксама павінны быць у файле правіл, таму што гэта дапамагае модэлю генералізаваць: праз рост продукту ролі сяўваюцца, дзелююцца і перайменоўваныя, і кожны чаканне, напісаны на адной з назв ролей, тыхо перастае работаць, калі гэта адбываецца. Коды правых ёсу стабільныя константы, якія застаюцца незменнымі пасля такіх рэорганізацый. У правіле таксама павінна быць згадка пра тое, дзе яны знаходзяцца — у гэтым случае src/common/constants/permissions.constant.ts.
Правіла: аляскі пацёкаў заместо рэлатыўных імпортаў
Трэцяе правіла, .claude/rules/imports.md, стандартызуе імпорты:
// Wrong
import { UserService } from "../../services/user.service";
// Correct
import { UserService } from "src/modules/user/services/user.service";
Алія працюе таму, што файл tsconfig.json задае baseUrl на значэнне "./", а функцыя moduleNameMapper у Jest таксама викорыстоўвае гэты прыметнік. Важна памянуць або баць два элементы: якбы асістэнт знаў толькі пра сторону TypeScript, ён мог бы вывести, што алія небезпечная пад час тэставання.
Іншыя правілы, якія варта запісаць
Той самы формат «забарыць і паказаць альтэрнатыўу» падходзіць для багацько часта з’яўляючыхся проблем у NestJS. Прыклады для сабеўных файлаў:
- Рэгулюванне адносоў з бядамі: выклікаць эксцэпцыі NestJS, створаныя на адной з констант
ErrorMessagesчыResponseCodeKeys; ніколі не кэдаваць сообщэнняя і не вяртаць сырые об’екты бяд. - Логаванне: викорыстоўваць структураваны функцыю-памочнік
logMessage()з адпаведным рэвэлем;console.logзабранены.
EntityManager аперат, тады брак усунення не можа заставіць данні застацца часткова запісанымі.class-validator. Пакалі ValidationPipe працуе ў режыме белай лісты, атрыбуты без декоратараў тыхо выкасываюцца, што выглядае як падзея з губленнем даных, а не як адказка.synchronize застаецца false.@ApiSpec і DTO з типамі адказу, ў результате чаго стварваная дакументацыя API застаецца точной.Шаг 4: ператварыць павтараючыяся рабочыя процесы на навыкі
Навыкі — это проект-спецыфічныя команды, якія аб’еднваюць процедуры, шаблоны і матэріялы для апавядання. Яны ўтаманны інструмент для будзь-якай багатофайловой задачы, яку вы часта виконвалі: дадзення канцэнтра, напісанне міграцыі, стварэння модуля, перагляд запрошэнняя прыўязкі. На адзінаку з CLAUDE.md, контэнт навыку завантажаецца толькі тады, калі ён викорыстоўваецца, таму деталізаваныя шаблоны не спрацоўваюць на додатковы ресурсы ў кожнай сэсіі.
Структура дыректорыя навыкаў
Навык для стварэння канцэнтра можа быць арганізаваны так: процес роботы описваецца у SKILL.md, шаблоны — у падкаталозе assets/, а фонавы матэріял — у references/:
.claude/skills/api-development/
├── SKILL.md # Workflow, trigger, steps
├── assets/
│ ├── controller-template.md
│ ├── service-template.md
│ ├── repository-template.md
│ └── dto-template.md
└── references/
├── nestjs-conventions.md
└── swagger-documentation.md
Процес роботы у SKILL.md
Файл пачынаецца з простага заглавля:
API Development Skill
Далей у яму паказана, калі трэба запускать навык, і описаны крокі ў фіксаванай парадку:
## TriggerInvoke with `/api-development` when building or modifying a NestJS endpoint.## Workflow1. **Determine service & module** — check CLAUDE.md routing; ask if ambiguous.
2. **Read what exists** — entities, repositories, DTOs already in the module.
3. **Generate the DTO first** — it defines the contract. class-validator
decorators; extend `PaginationRequestDTO` for lists.
4. **Generate the repository** — inject `DataSource`; accept an optional
`EntityManager` for transactions; queries only, no logic.
5. **Generate the service** — inject the repository interface token; use
`ErrorMessages` constants; throw `NotFoundException` etc.
6. **Generate the controller** — `@ApiSpec` + `@ApiOkResponse`; return
`{ data, meta }`; no business logic.
7. **Wire the module** — add to `providers`, export by interface token.
Парадакс выбран някрозь випадку. Першыя перагляды таблыцы маршрутазавання запобегаюць таму, што каскады задачі патрапляюць у неправильны сервіс. Чытанне існуючых энтытэтаў, репазітарыёў і DTO-аў узбегае ўдвойненню іх. Стварэнне DTO-а раней за ўсё інша выправляе кантракт, а кожны наступны шар будуець створаны на яго аднойчыні: репазітарый прыме неабавязковы EntityManager, каб могаць адмаўляць транзакцыі, сервіс інжектуецца через токен інтэрфейса і выклікае стандартныя абыекты з константамі ErrorMessages, а кантролер толькі документуе, делегуе і вяртае { data, meta }. Пасляпэльны крок паў’язвае прадастальнікі з модулем і экспортуе іх па токену.
Адзін практычны прытэк: чырвоныя версіі Claude Code выклікаюць навыки за дапамою YAML-фронтматэру на пачатку файла SKILL.md (значэння name і description, якія адказваюць на пытанне, калі яго викорыстоўваць). У прыкладзе вышэй гэта не паказана, таму, калі ствараеце свой файл, пераканайцеся ў актуальной даследчыцкай документацыі ўсуперш ці правільны формат.
Шаблоны павінны быть справжнім кодам
Шаблоны ў каталозе assets/ ёсць корыстныя толькі тады, калі яны можаць быть скомпіляваны. Псевдокод спакушае модель запэўніць прасоцы з своімі стандартнымі значэннямі. Шаблон кантролера пачынаецца з адказу класа і введэння токена:
@ApiTags("bookings")
@Controller("bookings")
export class BookingController {
constructor(
@Inject(SERVICE_INTERFACE.BOOKING_SERVICE)
private readonly bookingService: IBookingService,
) {}
Далей ідзе цэлы эндпоінт, які адразу паказвае порядак захоўнення, декоратары праваў, декоратары Swagger і формат рэзультата:
@Post()
@UseGuards(JwtAuthGuard, PermissionsGuard)
@Permissions([PermissionCodes.CREATE_BOOKING])
@ApiSpec({ summary: "Create a new booking" })
@ApiCreatedResponse({ type: CreateBookingSuccessDto })
async createBooking(
@Body() dto: CreateBookingDto,
@Req() req: UserRequest,
): Promise<{ data: BookingEntity }> {
const booking = await this.bookingService.createBooking(dto, req.user.id);
return { data: booking };
}
}
Зверніце увагу на тое, чым навучае гэты адзін метод: JwtAuthGuard выконваецца раней за PermissionsGuard, ідэнтыфікатар пользователя бераецца з об’екта UserRequest, кантролер не мае логіки бізнесу, і ён вяртае { data }, каб TransformInterceptor мог ўзяць гэты результат. Завдака такой практыкі сценарій, описаны тут, дазволяе створыць цэлы канчатковы пункт (кантролер, сервіс, репазітарый і DTO-ы, з’ўязаныя з модулем) за менш чым тры хвіліны, у працоўнай практыцы команды за першую спробу — працэс займаваў адносна двадзесят хвілін. Вашы скары гэту працэс залежаць будуць ад розмеру вашых шаблонаў і ад таго, сколькі пераглядаў вы ўсё яшчэ адрабатваеце.
Іншыя навыкі, якія варта рассмотрэць
Будзь-які повтараючыся рабочы процес, які выкарыстоўвае спецыфічныя для команды стандарты, є хорашым кандыдатам:
- Генератор міграцый: стварае міграцыю Flyway у правильным папаку схемы, выкарыстоўваючы вашу схему версіявання і называння, а таксама відпаведныя змены энтытэў.
- Скелетаўчык модуля: стварае файл модуля, тры шары і токены DI, якія вже падключаны.
- Перагляд запросу прыўязкі: пераканальваецца ў наявнасці разніцы для выкарыстоўвання запитаў типу N+1, правілаў выкарыстоўвання дазволаў, наявнасці абмежэнняў у шарах і відсутнасці тэстаў.
- Генератор тэстаў: запісвае файлы
*.spec.ts, якія выкарыстоўваюць стандарты мокінгу і фікстураў для служб. - Адаптар міжслужбовага взаімадзея: дадае метод адаптара IMS разам з інтерфейсам адпаведзі і падмогай для трансфармацыі.
- Дакументацыя кейсаў выкарыстоўвання: ператварае трэбаванні на історыі выкарыстоўвання з критэрамі адзначэння типу Given/When/Then.
Шаг 5: налаштаванне дазволаў
.claude/settings.json адмініструе, якія команды шэлу можа выканаць асистент без папераднага запытку. Разумны базовы набор праваў прадзеяна ўтверджэнне лінтингу, тэстаў і кампайлявання, а таксама чыста забраняе команды, якія разрушаюць роботу або публікуюць яе:
{
"permissions": {
"allow": [
"Bash(npm run lint:*)",
"Bash(npm run test:*)",
"Bash(npm run build)",
"Bash(npx jest *)"
],
"deny": ["Bash(rm -rf *)", "Bash(git push *)", "Bash(git reset --hard *)"]
}
}
Наладкі існуюць у двух роўнях:
.claude/settings.jsonдыяўчыць для всіх членоў команды і зберагаецца ў рэпозітарыі..claude/settings.local.jsonмае персональныя змены, дыяўчыць толькі для вас і яго трэба выключыць з обработкі git.
Спіс забраных команд — это захоўнічы механізм, а не сандбокс. Шаблоны падходзяць да строкаў команд, таму іх трэба спрыятаць як захоп проты нешчасных адбыткаў, а не як меру безпекі.
Практыкі, якія падтрымліваюць здаровы стан налараджэння
Ставіцеся да .claude/ як да коду для працы: ён распрасягае вашы стандарты між усіма інжынерамі і кожной сесіяй, таму ён заслуговае на перагляд, ведэнне історыі та аптимізацыю.
- Зберагачыце
CLAUDE.mdкароткім, не больш чым 300 ліній. Усё, што ў яму знаходзится, конкуруе за прыоритет увагі з кодам, які павінен прачытаць асистэнт. Якщо які-то факт можна вывести з коду, краща яго не пісаць. - Формулюйце правіла як забороны. На практыцы фраза "ніколи не выкананяйце запыты да базы дадзеных у цікле" набагато краща вытрымае тырон пад час роботы, чым фраза "вядомае прывяліце масовыя запыты".
- Зберагачыце шаблоны ў скіллах. Яны павінны завантажвацца толькі тады, калі запускаецца скілл, а не ў кожнай сесіі.
- Версію
.claude/трэба зберагачыць у git. Новыя правіла даступаюцься через pull requests; застарэлыя вычыраюцца. - Ўжывайце табліцы рашэння там, дзе можна выбраць два варыянты, напрыклад, для пазначэння месца розташоўвання DTO, локацыі энтытэта чы граніцаў сервіса. У файлах у формате Markdown для асистэнта табліца ўжоўця ясней, чым параграфы.
Полная структура для налаштавання, описанага ў гідзе:
.claude/
├── CLAUDE.md # Root guide (<300 lines)
├── settings.json # Team permissions (committed)
├── rules/
│ ├── database-queries.md # No N+1
│ ├── permissions.md # PermissionCodes, no role checks
│ └── imports.md # src/ alias only
└── skills/
└── api-development/
├── SKILL.md
├── assets/ # controller/service/repository/dto templates
└── references/ # conventions, swagger
Памылкі, які таямніча пагаршуюць рэзультат
Кожна з іх стварае код, які выглядае нормальна, але наражае на пагубы вашыя стандарты, і самэ гэта робіць іх такімі шкоднымі.
- Запіс
CLAUDE.mdяк туторыял для NestJS. Модель вже знае фрэймворк. Документавацыя патрабуе толькі таго, што ўнікальна для вас: назвы модуляў, константы абэрасцей, структуру адпаведзі, систему прав. - Ігнараванне негатыўных правіл. Найбольш шкодныя абэрасці — гэтыя, якія выглядаюць правільна; паведамленне асистэнту, чаго не робіць, дапамагае усунуць цэлыя категоріі такіх абэрасцей.
- Размешчанне всього ў корневым файле. Корневы файл завантажаецца ў кожной сесіі, таму спецыфічная для сервіса структура там паскладжуе контэкст, калі вы працуеце ў іншым месца.
synchronize: false. Модэль будзе прыпускать, што TypeORM керуе схемай. Калі ж адпаведальны Flyway, змяна энтытэта без міграцыі выконваецца бесшумна, таму трэба явна гаварыць пра гэта.Практычны прыклад: адна запытка, да і пасля
Падазроўваюце, кіраўнік продукту прасіа пра выдачу бронірацыяў, каб спожытнікі моглі бачыць статус на сваёй пакунку.
У неканалізаваным рэпазітарые асистент выводзіць, што пакеты задаюцца ў operator-service, і правяць змены ў аб’екте пакета там, хоць гэта некалькі іншы сервіс. Асистент закодавае роўным чынам строку з статусам і захоўвае змены за дапамогою if (user.roles.includes('admin')).
За дапамогою канфігурацыі з гэтага кяліку запит рашаецца пасляпас:
- Тэблы маршрутацыі класифікуе статус, видны для спожывача, як частку його взаімадзеяння, таму задача належыць у
api-service. - Правіла міжсервіснай взаімадзеяння нагадваюць, што даны пакета аператара чытаюцца через адаптэр IMS, таму поле дадаецца ў функцію трансформацыі адаптэра, а не ў іншую базу дадзеных.
- Запуск
/api-developmentгенеруе чатыры шары па спадчынству, пачынаючы з DTO і заканчваючы контролерам.
@Permissions([PermissionCodes.VIEW_BOOKING_STATUS]) заместо пераконтролу ролі.NotFoundException, які ствараецца з константы ErrorMessages.Адна нечыткае запаведзь прыводзіць да змян, які адпавядаюць стандартам, у чатыро файлаў, без патрэбы ў дапаможных запытаннях.
Што зміняецца ў кожны дзень
Настройка адбываецца за калькі гадзін. Змяны, якія яна мае стварыць:
- Акцэнт пераказачоў зменшыцца. Уместа таго, каб пераказачы перакантролвалі кожны створанны файл на жорсткаякодаваныя строкі, некоректныя імпорты і пераконтролы ролі, яны зосерадзяюць сваю увагу на логіцы.
- Канцэнтры стаюць быстрейшымі. Праўленне чатыро шароў вручную у описанай настройцы займала або-па двадзесят хвілін; за дапамогою даных навыкаў гэта займае менш чаму трох.
console.log запобегаюцца ў процэсе стварэння, а не выкрываюцца пазней у прыемных запитах.Дзеянне дзеяных прыемаў заставляецца чакаць калькі месцаў. Код, створаны ў разны час, выглядае аднакова, таму што ён базуецца на адных і тых жа шаблонах і правілах. Артыкуляры перестаюць пісаць аднаковыя каментары. Табелі маршрутаў і правілы выступаюць у ролі дакументацыі, якая фактычна выкорыстоўваецца. А ўмела структураваны CLAUDE.md плюс навыкі, якія можна атрымаць за патрэбай, значыць, ресурсы выделяюцца на чытанне вашага коду, а не на паўторную разведку стандартаў.
Частыя запытанні
Куды кластыць файлы ў манорепо? Спільны CLAUDE.md кладзіце ў падкаталог .claude/ на корані git для спільных праблем, а CLAUDE.md для кожнага сервісу — у ягонай самой структуре, для адпрацоўкі його специфічных патрэбаў. Файл з кораня завжды чытаецца; файл сервіса запускаецца тады, калі вы працуеце з тым сервісам.
Як CLAUDE.md адзінакоўваецца ад правіл? CLAUDE.md пояснюе, як працюе система; правілы назначаюць тое, чаго нельга выканаць, напрыклад запыткі ў циклах аб перакананні імен ролей.
Як паводзяцца навыкі? Навык, такі як /api-development, падтрымваецца за дапамою файлу SKILL.md, шаблонаў і апыланняў. Яго выкорыстоўванне змушвае асистента следаваць фіксаванай, багатоэтапной процедуре замест таго, каб ён сам ствараў способы рашэння.
Чы трэба зберагчы .claude/ у git? Так: CLAUDE.md, rules/, skills/ і settings.json усе патрабуюцься ў git, каб команда магла дзеліцца адной конфігурацыяй. Асобістыя змены калічуцца ў файле settings.local.json, які знаходзіцца ў дырэктарыі gitignored.
Ключовыя выводы
- У монарепазе NestJS правільна робота залежыць ад стандартоў, якія не практыкуюцца ў жадным адокладна файле, таму асистэнт без контекста будзе толькі здагадвацца.
- Раздзеліце гэтыя ведамасці па типах:
CLAUDE.md— пра тое, як усё працюе, правілы — пра тое, што заборанае, інструкцыі — пра процедуры, якія можна павтараць, настройкі — пра тое, што можа работаць без нагляду. - Табліца рашэнняў па адпаведнасці службам ёсць найважлівейшы элемент; запішыце ёю першай.
- Документавація намерованага выдалення элементаў і нестандартных выбораў, такіх як
synchronize: false, неабходная, адтолькі як што гэта саме тое, што модель інакш бы «вылагодзіла». - Правілы сильна вплываюць на процес стварэння коду, але не ўжо є засобамі прымусу; выкарыстоўвайце инструменты лінт-перагляду, тэсты і CI для зберання незменных элементаў, якія не можна рызыкуваты паспаліць.
- Гэтыя зусиллі — це одноразовая інвестыцыя у калькі гадзін, якая дае рэзультаты для кожной функцыі і кожнага новага працавальніка, як толькі файлы будуць пераглядзаны і аптимізаваны як код.