prompts.chatprompts.chatprompts.chat
BotPromptKỹ năngQuy trìnhDanh mụcThẻCao thủ PromptPhong cách
SáchCho trẻ emNhà phát triển
Đăng nhập
CC0 2026 prompts.chat
DeepWikiHướng dẫn...Tài liệuAPIQuyền riêng tưĐiều khoảnHỗ trợGiới thiệuGitHub
N

Nurullah Sevinçtekin

@nurullah

1prompt
0lượt bình chọn nhận được
0đóng góp
Tham gia about 5 hours ago
1 đóng góp trong năm qua
Tháng 11
Tháng 12
Tháng 1
Tháng 2
Tháng 3
Tháng 4
Tháng 5
Tháng 6
Tháng 7
Tháng 8
Tháng 9
Tháng 10
M
W
F
Ít
Nhiều
Đồng bộ hóa Swagger API
Văn bản

Prompt này tạo một lệnh Claude để kiểm tra và kéo về các thay đổi mới nhất từ điểm cuối (endpoint) Swagger bằng cách so sánh phiên bản trước đó với những thay đổi mới nhất tương tự như `git diff`. Công cụ này đảm bảo các kiểu dữ liệu (types) và tính năng API ở phía frontend luôn được cập nhật đồng bộ với backend khi lập trình viên liên tục cập nhật các điểm cuối API.

# Thiết lập quy trình đồng bộ hóa đặc tả OpenAPI (OpenAPI spec-sync workflow) trong dự án này

Tôi muốn áp dụng cùng quy trình làm việc với đặc tả backend mà tôi đang dùng ở một kho mã nguồn khác: một kịch bản so sánh sự khác biệt (diff) giữa
đặc tả OpenAPI trực tiếp (live) với một bản chụp nhanh (snapshot) lưu cục bộ và xuất ra một báo cáo thay đổi **hướng tới frontend**, cộng với một
lệnh gạch chéo `/api-sync` giúp chuyển hóa báo cáo đó thành một kế hoạch triển khai theo từng giai đoạn.

Hãy tự điền các thông tin sau từ kho mã nguồn trước khi bắt đầu (chỉ hỏi tôi nếu bạn không thể tự tìm ra):

- **Nguồn đặc tả (Spec source)**: hãy tự tìm kiếm — xem Phần 0. Đừng hỏi tôi URL cho đến khi bạn đã tự mình kiểm tra kỹ.
  Bất cứ nguồn nào bạn tìm thấy sẽ trở thành giá trị mặc định của kịch bản, và có thể ghi đè thông qua biến môi trường `OPENAPI_URL`.
- **Đường dẫn bản chụp nhanh (Snapshot path)**: `api-spec/openapi.yaml`  ·  **Đường dẫn báo cáo (Report path)**: `api-spec/CHANGES.md`
- **Thư mục mã nguồn gốc để đối chiếu chéo**: `src/` (điều chỉnh cho phù hợp với cấu trúc của kho mã nguồn này)
- **Thư viện xác thực phản hồi (Response-validation library)**: zod (điều chỉnh nếu kho mã nguồn này sử dụng thư viện khác)
- **Có lưu snapshot trong git không?** Giữ tệp yaml trong danh sách **gitignored** (quá lớn/gây nhiễu lịch sử commit) nhưng **commit
  tệp `CHANGES.md`** — báo cáo được tạo ra chính là bản ghi lưu trữ lâu dài về những gì đã thay đổi và thay đổi khi nào. Đồng thời
  thêm vào gitignore cả `api-spec/openapi-*.yaml` và `api-spec/CHANGES-*.md` (các bản lưu trữ thủ công theo ngày).

Hãy đọc kỹ kho mã nguồn này trước (trình quản lý gói, quy ước đặt tên script, cách viết các lệnh gọi API và schema phản hồi)
và tuân thủ đúng phong cách của nó. Đừng tự bịa ra đường dẫn — hãy dùng lệnh grep để tìm các đường dẫn thực tế.

---

## Phần 0 — tìm đặc tả trước khi bạn viết bất kỳ thứ gì

Hãy làm việc này trước tiên và cho tôi biết bạn đã tìm thấy gì. Đừng đoán mò URL, và đừng hỏi tôi cho đến khi bước tìm kiếm này
hoàn toàn không thu được kết quả nào.

**1. Tài liệu dự án (docs) — nơi ít tốn công nhất và thường chính xác.** `README.md`, `CLAUDE.md`,
`AGENTS.md`, `CONTRIBUTING.md`, bất kỳ tệp nào dưới thư mục `docs/`, `.github/`, `.cursor/rules/`, tệp
nháp `*.http`/`*.rest`, hoặc bản checkout của wiki. URL thường nằm ngay trong phần văn bản hướng dẫn ("API docs:
…/swagger"), trong một bước cài đặt, hoặc nằm cạnh liên kết dẫn tới kho mã nguồn backend:

```bash
grep -rniE 'swagger|openapi|api-?docs|redoc|\/v3\/api-docs' --include='*.md' --include='*.mdx' --include='*.txt' --include='*.http' --include='*.rest' . | grep -v node_modules
```

Hai điểm bẫy cần lưu ý: một **liên kết Swagger UI** (`…/swagger-ui/index.html`, `…/docs`, `…/redoc`) là một trang
HTML chứ không phải tệp đặc tả — hãy suy ra URL dành cho máy đọc từ địa chỉ đó (`/swagger-ui/index.html` →
`/v3/api-docs`, `/docs` → `/openapi.json`, `/redoc` → thuộc tính `spec-url` trong mã HTML của nó) và xác minh lại bằng
lệnh curl. Ngoài ra, một URL trong tài liệu có thể đã **lỗi thời** — hãy xác nhận rằng nó vẫn phản hồi trước khi sử dụng, và báo cho tôi biết nếu
tệp README đang trỏ tới một địa chỉ đã chết.

**2. Một tệp đặc tả đã có sẵn bên trong hoặc nằm gần kho mã nguồn** — thường đã có ai đó lưu sẵn một bản (vendored):

```bash
find . -path ./node_modules -prune -o -iregex '.*\(swagger\|openapi\|api-docs\).*\.\(ya?ml\|json\)' -print
git ls-files | grep -iE 'swagger|openapi|api-docs'
```

Đồng thời kiểm tra cả `node_modules/.cache/`, `.next/cache/`, `dist/`, `build/`, `coverage/` và bất kỳ
thư mục `api/`, `api-spec/`, `docs/`, `schemas/` nào đang nằm trong gitignore — một lần chạy công cụ sinh mã (codegen) trước đó thường để lại một
bản sao tại đây. Một bản sao lưu đệm (cached) cũ vẫn rất hữu ích: nó đóng vai trò là **mốc cơ sở (baseline) để khởi tạo bản chụp nhanh (snapshot)**,
giúp lần chạy diff thực tế đầu tiên mang lại kết quả có ý nghĩa thay vì báo cáo "mọi thứ đều mới". Nếu bạn tìm thấy một bản như vậy, hãy cho biết nó
đã cũ bao lâu (`git log -1` / thời gian sửa đổi tệp mtime) trước khi quyết định tin dùng nó.

**3. Một tệp cấu hình trình sinh mã (generator config) đã chỉ định sẵn nguồn đặc tả** — đây là dấu hiệu có giá trị cao nhất, bởi
nó trỏ thẳng tới bất kỳ URL hoặc đường dẫn nào mà nhóm phát triển thực sự đang sử dụng:

```bash
grep -rniE 'openapi|swagger|api-docs' --include='*.json' --include='*.ts' --include='*.js' --include='*.mjs' --include='*.yaml' --include='*.yml' --include='.env*' --include='Makefile' --include='*.sh' -l . | grep -v node_modules
```

Hãy tìm kiếm cụ thể các tệp: cấu hình `openapi-typescript` / `orval.config.*` / `kubb.config.*` /
`swagger-typescript-api` / `@hey-api/openapi-ts`, một npm script có chữ tương tự `openapi` trong
package.json, URL gốc của API trong các tệp `.env*`, các URL dịch vụ trong `docker-compose.yml`, các bước trong luồng CI workflow, hoặc một
client được sinh tự động đã commit vào repo mà phần chú thích đầu tệp (header comment) có trích dẫn nguồn đặc tả của nó.

**4. Suy ra từ URL gốc của API (API base URL).** Nếu bạn chỉ tìm thấy một URL gốc, hãy dò thử các đường dẫn theo quy ước phổ biến
tương ứng với framework của backend đó trước khi hỏi tôi — FastAPI `/openapi.json`, Spring/springdoc
`/v3/api-docs` (+ `.yaml`), ASP.NET `/swagger/v1/swagger.json`, NestJS `/api-json`, Rails/rswag
`/api-docs/v1/swagger.yaml`, cộng với các đường dẫn thuần túy `/openapi.yaml` và `/swagger.json`:

```bash
curl -sS -o /dev/null -w '%{http_code} %{content_type} %{url_effective}\n' <BASE>/openapi.json
```

Hãy báo cáo lại những đường dẫn nào có phản hồi. Nếu tất cả đều yêu cầu xác thực (auth), hãy nói rõ như vậy — tuyệt đối không nhúng cứng (bake) token vào trong kịch bản.

**5. Không cách nào hiệu quả?** Khi đó hãy hỏi tôi, và cho tôi biết những phương án nào bạn đã kiểm tra và loại trừ.

### Nếu đặc tả không thể truy cập qua giao thức HTTP

Đừng gượng ép sử dụng thiết kế tải qua mạng (fetch). Hãy biến nguồn đặc tả thành một biến `SPEC_SOURCE` duy nhất có thể nhận giá trị là **một URL, một đường dẫn
cục bộ, hoặc một lệnh shell** (ví dụ: lệnh `make openapi` của chính kho mã nguồn backend, hoặc một tệp được sinh ra từ thư mục checkout
ngang hàng), được phân giải theo đúng thứ tự ưu tiên sau: cờ `--to <file>` → biến môi trường `OPENAPI_URL` → giá trị mặc định mà bạn
đã khám phá được. Mọi bước xử lý phía sau — so sánh diff, xuất báo cáo, lưu snapshot — đều giữ nguyên không đổi. Hãy ghi rõ trong tệp `CLAUDE.md`
kho mã nguồn này đang sử dụng nguồn nào và cách làm mới (refresh) nó.

## Phần 1 — `scripts/sync-api.mjs`

Một kịch bản Node ESM đơn lẻ, ít phụ thuộc (`js-yaml` là gói phụ thuộc mới duy nhất; hãy dùng đúng trình quản lý gói
của kho mã nguồn này). Các cờ (flags) dòng lệnh:

```
node scripts/sync-api.mjs               tải bản từ xa (remote) → diff với snapshot → ghi báo cáo + ghi đè snapshot
node scripts/sync-api.mjs --check       chỉ chạy diff, giữ nguyên snapshot, thoát với mã lỗi 1 nếu có sai lệch (thân thiện với CI)
node scripts/sync-api.mjs --from <file> chạy diff so với <file> thay vì so với snapshot
node scripts/sync-api.mjs --to <file>   coi <file> là bản "từ xa" thay vì tải qua mạng (chế độ ngoại tuyến - offline)
node scripts/sync-api.mjs --json        đồng thời in kết quả diff thô dưới dạng JSON ra stdout
```

Thêm `"sync:api": "node scripts/sync-api.mjs"` vào tệp package.json.

**Nếu chưa tồn tại bản snapshot nào**: ghi đặc tả vừa tải về làm snapshot, in thông báo "seeded — re-run after
the backend ships to see a diff" (đã khởi tạo mốc cơ sở — hãy chạy lại sau khi backend cập nhật để xem sự khác biệt), và thoát với mã 0. Không bao giờ báo cáo toàn bộ API là "mới". Ngoại lệ: nếu ở Phần 0
bạn tìm thấy một bản đặc tả cũ hơn được lưu đệm (cached) hoặc lưu sẵn (vendored), hãy khởi tạo snapshot từ **bản cũ đó** và chạy so sánh
diff thực sự với đặc tả trực tiếp (live) ngay trong lần chạy đầu tiên — hãy cho tôi biết ngày tháng của bản sao lưu đệm đó để tôi nắm được
ý nghĩa của mốc cơ sở.

### Những nội dung kịch bản bắt buộc phải so sánh (diff)

Làm phẳng (flatten) `paths` thành một bảng ánh xạ từ `"GET /a/b"` → thao tác (operation) và so sánh sự khác biệt của các thao tác *cũng như*
`components.schemas` một cách tách biệt:

**Các thao tác (Operations)**
- đã thêm (added) / đã xóa (removed) / đã thay đổi (changed)
- tham số (params): các tham số mới (gắn cờ `required` nếu bắt buộc), sự đảo trạng thái giữa bắt buộc và tùy chọn (`required`↔`optional`), các giá trị enum được thêm vào/xóa đi —
  định danh khóa cho mỗi tham số bằng `in:name` (hoặc `ref:Name` đối với các tham số dùng `$ref`), không định danh bằng chỉ mục mảng (array index)
- phần thân yêu cầu (request body) và schema phản hồi thành công (success-response schema): nếu tên `$ref` thay đổi, hãy báo cáo việc đổi tên; nếu
  cấu trúc dữ liệu được viết **nội tuyến (inline)** (không dùng `$ref`), hãy so sánh các thuộc tính của nó ngay tại đây — một schema không tên hoặc được diff tại đây hoặc
  sẽ bị bỏ sót hoàn toàn. Phân giải các lớp bọc `allOf: [$ref]` về tên schema gốc bên dưới, và hiển thị các kiểu hợp (union) `oneOf`/`anyOf`
  dưới dạng `A | B` (việc thêm hoặc bớt một thành phần trong kiểu hợp là một thay đổi hành vi thực sự).
- các mã trạng thái không phải 2xx (non-2xx status codes) mới được thêm vào hoặc bị xóa bỏ
- các thay đổi về yêu cầu bảo mật (security requirement), hoặc mới bị đánh dấu ngừng hỗ trợ (`deprecated`)

**Các cấu trúc dữ liệu (Schemas)**
- các thuộc tính được thêm mới (đánh dấu nếu là required) / bị xóa bỏ / bị đổi kiểu dữ liệu (retyped)
- các giá trị enum được thêm vào hoặc xóa đi (trên bản thân schema và trên từng thuộc tính, bao gồm cả `items.enum`)
- sự đảo trạng thái giữa bắt buộc và tùy chọn (`required`↔`optional`)

### Hai yếu tố làm nên giá trị thực sự của báo cáo này

1. **Trích xuất `error_code` từ văn bản mô tả phản hồi.** Các mã lỗi dành cho máy đọc thường không được định nghĩa
   ở bất kỳ đâu ngoài phần văn bản `description` của từng phản hồi không phải 2xx ("… already an active member
   (already_member)"), vì vậy một nhánh xử lý lỗi mới mà chúng ta cần bổ sung sẽ trông như thể *không hề có gì thay đổi* đối với một
   bộ công cụ chỉ so sánh ở cấp độ schema. Hãy phân tích cú pháp để trích xuất chúng dựa theo **ngữ cảnh chứ không phải từ vựng cố định**: các chuỗi ký tự (tokens) nằm bên trong dấu ngoặc đơn `(...)`, các chuỗi
   nằm sau những cụm từ mang ý nghĩa tương tự `error_code`, và bất kỳ chuỗi viết kiểu snake_case nào xuất hiện trong tập giá trị enum
   `error_code` tường minh của một schema nào đó. **Không** lọc bỏ các chuỗi bị trùng tên với tên trường (field names) hoặc các giá trị enum —
   những sự trùng khớp đó chính xác là các mã lỗi quan trọng nhất. Hãy loại bỏ các chuỗi được giới thiệu sau cụm từ "field X"
   (đó là tên trường chứ không phải mã lỗi). Báo cáo các mã lỗi mới được thêm vào, và đối với một mã lỗi không còn
   được ghi trong tài liệu nữa, hãy dùng lệnh grep tìm `"that_code"` trong mã nguồn và chỉ rõ **tệp nào đang rẽ nhánh xử lý trên mã lỗi đó** —
   bởi đó chính là một nhánh mã chết (dead branch).

2. **Đối chiếu chéo mọi thay đổi với mã nguồn thực tế.** Tải toàn bộ danh sách tệp mã nguồn một lần duy nhất thông qua lệnh
   `git ls-files --cached --others --exclude-standard <src root>` (bao gồm cả các tệp chưa được theo dõi - untracked để một vị trí gọi API
   vừa được thêm vào trong phiên làm việc này vẫn được tính; bỏ qua các tệp có trong danh sách nhưng đã bị xóa khỏi cây thư mục làm việc), sau đó:
   - **Các vị trí gọi hàm (Call sites)** cho một đường dẫn: chuyển đổi các tham số đường dẫn (path params) thành ký tự đại diện cho một phân đoạn đơn lẻ (single-segment wildcards) và bắt buộc
     chuỗi khớp phải kết thúc tại dấu nháy đơn/nháy kép/backtick/`?` để đường dẫn `/orgs/{id}` không bị khớp nhầm với `/orgs/id/archive`.
     Mọi thao tác bị xóa hoặc bị thay đổi đều phải liệt kê các vị trí gọi nó trong mã nguồn, hoặc ghi "⬜ no call site" (không có vị trí gọi).
   - **Các bản sao đối chiếu schema (Schema mirrors)**: tìm tệp chứa bản sao xác thực phản hồi (response-validation mirror) tương ứng với một schema trong đặc tả —
     khớp tên `fooBarSchema` ở bất kỳ đâu, cộng với tên viết kiểu PascalCase trần **chỉ nằm bên trong tệp `schemas.ts`**
     (ở những nơi khác nó sẽ bị trùng lặp với các định danh TypeScript không liên quan). Hãy điều chỉnh quy ước đặt tên sao cho
     khớp với những gì kho mã nguồn này thực sự đang sử dụng — hãy chạy lệnh grep trước tiên.
   - Một thao tác mới có đường dẫn đã được tham chiếu sẵn trong thư mục `src/` sẽ nhận được ghi chú "⚠️ path already
     referenced — check the method" (đường dẫn đã được tham chiếu — hãy kiểm tra lại phương thức HTTP).

### Định dạng báo cáo (`api-spec/CHANGES.md`)

Phần tiêu đề mở đầu gồm ngày khởi tạo, nhãn mốc cơ sở (baseline label), `info.version` của đặc tả, cùng số lượng thao tác và
schema trước→sau; tiếp theo là một bảng tóm tắt nhỏ thống kê số lượng thêm mới/xóa bỏ/thay đổi; sau đó là các phần nội dung chi tiết theo đúng thứ tự sau:

- `## 🔴 Removed operations — breaking if we call them` (Các thao tác đã bị xóa — gây lỗi hỏng ứng dụng nếu chúng ta đang gọi chúng, kèm theo danh sách vị trí gọi)
- `## 🟠 Changed operations` (Các thao tác đã thay đổi, gồm các gạch đầu dòng lồng nhau cho từng thay đổi + danh sách vị trí gọi)
- `## 🟢 New operations` (Các thao tác mới), được nhóm theo khu vực đường dẫn (phân đoạn đầu tiên, có xử lý các trường hợp đặc biệt hợp lý đối với
  các tiền tố của API này) — gồm tóm tắt (summary), schema phản hồi (response schema), schema phần thân yêu cầu (request-body schema)
- `## 🔴 Removed schemas` (Các schema đã bị xóa, kèm theo các tệp mirror tương ứng)
- `## 🟠 Changed schemas` (Các schema đã thay đổi) — **các schema có bản sao mirror trong mã nguồn được xếp lên đầu tiên và in đậm kèm theo đường dẫn tệp mirror**, vì
  đây là những thay đổi có thể làm hỏng quá trình phân tích cú pháp (parsing) ngay lập tức; phần còn lại mang tính chất cung cấp thông tin
- `## 🟢 New schemas` (Các schema mới — liệt kê trên một dòng, phân cách bằng dấu phẩy)

Nếu không có gì thay đổi, phần nội dung chính xác là câu "No changes since the last snapshot." Đặt dòng cảnh báo
"do not edit by hand" (không chỉnh sửa thủ công) ở ngay đầu tệp.

Hãy viết chú thích (comment) đầy đủ trong kịch bản ở những chỗ có quyết định xử lý không hiển nhiên (thuật toán heuristic trích xuất error_code, điểm neo kết thúc
của bộ khớp đường dẫn, lý do tại sao lại bao gồm cả các tệp untracked) — để chính tôi trong tương lai đọc lại và hiểu rõ.

## Phần 2 — `.claude/commands/api-sync.md`

Một lệnh gạch chéo (`/api-sync [scope]`, tham số scope là tùy chọn, đồng thời chấp nhận cả từ khóa `implement`) dùng để thực thi
quy trình làm việc này. Phần frontmatter gồm: `description` + `argument-hint`. Các bước thực hiện:

1. **So sánh (Diff)** — chạy lệnh `npm run sync:api`, đọc tệp `api-spec/CHANGES.md`. Chỉ rõ hai quyết định đánh giá
   mà báo cáo có thể gắn cờ cảnh báo nhưng không thể tự kết luận thay con người: một **phần thân yêu cầu (request body)** bị thay đổi tại một vị trí gọi hàm đang hoạt động là
   điều cần phải xử lý ngay cả khi không có tệp schema mirror (vì chúng ta tự tạo phần thân yêu cầu bằng tay), và một mã **`error_code`** mới là
   một nhánh xử lý mà chúng ta chưa có — nếu đó là lỗi gắn với một trường nhập liệu cụ thể (field error) thì nó phải được hiển thị trực tiếp ngay tại trường đó (inline), chứ không
   chỉ hiện thông báo nổi (toast). Nếu báo cáo ghi không có thay đổi nào, hãy thông báo như vậy và dừng lại ngay — đừng tự vẽ thêm việc.
2. **Phân loại mọi mục thay đổi** vào các nhóm: Breaking (P0 - Gây lỗi nghiêm trọng) · Silently wrong — một schema có bản sao mirror vừa có thêm
   trường bắt buộc hoặc một kiểu enum có thêm các giá trị mới mà bộ xác thực hiện tại của chúng ta sẽ từ chối (P0 - Sai ngầm) · Now-incomplete — một
   phần thân yêu cầu tạo thủ công vừa có thêm trường mới, hoặc xuất hiện một `error_code` mới mà chúng ta chưa rẽ nhánh xử lý (P1 - Nay chưa hoàn chỉnh) ·
   Un-mocks a screen (P1 - Thay thế dữ liệu giả lập bằng API thật cho màn hình) · Extends a screen (P2 - Mở rộng tính năng màn hình) · Net-new feature (P3 - Tính năng hoàn toàn mới) · Backend-only (bỏ qua - chỉ liên quan tới backend).
   Tuyệt đối không bỏ sót bất kỳ mục nào; nếu có mục không khớp với nhóm nào cả, hãy liệt kê nó dưới dạng một câu hỏi mở. Hãy xác minh từng
   phân loại trực tiếp với mã nguồn thay vì phỏng đoán — mở tệp mirror được nêu tên, dùng lệnh grep tìm
   dữ liệu giả lập (mock fixture), và xác nhận màn hình đó thực sự tồn tại.
3. **Viết kế hoạch triển khai** — thêm một mục có ghi ngày tháng vào tệp `ROADMAP.md` (hoặc tệp tương đương trong kho mã nguồn này; hãy tạo mới nếu
   chưa có), được sắp xếp theo đúng thứ tự ưu tiên trên và chia thành các giai đoạn (phases) sao cho mỗi giai đoạn có thể được phát hành độc lập. Với
   mỗi mục: nêu rõ các điểm cuối (endpoints) và các tệp cần thay đổi, người dùng có thể làm được việc gì sau khi cập nhật mà hiện tại họ chưa làm được
   (mục đích thực sự của công việc — chứ không viết kiểu "kết nối endpoint X"), và liệu mục đó có đang bị chặn (blocked) hay không và bị chặn bởi ai.
   Mỗi mục viết gọn trên một dòng. Sau đó cập nhật bất kỳ tài liệu theo dõi tiến độ/độ phủ nào mà kho mã nguồn này đang duy trì.
4. **Báo cáo lại trong khung trò chuyện (chat)** — tóm tắt những gì phía backend vừa phát hành trong một đoạn văn ngôn ngữ tự nhiên dễ hiểu, bất kỳ điểm nào
   hiện đang bị lỗi kèm theo tên tệp cần sửa ngay, danh sách các giai đoạn triển khai mỗi giai đoạn một dòng, và những câu hỏi thực sự cần thiết dành riêng cho
   lập trình viên backend. Dừng lại ở đó; chỉ khi đối số truyền vào có chứa từ khóa `implement`, bạn mới tiến hành xây dựng **duy nhất Giai đoạn 1 (Phase 1)**,
   sau đó chạy lệnh kiểm tra kiểu dữ liệu (typecheck) + kiểm tra quy tắc mã nguồn (lint) của kho mã nguồn này rồi báo cáo kết quả trước khi tiếp tục.

## Phần 3 — Tích hợp vào dự án

- Thêm các mục cần thiết vào tệp gitignore.
- Thêm một mục ngắn có tiêu đề **Backend-change workflow** vào tệp `CLAUDE.md` (tạo mới tệp này nếu chưa có): giải thích rõ
  bản chụp nhanh (snapshot) được lưu cục bộ và nằm trong gitignore, `CHANGES.md` là bản ghi được commit vào git, `CHANGES.md` được
  sinh tự động nên tuyệt đối không bao giờ chỉnh sửa bằng tay, chạy lệnh `/api-sync` khi lập trình viên backend thông báo vừa phát hành thay đổi mới,
  dùng lệnh `npm run sync:api -- --check` để phát hiện sự sai lệch (drift), và duy trì thói quen lưu trữ một bản
  `api-spec/openapi-YYYY-MM-DD.yaml` có gắn ngày tháng trước mỗi đợt thay đổi lớn của backend để làm mốc tham chiếu được commit vào kho mã nguồn.
- Khởi tạo bản chụp nhanh (snapshot) bằng cách chạy kịch bản một lần, và cho tôi xem báo cáo đầu tiên — kèm theo một dòng
  ghi chú ngắn cho biết đặc tả được lấy từ đâu và nếu bạn khởi tạo từ một bản sao lưu đệm (cached copy), hãy cho biết bản sao đó đã cũ bao lâu.
N@nurullah
0