All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m21s
Final close session 5 — bao gồm: ==== Tests Phase 3 mini (NEW) ==== tests/SolutionErp.Infrastructure.Tests/Application/PeWorkflowAdminTests.cs - 6 test CreatePeWorkflowDefinitionCommandHandler: - First version → IsActive=true, Version=1, ActivatedAt set - Second version same Code → auto-increment v2 + deactivate v1 (atomic) - Different EvaluationType (A vs B) → independent active state - Persists steps ordered by Order field - Persists approvers per step - Third version → v1 + v2 deactivate, v3 active Total tests: 71 → 77 pass / ~2s (54 Domain + 23 Infra). Skip Phase 3 full (UpsertOpinion + Budget link validation) — cần Identity UserManager DI helper, defer session sau. ==== 3 gotcha CI mới (#39 #40 #41) ==== - #39 act_runner github.com TCP timeout 21s → manual checkout fix (run #108/#109 fail, #110 pass) - #40 npm junction cache `tsc not found` after Move-Item — rolled back, hypothesis nested junctions trong node_modules disrupt .bin/ paths. TODO debug session sau với robocopy hoặc act_runner cache.host - #41 Gitea Actions paths-ignore behavior — workflow file change vẫn trigger (correct), commit MD-only skip 100% (verify512880c→ no run #113) + Checklist debug bug mới items 18-20 referencing 3 gotcha trên. ==== Doc updates (8 file) ==== - STATUS.md: header Phase 8 update + 3 row Recently Done CI fixes + cumulative test 71→77 - HANDOFF.md: TL;DR + CI optimize section + Phase status + gotcha count 38→41 - migration-todos.md: Phase 8 §E updated với Phase 3 mini done + CI fixes - rules.md §7 Testing: rewrite full — stack + test pyramid + quy tắc bổ sung mỗi feature + workflow user end-of-task (`dotnet test` local trước push) + CI gate behavior - architecture.md §11: update test pyramid + phased priority + CI optimization sub-section (3 fix manual checkout / path filter / npm cache rollback) + tốc độ deploy table - gotchas.md: + #39 #40 #41 đầy đủ (triệu chứng + nguyên nhân + fix + reference) - ef-core-migration SKILL: Phase 8 update note thêm CI fixes + 77 test - CLAUDE.md root: test count 71→77 + folder structure + CI/CD pipeline 3 fix section - memory project_solution_erp.md: session 5 summary + workflow user mới - session log 2026-04-29-2300-chot-final-ci-tests-gotchas.md (NEW — 9 section detail) ==== Skill audit cron ==== `solution-erp-skill-audit-monthly` next fire 2026-05-01 (2 ngày sau). Cron survives across sessions (setup commitb904a25). Khi fire sẽ: - Cross-check 6 skill với STATUS/gotchas/migration-todos - Auto-refresh stale + đề xuất add/archive cho human approve - Log vào docs/changelog/skill-audit-2026-05.md - ABORT nếu repo dirty ==== Verify ==== - dotnet test SolutionErp.slnx → 77 pass / ~2s (54 Domain + 23 Infra) - git status clean sau commit này - CI: commit này chứa code (test + workflow) → trigger CI test gate Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
453 lines
16 KiB
Markdown
453 lines
16 KiB
Markdown
# Rules — Coding Conventions SOLUTION_ERP
|
|
|
|
> Nguồn duy nhất cho rules. Bất cứ commit nào vi phạm cần justify trong message.
|
|
|
|
## 1. Ngôn ngữ
|
|
|
|
| Thành phần | Ngôn ngữ |
|
|
|---|---|
|
|
| UI FE | **100% tiếng Việt** |
|
|
| Code (.cs/.ts) | **English** (tên biến/hàm/class) |
|
|
| Comment code | Tiếng Anh hoặc Việt — miễn rõ |
|
|
| Tên DB table + column | **English PascalCase** (Contracts, SupplierId) |
|
|
| Business label | Tiếng Việt (vd `"Đang soạn thảo"` cho phase 2) |
|
|
| Commit message | English hoặc Việt — preferred English |
|
|
| Doc MD (docs/) | **Tiếng Việt** (audience là người Việt) |
|
|
|
|
## 2. Backend — .NET 10
|
|
|
|
### 2.1 Clean Architecture dependency rule
|
|
|
|
```
|
|
Api → Application ← Domain
|
|
↑
|
|
Infrastructure ──┘
|
|
```
|
|
|
|
- **Domain:** pure, chỉ dùng `Microsoft.Extensions.Identity.Stores` (cần cho IdentityUser) — không depend ASP.NET Core framework
|
|
- **Application:** depend Domain; CQRS handlers + interfaces + DTOs + validators
|
|
- **Infrastructure:** depend Application + Domain; impl interfaces (EF, JWT, rendering, services)
|
|
- **Api:** depend Application + Infrastructure; Controllers + middleware + composition root
|
|
|
|
### 2.2 CQRS + MediatR pattern
|
|
|
|
- 1 feature = 1 file `{Verb}{Entity}Command.cs` / `{Verb}{Entity}Query.cs`
|
|
- File chứa: Command record + Validator + Handler (cùng 1 file cho compact)
|
|
- Dài thì tách: `{Feature}/Commands/{Create}/...`
|
|
|
|
**Command naming:**
|
|
```
|
|
Create{Entity}Command // tạo mới
|
|
Update{Entity}Command // update full
|
|
Patch{Entity}FieldCommand // update 1 field
|
|
Delete{Entity}Command // soft delete (default)
|
|
{Action}{Entity}Command // action domain-specific (vd TransitionContract)
|
|
```
|
|
|
|
**Query naming:**
|
|
```
|
|
Get{Entity}Query // single by Id
|
|
List{Entity}sQuery // list với paging
|
|
{Entity}{Purpose}Query // custom query (vd GetMyInboxQuery)
|
|
```
|
|
|
|
### 2.3 Validation
|
|
|
|
- FluentValidation (KHÔNG dùng DataAnnotation)
|
|
- Validator = class trong cùng file command: `{Command}Validator : AbstractValidator<{Command}>`
|
|
- Pipeline: `ValidationBehavior` auto-chạy trước Handler — throw `ValidationException` → 400 ProblemDetails
|
|
|
|
### 2.4 Error handling
|
|
|
|
- KHÔNG try-catch ở Controller
|
|
- Throw domain exception: `NotFoundException`, `ForbiddenException`, `UnauthorizedException`, `ConflictException`, `ValidationException`
|
|
- `GlobalExceptionMiddleware` map exception → HTTP status + ProblemDetails JSON
|
|
- Logging: Serilog structured, không `Console.WriteLine`
|
|
|
|
### 2.5 Async/await
|
|
|
|
- Tất cả I/O (DB, HTTP, file) PHẢI async
|
|
- Truyền `CancellationToken` mọi async call
|
|
- Tên method async: suffix `Async` (trừ ASP.NET action signature)
|
|
|
|
### 2.6 Entity rules
|
|
|
|
- Mọi entity mới extend `BaseEntity` (Id Guid + audit) hoặc `AuditableEntity` (+ soft delete)
|
|
- PK: `Id` type `Guid`, default `Guid.NewGuid()` trong constructor
|
|
- FK: `{Entity}Id` type `Guid`
|
|
- Enum: `HasConversion<int>()` trong EF config
|
|
- String: luôn `HasMaxLength(n)` trong EF config — không để `nvarchar(max)` trừ khi là JSON/rich text
|
|
- Money: `decimal` + `HasPrecision(18, 2)`
|
|
- DateTime: luôn UTC, lấy từ `IDateTime.UtcNow` (không `DateTime.Now`)
|
|
- Query filter soft delete: `HasQueryFilter(x => !x.IsDeleted)` cho AuditableEntity
|
|
|
|
### 2.7 DI registration
|
|
|
|
- Singleton: stateless services (DateTimeService, FormRenderer)
|
|
- Scoped: per-request services (JwtTokenService, ContractWorkflowService, DbContext)
|
|
- Transient: lightweight utility (hiếm dùng)
|
|
|
|
### 2.8 Package version pinning
|
|
|
|
- **KHÔNG dùng `*` hoặc `latest`** — luôn pin version cụ thể
|
|
- Check compatibility với .NET 10 trước khi add. Gotchas đã biết:
|
|
- MediatR 14 → lỗi IMediator DI, **pin 12.4.1**
|
|
- Swashbuckle 10 → conflict OpenApi 2, **pin 6.9.0**
|
|
- Xem [`gotchas.md`](gotchas.md) cho full list
|
|
|
|
## 3. Frontend — React 19 + Vite 8 + TS 6
|
|
|
|
### 3.1 Named export, không default export
|
|
|
|
```tsx
|
|
// ✅
|
|
export function SuppliersPage() { }
|
|
export const MyConstant = 1
|
|
|
|
// ❌
|
|
export default function SuppliersPage() { }
|
|
|
|
// Exception: App.tsx dùng default export (Vite convention)
|
|
```
|
|
|
|
### 3.2 erasableSyntaxOnly (Vite 8)
|
|
|
|
KHÔNG dùng `enum` — dùng const-object pattern:
|
|
|
|
```ts
|
|
// ❌
|
|
export enum SupplierType { NhaCungCap = 1 }
|
|
|
|
// ✅
|
|
export const SupplierType = { NhaCungCap: 1, NhaThauPhu: 2 } as const
|
|
export type SupplierType = typeof SupplierType[keyof typeof SupplierType]
|
|
```
|
|
|
|
### 3.3 Path alias
|
|
|
|
- Dùng `@/` cho absolute import: `import { api } from '@/lib/api'`
|
|
- Config ở `vite.config.ts` + `tsconfig.app.json` (chỉ `paths`, không `baseUrl`)
|
|
|
|
### 3.4 Data fetching
|
|
|
|
- **TanStack Query** cho mọi API call (KHÔNG useState + useEffect thủ công)
|
|
- `useQuery` cho GET, `useMutation` cho POST/PUT/DELETE
|
|
- `invalidateQueries` sau mutation thành công
|
|
|
|
### 3.5 API calls
|
|
|
|
- Qua `api` instance (`src/lib/api.ts`) — đã wire axios interceptor JWT + 401 redirect
|
|
- Base URL: `/api` (Vite proxy → `:5443`)
|
|
|
|
### 3.6 Permission guard
|
|
|
|
```tsx
|
|
<PermissionGuard menuKey="Contracts" action="Update">
|
|
<Button>Sửa</Button>
|
|
</PermissionGuard>
|
|
|
|
// Hook
|
|
const { can } = usePermission()
|
|
if (!can('Contracts', 'Update')) return null
|
|
```
|
|
|
|
Nhớ: FE guard chỉ là UX. BE policy `[Authorize(Policy = "Contracts.Update")]` là source of truth.
|
|
|
|
### 3.7 Component naming
|
|
|
|
- PascalCase cho file: `SuppliersPage.tsx`, `DataTable.tsx`
|
|
- kebab-case cho utility: `api.ts`, `cn.ts`
|
|
- React component = PascalCase
|
|
- Hook: prefix `use`, ví dụ `usePermission`
|
|
|
|
### 3.8 Toast + error
|
|
|
|
- Dùng `sonner` (đã wire `<Toaster>` ở App)
|
|
- `toast.success('...')`, `toast.error(getErrorMessage(err))`
|
|
- Error helper: `src/lib/apiError.ts` extract từ ProblemDetails
|
|
|
|
### 3.9 Duplicate giữa 2 FE
|
|
|
|
**CÓ CHỦ ĐÍCH.** Mỗi app (`fe-admin` + `fe-user`) là standalone — copy shared code giữa 2 app thay vì extract ra package chung. Lý do: 2 app có UX rất khác (admin mission-critical, user workflow-heavy), evolution độc lập.
|
|
|
|
Khi share code: `cp` file từ app này sang app kia. Đồng bộ tay khi có breaking change.
|
|
|
|
## 4. Database
|
|
|
|
### 4.1 Convention
|
|
|
|
| Item | Rule |
|
|
|---|---|
|
|
| Schema | 1 schema duy nhất: `dbo` |
|
|
| Table | PascalCase tiếng Anh, plural: `Contracts`, `Suppliers` |
|
|
| Column | PascalCase: `FullName`, `CreatedAt` |
|
|
| PK | `Id` — `uniqueidentifier` |
|
|
| FK | `{Entity}Id` — `uniqueidentifier` |
|
|
| Index | `IX_{Table}_{Col}` |
|
|
| Unique | `UX_{Table}_{Col}` |
|
|
|
|
Full: xem [`database/database-guide.md`](database/database-guide.md).
|
|
|
|
### 4.2 Migration
|
|
|
|
- Một commit = 1 migration (trừ khi nhiều change nhỏ trong cùng feature)
|
|
- Naming PascalCase: `AddMasterData`, `AddContractsWorkflow`
|
|
- Commit đủ 3 file: `{Name}.cs`, `{Name}.Designer.cs`, `ApplicationDbContextModelSnapshot.cs`
|
|
|
|
## 5. Git & commits
|
|
|
|
### 5.1 Branch
|
|
|
|
- `main` — deploy branch
|
|
- Feature branch (nếu nhiều người): `feature/phase{N}-{feature}`
|
|
|
|
### 5.2 Commit format
|
|
|
|
```
|
|
[CLAUDE] <scope>: <imperative message>
|
|
|
|
<body optional — chi tiết what + why>
|
|
|
|
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|
```
|
|
|
|
**Scope:** `Contract` · `Form` · `Workflow` · `Supplier` · `Auth` · `Admin` · `Api` · `App` · `Domain` · `Infra` · `FE-Admin` · `FE-User` · `Docs` · `CICD` · `Scripts` · `Report` · `Dashboard`
|
|
|
|
### 5.3 Một commit nên
|
|
|
|
- Build pass (BE + FE)
|
|
- Không leave WIP nửa chừng (trừ khi commit message nói rõ)
|
|
- Test E2E với endpoint mới (curl trong session log)
|
|
|
|
### 5.4 Không commit
|
|
|
|
- `.env`, `appsettings.*.Local.json`
|
|
- `node_modules/`, `bin/`, `obj/`
|
|
- `wwwroot/uploads/` (user files)
|
|
- `SolutionErp_Design` database (tạm cho EF CLI)
|
|
|
|
## 6. Docs
|
|
|
|
### 6.1 Khi nào viết session log
|
|
|
|
- Session có commit thay đổi code → PHẢI tạo `docs/changelog/sessions/YYYY-MM-DD-HHMM-{topic}.md`
|
|
- Session chỉ Q&A, không đụng file → không cần
|
|
|
|
### 6.2 Session log format
|
|
|
|
```markdown
|
|
# Session YYYY-MM-DD HH:MM — <topic>
|
|
|
|
**Dev:** Claude / Copilot / <name>
|
|
**Duration:** ~Nh
|
|
**Base commit:** <sha>
|
|
|
|
## Làm được
|
|
|
|
### Chunk X — <name>
|
|
- bullet list deliverable
|
|
|
|
## E2E verified
|
|
|
|
<curl output hoặc screenshot>
|
|
|
|
## Bug gặp + fix
|
|
|
|
| Bug | Fix |
|
|
|
|
## Docs updates
|
|
|
|
## Handoff
|
|
|
|
## Thông số cumulative
|
|
```
|
|
|
|
### 6.3 Update khi thêm feature
|
|
|
|
- Thêm entity → update [`database/database-guide.md`](database/database-guide.md) schema section
|
|
- Thêm endpoint → update [`flows/`](flows/) relevant flow
|
|
- Thêm bug fix lặp lại → update [`gotchas.md`](gotchas.md)
|
|
- Thêm pattern → update skill tương ứng ở `.claude/skills/`
|
|
- Phase đổi → update [`STATUS.md`](STATUS.md) + [`HANDOFF.md`](HANDOFF.md) + [`changelog/migration-todos.md`](changelog/migration-todos.md)
|
|
|
|
## 7. Testing (Phase 8 active — 77 test pass + CI gate live)
|
|
|
|
### Stack đã apply
|
|
|
|
- **xUnit 2.9.3** + **FluentAssertions 7.2** (pin trước v8 commercial license)
|
|
- **Microsoft.EntityFrameworkCore.Sqlite 10** (in-memory testing — supports transactions, không như InMemory provider)
|
|
- **Custom `TestApplicationDbContext`** override `nvarchar(max) → TEXT` cho SQLite compat (xem `tests/.../Common/SqliteDbFixture.cs`)
|
|
- **NO mock framework** (tránh mock-heavy, prefer EF in-memory hoặc fake data)
|
|
|
|
### Test pyramid (bottom-heavy, KHÔNG E2E)
|
|
|
|
```
|
|
✅ Phase 1: Domain policy 54 test (pure functions, no DB)
|
|
✅ Phase 2: Infra code generator 17 test (SQLite in-mem)
|
|
✅ Phase 3 mini: Application versioning 6 test (SQLite, no UserManager)
|
|
⏸️ Phase 3 full: Application handlers w/ Identity (cần UserManager DI helper)
|
|
⏸️ Phase 4: API smoke (WebApplicationFactory)
|
|
⏸️ Phase 5: FE Vitest cho lib utility
|
|
❌ E2E (Playwright) — KHÔNG làm (brittle cho solo dev)
|
|
```
|
|
|
|
### Quy tắc bổ sung mỗi feature mới
|
|
|
|
- **Domain entity / enum** → 0 test (compile check đủ)
|
|
- **Domain policy method** → 2-3 test (positive + negative + edge case)
|
|
- **CQRS handler có guard logic** → 1 test mỗi guard branch
|
|
- **Migration mới** → smoke test "DbInitializer chạy được + seed không lỗi"
|
|
- **API endpoint mới** → 1 happy path smoke (cho endpoint critical)
|
|
- **Bug found in production / staging** → 1 regression test BEFORE merge fix
|
|
|
|
Pattern: **"1 bug found → 1 regression test added"**.
|
|
|
|
### Workflow user end-of-task
|
|
|
|
```bash
|
|
# Sau mỗi task code (BẮT BUỘC trước commit code):
|
|
dotnet test SolutionErp.slnx # local verify ~3s
|
|
git add -A && git commit -m "..."
|
|
git push # CI tự run test gate trước build/deploy
|
|
```
|
|
|
|
Test fail local → fix trước khi push. Test fail trên CI → no deploy.
|
|
|
|
### CI gate behavior
|
|
|
|
`.gitea/workflows/deploy.yml`:
|
|
|
|
```yaml
|
|
# Path filter: skip CI hoàn toàn cho commit MD-only
|
|
on:
|
|
push:
|
|
paths-ignore:
|
|
- 'docs/**'
|
|
- '**/*.md'
|
|
- '.claude/skills/**'
|
|
|
|
# 2 step test gate trước build/deploy (fail → exit → no deploy)
|
|
- name: Run unit tests (Domain)
|
|
- name: Run integration tests (Infrastructure)
|
|
```
|
|
|
|
### Pending (Phase 3-5 future)
|
|
|
|
- Application handler tests cần Identity UserManager DI setup helper
|
|
- API smoke tests via `WebApplicationFactory` + SQLite
|
|
- FE Vitest cho `lib/queryMatches`, `lib/cn`, money formatter
|
|
|
|
Detail: `docs/architecture.md §11 Testing strategy`.
|
|
|
|
## 8. Security baseline
|
|
|
|
- HTTPS everywhere prod
|
|
- JWT Secret trong user-secrets / env var (không commit appsettings)
|
|
- Password hash: PBKDF2 (Identity default)
|
|
- CORS whitelist chỉ 2 FE origin
|
|
- SQL injection: EF Core parameterized (không raw SQL trừ khi phải)
|
|
- Audit log: mọi ghi phải log qua `ContractApproval` hoặc `AuditLog` (future)
|
|
- Rate limit: `/api/auth/login` 5 req/min/IP (chưa implement — Phase 5)
|
|
|
|
## 9. Skills (.claude/skills/)
|
|
|
|
> Project-level skills encode kiến thức SOLUTION_ERP-specific. Claude tự auto-invoke qua Skill tool dựa trên semantic match với `description` trong `SKILL.md`. **PHẢI dùng skill khi gặp task tương ứng — không tự suy luận lại.**
|
|
|
|
### 9.1 Skills hiện có (6)
|
|
|
|
**Domain (3) — logic nghiệp vụ:**
|
|
|
|
| Skill | Trigger khi |
|
|
|---|---|
|
|
| `contract-workflow` | Bug chuyển phase, 403, mã HĐ sai, versioned WF, "HĐ cũ giữ cũ" |
|
|
| `form-engine` | Render template docx/xlsx, FieldSpec, PDF export, upload form mới |
|
|
| `permission-matrix` | Permission denied, gán role, menu không hiện, inherit Contracts/Workflows |
|
|
|
|
**Ops (3) — devops + security + schema:**
|
|
|
|
| Skill | Trigger khi |
|
|
|---|---|
|
|
| `dependency-audit-erp` | `npm audit`, `dotnet vulnerable`, scan CVE, nâng cấp package |
|
|
| `ef-core-migration` | `migrations add`, schema change, snapshot lỗi, revert migration, DesignTimeDbContextFactory |
|
|
| `iis-deploy-runbook` | Prod 500/502, cert hết hạn, restart app pool, gitea-runner fail, SignalR 401 |
|
|
|
|
### 9.2 Nguyên tắc tạo skill mới
|
|
|
|
**Project-specific, KHÔNG clone generic.** User-level skills global đã có sẵn (`code-reviewer`, `sql-database-assistant`, `focused-fix`, `senior-frontend`, `mcp-builder`, `webapp-testing`, `review`, `security-review`, ...). Project-level skills chỉ thêm khi:
|
|
|
|
- Encode kiến thức **SOLUTION_ERP-only** (path, version pin, gotcha number, commit convention)
|
|
- Generic skill không thể có (vd: 8 migration history cụ thể của project)
|
|
- Có YAML `when-to-use` triggers rõ ràng (cả tiếng Việt + Anh)
|
|
- Workflow Vietnamese-first (audience là dev Việt)
|
|
|
|
### 9.3 Format bắt buộc `SKILL.md`
|
|
|
|
```markdown
|
|
---
|
|
name: kebab-case-name
|
|
description: 1-3 câu mô tả + stack specificity (cho semantic match đúng)
|
|
when-to-use:
|
|
- "trigger english"
|
|
- "trigger tiếng Việt"
|
|
---
|
|
|
|
# Skill Name
|
|
|
|
## Context
|
|
## Workflow / Commands (copy-pastable, không pseudocode)
|
|
## Pitfalls
|
|
## Code pointers (path đầy đủ src/Backend/...)
|
|
## Related (dẫn chiếu gotcha #N, docs/...)
|
|
```
|
|
|
|
### 9.4 Audit định kỳ — mỗi 4 tuần
|
|
|
|
**Cadence:** Mỗi đầu tháng (hoặc thứ Hai tuần đầu tháng), chạy audit skill list:
|
|
|
|
```
|
|
1. Đọc .claude/skills/README.md — list 6 skill hiện có
|
|
2. Cross-check với:
|
|
- docs/STATUS.md "Recently Done" — feature mới nào chưa có skill cover?
|
|
- docs/gotchas.md — gotcha mới (>3 dòng) nào nên gom thành skill mới?
|
|
- migration-todos.md "In Progress" / "Next up" — task lớn sắp tới có cần skill?
|
|
3. Check repo nguồn skill 3rd party có gì mới:
|
|
- https://github.com/alirezarezvani/claude-skills (default-branch)
|
|
- Anthropic skills built-in (xem system reminder skill list)
|
|
4. Đánh giá staleness:
|
|
- Mỗi skill: SKILL.md có còn match code thực tế không?
|
|
- Trigger phrases có còn hiệu quả?
|
|
- Code pointers có còn đúng path?
|
|
5. Hành động:
|
|
- Skill stale → update SKILL.md + commit `[CLAUDE] Skill: refresh <name>`
|
|
- Skill cần thêm → tạo theo §9.2 §9.3 + commit `[CLAUDE] Skill: add <name>`
|
|
- Skill không còn cần → archive vào .claude/skills/_archived/ + commit
|
|
6. Update bảng §9.1 trong rules.md + .claude/skills/README.md + docs/CLAUDE.md count
|
|
7. Log vào docs/changelog/skill-audit-{YYYY-MM}.md (1 page max)
|
|
```
|
|
|
|
**Trigger:** Khi user nói "audit skill", "check skill list", "skill staleness", "định kỳ kiểm tra skill" → chạy workflow này.
|
|
|
|
**Lịch chính thức:**
|
|
- Tháng 1, 2, 3, ... — đầu tháng audit (1 buổi sáng)
|
|
- Hoặc khi bắt đầu Phase mới (vd Phase 6) → audit ngay trước phase
|
|
- Hoặc khi `docs/gotchas.md` vượt mốc (cứ +5 gotcha thì xem có gom thành skill được không)
|
|
|
|
### 9.5 Anti-patterns
|
|
|
|
❌ **KHÔNG bulk-clone repo skill 3rd party** — phần lớn doc-dump generic, không có `when-to-use`, dễ trigger sai.
|
|
|
|
❌ **KHÔNG viết skill chỉ để "có thêm"** — skill = trigger semantic match, nếu description quá chung sẽ trigger nhầm trong session khác.
|
|
|
|
❌ **KHÔNG copy nội dung skill từ docs/ sang SKILL.md** — skill phải ngắn gọn, action-oriented; docs/ là reference dài. Skill dẫn chiếu docs.
|
|
|
|
❌ **KHÔNG bỏ qua skill khi gặp task khớp** — tự suy luận lại = lãng phí context + dễ sai.
|
|
|
|
## 10. Liên quan
|
|
|
|
- [`CLAUDE.md`](../CLAUDE.md) — entry point cho AI agent
|
|
- [`architecture.md`](architecture.md) — kiến trúc chi tiết (layered, CQRS, state machine)
|
|
- [`gotchas.md`](gotchas.md) — pitfalls đã gặp
|
|
- [`database/database-guide.md`](database/database-guide.md) — DB conventions
|
|
- [`flows/`](flows/) — sequence diagram per feature
|
|
- [`../.claude/skills/README.md`](../.claude/skills/README.md) — skill index 6 skill
|