Session 15 (2026-05-07) docs update: STATUS.md: - Last updated Session 15 (1 commit `835cc7f` tooltip + working tree drastic refactor revert) - Recently Done row Session 15 chi tiết (diagnose + plan drastic + attempt 12 file edits + REVERT decision) HANDOFF.md: - TL;DR Session 15 prepend với 2 phần: Diagnose tooltip + Drastic refactor DEFER decision - 4 cảnh báo Session 16+: Drastic refactor pending (8-10h dedicated hoặc fallback Approach Y), Task 2 sample seed pending, schema-diagram defer cron audit, Hard blockers giữ nguyên migration-todos.md: - Phase 9 + Session 15 block với 1 task done (tooltip) + 1 defer (drastic refactor) + memory entry note - Defer Session 16+ list Session log NEW `2026-05-07-2600-tooltip-defer-drastic.md`: - Bối cảnh user UAT báo button silent disabled - Phần 1 — Diagnose tooltip (root cause + fix UX + "trùng ID" KHÔNG phải bug FE) - Phần 2 — Plan drastic refactor flat workflow → DEFER: * User spec mới (Phòng × Cấp × Users[] flat) * Plan 6 chunk + estimate scope realistic ~8-10h * Attempt 12 file working tree edits → REVERT decision * Memory entry capture decision rule - Plan organization sau S15 (defer queue) Memory entry NEW `feedback_drastic_refactor_scope.md`: - Quy tắc: drastic refactor cần dedicated session, scope conservative 2x buffer - Anti-patterns mid-session big refactor + commit broken state - Defer pattern (revert working tree → document → memory entry → surface trade-off cho user) - Cross-ref `feedback_per_chunk_commit.md` discipline 🎉 Session 15 wrap-up. Cumulative since session start (13h17): 16 commit (1 button removal + 6 PE N-stage + 5 Contract N-stage + 1 3-button + 1 Session 14 wrap-up + 1 tooltip + 1 Session 15 wrap-up). Verify: dotnet test 96 pass + working tree clean. Defer Session 16+ priority order: 1. Drastic refactor flat workflow (dedicated session ~8-10h) OR fallback Approach Y (FE flat UI 5 phòng, 1-2h) 2. Task 2 sample data seed N-stage 3. Hard blockers Ops (UAT, SMTP, etc.) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
46 KiB
STATUS — Snapshot hiện tại
Update rule: trước khi bắt đầu 1 task → ghi row vào
🔥 In Progress. Xong → chuyển sang✅ Recently Done.
Last updated: 2026-05-07 (Session 15 — Diagnose "Lưu & Gửi Duyệt" silent disabled → tooltip reason + dialog warning rõ phase. User feedback bug suy đoán "trùng ID" — không phải bug FE. 1 commit 835cc7f. Tiếp đó Plan drastic refactor flat workflow user chốt → attempt edit Domain/Configurations 12 files, scope realistic ~8-10h vượt session, REVERT working tree about session sau. 0 test mới. State: 96 test pass.)
📍 Phase hiện tại: Phase 9 active — UAT — 57 DB tables, 20 migrations, ~134 API endpoints, 32 FE pages. 96 unit test pass (54 Domain + 42 Infra). 41 gotcha. 30 demo user. 6 skill. 5 PE display status (Bản nháp / Đã gửi duyệt / Trả lại / Đã duyệt / Từ chối). 9 PE phase enum (+TraLai = 98 — orphan, KHÔNG wire). N-stage workflow Phòng × PositionLevel (NV/PP/TP) cấu hình động per WorkflowStep cha — Mig 18+19 (PE) + Mig 20 (Contract). Budget defer (cần versioned WF migration trước). PE 3-button approval (Duyệt forward / Trả lại smart-reject / Từ chối khoá phiếu).
🌐 Production URLs
- https://api.solutions.com.vn — API (Let's Encrypt, auto-renew via win-acme)
- https://admin.solutions.com.vn — Admin FE (HTTP→HTTPS auto-redirect)
- https://eoffice.solutions.com.vn — User FE (HTTP→HTTPS auto-redirect)
- https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp — Gitea repo + Actions
- Default admin:
admin@solutionerp.local/Admin@123456⚠️ RE-ROTATE sau login đầu
🔥 In Progress — Session 7+ (Phase 9 active)
A. Hard blockers (chờ user / ops)
- UAT thật 1 tuần với 2-3 user (Drafter / CCM / BOD) — hard requirement Phase 5 roadmap
- SMTP config → Email outbox (BLOCKED chờ user cấp host/user/pass)
- Rotate creds — admin + 30 demo + SA + vrapp + JWT secret + Gitea runner token
- Schedule SQL backup daily —
scripts/backup-sql.ps1đã sẵn, chưa schedule Task Scheduler - Remove binding cũ
.huypham.vnsau verify stable:ssh vietreport-vps ; .\migrate-domains.ps1 -RemoveOld -SkipCert - win-acme scheduled task "unhealthy" — auto-renew fix trước 2026-06-18
B. Carry over feature gap
- Export phiếu PDF/Excel PE — tái dùng
IDocumentConverter+ templatePE-TrinhDuyet.docx(user pending — không quan trọng lắm)
C. Optional polish (khi UAT phát sinh bug)
- Budget MaNganSach atomic sequence (hiện Random.Shared → migration
AddBudgetCodeSequences) - Budget versioned workflow (admin config UI thay hardcoded
BudgetPolicy.Default) - Payment terms PE tách field (JSON blob → 6 column riêng)
- Auto-map PE Details → Contract per-type Details khi gen HĐ
- Matrix Quotes bulk paste từ Excel
- fe-user Inbox thêm section "Phiếu Duyệt NCC chờ tôi"
D. Tests Phase 3-5 (làm khi gặp bug recurring để justify ROI — rule §7)
- Phase 3 full — Application handler tests cần UserManager DI helper (PE Opinion Upsert, Budget validate, CreateContractFromEvaluation BudgetId carry) ~15 test
- Phase 4 — API smoke tests qua WebApplicationFactory ~7 test
- Phase 5 — FE Vitest cho lib utility (queryMatches, fmtMoney) ~10 test
E. 2-stage dept approval — Chunk E-bis ✅ DONE (Session 9)
- FE Workflow Panel PE — section "Tiến trình duyệt 2-cấp phòng ban" group by phase × dept, highlight amber khi chờ TPB confirm
- FE UserManager toggle
CanBypassReview— column "Bypass" badge fuchsia + button toggle ShieldCheck (UsersPage) - HĐ 2-stage mở rộng —
ContractWorkflowServicethêm UserManager DI + 2-stage logic mirror PE +ContractDepartmentApprovalFeatures.cs+ endpointGET /contracts/{id}/department-approvals+ FE WorkflowHistoryPanel section mới - Budget 2-stage mở rộng —
TransitionBudgetCommandHandlerthêm INotificationService + IDateTime + 2-stage logic +BudgetDepartmentApprovalFeatures.cs+ endpoint + FE BudgetWorkflowPanel section - Tests 2-stage (6 test) —
IdentityFixturesetup full Identity stack + 6 test PE workflow service: NV review block / TPB confirm allow / NV bypass / Admin skip / Reject set / Resume jump-back. Pattern reusable.
F. Audit định kỳ (cron tự fire)
- 2026-05-01 (audit 2026-05-04 manual trigger sau trễ 4 ngày) — combined audit log
docs/changelog/skill-audit-2026-05.md. Cron Claude SDK KHÔNG fit monthly cadence (auto-expire 7d) → user setup OS Task Scheduler nếu cần auto-remind. - 2026-06-01 — combined audit kế. Trigger thủ công khi đến ngày hoặc user nói "audit MD" / "kiểm tra docs" / "định kỳ kiểm tra".
✅ Recently Done (newest on top)
| Ngày | Ai | Task | Commit |
|---|---|---|---|
| 2026-05-07 | Claude | 🎯 SESSION 15 — Tooltip diagnose "Lưu & Gửi Duyệt" + Plan drastic refactor flat workflow → DEFER — User UAT live screenshot phiếu PE Bản nháp + báo "Lưu & Gửi Duyệt" KHÔNG hoạt động + suy đoán "trùng ID với phiếu khác". Chẩn đoán: button silent disabled khi evaluation.workflow.nextPhases không có forward phase (chỉ TuChoi/TraLai). FE chưa có visual feedback → user không biết. Improvement (commit 835cc7f): compute forwardPhase once + add submitDisabledReason string giải thích reason (canEditPhase=false / readOnly / !forwardPhase với hint admin kiểm tra cấu hình quy trình) + button title attribute show reason hover hoặc forward phase label khi enabled + Dialog confirm show forward phase explicit "Sẽ chuyển sang Chờ Purchasing". Mirror fe-admin + fe-user. Build pass cả 2. "Trùng ID" KHÔNG phải bug FE — PurchaseEvaluationWorkspacePage URL state đúng (+ Thêm mới clear id, save set new), mỗi PE row unique GUID + MaPhieu. Tiếp theo plan drastic refactor: User chốt "bỏ phase enum hoàn toàn, dùng ChoDuyet=10 đơn nhất + currentStepIndex tracking" + workflow flat list (Phòng × Cấp × Users[]) thay InnerStep model. Surface 6 chunk plan + start Chunk A: edit Domain entities (Phase enum +ChoDuyet=10, WorkflowStep +DeptId/PositionLevel, drop InnerStep class+nav, PE/Contract +CurrentWorkflowStepIndex/RejectedAtStepIndex, *DeptApproval drop InnerStepId) + EF Configurations (drop InnerStep config + nav, restore simple unique non-filtered) + DbContext drop DbSets — 12 files trong working tree. Realize scope realistic ~8-10h (PolicyRegistry rewrite + 2 Service rewrite + App CQRS + 12 tests rewrite + Designer FE + Migration 21 + Docs) vượt session boundary + risk session context deep ~30 commits. REVERT working tree về 835cc7f clean. Add memory feedback_drastic_refactor_scope decision rule: drastic refactor cần dedicated session, ước tính conservative (2x buffer), tránh mid-session big refactor. Stats unchanged: 96 test pass, 20 mig, 57 bảng. |
835cc7f |
| 2026-05-07 | Claude | 🎯 SESSION 14 — PE 3-button workflow Duyệt/Trả lại/Từ chối + Task 2 sample seed in-progress — User chỉ thị thay 2-button approval bằng 3 hành động rõ ràng cho approver: Duyệt (forward), Trả lại (về DangSoanThao + Drafter sửa, smart reject Mig 16 + clear N-stage rows + Drafter resume jump-back), Từ chối (Phase=TuChoi, phiếu khoá vĩnh viễn 17 handler Mig 16 lock edit, Drafter phải tạo phiếu mới). 1 commit (0d77698): Domain PurchaseEvaluationPolicy.cs NccOnly + NccWithPlan thêm (X → TuChoi) transition cho mọi phase trung gian (ChoPurchasing/ChoCCM/ChoDuAn/ChoCEODuyetPA/ChoCEODuyetNCC) với roles của phase. FromDefinition expand: mỗi step (trừ DangSoanThao) thêm (step.Phase → TuChoi) với roles step. Service PurchaseEvaluationWorkflowService.TransitionAsync — Reject branch tách 2 case: target=TuChoi giữ nguyên (KHÔNG override + KHÔNG set RejectedFromPhase + KHÔNG clear N-stage); target khác (DangSoanThao) → smart reject (force DangSoanThao + RejectedFromPhase + clear N-stage). FE PeWorkflowPanel (admin + user mirror): render 3 button rõ ràng "✓ Duyệt → X" brand / "← Trả lại (về Drafter sửa)" red / "✗ Hủy / Từ chối" red. Decision logic: target=TuChoi |
|
| 2026-05-07 | Claude | 🎯 SESSION 13 — Mirror N-stage workflow sang Contract (Mig 20, 5 commit per-chunk + skip Chunk E API) — User chỉ thị mirror N-stage từ PE sang Contract. Budget defer (cần versioned WF migration trước, hardcoded BudgetPolicy hiện tại chưa có WorkflowDefinition). 5 chunk per-commit (build + ef + test pass mỗi chunk): Chunk A (951ffa3) Domain entity WorkflowStepInnerStep (Domain/Contracts/) + nav WorkflowStep.InnerSteps + ALTER ContractDepartmentApproval.InnerStepId Guid? + EF config FK Cascade Step / Restrict Dept+InnerStep + Migration 20 AddContractWorkflowInnerStepsAndAlterDeptApprovalUnique GỘP 1 (CREATE TABLE WorkflowStepInnerSteps + ALTER InnerStepId + DropIndex old + Recreate filtered legacy WHERE InnerStepId IS NULL + new filtered N-stage WHERE InnerStepId IS NOT NULL + 3 IX + 3 FK). Chunk B (04cf2a0) Application CQRS DTO — WorkflowStepInnerStepDto + extend WorkflowStepDto + GetWorkflowAdminOverview Include InnerSteps + DeptNames map + CreateWorkflowStepInnerStepInput + CreateWorkflowStepInput extend (default null backward compat) + Validator child rules + Handler atomic batch insert. Chunk C (e247b67) ContractWorkflowService refactor mirror PE — load definition InnerSteps eager, reject branch clear N-stage rows tại fromPhase, dept approval block split hasInnerSteps→N-stage logic / else→legacy 2-stage. N-stage flow giống PE: yêu cầu actor có DeptId+PositionLevel, match firstPending Order asc + (exact level OR canBypass + level≥), exact upsert 1 row InnerStepId, bypass batch upsert NV+PP+TP cùng dept ≤ actor (audit IsBypassed cho cấp dưới), recheck stillPending → BLOCK + log "duyệt cấp X (còn Y pending)". Chunk D (7c0772a) Tests 6 N-stage Contract mirror PE pattern + helper SeedWorkflowDefinitionAsync 2 step adjacent (DangGopY + DangDamPhan) + SeedContractAsync với Project + Supplier seed + FakeChangelogService + FakeContractCodeGenerator stubs. Bug fix: legacy fallback test ban đầu fail (Standard policy DangGopY → DangDamPhan chỉ cho [Drafter, DeptManager], không Procurement) → switched phase pair sang DangKiemTraCCM → DangTrinhKy + role CostControl khớp. Total 89 → 95 test pass. Chunk E SKIP — WorkflowsController auto-bind [FromBody] CreateWorkflowDefinitionCommand record qua JSON, no code change cần. Chunk F (current) FE-Admin types/users.ts đã có PositionLevel const từ Session 12 reuse. WorkflowsPage Designer extend mirror PeWorkflowsPage Chunk F: InnerStepDto + EditInnerStep types + copyFromDefinition include + departmentsList query + sub-section "Cấp duyệt nhỏ trong phòng" drag-list { Phòng × Cấp + required } + button "+ Thêm cấp duyệt" emerald + payload include Order asc. Empty state hint fallback 2-cấp legacy. KHÔNG đụng fe-user (admin-only). Docs/Skill update. Backward compat 100%: workflow Contract no InnerSteps → fallback legacy 2-stage Mig 16. Data legacy InnerStepId=null vẫn enforce unique cũ qua filtered index. Defer Budget mirror cho session sau (cần migration AddBudgetVersionedWorkflow trước). |
951ffa3 (A) · 04cf2a0 (B) · e247b67 (C) · 7c0772a (D) · (current F) |
| 2026-05-07 | Claude | 🎯 SESSION 12 — N-stage workflow approval Phòng × PositionLevel cấu hình động (PE-only first, 6 commit per-chunk + Mig 18+19) — User yêu cầu mở rộng từ 2-stage Mig 16 (NV.Review/TPB.Confirm) sang N-stage cấu hình động: mỗi WorkflowStep cha (= 1 phase) có thể cấu hình chuỗi InnerSteps con theo Department × PositionLevel với Order sequential. Spec defaults chốt 6 câu (PositionLevel int 1=NV/2=PP/3=TP, sequential pure, bypass cùng dept TP skip NV+PP, smart reject reset N-stage rows về DangSoanThao, PE-only first, designer 1 sub-section InnerSteps). 6 chunk per-commit (build + ef + test pass mỗi chunk per feedback_per_chunk_commit.md): Chunk A (13ab533) Domain enum PositionLevel (NV/PP/TP) + entity PurchaseEvaluationWorkflowStepInnerStep + ALTER User.PositionLevel int? + ALTER PEDeptApprovals.InnerStepId Guid? + EF config + Migration 18 AddPeWorkflowInnerStepsAndPositionLevel (1 CREATE TABLE + 2 ALTER + 3 index + FK Cascade Step / Restrict Dept/InnerStep). 3-file rule. Chunk B (0e56bd0) Application CQRS DTO — PeWorkflowStepInnerStepDto + extend PeWorkflowStepDto + CreatePeWorkflowStepInnerStepInput (default null backward compat existing PeWorkflowAdminTests) + Validator child rules + Handler atomic batch insert + UserDto +PositionLevel field + SetUserPositionLevelCommand mirror SetBypassReview. Chunk C (0c62e24) Service N-stage logic — Migration 19 AlterPeDeptApprovalsUniqueFilteredForInnerSteps (filtered unique: legacy WHERE InnerStepId IS NULL + N-stage WHERE InnerStepId IS NOT NULL) cho phép multi-row cùng dept khác inner step. PurchaseEvaluationWorkflowService refactor: load definition InnerSteps eager + reject branch clear N-stage rows + dept block split hasInnerSteps→N-stage logic / else→legacy 2-stage. N-stage flow: yêu cầu actor có DeptId+PositionLevel, match firstPending (Order asc IsRequired) same dept + (exact level OR canBypass + level≥), exact match upsert 1 row InnerStepId, bypass batch upsert NV+PP+TP cùng dept ≤ actor level (audit IsBypassed cho cấp dưới skip), recheck stillPending → BLOCK + log "duyệt cấp X (còn Y pending)" / all done → fall through phase transition. Backward compat: workflow no InnerSteps fallback legacy + InnerStepId=null filter unique cũ vẫn enforce. Chunk D (3d76c6b) Tests N-stage 6 test mới (NV first blocks / 3-level sequential pass / TP bypass skips / wrong dept throws 403 / reject clears rows / legacy fallback no inner) + IdentityFixture extend +positionLevel arg + helper SeedWorkflowDefinitionAsync 2 step adjacent (ChoPurchasing+ChoCCM) cho FromDefinition build transition policy guard pass. Total 83→89 test pass. Chunk E (83ffabd) API PATCH /users/{id}/position-level mirror SetBypassReview pattern + body {positionLevel:int?} Authorize Users.Update. Chunk F (current) FE-Admin types/users.ts +positionLevel field + PositionLevel const + Label/Short maps. PeWorkflowsPage Designer extend: InnerStepDto type + EditInnerStep type + copyFromDefinition include + departmentsList query + sub-section "Cấp duyệt nhỏ trong phòng" per step card với drag-drop list { Phòng × Cấp + required checkbox } + button "+ Thêm cấp duyệt" (xanh emerald) + payload include innerSteps Order asc. UsersPage column "Cấp" badge NV/PP/TP emerald + action button cycle null→1→2→3→null call positionLevelMut PATCH. KHÔNG đụng fe-user (admin-only feature). Docs/Skill update. PE-only first. Backward compat 100%: workflow no InnerSteps + data legacy 2-stage rows không phá. |
13ab533 (A) · 0e56bd0 (B) · 0c62e24 (C) · 3d76c6b (D) · 83ffabd (E) · (current F) |
| 2026-05-08 00:30 | Claude | 🎯 SESSION PHASE 2 WRAP-UP — B12-B14 PE detail polish iterate (3 commit FE-only sau wrap-up 6e7a6db) — User UAT iteration tiếp, áp rule strict verify khi rename/remove (lesson hotfix CI). 3 batch nhỏ: B12 (378c993) "Lưu" no-close (chỉ toast + invalidate, KHÔNG đóng workspace) + nút "Xóa phiếu" red bottom CHỈ Bản nháp (soft-delete IsDeleted=true qua AuditableEntity, không xóa hoàn toàn DB) + bỏ header bar workspace mode "Sửa header"/"Xóa"/"Đóng" (chuyển hết xuống bottom action bar) + Section 4 column header dùng s.supplierName thay displayName (NCC master) + Section 3 row chặn xóa NCC khi đã có quotes (hasQuotes computed) + tooltip "xóa báo giá trước". B13 (e320027) InfoTab useEffect watch [autoEdit, canEdit, ev.id, ...] → re-trigger edit mode khi pencil click phiếu khác (fix useState mount-time only) + sync values từ ev mới (tránh stale state) + Pencil "sáng lên" active state khi editingRowId === p.id (bg-brand-100 + text-brand-700 + ring-brand-300 + shadow-sm + tooltip cập nhật) + wire editingRowId={autoEditHeader ? selectedId : null} từ Workspace → PeListPanel. B14 (d2306b8) QuoteDialog bỏ checkbox "Chọn NCC này cho hạng mục" (consolidate winner ở Section 2.a NccSelectorRow, isSelected vẫn gửi BE giữ trạng thái cũ) + winner column Section 4 matrix highlight emerald (header bg-emerald-50 + ✓ prefix + cells bg-emerald-50 font-semibold cho ENTIRE column, không chỉ cell có quote) + loading overlay full-screen QuoteDialog (bg-white/70 backdrop-blur-sm + spinner ring brand-600 + text "Đang lưu báo giá…"/"Đang xóa…") + NccSelectorRow inline spinner "Đang chọn NCC + sync cột giá Section 4…" + disable Hủy/Xóa/Lưu buttons khi isSaving. Verify: npm run build × 2 app pass mỗi commit · dotnet test 83 pass (KHÔNG regression). |
378c993 (B12) · e320027 (B13) · d2306b8 (B14) |
| 2026-05-07 | Claude | 🎯 SESSION WRAP-UP S10-11+++++++ — PE Workspace UX overhaul đầy đủ (23 commit / ~3500 LOC FE + Mig 17 BE) — User UAT live mode iterate liên tục, áp rule feedback_uat_skip_verify (skip dotnet test sau mỗi chunk, push ngay). 7 batch chính: B1 (S10) PE Thao tác 2-panel workspace — leaf Pe_*_Create từ page Create header riêng → workspace 2-panel [320px_1fr] mirror HĐ Thầu phụ; PeListPanel pure picker + sticky "+ Thêm mới"; PeDetailTabs mode='workspace' ẩn Workflow/Approvals/History + Section 5 disabled "nhập khi duyệt" (4 commit). B2 (S11) Migration 17 AddManualBudgetFieldsToPeAndContract — 4 ALTER (PE + HĐ × BudgetManualName nvarchar(200) + BudgetManualAmount decimal(18,2)) cho fallback "user nhập tay khi không link Budget entity approved". Domain + EF config + App CQRS Create/Update + DTO + Validator + carry-forward CreateContractFromEvaluation. FE toggle "Nhập tay" trong PeHeaderForm + ContractCreatePage NewForm/EditForm × 2 app (5 commit). B3 (S11+) BudgetFieldRow inline editor — Section 2 "b. Ngân sách" thay FormRow tĩnh → editable component (toggle + Select OR 2 input + Save dirty + Hủy). canEdit cho cả 3 view (Workspace/Danh sách/Duyệt mode), readOnly chỉ display (3 commit). B4 (S11++) InfoTab inline edit + PeListPanel pencil hover — Section 1 "✎ Sửa" button flip display↔inputs (Tên/Địa điểm/Mô tả/Payment editable, Dự án locked). PeListPanel thêm pencil icon group-hover absolute right + URL ?editHeader=1 chain → autoEditHeader prop trigger mount-time edit (3 commit). B5 (S11+++) Workspace "new" sectioned create view — PeWorkspaceCreateView.tsx ~230 LOC layout 5 sections giống PeDetailTabs visual. S1 + S2.b editable, S3-5 LockedHint "Lưu phiếu trước". POST trigger create. Replace PeHeaderForm trong workspace mode='new' (1 commit). B6 (S11++++) Danh sách disable toàn bộ interactions — PurchaseEvaluationsListPage readOnly={true} hardcoded cho PeDetailTabs + readOnly={!pendingMe} cho PeWorkflowPanel (List view → ẩn Chuyển tiếp + show hint "Vào menu Duyệt"; Pending vẫn approve được) (2 commit). B7 (S11+++++) Lock Loại quy trình + payment preset — workspace <Select> Loại quy trình → <Input disabled> theo URL ?type=N. <Textarea> JSON Điều khoản TT → <Select> 8 preset Việt + "Khác (nhập tay)" → text input fallback (1 commit). B8 (S11++++++) Display status meta — PeDisplayStatus enum 4-5 trạng thái UI (Bản nháp / Đã gửi duyệt / Trả lại / Đã duyệt / Từ chối) gom phase chi tiết. getPeDisplayStatus() helper. Workflow timeline Panel 3 vẫn giữ phase chi tiết (1 commit). B9 (S11+++++++) Phase TraLai + pencil always visible + edit gating — Domain PurchaseEvaluationPhase thêm TraLai = 98 (giữa DaDuyet=7 + TuChoi=99). FE label/color + display status badge. isEditablePhase() helper: chỉ DangSoanThao + TraLai. PeListPanel pencil bỏ hover-only → LUÔN visible (bright khi editable / xám disabled khi không) + click guard. Workspace editableOnly filter client-side (1 commit). B10 (hotfix CI) — TS strict catch fail 2 commit B7+B8 do skip-verify (forcedPhase rename quên xóa destructuring args + unused PurchaseEvaluationType import). Update memory feedback_uat_skip_verify.md thêm exception "rename/remove → BẮT BUỘC npm run build" (1 commit). B11 (last) PE detail polish — NccSelectorRow Section 2.a thay FormRow tĩnh → Select dropdown từ ev.suppliers (Section 3 list) wire /select-winner API. Section 2.c text rõ "(chọn NCC trước)" / "(chưa nhập báo giá)". Section 3 row khi isWinner → ẩn ✏ + 🗑 (chỉ giữ ✓ active). Bottom action bar workspace mode: 2 nút "Lưu (đóng)" + "Lưu & Gửi Duyệt →" confirm dialog → POST /transitions với targetPhase = first nextPhase skip TuChoi/TraLai → workflow chuyển từ Bản nháp/Trả lại → Đã gửi duyệt (ChoPurchasing) → onBack đóng workspace (1 commit). |
ee0d360 (S10 C1) → 4c0625c (B11) — 23 commit total |
| 2026-05-07 | Claude | PE InfoTab inline edit Section 1 + PeListPanel pencil edit hover — User feedback 2026-05-07: muốn thêm nút edit kế bên row trong Panel 1, click sáng nội dung Section 1 lên cho user sửa header inline (KHÔNG cần đi "Sửa header" page). 2 chunk per-commit (build pass mỗi chunk): C1 fe-admin (3 file) — InfoTab thêm prop readOnly + autoEdit, canEdit=!readOnly && isDraft: display mode hiển thị FormRow + button "✎ Sửa" góc trên phải, editing mode card border brand-200 + 4 input (Tên */Dự án locked/Địa điểm/Mô tả/Payment) + Save (PUT /pe/:id full payload + invalidate detail+list)/Hủy. PeListPanel thêm prop onEditClick, pencil icon absolute right-2 top-2 mỗi row, opacity-0 group-hover:opacity-100. PurchaseEvaluationWorkspacePage đọc URL ?editHeader=1 → pass autoEditHeader xuống PeDetailTabs → trigger edit auto. C2 fe-user mirror y hệt 3 file (rule §3.9). KHÔNG đụng BE. KHÔNG refactor workspace "new" mode (defer — PeHeaderForm hiện tại đủ dùng, làm thêm khi user feedback). |
5a89dd2 (C1) · (current C2) · (current C3 docs) |
| 2026-05-07 | Claude | PE BudgetFieldRow inline editor — toggle + 2 fields trong Section 2 (cả 3 view) — User feedback after Session 11: muốn toggle "Nhập tay" + 2 input fields hiển thị trực tiếp trong Section 2 "b. Ngân sách" của PeDetailTabs — KHÔNG chỉ ở "Sửa header" page, mà cả 3 view (Workspace / Danh sách / Duyệt). Empty values cứ hiển thị empty (không text "(chưa link)" verbose). 2 chunk mirror per-commit (build pass mỗi chunk): C1 fe-admin BudgetFieldRow component (~125 LOC) thay FormRow tĩnh ở b. Ngân sách. canEdit=!readOnly && isDraft: render toggle + Select Budget OR 2 input grid 2-col + nút "Lưu ngân sách" (chỉ hiện khi dirty) + "Hủy thay đổi". Save: full PUT /pe/:id với current entity values + new budget payload. Read-only mode (Duyệt + !isDraft): chỉ display, KHÔNG toggle/inputs, empty hiển thị "—". C2 fe-user mirror y hệt 1 file (rule §3.9). Mỗi chunk: build pass + 0 TS error. KHÔNG đụng BE — re-use existing PUT endpoint. |
19712d8 (C1) · d5c6f12 (C2) · (current C3) |
| 2026-05-07 | Claude | Migration 17 — manual budget fields fallback cho PE + HĐ (toggle "Nhập tay") — User feedback: khi project chưa có Budget approved (Phase=DaDuyet eligible), user phải break flow đi tạo Budget + duyệt + quay lại link. UX kém. Solution: thêm fallback "Nhập tay" — checkbox toggle cạnh Label Ngân sách, khi ON → hide Select Budget, show 2 input field grid 2-col (Tên tham chiếu text + Số tiền number formatted VND). Lưu trên entity row, KHÔNG cần Budget entity. Q1-3 chốt: 1 = stick-toggle reveal 2 input fields; 2 = cả BudgetId + manual fields cùng null OK (KHÔNG XOR validate); 3 = mirror logic sang HĐ luôn (cả 7 ContractType qua ContractCreatePage). 5 chunk per-commit (build + 83 test pass mỗi chunk): C1 Migration 17 AddManualBudgetFieldsToPeAndContract 4 ALTER (PE + HĐ × Name nvarchar(200) + Amount decimal(18,2)) + Domain 2 entity + 2 EF config (HasMaxLength + HasPrecision) — applied LocalDB OK, 3-file rule. C2 App CQRS — CreatePurchaseEvaluationCommand + Update + DTO + Validator (>=0 when has value), CreateContractCommand + Update + DTO + diff log audit, CreateContractFromEvaluation carry forward pe.BudgetManualName/Amount → contract khi gen HĐ từ phiếu. C3 FE-Admin — types +2 field, PeHeaderForm toggle + 2 input + payload conditional (manual mode clear budgetId, link mode clear manual), PeDetailTabs Section "b. Ngân sách" fallback display "Tên · Số tiền + badge nhập tay" khi !budget + có manual data, refactor PurchaseEvaluationCreatePage wrap PeHeaderForm DRY (222→30 LOC), ContractCreatePage NewContractForm + EditContractForm cùng pattern + read-only display branch khi !isDraft. C4 fe-user mirror y hệt 6 file. C5 docs (this row + HANDOFF + session log). KHÔNG đụng Budget entity / Phase=DaDuyet validation (giữ invariant). |
ecd5f7e (C1) · 0f7901c (C2) · bab5031 (C3) · 14f8d9d (C4) · (current C5) |
| 2026-05-07 | Claude | PE "Thao tác" 2-panel workspace + Panel 1 read-only picker + Section 5 disabled — User chỉ thị restructure leaf "Thao tác" (Pe_DuyetNcc_Create + Pe_DuyetNccPhuongAn_Create) từ page tạo header riêng (/purchase-evaluations/new?type=N — chỉ form Tên/Project/Địa điểm/Payment/Budget) sang workspace 2-panel mirror pattern HĐ Thầu phụ ContractCreatePage. 5 câu chốt spec trước code: Q1 Panel 2 KHÔNG render Workflow Panel + Approvals + History (chỉ data entry); Panel 1 = pure picker, KHÔNG inline edit/delete; Q2 mirror HĐ Thầu phụ pattern (sticky "+ Thêm mới" + Panel 2 transition new→edit form); Q3 leaf "Danh sách" + "Duyệt" giữ 3-panel hiện tại; Q4 route mới /purchase-evaluations/workspace?type={1|2}; Q5 Section 5 Ý kiến 4PB disable trong workspace (vì người ta nhập khi duyệt, không phải lúc nhập liệu). 2 chunk per-commit (build + 83 test pass mỗi chunk): C1 fe-admin (3 file mới PeListPanel.tsx ~180 LOC pure picker reuse + PeHeaderForm.tsx ~210 LOC extract + PurchaseEvaluationWorkspacePage.tsx ~120 LOC, 3 file sửa PeDetailTabs.tsx thêm prop mode?: 'detail' | 'workspace' + Section 5 hint banner amber + Layout.tsx resolver Pe_*_Create→/workspace?type=N + App.tsx route mới). C2 fe-user mirror y hệt 6 file (rule §3.9). KHÔNG đụng BE / migration / schema / endpoint. Route /new cũ giữ tồn tại cho deep-link "Sửa header" button. Total +1142 LOC FE / 0 BE / 32 FE pages. |
ee0d360 (C1) · ecf3c59 (C2) · (current C3) |
| 2026-05-04 | Claude | User Manual 7 file rewrite compact cho end-user — User feedback "ko cần quá đầy đủ chi tiết, cho end-user họ làm". Setup package.json + npm install docx@9.5.0 + script npm run gen:all. Rewrite 7 generator scripts theo style end-user friendly: BỎ field validation table 5 cột (Tên field/Kiểu/Bắt buộc/Validation/Ví dụ), BỎ error troubleshoot table 3 cột (Lỗi/Nguyên nhân/Cách xử lý), BỎ FAQ chi tiết 8 câu (giữ 1 chương "Khi gặp lỗi" 4-5 bullet), BỎ phím tắt table. GIỮ: tổng quan ngắn 1-2 câu mỗi chức năng, numbered steps đơn giản 3-7 bước, note/warn/tip chỉ critical, bullet liệt kê. 7 file: 01-Bat-dau (12.1KB cũ 21.7KB ↓44%) / 02-Hop-dong / 03-Duyet-Workflow (mention 2-stage NV/TPB Mig 16) / 04-PE-Phieu-Duyet-NCC (A/B + 4PB + tạo HĐ) / 05-Budget / 06-7-Loai-HD-Cheatsheet / admin-02-Quan-ly-Users-Roles (mention bypass review S9). Refactor user-01 dùng _helpers.js shared (trước có helpers inline 793 dòng, giờ ~110 dòng). Tổng output ~86KB / 7 file (cũ ~123KB ↓30%). |
16c2c9c |
| 2026-05-04 | Claude | Optional polish — fe-user Inbox thêm section "Phiếu Duyệt NCC chờ tôi" — User chỉ thị "tiếp tục plan tổng" → pick task không blocked. useQuery thứ 2 cho /purchase-evaluations/inbox (endpoint có sẵn), peRows filter theo search. Stats overdue/dueSoon đếm cả PE rows (totalValue chỉ HĐ vì PE không có giá trị). Panel 1 chia 2 section sticky header: "Hợp đồng (N)" giữ behavior cũ click → inline detail Panel 2; "Phiếu Duyệt NCC (M)" click → navigate /purchase-evaluations/:id page riêng (PE entity shape khác Contract, không inline). EmptyState mới: "Không có HĐ hoặc Phiếu Duyệt NCC nào chờ". Chỉ fe-user (Drafter + TPB dùng Inbox) — fe-admin defer. Build pass. |
332a90f |
| 2026-05-04 | Claude | Audit định kỳ 2026-05 (combined skill + doc drift theo §6.4 + §9.4) — Cron solution-erp-skill-audit-monthly empty (No scheduled jobs), trễ 4 ngày so schedule 2026-05-01 → manual trigger sau Session 9 close. Phase 1 cross-check counts: tests=83, migrations=16, gotchas=41, skills=6, STATUS rows=12 (<30 chưa archive) — toàn bộ khớp. Drift patches 5 file: docs/CLAUDE.md (52→55 bảng + §14 DepartmentApprovals), docs/rules.md (Phase 8→9, 77→83 test), docs/architecture.md (77→83 test 2 chỗ), .claude/skills/ef-core-migration (77→83 + ghi 6 PE 2-stage), .claude/skills/dependency-audit-erp (26+→41 bẫy). Phase 2 skill staleness: contract-workflow thêm "Phase 9 cross-ref Mig 16" block + section "Phase 9 done" (2-stage + smart reject + lock edit + bypass). KHÔNG tạo skill mới (§9.5 anti-pattern "viết skill chỉ để có thêm" — pattern 2-stage đủ generic, đã ghi đủ Domain/Service/6 test reusable). Cron recreate SKIP (CronCreate Claude SDK auto-expire 7 days, không fit monthly cadence). Audit log docs/changelog/skill-audit-2026-05.md (1 page). 6 file ~+30/~12 line patch, validation §6.5 OK. |
7dc0233 |
| 2026-05-04 | Claude | Session 9 — Chunk E-bis complete: FE 2-stage panel + UserManager bypass toggle + HĐ/Budget 2-stage mirror PE + 6 test + IdentityFixture — User chỉ thị "làm hết cho xong tính năng luôn". 5 chunk per-commit (build + 83 test pass mỗi chunk): (E2) FE PeWorkflowPanel section "Tiến trình duyệt 2-cấp phòng ban" group by phase × dept, highlight amber chờ TPB, badge fuchsia bypass — cả 2 app (rule §3.9). (E3) FE UsersPage column "Bypass" + ShieldCheck toggle button + UserDto.CanBypassReview field. (E4) ContractWorkflowService thêm UserManager DI + mirror 2-stage logic từ PE + ContractDepartmentApprovalFeatures.cs (List query) + endpoint GET /contracts/{id}/department-approvals + FE WorkflowHistoryPanel section. (E5) Budget mirror đầy đủ — TransitionBudgetCommandHandler thêm INotificationService + IDateTime DI + 2-stage logic + BudgetDepartmentApprovalFeatures.cs + endpoint + FE BudgetWorkflowPanel. (E6) IdentityFixture setup ServiceProvider với Identity stack đầy đủ (DbContext SQLite + AddIdentityCore + AddRoles + EF stores) + 6 test PE 2-stage: NV_Review_Blocks / TPB_Confirm_Allows / NV_Bypass / Admin_Skip / Reject_Sets_RejectedFromPhase / Resume_Jumps_Back. Tests Contract + Budget skip vì logic identical PE, ROI thấp. Total 77→83 test pass. 5 commit pushed lên Gitea. |
f8eebd5 (E2) · 4380bdc (E3) · b6f5a16 (E4) · 1fc439b (E5) · 8353fe8 (E6) · (current E7) |
| 2026-05-04 | Claude | Session 8 — Migration 16: 2-stage dept approval + smart reject + lock edit (đóng bug anh Kiệt) — Anh Kiệt báo: NV.PRO tạo phiếu PE → duyệt được hết phase = phân quyền sai. Schema mới: 3 bảng *DepartmentApprovals (Contract/PE/Budget) UNIQUE (TargetId, Phase, Dept, Stage). 4 cột mới: Users.CanBypassReview bit + 3 RejectedFromPhase int. Logic 2-stage trong PurchaseEvaluationWorkflowService.TransitionAsync: user.DepartmentId != null → DeptManager (TPB) Stage=Confirm; CanBypassReview=true → Stage=Confirm+IsBypassed; else NV → Stage=Review only, BLOCK transition cho đến khi TPB confirm. Smart reject: Decision=Reject → set RejectedFromPhase, force về DangSoanThao. Resume sau reject: Drafter trình lại từ DangSoanThao + RejectedFromPhase != null → jump straight tới phase đã reject (skip phase trung gian). Lock edit: 17 handler thêm guard Phase != DangSoanThao (Contract Detail × 15, PE Detail × 5, Budget Detail × 3). 3 endpoint mới: GET /pe/{id}/department-approvals (FE Workflow Panel hiển thị progress) + PATCH /users/{id}/bypass-review (admin toggle) + Notify TPB cùng dept khi NV review. HĐ + Budget 2-stage scope defer (chỉ PE first đóng bug). FE update + Tests defer Chunk E-bis. |
5fe61cc (A) · 14f3c9f (B) · 9747f8c (C) · a532ba6 (D) · (current) |
| 2026-04-30 | Claude | Session 6 — MD audit + compact + 3 skill refresh + 2 rule mới — Compact 3 file core (-288 dòng): STATUS -27%, HANDOFF -32%, migration-todos -35%. Archive 51 row Recently Done Phase 0-7 → changelog/recently-done-archive-2026-04.md. Refresh 3 skill stale: form-engine (Phase 2 MVP → Tier 3 feature-complete + bỏ section duplicate gen mã HĐ), permission-matrix (12 menu → ~60 menu key + Bg_/Pe_/PeWf_* + inheritance roots), ef-core-migration (24 DbSet → 52 bảng + ERD update). Rule mới rules.md §7 Khi nào viết test — timing rule (5-row table compact, sau khi rút gọn từ 70 dòng overkill). Rule mới rules.md §6.4 Audit + compact MD định kỳ (cadence + checklist + anti-pattern, KHÔNG rewrite toàn bộ). rules.md §9.4 Skill audit mở rộng cross-ref §6.4. |
(current) |
| 2026-04-29 | Claude | Tests Phase 3 mini + 3 gotcha CI mới (#39 #40 #41) — tests/.../Application/PeWorkflowAdminTests.cs 6 test versioning logic (CreatePeWorkflowDefinition: first version IsActive=true, second deactivates first, different EvaluationType independent, persists steps ordered + approvers per step, third version increments to v3). Total 77 test (54 Domain + 17 Infra + 6 PE WF Application). Gotcha #39 act_runner github.com TCP timeout 21s + manual checkout fix. #40 npm junction cache fail tsc not found rolled back. #41 paths-ignore behavior + workflow file exclusion. |
b874743 |
| 2026-04-29 | Claude | CI Path filter docs-only skip live — paths-ignore trong on:push lookup docs/**/**/*.md/.claude/skills/**/.gitignore. Commit chỉ touch docs SKIP CI hoàn toàn (saving ~196s/commit, ~30% commit thuộc loại này). Verify 512880c (docs-only) → Gitea NO trigger run #113. |
29eb5d9 · a21790d · 512880c |
| 2026-04-29 | Claude | CI manual checkout bypass github.com (fix #108/#109) — Run #108/#109 fail TCP timeout 21s khi act_runner fetch actions/checkout@v4 từ github.com. Replace uses: actions/checkout@v4 + actions/upload-artifact@v4 bằng manual git init + git fetch từ Gitea internal. Token ${{ github.token }} auth tự sẵn per-job. Fetch by ref + depth=30. Run #110 pass 3m16s. |
14b7d18 · 26075c4 |
| 2026-04-29 | Claude | Tests Phase 2 — Code generator format + sequence (SQLite in-memory) — tests/SolutionErp.Infrastructure.Tests/ xUnit + EF SQLite 10. SqliteDbFixture + TestApplicationDbContext subclass override nvarchar(max) → TEXT (SQLite không support max). 17 test: ContractCodeGenerator (format RG-001 5 type + Framework year scope vs Project scope + sequence per prefix + year boundary reset + persistence verify) + PurchaseEvaluationCodeGenerator (format A/B + 3-digit pad + independent A/B sequences + year boundary). CI gate +1 step. Total 71 test pass / 2.1s. |
df5988b |
| 2026-04-29 | Claude | Tests Phase 1 — Domain unit tests + CI gate — tests/SolutionErp.Domain.Tests/ xUnit 2.9 + FluentAssertions 7.2 (pin trước v8 commercial). 54 test pure function (no DB/IO): WorkflowPolicy (Standard 9-phase + SkipCcm 7-phase + Registry per ContractType + FromDefinition versioned + UserKindApprover) / PEPolicy (NccOnly 3-step + NccWithPlan 5-step + reject paths) / BudgetPolicy (Default 3-step + terminals + SLA spec). .gitea/workflows/deploy.yml thêm step "Run unit tests" trước build, fail → exit $LASTEXITCODE → no deploy. SolutionErp.slnx + folder /tests/. |
d3f9346 |
| 2026-04-29 | Claude | PE Workflow designer admin UI + Ý kiến 4 phòng ban — Migration 15 AddPurchaseEvaluationDepartmentOpinions (UNIQUE PEId+Kind, 1 row/phòng/phiếu). Domain PurchaseEvaluationDepartmentOpinion + enum PeDepartmentKind (PheDuyet/Ccm/MuaHang/SmPm). BE: PeWorkflowAdminFeatures.cs ~250 LOC mirror Contract pattern (GetOverview + Create version, deactivate cũ atomic) + PeWorkflowsController 2 endpoint reuse policy Workflows.*. PeDepartmentOpinionFeatures.cs Upsert (sign=true→set SignedAt+UserId, sign=false giữ chữ ký cũ) + Delete + 2 endpoint. FE: PeWorkflowsPage.tsx ~500 LOC + designer dialog (clone version + add/remove steps + +Role/+User approvers). Section "5. Ý kiến 4 phòng ban (sign-off)" 2x2 grid OpinionBox (read mode chữ ký vs edit textarea + 2 button Lưu/Lưu&Ký). |
5d94bb4 |
| 2026-04-29 | Claude | PE Detail UI restructure theo spec form PHIẾU TRÌNH KÝ — 4 section đánh số match form chính thức: "1. Thông tin gói thầu" (a/b chỉ Tên + Dự án) / "2. Chọn NCC/TP" (a NCC chọn / b Ngân sách / c Giá chào thầu auto-compute từ winner quotes / d Bản so sánh embed GeneralAttachments) / "3. NCC/TP tham gia" / "4. Hạng mục + Báo giá". FormRow helper (label 176px + value flex) thay cho dl grid 2-col cũ. | 7e36241 |
| 2026-04-29 | Claude | PE/Contract → Budget integration + cột "So với ngân sách" — BE: BudgetSummaryDto shared (PE & Contract DetailBundle), Create/Update PE+Contract commands + BudgetId? validate cùng Project + Phase=DaDuyet. CreateContractFromEvaluation carry forward pe.BudgetId → contract.BudgetId. FE: PE & Contract Create form + Select "Ngân sách" filter Phase=DaDuyet + Project match. PE InfoTab + Contract Edit display Budget link clickable. PE ItemsTab matrix + cột "NS link · Δ" — match per-row qua key groupCode|itemCode, fetch /budgets/{id} riêng + footer aggregate (xanh dưới / đỏ vượt / xám khớp). |
61e5d4d |
| 2026-04-29 | Claude | Budget FE 3-panel pages cả 2 app — types/budget.ts (BudgetPhase 5-state enum + DTO) + BudgetsListPage 3-panel [340px_1fr_360px] + filter Phase + Năm + alias ?phase=Pending + readOnly mode menu Duyệt + BudgetCreatePage form Header + BudgetDetailTabs flat (Section Thông tin Header + Section Hạng mục table CRUD inline auto-compute ThanhTien=KL×ĐG) + BudgetWorkflowPanel Panel 3 timeline + dialog comment + Approvals/Changelog. Mirror fe-user. App.tsx 3 route + Layout resolver Bg_*. TS build pass cả 2 app. |
df12fb1 |
51 row Phase 0-7 (2026-04-21..28) đã archive →
changelog/recently-done-archive-2026-04.md
Session logs: P0 · P1f · P1.2 · P2 · P3 · P4 · P5prep · Tier 3 · Skill gov · Toolkit+4-bảng+Roles VN · Roles+Demo+Pending · PE polish iter 2 + rebrand · Budget BE + 14 Solutions users · Budget FE + PE/HD-Budget + PE WF Designer + Tests Phase 1-2
Docs entry points:
rules.md·architecture.md·HANDOFF.mdworkflow-contract.md·forms-spec.mddatabase/database-guide.md·database/schema-diagram.mdflows/(7 file) ·guides/(4 file) ·gotchas.mdchangelog/migration-todos.md·changelog/sessions/(17 file).claude/skills/README.md— 6 skill (3 domain + 3 ops) · audit định kỳ 1/tháng (cronsolution-erp-skill-audit-monthlynext 2026-05-01)
🎯 Next up
Hard blockers (chờ user / ops)
- UAT 1 tuần 2-3 user thật — hard requirement từ roadmap Phase 5
- Email outbox — MailKit + SMTP (BLOCKED chờ user cấp SMTP host/user/pass)
- Rotate credentials — SA, vrapp, JWT secret, runner token (đã post chat)
- SQL backup daily — Task Scheduler (script
scripts/backup-sql.ps1đã có, chưa schedule)
Optional polish (khi rảnh / UAT phát sinh)
- Roles CRUD — admin tạo custom role ngoài 12 hardcoded (schema sẵn, chỉ cần CQRS + FE)
- User-level approver targeting runtime — data model đã có (
WorkflowStepApprover.Kind=User), chỉ cần wire User-kind vàoContractWorkflowService.TransitionAsyncguard - PermissionsPage: grant
Workflows.Readcho non-admin role → menu Wf_* visible - Warning notification khi còn 20% SLA (
SlaWarningSentflag đã có, chỉ thiếu job emit) - E2E test reject → quay về DangSoanThao (multi-role)
- Dependencies scan CI (
dotnet list package --vulnerable,npm audit)
Tier 3 ERP roadmap ✓ (close)
- Attachment upload BE + FE ✓
- SignalR real-time push ✓
- Form template builder CRUD + DynamicForm ✓
- PDF export qua LibreOffice headless ✓
- .doc/.xls → .docx/.xlsx auto-conversion ✓
- Dynamic workflow policy per ContractType ✓
- Versioned workflow (WorkflowDefinition pinned per Contract) ✓
- Admin workflow designer UI (per-type, per-step approvers) ✓
- Nested sidebar menu per ContractType (fe-user) + menu split admin/user ✓
- PermissionsPage 3-panel layout ✓
- Email outbox for Notification (blocked — SMTP config)
📊 Thông số cumulative
| P0 | P1f | P1.2 | P2 | P3 | P4 | P5prep | Tier3 | +Toolkit | +RolesPg+Demo | +PE module | +PE polish | +Budget+30 users | +Session 5 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| BE LOC | 0 | ~400 | ~1500 | ~1900 | ~2700 | ~3100 | ~3300 | ~4800 | ~7800 | ~8800 | ~11100 | ~11400 | ~11750 | ~13050 (+1300 PE WF Designer + Opinion + Budget integration) |
| DB tables | 0 | 7 | 12 | 14 | 19 | 19 | 19 | 24 | 36 | 36 | 46 | 47 | 51 | 52 (+1 PEDepartmentOpinions) |
| API endpoints | 0 | 4 | 20 | 23 | 31 | 33 | 35 | ~50 | ~80 | ~93 | ~110 | ~113 | ~124 | ~128 (+2 PE WF + 2 Opinion) |
| Migrations | 0 | 1 | 3 | 4 | 5 | 5 | 5 | 8 | 11 | 11 | 12 | 13 | 14 | 15 (AddPEDepartmentOpinions) |
| FE pages | 0 | 2 | 6 | 7 | 14 | 16 | 16 | ~20 | ~22 | ~23 | ~26 | ~26 | ~26 | ~31 (+5 Budget × 2 app + PeWorkflowsPage) |
| FE components | — | — | — | — | — | — | — | many | many+ | +EditRowDialog | +PE 5-tab | +Compare section | — | +Budget tabs/panel + PE OpinionBox + PE 4-section restructure |
| Scripts PS | 0 | 0 | 0 | 1 | 1 | 1 | 3 | 4 | 4 | 5 | 5 | 6 | 6 | 6 |
| CI/CD workflow | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1+test gate+path filter+manual checkout |
| Tests | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 77 (54 Domain + 17 Infra + 6 PE WF Application) |
| Docs | 10 | 13 | 14 | 24 | 26 | 30 | 35 | ~40 | ~42 | ~44 | ~46 | ~48 | ~50 | ~52 (+session log + Test plan) |
| Demo data | 0 | 0 | empty | 0 | 0 | 0 | 0 | 0 | 5+3 | 15+8+7+13+4 | +PE 4 phiếu | +rebrand email | 30 user | 30 user |
| Commits | 1 | 2 | 3 | 5 | 6 | 7 | 8 | ~25 | ~47 | ~52 | ~63 | ~70 | ~75 | ~82 (+6 session 5) |
🚨 Blockers / risks
- ⚠️ Email SMTP chưa có — blocker cho notification outbound
- ⚠️ UAT real user chưa chạy — risk phát sinh bug edge-case quan trọng
- ⚠️ Credentials leaked trong chat — cần rotate trước go-live thật
- ⚠️ SQL backup không auto — risk data loss nếu VPS crash
- ⚠️ Permission
Workflows.Readcho non-admin — cần grant để họ thấy menu Wf_* (hiện chỉ admin thấy) - ⚠️ User-kind approver chưa enable runtime — designer cho chọn User nhưng guard fall back DeptManager
Credentials + URLs
admin@solutionerp.local / Admin@123456
- API prod: https://api.solutions.com.vn — Health
/health/live+/health/ready - API dev: http://localhost:5443 — Swagger
/swagger - Admin FE prod: https://admin.solutions.com.vn · dev
http://localhost:8082 - User FE prod: https://eoffice.solutions.com.vn · dev
http://localhost:8080 - SQL prod:
.\SQLEXPRESS/SolutionErp/vrapp - SQL dev:
(localdb)\MSSQLLocalDB/SolutionErp_Dev