SUA-1..6b tron 6/6, acceptance C1-C6b 12/12. Vong-2 sua chinh vong-1 sau reviewer C7 (PASS-WITH-8, 3 MAJOR):
- Doi ba-cham -> hai-cham la REGRESSION co dieu-kien, KHONG phai cosmetic: chi tuong-duong khi origin/main
con ancestor; cay phan-ky thi hai-cham liet ca file CHI CO tren origin/main (= DA PRODUCTION) vao "phan MOI".
Thu pham that = git diff mu untracked. Sandbox 2 chieu CONFIRMED.
- git status --porcelain | cut -c4- de path RAC (rename in MOT dong "R old -> new"; path co dau cach bi quote).
Sandbox: 2/2 MISS; thuoc moi 2/2 OK.
- Thuoc CHOT 4/4 site: { git diff --name-only origin/main...HEAD; git diff --name-only HEAD;
git ls-files -o --exclude-standard; } | sort -u
Bai: chan-doan sai VAN pass acceptance — acceptance do HINH-DANG chuoi, khong do HANH-VI.
Lop mo-neo TU-VO-HIEU: con-tro so-dong tro vao CHINH tep chua no tu thoi moi lan sua dau tep
(112->118->121 trong 1 phien) => neo TEN, khong neo SO DONG. Ap cho index.css, gotchas.md, PipelineStageFolders.
Con-tro verbatim _mind doi ve commit DA PUSH (ee21056/d081681) — ban truoc tro 727a512 nam trong dai squash
=> tu de con-tro mo-coi.
H24 light-audit 9 FLAG, flush 8 o canonical: Mig 71->72 - Gotchas 86->87 - Tests 644->645 (chay that
dotnet test: 45 Domain + 600 Infra, 0 fail) - user-mem 59->60 - header S168->S179 - roster 23->26 (go han so
theo B1) - HANDOFF dong 4 slot (68)-(71) + E4.
"So noi doi theo huong BI QUAN" x3 ca/1 phien (4 slot - E4 - run.md S173) => leo thang lan 3 phai DO LAI TIEN-DE.
Kem: 2 NO vong-3 - 2 synthesis ORPHAN (run-chua-gom 2->0) - di-tru cua-so 6 vao _context - keo+ap 2 thu
loi-do-luong (BAC Lop 8 CO SO: mtime cum SE 0,7% vs hub 69%) - drift-audit thang PASS_WITH_FLAGS-8 (va 2, con 6)
- _mind 99,67%->84,2% - don 9 dir rong - archive-gate strike 1/2.
#53: 4/4 vai garble return dau, vot tron 4/4 bang resume-in-session. Mat 0 byte.
0 file code nghiep-vu. Build 2/2 app PASS. Test 645/645.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
17 KiB
CLAUDE.md — AI Agent Context
Full content:
docs/CLAUDE.md
SOLUTION_ERP — Hệ thống Quản lý Hợp đồng Nhà cung cấp / Thầu phụ / Tổ đội + Phiếu Duyệt NCC tiền-HĐ cho Công ty TNHH Xây dựng Solutions.
Kiến trúc: .NET 10 Clean Architecture + 2 React FE (admin + user) + SQL Server + IIS.
🚀 BẮT ĐẦU SESSION — 5 file đọc trước tiên
1. docs/STATUS.md ← Snapshot HIỆN TẠI (phase nào, việc gì đang làm — PE module CÒN CHỈNH NHIỀU)
2. docs/HANDOFF.md ← Brief 5 phút: session trước làm gì + cảnh báo session tiếp
3. docs/PROJECT-MAP.md ← Bản đồ toàn cảnh
4. docs/changelog/migration-todos.md ← Atomic tasks theo phase (active-work đọc TRONG file — KHÔNG neo nhãn phase ở đây, H24-DEEP F-10)
5. docs/workflow-contract.md ← ⭐ State machine 9 phase HĐ — base pattern cho PE workflow
⛓️ Mạch việc dở (H22): nằm ở
.claude/WAL.md; nối lại DUY-NHẤT bằng/tiep— kể cả khi anh gõ "làm tiếp" bằng text thường. Không tự recovery cách khác. (Chốt dừng chủ-động =/pause; cơ-chế →docs/governance/harness-11-engine.mdPHẦN N.)
🎛️ Chế-độ đang hiệu-lực (operating-posture) — TRA Ở ĐÂU (adap đợt-11,
3-khoan:31-41discoverability-home ⟂ implement-home): file này CỐ Ý KHÔNG chép giá-trị ON/OFF — chép là sai ngay lượt sau khi anh toggle. Chỉ trỏ nơi tra:
- HMW-mode (fan-out Workflow) → marker
.claude/hmw-mode.on;/session-startBƯỚC 0.5 in trạng-thái mỗi phiên. Bật/tắt:/ultra-on·/ultra-off.- Engine-đắt (
/fable-real·/fable-clone) → per-invocation, KHÔNG persist (H21) — không có mode để tra, chỉ sống trong lượt anh gõ.- Lead model →
~/.claude/settings.json(global, NGOÀI git — grep trong repo sẽ ra 0 hit); probe runtime mỗi phiên ở BƯỚC 0.6.- Nhịp H24 / ngân-sách memory →
.claude/agent-memory/memory-budget.json(single-source; doc trỏ key, không chép số).
⚡ Quick Rules
Backend — .NET 10 Clean Architecture
- Solution:
SolutionErp.slnxở root, projects ởsrc/Backend/ - 4 layer:
Api → Application ← Domain+Infrastructure → Application - Pattern: CQRS + MediatR, FluentValidation, AutoMapper
- Repository qua
IApplicationDbContextinterface (Application layer) - Auth: JWT Bearer + ASP.NET Identity
- DB: SQL Server (LocalDB dev / SQL Server prod), EF Core 10 Code-First migrations
- Error handling:
GlobalExceptionMiddlewaremap exception → HTTP status - Commit scope tech stack:
Api·App·Domain·Infra
Frontend — 2 app React 19 + Vite + TS + shadcn/ui + TanStack Query
fe-admin/(port 8082) ·fe-user/(port 8080)- Vite proxy
/api → http://localhost:5443(SolutionErp.Api) - Named export, không default export (trừ
App) - shadcn/ui copy-paste, duplicate giữa 2 app là CÓ CHỦ ĐÍCH (mỗi app UX riêng)
- Auth context:
solution-erp-admin-token/solution-erp-user-tokenởlocalStorage - TanStack Query cho data fetching
- Node pin
>=20trongengines; CI pin20.xqua.nvmrc(bài học NamGroup — KHÔNG dùng Node latest trên CI) - UI 100% tiếng Việt
Database conventions
- Schema:
dbo(single schema) - Table: PascalCase tiếng Anh (Contracts, Suppliers, Projects, ContractApprovals, PurchaseEvaluations, ...)
- PK:
Id(Guid), FK:{Entity}Id - Audit fields:
CreatedAt,UpdatedAt,CreatedBy,UpdatedBy(BaseEntity) - Soft delete:
IsDeleted,DeletedAt,DeletedBy(AuditableEntity) - Migrations:
dotnet ef migrations add <Name> --project src/Backend/SolutionErp.Infrastructure --startup-project src/Backend/SolutionErp.Api - Số migration · bảng hiện tại →
docs/STATUS.md(canonical — KHÔNG copy số ở đây để tránh drift; Harness-11 B1). Lịch sử mig gần đây: +S164/S165 Mig 70AddContractCatalogEntries(K1 SP-002 — danh mục hạng-mục HĐ 86 dòng, +1 bảng 96→97) + Mig 71AddKhkkApprovalGroupCatalogAndFinalizeRuntime(K2/K3 — phiếu KHKK +nhóm duyệt N1-N8 backfill=1 + Line +hạng-mục + unique 3-cột + cờEndedByLevelFinalize, 0 bảng mới) · +S161 Mig 69AddContractSigningPlans(module MỚI Kế hoạch Ký kết HĐ — 7CreateTable, bảng 89→96; menu-keyKeHoachKyKetsinh policy KHÔNG sinh menu-row; gotcha #85 menu-key OR-gate FE ≠ policy per-action BE) · +S157 Mig 68AddPeAllowApproverDelete(PE nút XÓA phiếu ở màn duyệt — AddColumn, no new table) · +S133 Mig 67AddPeApprovedBudgetSnapshot(PE freeze ngân sách phiếu DaDuyet — snapshot 11 cột AddColumn chốt tại finalize choke-point + site-5 admin-override + backfillSql()OUTER APPLY 18/18 prod, no new table; display-gatebudgetFrozenphiếu DaDuyet đọc snapshot/phiếu mới đọc live; gotcha #81-EXT) · +S97 Mig 60AddPeEndedByLevelFinalize+ Mig 61BackfillEndedByLevelFinalizeFromChangelog(PE cờ RUNTIME finalize-sớm — display đọc runtime thay suy-config; backfill Mig 60 soi nhầm bảng Approvals → Mig 61 đúng Changelogs; gotcha #78/#79) · +S74 Mig 55AddCcmNoteToPeWorkItemBudget(PE CcmNote) · +S73 Mig 54AddPeSuggestedAndApprovedPrice(PE giá đề xuất PRO/CCM). +S69: Mig 53AddPeUrgentAndCeoApprovalThreshold— PE +IsUrgentByPro/Ccm cờ gấp PRO/CCM + ApprovalWorkflow +CeoApprovalThreshold ngưỡng CCM duyệt-final, 3 AddColumn no new table. +S65: Mig 51AddDepartmentParentIdDepartment.ParentId loose-Guid no-FK org-tree phân cấp + Mig 52AddHoSoLinkToPurchaseEvaluationPE HoSoLink nvarchar(1000) hyperlink NAS — cả 2 AddColumn no new table, tables giữ 88. Phase 10 COMPLETE + Phase 11 P11-A→F done — Mig 34-42 HRM/Office/WorkflowApps/Attendance + Contract V2 (32-33) + WireWorkflowApps V2 (41) + LeaveBalance (42) + Holiday filtered-unique (43, S45) + Vehicle/Driver catalog (44, S51) + HRM-catalog filtered-unique 3× (45, S51) + ItTicket SLA (46, S52) + Master filtered-unique 3× (47, S53 gotcha #57 EXT) + Project master fields Year/Investor/Location/Package (48, S55 — AddColumn no new table, kèm nạp 62 dự án + 71 hạng mục + 3 NCC real data từ Excel quaSeedRealMasterDataAsyncungated idempotent) + PE gắn Hạng mục công việc WorkItemId loose-Guid KHÔNG FK vật lý (49, S57bis — AddColumn+CreateIndex, no new table) + Mig 50ReplaceBudgetModuleWithPeWorkItemBudgets(S61, 2026-06-13) — XÓA module Budget cũ, thay bằngPeWorkItemBudgetsngân sách per-gói-thầu (1 record/cặp Dự án × Hạng mục, nhập theo role PRO/CCM, vượt ngân sách = cảnh báo mềm cho lưu S62); backfillBudgetManualAmount→BudgetPeriodAmountTRƯỚC DropColumn (phiếu UAT giữ số); net bảng 93→88; gotcha #63/#64. V2 schema history S29-era bên dưới giữ nguyên — Mig 32+33 Plan B Contract V2 cookie-cutter mirror PE Mig 22-26 (S29). Mig 26AddPeLevelOpinionsForV2: bảng mớiPurchaseEvaluationLevelOpinionsUNIQUE composite (PEId, LevelId), FK Cascade Pe + Restrict Level. Section 5 "Ý kiến cấp duyệt" V2 dynamic theo workflow đã pin: forEach Step (Phòng) → forEach Level (Cấp) → forEach NV → 1 OpinionBox. ServiceApproveV2AsyncUPSERT auto khi NV duyệt — Q1=1B (sync gắn với Duyệt, KHÔNG form input rời). SignedByUserId track signer thật, FE banner "Admin duyệt thay" khi !== ApproverUserId. Comment empty → "(duyệt — không ý kiến)" placeholder. Phiếu V1 legacy fallback Mig 15 4 box readOnly (data history). Mig 25AddIsUserSelectableToApprovalWorkflows: ALTERApprovalWorkflows+IsUserSelectable bit(admin pin/unpin workflow nào cho user pick lúc create phiếu, multi-select độc lập IsActive). BackfillWHERE IsActive=1 SET 1giữ behavior cũ. Designer +badge "Cho user chọn" + button Ghim/Bỏ ghim. Workspace filter dropdown chỉ workflowsIsUserSelectable=true. Mig 22-24 V2 schema (Session 17):ApprovalWorkflows/Steps/Levels — Quy trình > Bước (Phòng) > Cấp (N NV cụ thể qua ApproverUserId, OR-of-N cùng cấp). PE.ApprovalWorkflowId pin V2. PE.CurrentApprovalLevelOrder track. State machine 5 trạng thái: Nháp / Đã gửi duyệt / Trả lại (Phase riêng TraLai=98) / Từ chối / Đã duyệt. PE Service V2 wire matchactor.Id == ApproverUserId. Contract V2 ĐÃ WIRE (Mig 32+33 Plan B S29 — cookie-cutter mirror PE V2:ApproveV2Async+ContractLevelOpinionsUPSERT + Workspace V2 Select dropdown). Mig 21 V1 flat workflow vẫn live cho phiếu cũ.)
Modules
| Module | Namespace | Migration | Trạng thái |
|---|---|---|---|
| Contract (HĐ) | Domain/Contracts/ |
1-11 | Feature-complete (7 ContractType × 9 phase) |
| PurchaseEvaluation (Duyệt NCC tiền-HĐ) | Domain/PurchaseEvaluations/ |
12,13,15,49,50,52-61,65-68 | Feature-complete — +Hạng mục (Mig 49) +ngân sách per-gói-thầu role PRO/CCM (Mig 50) +Link hồ sơ NAS (Mig 52) +cờ gấp PRO/CCM + CCM duyệt-final theo ngưỡng (Mig 53) +giá đề xuất PRO/CCM + CCM-note (Mig 54/55) +PRO-split + ghi-chú-giá (Mig 56/57) +multi-winner liên-danh + level-finalize + NS-kỳ-CCM (Mig 58/59) +EndedByLevelFinalize runtime-flag + backfill-fix (Mig 60/61, S97 — gotcha #78/#79) +multi-NCC per-hạng-mục (Mig 65, S114 — gotcha #81) +duyệt-khoảng giá Min–Max (Mig 66, S117) +freeze NS phiếu DaDuyet snapshot 11-cột + display-gate budgetFrozen (Mig 67, S133 — gotcha #81-EXT indirect-assignment) +lũy kế TẠM TÍNH vs CHÍNH XÁC (S134, 0-mig — ComputePendingAsync complementary [ChoDuyet-winner vào tạm-tính, nháp list-only] + sub-dòng amber matrix + banner màn duyệt + D4 audit-note changelog) +nút XÓA phiếu ở màn duyệt (Mig 68, S157/S162 — AllowApproverDelete, AddColumn no new table). Export PDF pending |
| ContractSigningPlans (Kế hoạch Ký kết HĐ — KHKK) | Domain/ContractSigningPlans/ |
69, 71 | Feature-complete — Mig 69 AddContractSigningPlans (S161, 7 bảng, 89→96): CRUD + Dossier 15 policy (W2) · duyệt V2 3-trạm test-before RED→GREEN (W3) · đường-ống HĐ V2 (W6) · bản-cứng 1-MỐC theo owner (form điền đủ → duyệt nếu có → upload bản cứng = xong) (W7) · cây 4-folder GĐ ×2 app (S162) · chuỗi K SP-002 @S164-S167 (Mig 71 nhóm-duyệt N1-N8 + Line hạng-mục + 8 workflow nhóm + bridge KHKK→HĐ hội-2-khóa K7 aaed699). 🔴 Gate quyền dùng đúng key policy của endpoint (KeHoachKyKet), KHÔNG OR key con — gotcha #85 |
| — | 14 → Mig 50 DROP | ⚠️ REMOVED S61 — module Budget cũ XÓA, thay bằng PE-budget-per-gói-thầu (PeWorkItemBudgets). FE pages/types/menu Bg_* gỡ hết |
|
| Master (Supplier/Project/Department) | Domain/Master/ |
2, 10, 48, 51, 62-64 | Feature-complete — +Project fields Year/Investor/Location/Package (Mig 48) +Department.ParentId org-tree (Mig 51) +Supplier expand 30-field/import/publish-state (Mig 62-64) |
| Identity (User/Role/Permission/MenuItem) | Domain/Identity/ |
1, 3, 11 | Feature-complete (30 demo user — 16 sample + 14 Solutions thật) |
| Forms (Template + Clause) | Domain/Forms/ |
4 | Feature-complete |
| Notifications | Domain/Notifications/ |
6 | In-app + SignalR OK, email SMTP TODO |
| Tests | tests/SolutionErp.{Domain,Infrastructure}.Tests/ |
— | Test pass — số hiện tại → docs/STATUS.md — CI gate + path filter docs-only skip |
Commit convention
[CLAUDE] <scope>: <imperative message>
Scope: Contract · PurchaseEvaluation · Budget · Form · Workflow · Supplier · Auth · Admin · Api · App · Domain · Infra · FE-Admin · FE-User · Tests · Docs · CICD · Scripts · Skill
🧪 Tests (Phase 9 — Session 9 +6)
tests/
├── SolutionErp.Domain.Tests/ (Domain policy: Workflow / PE)
└── SolutionErp.Infrastructure.Tests/ (codegen + CQRS handler + authz regression)
├── Common/ (SqliteDbFixture + TestApplicationDbContext + IdentityFixture S9)
├── Services/ (17 codegen + 6 PE 2-stage approval S9)
└── Application/ (6 test - PeWorkflowDefinition versioning)
Unit test pass — số hiện tại → docs/STATUS.md (canonical). CI gate + path filter live. (Lịch sử: S74 +5 CcmNote; S69 +20 Office-golive/PE-threshold; S67 +23 HRM test-after; S61 +22 PeWorkItemBudgetTests −14 BudgetPolicyTests, Domain drop BudgetPolicyTests cùng module Budget đã REMOVE S61.)
dotnet test SolutionErp.slnx # chạy cả 2 test project
Quy tắc timing test: feature mới = test-after (UAT ổn → viết). Bug fix = test-before BẮT BUỘC (reproduce → fix). Critical algorithm (codegen/guard/financial/security) = test-before merge. Spec change = update test cũ + code chung commit. Skip: DTO mapping, CRUD master, FE snapshot. Detail docs/rules.md §7.
CI/CD pipeline (3 fix lớn 29/04)
- ✅ Manual checkout bypass github.com (fix gotcha #39 TCP timeout)
- ✅ Path filter docs-only skip —
paths-ignore(gotcha #41) - ⏸️ npm cache (gotcha #40 — failed, rolled back)
Tốc độ: code commit ~3 phút / docs-only commit 0s (skip).
🛠️ Skills (.claude/skills/) — 6 skill PHẢI dùng khi task khớp
| Domain (3) | Ops (3) |
|---|---|
contract-workflow — state machine + versioned WF |
dependency-audit-erp — npm/dotnet CVE scan |
form-engine — render docx/xlsx + PDF |
ef-core-migration — EF migration + 3-file rule |
permission-matrix — role × menu × CRUD |
iis-deploy-runbook — 3 site IIS + win-acme + runner |
Audit định kỳ: đầu mỗi tháng — combined skill + doc drift audit theo docs/rules.md §6.4 + §9.4, em-main chạy thủ-công session đầu-tháng (🧊 ghost-wire cron gỡ S100 H18 — CronList runtime = 0 job). ĐÃ CHẠY 2026-08-07 (S179) — trễ 6 ngày so hạn 08-01; verdict tooling-auditor = PASS_WITH_FLAGS — 8. Lần kế: 2026-09-01. 🔴 Ô ngày này là giá-trị SỐNG duy nhất trong repo (rules.md:546 trỏ về STATUS nhưng STATUS KHÔNG có row canonical) ⇒ đóng audit thì phải lật ô này trong CÙNG lượt, không thì đúng lượt đóng lại đẻ neo thối mới. 🧊 lineage: hạn 08-01 (S96 chạy 07-01).
Quy tắc:
- KHÔNG bulk-clone repo skill 3rd party. Chỉ thêm skill PROJECT-SPECIFIC. Xem
docs/rules.md §9đầy đủ. - KHÔNG rewrite toàn bộ MD định kỳ. Chỉ compact + patch drift. Xem
docs/rules.md §6.4đầy đủ.
📖 Tài liệu quan trọng
| File | Nội dung |
|---|---|
docs/STATUS.md |
🔥 Current state — đọc đầu tiên |
docs/HANDOFF.md |
Brief 5 phút: session trước làm gì + next tasks |
docs/rules.md |
⭐ Coding conventions (BE Clean Arch, FE React, DB, Git, Docs) |
docs/architecture.md |
⭐ Layered architecture + request lifecycle + deployment |
docs/PROJECT-MAP.md |
Bản đồ tổng quan |
docs/changelog/migration-todos.md |
Roadmap 5 phase + atomic tasks |
docs/CLAUDE.md |
Full context — tech stack chi tiết |
docs/workflow-contract.md |
State machine 9 phase HĐ + role matrix |
docs/forms-spec.md |
Catalog 8 form + quy định mã HĐ RG-001 |
docs/database/database-guide.md |
DB conventions + migration workflow + cheatsheet |
docs/database/schema-diagram.md |
⭐ ERD + luồng DB + data flow (số bảng → docs/STATUS.md) (+ §11 PE + §12 |
docs/flows/README.md |
Index 6 flow (auth, permission, contract, form, SLA) |
docs/gotchas.md |
⭐ Bẫy đã gặp (số hiện tại → docs/STATUS.md) — đọc trước khi debug tương tự |
.claude/skills/ |
6 skill: contract-workflow, form-engine, permission-matrix, dependency-audit-erp, ef-core-migration, iis-deploy-runbook |
docs/guides/vps-setup.md |
⭐ Master runbook deploy VPS shared với VIETREPORT |
⚠️ Kết thúc session
- Update
docs/STATUS.md(In Progress→Recently Done) - Tick checklist tương ứng trong
docs/changelog/migration-todos.md - Tạo session log
docs/changelog/sessions/YYYY-MM-DD-HHMM-{topic}.mdnếu đáng ghi - Commit
[CLAUDE] <scope>: <message> - ⚠️ Update
SolutionErp.slnxnếu có.cs/.csprojmới
Bỏ qua nếu chỉ trả lời câu hỏi, không sửa file nào.