Галоўная / Артыкулы

Навчанне Claude Code вашага Monorepo для NestJS: маршрутызацыя, правіла та навыкі

Навучыце Claude Code працаваць з NestJS манорепа: CLAUDE.md, правілы, навыкі і правыя на адпрацоўкі коду, якія керуюць тым, куды кладзіцца код у правы сервіс, і старавацца, каб ён паследаваў стандарты команды.

Выдавец: REACTAPP.TOP20 хв чытання4492 слоў

Крыніцы: Claude Code for NestJS Monorepos: A Practical Setup Guide

Якщо запрацавіць неканфігураванага AI-асистента з запитам, такім як «дадзіць статус, видны для спаканта, да броніраванню» у вялікам NestJS манорепа, рэзультат будзе прыгадным: змены паляцуюць у неправім мікросервісе, паведамленне пра адзію — гэта жорсткая строка, а доступ контролюецца за дапамою user.role === 'admin'. Модэль не выканаляеся ў TypeScript; яна толькі здагадваецца пра рашэнні, якія ваша каманда прыняла давно і ніколі не запісала, дзе яны можна прачытаць. Шэры рукаводства паказвае, як заменіць гэтыя здагадкі на контекст, кантролюемы версіямі, выкарыстоўваючы чатыры элемента, якія праспекуе Claude Code: CLAUDE.md, правілы, навыкі і настройкі дазволаў. До канца вы будете мяць структуру, яю можна будзе зафіксаваць у вашым репазітарые, так што кожны інжынер і кожная сесія AI будуць працаваць па адных і тых жа стандартах.

Якщо вам трэбая загальная практычная адказка пра напісанне самага файла з інструкцыямі, адзірніце нашу інструкцыю па стварэнні эфектыўнага CLAUDE.md. У гэтай статыце акцэнтаванае увага на тых змяненнях, якія выступаюць, калі база коду — это бэкенд NestJS з калькама служб.

Короткая версія

Для чытальнікаў, якія хочуць практычны список пераканаў прымусова:

  1. З’явіце Claude Code (напрыклад, за дапамогою npm install -g @anthropic-ai/claude-code) і автентыфікуйцеся аднойчы, запускаючы claude.
  2. Створыце карэнтны файл .claude/CLAUDE.md, у яком будуць паспісаныя, калькая служба адпаведнае дадзеныя, порядак обробкі запытанняў і формат адпаведзення, якое вяртае кожны эндпаінт.
  3. Дадзіце каталог .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 — гэта файл з найбольшым уплывам, таму што гэта контекст, які асистент чытае перш за ўсё. Напісайце яго так, як бы вы інформавалі старшага інжынера ў першы дзень: прыпускайце загальную кампетэнцію, адказвайце толькі на пытанні, спецыфічныя для вашай системы. У манорепо логічна наявнасць двух рэўлёў:

    1. Корневы файл .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 аперат, тады брак усунення не можа заставіць данні застацца часткова запісанымі.
  • Праверкі DTO: кожны DTO запиту патрэбуюць декоратараў class-validator. Пакалі ValidationPipe працуе ў режыме белай лісты, атрыбуты без декоратараў тыхо выкасываюцца, што выглядае як падзея з губленнем даных, а не як адказка.
  • Парнасць энтытэў і міграцый: кожная змяна энтытэў патрэбуе адпаведной міграцыі Flyway, і значэнне synchronize застаецца false.
  • Пакрыцча Swagger: кожны канец пункту атрыбутуўваецца @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
    

    Памылкі, які таямніча пагаршуюць рэзультат

    Кожна з іх стварае код, які выглядае нормальна, але наражае на пагубы вашыя стандарты, і самэ гэта робіць іх такімі шкоднымі.

    1. Запіс CLAUDE.md як туторыял для NestJS. Модель вже знае фрэймворк. Документавацыя патрабуе толькі таго, што ўнікальна для вас: назвы модуляў, константы абэрасцей, структуру адпаведзі, систему прав.
    2. Ігнараванне негатыўных правіл. Найбольш шкодныя абэрасці — гэтыя, якія выглядаюць правільна; паведамленне асистэнту, чаго не робіць, дапамагае усунуць цэлыя категоріі такіх абэрасцей.
    3. Размешчанне всього ў корневым файле. Корневы файл завантажаецца ў кожной сесіі, таму спецыфічная для сервіса структура там паскладжуе контэкст, калі вы працуеце ў іншым месца.
  • Айначэнне табелі маршрутацыі. Неправильная прызначэння службы выходзіць з неяснасцяў, а не з незнаёмства, і табелі робяць прыняттые рашэнні дэтэрміністычнымі.
  • Недастатак документацыі па шаблоне адаптара. У службах, якія з’ѐеднаны через HTTP, асистэнт інакша будзе прабаваць выконваць імпорты межы службамі або запыткі да базы дадзеных іншай службы.
  • Незгадка пра synchronize: false. Модэль будзе прыпускать, што TypeORM керуе схемай. Калі ж адпаведальны Flyway, змяна энтытэта без міграцыі выконваецца бесшумна, таму трэба явна гаварыць пра гэта.
  • Практычны прыклад: адна запытка, да і пасля

    Падазроўваюце, кіраўнік продукту прасіа пра выдачу бронірацыяў, каб спожытнікі моглі бачыць статус на сваёй пакунку.

    У неканалізаваным рэпазітарые асистент выводзіць, што пакеты задаюцца ў operator-service, і правяць змены ў аб’екте пакета там, хоць гэта некалькі іншы сервіс. Асистент закодавае роўным чынам строку з статусам і захоўвае змены за дапамогою if (user.roles.includes('admin')).

    За дапамогою канфігурацыі з гэтага кяліку запит рашаецца пасляпас:

    1. Тэблы маршрутацыі класифікуе статус, видны для спожывача, як частку його взаімадзеяння, таму задача належыць у api-service.
    2. Правіла міжсервіснай взаімадзеяння нагадваюць, што даны пакета аператара чытаюцца через адаптэр IMS, таму поле дадаецца ў функцію трансформацыі адаптэра, а не ў іншую базу дадзеных.
    3. Запуск /api-development генеруе чатыры шары па спадчынству, пачынаючы з DTO і заканчваючы контролерам.
  • Правілла дазволу ствараюць @Permissions([PermissionCodes.VIEW_BOOKING_STATUS]) заместо пераконтролу ролі.
  • Правілла карантавану бягаў выклікаюць NotFoundException, які ствараецца з константы ErrorMessages.
  • Адна нечыткае запаведзь прыводзіць да змян, які адпавядаюць стандартам, у чатыро файлаў, без патрэбы ў дапаможных запытаннях.

    Што зміняецца ў кожны дзень

    Настройка адбываецца за калькі гадзін. Змяны, якія яна мае стварыць:

    • Акцэнт пераказачоў зменшыцца. Уместа таго, каб пераказачы перакантролвалі кожны створанны файл на жорсткаякодаваныя строкі, некоректныя імпорты і пераконтролы ролі, яны зосерадзяюць сваю увагу на логіцы.
    • Канцэнтры стаюць быстрейшымі. Праўленне чатыро шароў вручную у описанай настройцы займала або-па двадзесят хвілін; за дапамогою даных навыкаў гэта займае менш чаму трох.
  • Размешчэнне файлаў адбываецца правільна з першага разу. Тэблы маршрутацыі практычна без адлікання размешчаюць файлы ў правильным сервісе, а не прыводзяць да ўпынку пазней.
  • Звычныя багі усунуцься ў самай пачатковай стадыі. Запиты типу N+1 і некальканастае выкліканне console.log запобегаюцца ў процэсе стварэння, а не выкрываюцца пазней у прыемных запитах.
  • Процес адкуплення новых спецыялістаў павышаецца. Новыя інжынеры больш не мусяць здогадваліся пра межы модуляў, калі ўсе стандарты зафіксаваны і прыменяюцца да ўсіх першых функцый, створаных за дапамогою AI.
  • Дзеянне дзеяных прыемаў заставляецца чакаць калькі месцаў. Код, створаны ў разны час, выглядае аднакова, таму што ён базуецца на адных і тых жа шаблонах і правілах. Артыкуляры перестаюць пісаць аднаковыя каментары. Табелі маршрутаў і правілы выступаюць у ролі дакументацыі, якая фактычна выкорыстоўваецца. А ўмела структураваны 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 для зберання незменных элементаў, якія не можна рызыкуваты паспаліць.
    • Гэтыя зусиллі — це одноразовая інвестыцыя у калькі гадзін, якая дае рэзультаты для кожной функцыі і кожнага новага працавальніка, як толькі файлы будуць пераглядзаны і аптимізаваны як код.