@longph2102/v-flow 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +265 -0
- package/CHANGELOG.md +318 -0
- package/LICENSE +21 -0
- package/README.md +326 -0
- package/agents/ba-agent.md +437 -0
- package/agents/ba-critic-agent.md +156 -0
- package/agents/ba-to-ptyc-agent.md +112 -0
- package/agents/bugfix-analyst-agent.md +221 -0
- package/agents/constitute-agent.md +155 -0
- package/agents/help-agent.md +168 -0
- package/agents/implement-agent.md +220 -0
- package/agents/import-ba-docs-agent.md +164 -0
- package/agents/master-check-agent.md +228 -0
- package/agents/metrics-agent.md +180 -0
- package/agents/operations-agent.md +123 -0
- package/agents/plan-agent.md +218 -0
- package/agents/prototype-agent.md +191 -0
- package/agents/retrospective-agent.md +196 -0
- package/agents/review-agent.md +210 -0
- package/agents/sprint-agent.md +191 -0
- package/agents/status-agent.md +186 -0
- package/agents/sync-agent.md +201 -0
- package/agents/test-agent.md +166 -0
- package/agents/understand-agent.md +339 -0
- package/cli/commands/check.js +96 -0
- package/cli/commands/dev-quiz.js +107 -0
- package/cli/commands/doctor.js +348 -0
- package/cli/commands/feature.js +259 -0
- package/cli/commands/hooks.js +163 -0
- package/cli/commands/init.js +189 -0
- package/cli/commands/log.js +199 -0
- package/cli/commands/plugin.js +230 -0
- package/cli/commands/score-card.js +203 -0
- package/cli/commands/status.js +269 -0
- package/cli/commands/sync.js +59 -0
- package/cli/commands/upgrade.js +150 -0
- package/cli/commands/validate.js +1259 -0
- package/cli/commands/watch.js +151 -0
- package/cli/index.js +46 -0
- package/cli/lib/ac-test-gate.js +89 -0
- package/cli/lib/activity-log.js +209 -0
- package/cli/lib/cli-error.js +183 -0
- package/cli/lib/constitution-lint.js +561 -0
- package/cli/lib/dev-quiz-grade.js +127 -0
- package/cli/lib/governance.js +78 -0
- package/cli/lib/hook-targets.js +167 -0
- package/cli/lib/i18n.js +375 -0
- package/cli/lib/knowledge-oracle.js +379 -0
- package/cli/lib/logger.js +203 -0
- package/cli/lib/module-card-lint.js +304 -0
- package/cli/lib/module-card-score.js +223 -0
- package/cli/lib/plugins.js +481 -0
- package/cli/lib/scanner.js +692 -0
- package/cli/lib/sync-core.js +232 -0
- package/cli/lib/sync-targets.js +84 -0
- package/cli/lib/templates.js +268 -0
- package/cli/lib/yaml-parser.js +203 -0
- package/commands/v.ba-critic.md +101 -0
- package/commands/v.ba-to-ptyc.md +71 -0
- package/commands/v.bugfix.md +86 -0
- package/commands/v.check.md +131 -0
- package/commands/v.constitute.md +87 -0
- package/commands/v.constitution.md +84 -0
- package/commands/v.fork.md +127 -0
- package/commands/v.help.md +73 -0
- package/commands/v.hotfix.md +200 -0
- package/commands/v.implement.md +92 -0
- package/commands/v.import-ba-docs.md +222 -0
- package/commands/v.metrics.md +74 -0
- package/commands/v.operations.md +70 -0
- package/commands/v.plan.md +78 -0
- package/commands/v.prototype.md +121 -0
- package/commands/v.quickfix.md +169 -0
- package/commands/v.retrospective.md +80 -0
- package/commands/v.review.md +78 -0
- package/commands/v.rewind.md +127 -0
- package/commands/v.specify.md +118 -0
- package/commands/v.sprint.md +75 -0
- package/commands/v.status.md +62 -0
- package/commands/v.sync.md +81 -0
- package/commands/v.test.md +67 -0
- package/commands/v.understand.md +112 -0
- package/package.json +65 -0
- package/skills/_shared/constitution-reader/SKILL.md +109 -0
- package/skills/_shared/constitution-reader/config.json +52 -0
- package/skills/_shared/constitution-reader/examples/good/b1-phase-output.md +48 -0
- package/skills/_shared/constitution-reader/gotchas.md +46 -0
- package/skills/_shared/context-reader/SKILL.md +111 -0
- package/skills/_shared/context-reader/config.json +54 -0
- package/skills/_shared/context-reader/examples/good/legacy-nodejs-output.md +35 -0
- package/skills/_shared/context-reader/gotchas.md +49 -0
- package/skills/_shared/ears-notation/SKILL.md +63 -0
- package/skills/_shared/ears-notation/config.json +55 -0
- package/skills/_shared/ears-notation/examples/good/plan-test-interpretation.md +29 -0
- package/skills/_shared/ears-notation/gotchas.md +43 -0
- package/skills/check/cross-validator/SKILL.md +206 -0
- package/skills/check/cross-validator/config.json +33 -0
- package/skills/check/cross-validator/examples/good/validation-report-pass-with-concerns.md +105 -0
- package/skills/check/cross-validator/gotchas.md +43 -0
- package/skills/implement/constitution-enforcer/SKILL.md +134 -0
- package/skills/implement/constitution-enforcer/config.json +16 -0
- package/skills/implement/constitution-enforcer/examples/bad/vague-report.md +42 -0
- package/skills/implement/constitution-enforcer/examples/good/compliance-report.md +57 -0
- package/skills/implement/constitution-enforcer/gotchas.md +26 -0
- package/skills/implement/constitution-enforcer/scripts/check-constitution.sh +88 -0
- package/skills/implement/no-go-zone-guard/SKILL.md +173 -0
- package/skills/implement/no-go-zone-guard/config.json +28 -0
- package/skills/implement/no-go-zone-guard/examples/good/adapter-workaround.md +46 -0
- package/skills/implement/no-go-zone-guard/gotchas.md +27 -0
- package/skills/implement/no-go-zone-guard/scripts/check-nogo-zones.sh +148 -0
- package/skills/implement/no-go-zone-guard/scripts/nogo-precommit.sh +96 -0
- package/skills/implement/tdd-driver/SKILL.md +159 -0
- package/skills/implement/tdd-driver/config.json +33 -0
- package/skills/implement/tdd-driver/examples/good/tdd-cycle-product-repo.md +81 -0
- package/skills/implement/tdd-driver/gotchas.md +34 -0
- package/skills/metrics/metrics-collector/SKILL.md +133 -0
- package/skills/metrics/metrics-collector/config.json +16 -0
- package/skills/metrics/metrics-collector/examples/bad/incomplete-report.md +48 -0
- package/skills/metrics/metrics-collector/examples/good/full-metrics-report.md +101 -0
- package/skills/metrics/metrics-collector/gotchas.md +26 -0
- package/skills/operations/incident-runbook/SKILL.md +167 -0
- package/skills/operations/incident-runbook/config.json +21 -0
- package/skills/operations/incident-runbook/examples/bad/vague-incident-report.md +48 -0
- package/skills/operations/incident-runbook/examples/good/p1-hotfix-response.md +119 -0
- package/skills/operations/incident-runbook/gotchas.md +26 -0
- package/skills/plan/architecture-designer/SKILL.md +228 -0
- package/skills/plan/architecture-designer/config.json +32 -0
- package/skills/plan/architecture-designer/examples/bad/vague-plan.md +62 -0
- package/skills/plan/architecture-designer/examples/good/expand-contract-migration.md +56 -0
- package/skills/plan/architecture-designer/examples/good/plan-structure.md +58 -0
- package/skills/plan/architecture-designer/gotchas.md +45 -0
- package/skills/plan/task-breakdown/SKILL.md +208 -0
- package/skills/plan/task-breakdown/config.json +26 -0
- package/skills/plan/task-breakdown/examples/bad/vague-tasks.md +77 -0
- package/skills/plan/task-breakdown/examples/good/spike-clarify-tasks.md +66 -0
- package/skills/plan/task-breakdown/examples/good/tasks-login-feature.md +111 -0
- package/skills/plan/task-breakdown/gotchas.md +39 -0
- package/skills/prototype/LOGIC.md +240 -0
- package/skills/prototype/SKILL.md +185 -0
- package/skills/prototype/UI.md +407 -0
- package/skills/prototype/config.json +104 -0
- package/skills/prototype/examples/bad/prototype-notes.md +68 -0
- package/skills/prototype/examples/good/prototype-notes-ui.md +109 -0
- package/skills/prototype/examples/good/prototype-notes.md +67 -0
- package/skills/prototype/gotchas.md +128 -0
- package/skills/prototype/scripts/check-flow-state.ps1 +112 -0
- package/skills/prototype/scripts/check-flow-state.sh +104 -0
- package/skills/prototype/scripts/check-prototype-cleanup.ps1 +124 -0
- package/skills/prototype/scripts/check-prototype-cleanup.sh +109 -0
- package/skills/prototype/scripts/check-prototype-notes.ps1 +107 -0
- package/skills/prototype/scripts/check-prototype-notes.sh +102 -0
- package/skills/review/adversarial-reviewer/SKILL.md +137 -0
- package/skills/review/adversarial-reviewer/config.json +32 -0
- package/skills/review/adversarial-reviewer/examples/good/review-report-template.md +56 -0
- package/skills/review/adversarial-reviewer/gotchas.md +46 -0
- package/skills/review/adversarial-reviewer/scripts/quick-security-scan.sh +52 -0
- package/skills/specify/ba-bpmn-doc-gen/SKILL.md +108 -0
- package/skills/specify/ba-bpmn-doc-gen/reference/reference-bpmn-generation.md +528 -0
- package/skills/specify/ba-bpmn-doc-gen/reference/reference-drawio-flowchart.md +466 -0
- package/skills/specify/ba-critic/SKILL.md +172 -0
- package/skills/specify/ba-critic/config.json +32 -0
- package/skills/specify/ba-critic/examples/good/critic-report-round1.md +51 -0
- package/skills/specify/ba-critic/gotchas.md +40 -0
- package/skills/specify/ba-critic/scripts/check-spec-quality.sh +72 -0
- package/skills/specify/ba-doc-generator/SKILL.md +102 -0
- package/skills/specify/ba-doc-generator/references/template-clevel.md +84 -0
- package/skills/specify/ba-doc-generator/references/template-compliance.md +83 -0
- package/skills/specify/ba-doc-generator/references/template-dev.md +138 -0
- package/skills/specify/ba-doc-generator/references/template-partner.md +167 -0
- package/skills/specify/ba-doc-generator/references/template-pm.md +92 -0
- package/skills/specify/ba-doc-generator/references/template-review.md +114 -0
- package/skills/specify/ba-doc-generator/references/template-tester.md +108 -0
- package/skills/specify/ba-doc-generator/references/template-user.md +98 -0
- package/skills/specify/bugfix-analyst/SKILL.md +296 -0
- package/skills/specify/bugfix-analyst/config.json +41 -0
- package/skills/specify/bugfix-analyst/examples/bad/common-mistakes.md +71 -0
- package/skills/specify/bugfix-analyst/examples/good/email-validation-bugfix.md +53 -0
- package/skills/specify/bugfix-analyst/gotchas.md +51 -0
- package/skills/specify/ears-writer/SKILL.md +129 -0
- package/skills/specify/ears-writer/config.json +20 -0
- package/skills/specify/ears-writer/examples/bad/common-mistakes.md +17 -0
- package/skills/specify/ears-writer/examples/good/login-requirements.md +41 -0
- package/skills/specify/ears-writer/gotchas.md +43 -0
- package/skills/specify/ears-writer/scripts/check-ears-compliance.sh +51 -0
- package/skills/test/test-case-generator/SKILL.md +161 -0
- package/skills/test/test-case-generator/config.json +33 -0
- package/skills/test/test-case-generator/examples/good/test-cases-login.md +104 -0
- package/skills/test/test-case-generator/gotchas.md +43 -0
- package/skills/understand/ba-docs-scanner/SKILL.md +239 -0
- package/skills/understand/ba-docs-scanner/config.json +47 -0
- package/skills/understand/ba-docs-scanner/examples/good/work-order-br-extract.md +28 -0
- package/skills/understand/ba-docs-scanner/gotchas.md +44 -0
- package/skills/understand/ba-docs-scanner/merge-rules.md +47 -0
- package/skills/understand/codebase-scanner/SKILL.md +260 -0
- package/skills/understand/codebase-scanner/config.json +56 -0
- package/skills/understand/codebase-scanner/examples/good/menu-module-output.md +44 -0
- package/skills/understand/codebase-scanner/gotchas.md +42 -0
- package/skills/understand/codebase-scanner/scripts/scan-project-structure.sh +64 -0
- package/templates/DESIGN.md +456 -0
- package/templates/agent-command-template.yaml +240 -0
- package/templates/agent-config-template.md +170 -0
- package/templates/agent-definition-template.md +145 -0
- package/templates/agent-metrics-template.md +150 -0
- package/templates/api-contract-template.md +72 -0
- package/templates/bugfix-report-template.md +195 -0
- package/templates/bugfix-spec-template.md +134 -0
- package/templates/code-review-report-template.md +119 -0
- package/templates/constitution-template.md +234 -0
- package/templates/context-template.md +94 -0
- package/templates/data-model-template.md +95 -0
- package/templates/decision-log-template.md +92 -0
- package/templates/flow-state-template.yaml +208 -0
- package/templates/github/workflows/v-flow-validate.yml +30 -0
- package/templates/knowledge/adr-template.md +70 -0
- package/templates/knowledge/api-contract-template.md +140 -0
- package/templates/knowledge/domain-glossary.md +29 -0
- package/templates/knowledge/golden-tests-readme.md +115 -0
- package/templates/knowledge/lessons-learned.md +41 -0
- package/templates/knowledge/patterns.md +103 -0
- package/templates/module-card/SKILL.md +85 -0
- package/templates/module-card/api-specs.md +96 -0
- package/templates/module-card/business-quiz.md +119 -0
- package/templates/module-card/cross-service.md +125 -0
- package/templates/module-card/db.md +85 -0
- package/templates/module-card/dev-quiz.md +62 -0
- package/templates/module-card/permissions.md +83 -0
- package/templates/module-card/state-diagram.md +64 -0
- package/templates/module-card/tech-context.md +90 -0
- package/templates/module-card/ui-flows.md +91 -0
- package/templates/module-card/use-cases.md +142 -0
- package/templates/module-template.yaml +161 -0
- package/templates/operations-report-template.md +108 -0
- package/templates/plan-template.md +308 -0
- package/templates/prototype-notes-template.md +116 -0
- package/templates/ptyc/PTYC.template.docx +0 -0
- package/templates/ptyc/ptyc.meta.example.yaml +44 -0
- package/templates/retrospective-report-template.md +136 -0
- package/templates/security-review-template.md +84 -0
- package/templates/session-template.md +167 -0
- package/templates/spec-review-log-template.md +75 -0
- package/templates/spec-template.md +229 -0
- package/templates/sprint-status-template.md +101 -0
- package/templates/tasks-template.md +275 -0
- package/templates/test-cases-template.md +124 -0
- package/templates/ux-checklist-template.md +79 -0
- package/templates/validation-report-template.md +125 -0
- package/templates/vflow-config-template.yaml +22 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Mẫu Prototype Notes — ✅ Tốt (UI Branch)
|
|
2
|
+
|
|
3
|
+
> Đây là mẫu `prototype-notes.md` đúng format cho **UI branch**.
|
|
4
|
+
> Xem `good/prototype-notes.md` cho mẫu LOGIC branch.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
```markdown
|
|
9
|
+
# Prototype Notes — Feature 012: Dashboard Analytics Panel
|
|
10
|
+
|
|
11
|
+
**Date**: 2026-05-20
|
|
12
|
+
**Agent**: Prototype Agent
|
|
13
|
+
**Branch**: UI
|
|
14
|
+
**Phase**: S.1.5
|
|
15
|
+
|
|
16
|
+
## Câu hỏi được trả lời
|
|
17
|
+
|
|
18
|
+
> "Dashboard analytics panel nên hiển thị theo layout nào?
|
|
19
|
+
> REQ-U03 nêu 'user có thể xem tổng quan metrics' nhưng không chỉ định
|
|
20
|
+
> layout — sidebar metrics vs card grid vs table view đều khả thi."
|
|
21
|
+
|
|
22
|
+
**REQ refs**: REQ-U03, REQ-O01
|
|
23
|
+
|
|
24
|
+
## Sub-shape
|
|
25
|
+
|
|
26
|
+
**Sub-shape A** — Embedded vào existing route `/dashboard`
|
|
27
|
+
|
|
28
|
+
Lý do: Feature analytics panel sẽ nằm trong `/dashboard` đã có. Đặt variants
|
|
29
|
+
vào existing page để kiểm tra xem layout nào hoạt động tốt với header/sidebar
|
|
30
|
+
thật, không phải trong vacuum.
|
|
31
|
+
|
|
32
|
+
## Design source
|
|
33
|
+
|
|
34
|
+
`/DESIGN.md` — project override (tồn tại ở project root)
|
|
35
|
+
|
|
36
|
+
## Run command
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Dev server phải đang chạy (Angular)
|
|
40
|
+
ng serve
|
|
41
|
+
|
|
42
|
+
# Mở trình duyệt tại:
|
|
43
|
+
# http://localhost:4200/dashboard?variant=A ← Card Grid
|
|
44
|
+
# http://localhost:4200/dashboard?variant=B ← Sidebar Metrics
|
|
45
|
+
# http://localhost:4200/dashboard?variant=C ← Table View
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Variants
|
|
49
|
+
|
|
50
|
+
| Variant | Mô tả | Primary affordance |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| A | Card Grid — 4 metric cards across top, chart below | Glance metrics |
|
|
53
|
+
| B | Sidebar Metrics — left sidebar với numbers, main area là chart | Deep analysis |
|
|
54
|
+
| C | Table View — tất cả metrics trong sortable table, no chart | Export-friendly |
|
|
55
|
+
|
|
56
|
+
## Kết quả thực hiện
|
|
57
|
+
|
|
58
|
+
User đã flip qua 3 variants với real data (~20 phút):
|
|
59
|
+
|
|
60
|
+
- [x] **Variant A** — "Card grid trông đẹp nhưng mất quá nhiều vertical space. Chart bị đẩy xuống dưới fold."
|
|
61
|
+
- [x] **Variant B** — "Sidebar layout tốt hơn — chart luôn visible. Nhưng sidebar quá rộng trên mobile."
|
|
62
|
+
- [x] **Variant C** — "Table useful cho export nhưng không phải default view người dùng cần."
|
|
63
|
+
- [x] **Feedback quan trọng**: "Tôi muốn header của B (sidebar) nhưng sidebar collapse được trên mobile"
|
|
64
|
+
|
|
65
|
+
## Verdict
|
|
66
|
+
|
|
67
|
+
**VALIDATED** ✅
|
|
68
|
+
|
|
69
|
+
Variant B (Sidebar Metrics) được chọn làm hướng chính, với yêu cầu bổ sung:
|
|
70
|
+
sidebar phải responsive/collapsible trên mobile.
|
|
71
|
+
|
|
72
|
+
## Spec impact
|
|
73
|
+
|
|
74
|
+
- **REQ-U03**: Cần cập nhật AC: "Analytics panel dùng sidebar layout. Sidebar collapse trên màn hình < 768px."
|
|
75
|
+
- **REQ-O01**: Không thay đổi — Table View (Variant C) sẽ là secondary view/export mode
|
|
76
|
+
|
|
77
|
+
## Decisions to carry-forward → _session.md
|
|
78
|
+
|
|
79
|
+
1. **Layout pattern**: Sidebar left (240px desktop) + main chart area — không phải card grid
|
|
80
|
+
2. **Responsive**: Sidebar collapse về hamburger menu trên mobile (`< 768px`)
|
|
81
|
+
3. **Variant C insight**: Table view được giữ lại làm "Export mode" — Plan Agent cần thêm toggle
|
|
82
|
+
4. **Design token**: Dùng `--surface-secondary` từ DESIGN.md cho sidebar background
|
|
83
|
+
|
|
84
|
+
## Routing
|
|
85
|
+
|
|
86
|
+
→ Sửa REQ-U03 trong `spec.md` (thêm sidebar AC + mobile collapse AC)
|
|
87
|
+
→ Sau khi sửa spec → `/v.plan + /v.test` (song song)
|
|
88
|
+
|
|
89
|
+
## Cleanup
|
|
90
|
+
|
|
91
|
+
- [ ] Xóa `.v-flow/features/012/prototype/` sau khi Plan Agent đọc notes này
|
|
92
|
+
- [ ] Xóa `VariantA`, `VariantB`, `VariantC` components khỏi `/dashboard`
|
|
93
|
+
- [ ] Xóa `PrototypeSwitcher` khỏi `/dashboard` route
|
|
94
|
+
- [x] `prototype-notes.md` đã được ghi đầy đủ
|
|
95
|
+
- [x] `_session.md` đã được append
|
|
96
|
+
- [x] `.flow-state.yaml` đã được update: `artifacts.prototype.verdict = VALIDATED`
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Tại sao mẫu này tốt
|
|
102
|
+
|
|
103
|
+
| Điểm | Lý do |
|
|
104
|
+
|---|---|
|
|
105
|
+
| Ghi rõ **Sub-shape A** và lý do | Tránh G-005 — không tạo route mới khi có existing page |
|
|
106
|
+
| Liệt kê **3 variants với mô tả rõ** | Plan Agent hiểu design space đã được explore |
|
|
107
|
+
| **Feedback verbatim** ("Tôi muốn header của B...") | Ghi lại insight thật, không chỉ "B tốt hơn" |
|
|
108
|
+
| **Spec impact cụ thể** | BA Agent biết chính xác AC nào cần thêm |
|
|
109
|
+
| **Cleanup checklist đầy đủ** | Không để variant components rot trong codebase |
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Mẫu Prototype Notes — ✅ Tốt
|
|
2
|
+
|
|
3
|
+
> Đây là mẫu `prototype-notes.md` đúng format và đủ thông tin.
|
|
4
|
+
> Xem `bad/prototype-notes.md` để biết mẫu thiếu thông tin.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
```markdown
|
|
9
|
+
# Prototype Notes — Feature 005: Order Cancellation Flow
|
|
10
|
+
|
|
11
|
+
**Date**: 2026-05-15
|
|
12
|
+
**Agent**: Prototype Agent
|
|
13
|
+
**Branch**: LOGIC
|
|
14
|
+
**Phase**: S.1.5
|
|
15
|
+
|
|
16
|
+
## Câu hỏi được trả lời
|
|
17
|
+
|
|
18
|
+
> "State machine của Order cancellation xử lý case concurrent cancel (2 users cancel cùng 1 order) như thế nào? REQ-S02 không chỉ định behavior khi CANCELLING → CANCELLED bị race condition."
|
|
19
|
+
|
|
20
|
+
**REQ refs**: REQ-S02, REQ-E05
|
|
21
|
+
|
|
22
|
+
## Run command
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm prototype:005
|
|
26
|
+
# hoặc: tsx .v-flow/features/005/prototype/tui.ts
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Kết quả thực hiện
|
|
30
|
+
|
|
31
|
+
User đã interact với prototype ~15 phút, test các case:
|
|
32
|
+
- [x] Single user cancel → `PENDING → CANCELLING → CANCELLED` ✅
|
|
33
|
+
- [x] Cancel sau khi đã ship → correctly rejected bởi state machine ✅
|
|
34
|
+
- [x] **Concurrent cancel (2 requests)**: First request wins, second nhận `AlreadyCancellingError` ⚠️
|
|
35
|
+
- [x] Cancel order đã CANCELLED → `AlreadyCancelledError` ✅
|
|
36
|
+
|
|
37
|
+
**Phát hiện quan trọng**: `AlreadyCancellingError` case chưa được định nghĩa trong REQ-S02. Hiện prototype trả về generic error. User confirm: "Đây là behavior đúng — cần thêm vào spec."
|
|
38
|
+
|
|
39
|
+
## Verdict
|
|
40
|
+
|
|
41
|
+
**VALIDATED** ✅
|
|
42
|
+
|
|
43
|
+
State machine logic cơ bản đúng. Phát hiện 1 gap trong spec cần bổ sung.
|
|
44
|
+
|
|
45
|
+
## Spec impact
|
|
46
|
+
|
|
47
|
+
- **REQ-S02**: Cần thêm AC: "Khi order đang ở trạng thái CANCELLING, request cancel thứ hai phải nhận `AlreadyCancellingError` (HTTP 409)"
|
|
48
|
+
- **Không cần REQ mới** — là AC bổ sung cho REQ-S02 hiện có
|
|
49
|
+
|
|
50
|
+
## Decisions to carry-forward → _session.md
|
|
51
|
+
|
|
52
|
+
1. State machine pattern: Pure reducer `(OrderState, CancelAction) => OrderState` — liftable vào `OrderCancellationUseCase`
|
|
53
|
+
2. Error types cần định nghĩa: `AlreadyCancellingError`, `AlreadyCancelledError`, `ShippedOrderError`
|
|
54
|
+
3. Concurrent access: First-write-wins với optimistic lock — Plan Agent cần design DB transaction cho case này
|
|
55
|
+
|
|
56
|
+
## Routing
|
|
57
|
+
|
|
58
|
+
→ Sửa REQ-S02 trong `spec.md` (thêm AC)
|
|
59
|
+
→ Sau khi sửa spec → `/v.plan + /v.test` (song song)
|
|
60
|
+
|
|
61
|
+
## Cleanup
|
|
62
|
+
|
|
63
|
+
- [ ] Xóa `.v-flow/features/005/prototype/` sau khi Plan Agent đọc notes này
|
|
64
|
+
- [x] `prototype-notes.md` đã được ghi đầy đủ
|
|
65
|
+
- [x] `_session.md` đã được append
|
|
66
|
+
- [x] `.flow-state.yaml` đã được update: `artifacts.prototype.verdict = VALIDATED`
|
|
67
|
+
```
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Prototype Skill — Gotchas
|
|
2
|
+
|
|
3
|
+
> Cập nhật liên tục khi Agent mắc lỗi mới. Mỗi gotcha = 1 lesson learned từ thực tế.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## G-001: Prototype trước khi có câu hỏi rõ ràng
|
|
8
|
+
|
|
9
|
+
**Lỗi**: Agent bắt đầu build prototype ngay mà chưa viết rõ câu hỏi cần trả lời.
|
|
10
|
+
|
|
11
|
+
**Hậu quả**: Prototype scope creep — người dùng không biết prototype này đang kiểm tra gì, không thể ra verdict.
|
|
12
|
+
|
|
13
|
+
**Fix**: Bắt buộc ghi `# Question: ...` ở đầu README prototype TRƯỚC khi viết 1 dòng code. Nếu câu hỏi chưa rõ → hỏi user hoặc detect từ spec trước.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## G-002: Chọn sai branch
|
|
18
|
+
|
|
19
|
+
**Lỗi**: Câu hỏi về state machine nhưng tạo UI prototype. Hoặc câu hỏi về layout nhưng tạo LOGIC TUI.
|
|
20
|
+
|
|
21
|
+
**Hậu quả**: Prototype trả lời sai câu hỏi, waste toàn bộ thời gian.
|
|
22
|
+
|
|
23
|
+
**Fix**: Đọc lại SKILL.md branch selection guide. Rule of thumb: nếu câu hỏi kết thúc bằng "có đúng không?" → LOGIC; "nên trông như thế nào?" → UI.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## G-003: LOGIC branch — Trộn TUI code vào logic module
|
|
28
|
+
|
|
29
|
+
**Lỗi**: `logic.ts` có `console.log`, readline, hoặc escape codes (`\x1b[1m`).
|
|
30
|
+
|
|
31
|
+
**Hậu quả**: Logic module không portable — không thể lift vào real code sau khi prototype done.
|
|
32
|
+
|
|
33
|
+
**Fix**: Logic module phải 100% pure. TUI là thin shell bọc ngoài. `console.log` chỉ được xuất hiện trong `tui.ts`, không bao giờ trong `logic.ts`.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## G-004: UI branch — Variants chỉ khác màu
|
|
38
|
+
|
|
39
|
+
**Lỗi**: Tạo 3 variants nhưng chúng chỉ khác color scheme hoặc spacing nhỏ.
|
|
40
|
+
|
|
41
|
+
**Hậu quả**: Không phải UI prototype thật — chỉ là tweak. Không giúp user ra quyết định về structure.
|
|
42
|
+
|
|
43
|
+
**Fix**: Mỗi variant phải có **khác biệt về structure**: layout khác (sidebar vs top nav vs cards), information hierarchy khác, primary affordance khác. Nếu 2 variants quá giống → redo 1 cái với explicit constraint "no card grid" hoặc "no sidebar".
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## G-005: UI branch — Bỏ qua Sub-shape A
|
|
48
|
+
|
|
49
|
+
**Lỗi**: Luôn tạo new throwaway route (Sub-shape B) mà không xét Sub-shape A (embed trong existing page).
|
|
50
|
+
|
|
51
|
+
**Hậu quả**: Prototype chạy trong vacuum — mọi variant đều trông ổn vì không có real data, real header, real sidebar. Design issues chỉ lộ ra khi đặt trong context thật.
|
|
52
|
+
|
|
53
|
+
**Fix**: Luôn hỏi "có existing page nào có thể host variants này không?" trước khi chọn Sub-shape B. Nếu có → Sub-shape A là default.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## G-006: Scope creep — Prototype trở thành MVP
|
|
58
|
+
|
|
59
|
+
**Lỗi**: Prototype được thêm error handling, tests, abstractions, auth integration.
|
|
60
|
+
|
|
61
|
+
**Hậu quả**: Tốn thời gian gấp 10x; khó xóa khi done; đôi khi bị promote lên production dưới prototype constraints.
|
|
62
|
+
|
|
63
|
+
**Fix**: Mỗi khi muốn thêm gì → hỏi "Cái này có giúp trả lời câu hỏi không?" Nếu không → đừng thêm. Prototype là throwaway, không phải MVP.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## G-007: Không update `.flow-state.yaml` sau verdict
|
|
68
|
+
|
|
69
|
+
**Lỗi**: Có verdict rồi nhưng quên update `artifacts.prototype.*` trong `.flow-state.yaml`.
|
|
70
|
+
|
|
71
|
+
**Hậu quả**: `/v.status` dashboard hiển thị sai pipeline state. Plan Agent không biết prototype đã done.
|
|
72
|
+
|
|
73
|
+
**Fix**: Sau khi ghi `prototype-notes.md` → ngay lập tức update `.flow-state.yaml`. Thứ tự bắt buộc: notes → session → flow-state → cleanup code.
|
|
74
|
+
|
|
75
|
+
**Validate**: Chạy `.v-flow/skills/prototype/scripts/check-flow-state.sh <feature-number>` để verify.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## G-008: `--req` flag nhưng REQ không có ambiguity
|
|
80
|
+
|
|
81
|
+
**Lỗi**: User dùng `--req REQ-E01` nhưng REQ-E01 rõ ràng, không ambiguous.
|
|
82
|
+
|
|
83
|
+
**Hậu quả**: Prototype giải quyết thứ không cần giải quyết — waste effort.
|
|
84
|
+
|
|
85
|
+
**Fix**: Dù user chỉ định `--req`, vẫn phải đọc REQ đó và confirm với user "REQ này cụ thể rồi, bạn có chắc muốn prototype không?" Nếu user confirm → tiến hành, ghi rõ lý do trong prototype-notes.md.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## G-009: Prototype không chạy được ngay (one-command requirement)
|
|
90
|
+
|
|
91
|
+
**Lỗi**: User cần thực hiện 4-5 bước setup trước khi chạy prototype.
|
|
92
|
+
|
|
93
|
+
**Hậu quả**: Friction ngăn user interact sớm với prototype. Prototype mất đi giá trị "fast feedback".
|
|
94
|
+
|
|
95
|
+
**Fix**: Test run command trước khi hand over. Với HTML mode: mở file trong browser phải work ngay (inline JS, không external deps). Với LOGIC: `pnpm prototype:NNN` phải chạy được ngay từ project root.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## G-010: Không cleanup sau verdict
|
|
100
|
+
|
|
101
|
+
**Lỗi**: `prototype/` folder vẫn còn trong `.v-flow/features/NNN/` sau khi có verdict.
|
|
102
|
+
|
|
103
|
+
**Hậu quả**: Code prototype (không có tests, không production-quality) bị confuse với real code. Repo bloat.
|
|
104
|
+
|
|
105
|
+
**Fix**: Luôn nhắc user xóa `prototype/` sau khi verdict đã được ghi vào `prototype-notes.md`. Chỉ giữ `prototype-notes.md`.
|
|
106
|
+
|
|
107
|
+
**Validate**: Chạy `.v-flow/skills/prototype/scripts/check-prototype-cleanup.sh` (không cần args) để scan tất cả features.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## G-011: Xung đột phím nhập liệu trong TUI (Raw Mode Input Crash)
|
|
112
|
+
|
|
113
|
+
**Lỗi**: Agent viết code TUI để hỏi người dùng nhập liệu (nhập số tiền, tên, câu trả lời) nhưng vẫn giữ nguyên chế độ lắng nghe phím Raw Mode (`setRawMode(true)`).
|
|
114
|
+
|
|
115
|
+
**Hậu quả**: Khi người dùng nhấn phím đầu tiên để nhập liệu, TUI hiểu nhầm đó là một phím tắt menu, gây ra lỗi crash chương trình ngay lập tức hoặc nhảy menu sai lệch.
|
|
116
|
+
|
|
117
|
+
**Fix**: Bắt buộc phải tắt Raw Mode (`process.stdin.setRawMode(false)`) và pause stdin trước khi tạo giao diện `readline`/`prompt`. Sau khi nhận được dữ liệu (User nhấn Enter), mới bật lại Raw Mode (`setRawMode(true)`) và resume stdin để nhận phím tắt. Xem blueprint mẫu trong `LOGIC.md` phần `4.5. Handling Text & Number Inputs`.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## G-012: Bàn giao "mù" (Blind Handover)
|
|
122
|
+
|
|
123
|
+
**Lỗi**: Agent tạo xong mã nguồn prototype và đưa ngay lệnh chạy cho người dùng mà không tự chạy thử trước.
|
|
124
|
+
|
|
125
|
+
**Hậu quả**: Người dùng nhận được lệnh nhưng không chạy được do lỗi cú pháp TypeScript, lỗi đường dẫn import path (`@/` resolving), hoặc thiếu thư viện phụ thuộc chưa cài đặt.
|
|
126
|
+
|
|
127
|
+
**Fix**: Agent bắt buộc phải chạy thử lệnh (sử dụng `run_command` trên terminal của workspace) và đảm bảo chương trình biên dịch/khởi động thành công không bị crash trong ít nhất 500ms - 1s trước khi bàn giao lệnh chạy cho người dùng.
|
|
128
|
+
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# check-flow-state.ps1 — Kiểm tra .flow-state.yaml đã được update sau prototype
|
|
2
|
+
# Usage: .\check-flow-state.ps1 [<feature-number>]
|
|
3
|
+
# .\check-flow-state.ps1 005
|
|
4
|
+
#
|
|
5
|
+
# Checks: artifacts.prototype.* fields tồn tại và có giá trị
|
|
6
|
+
|
|
7
|
+
param(
|
|
8
|
+
[string]$FeatureNum = ""
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
# ── Resolve feature dir & flow-state path ─────────────────────────
|
|
12
|
+
|
|
13
|
+
if (-not $FeatureNum) {
|
|
14
|
+
# Auto-detect: tìm feature có prototype-notes.md
|
|
15
|
+
$featureDir = Get-Item ".v-flow/features/*/" -ErrorAction SilentlyContinue |
|
|
16
|
+
Where-Object { Test-Path (Join-Path $_.FullName "prototype-notes.md") } |
|
|
17
|
+
Select-Object -First 1
|
|
18
|
+
|
|
19
|
+
if (-not $featureDir) {
|
|
20
|
+
Write-Host "❌ Cannot find feature directory with prototype-notes.md" -ForegroundColor Red
|
|
21
|
+
Write-Host " Usage: .\check-flow-state.ps1 <feature-number> (e.g. .\check-flow-state.ps1 005)"
|
|
22
|
+
exit 1
|
|
23
|
+
}
|
|
24
|
+
$flowState = Join-Path $featureDir.FullName ".flow-state.yaml"
|
|
25
|
+
} else {
|
|
26
|
+
$padded = $FeatureNum.PadLeft(3, '0')
|
|
27
|
+
$featureDir = Get-Item ".v-flow/features/$padded-*/" -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
28
|
+
if (-not $featureDir) {
|
|
29
|
+
$featureDir = [PSCustomObject]@{ FullName = ".v-flow/features/$FeatureNum/" }
|
|
30
|
+
}
|
|
31
|
+
$flowState = Join-Path $featureDir.FullName ".flow-state.yaml"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (-not (Test-Path $flowState)) {
|
|
35
|
+
Write-Host "❌ .flow-state.yaml not found: $flowState" -ForegroundColor Red
|
|
36
|
+
exit 1
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
$content = Get-Content $flowState -Raw
|
|
40
|
+
Write-Host "📋 Flow State Check (prototype section): $flowState"
|
|
41
|
+
Write-Host "════════════════════════════════════════════════════"
|
|
42
|
+
$errors = 0
|
|
43
|
+
$warnings = 0
|
|
44
|
+
|
|
45
|
+
# 1. Section artifacts.prototype tồn tại
|
|
46
|
+
Write-Host ""
|
|
47
|
+
Write-Host "### 1. Prototype Section Exists"
|
|
48
|
+
if ($content -match "prototype") {
|
|
49
|
+
Write-Host " ✅ 'prototype' section found" -ForegroundColor Green
|
|
50
|
+
} else {
|
|
51
|
+
Write-Host " ❌ No 'prototype' section in .flow-state.yaml" -ForegroundColor Red
|
|
52
|
+
Write-Host " Add: artifacts.prototype.verdict, artifacts.prototype.branch, etc."
|
|
53
|
+
$errors++
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# 2. Verdict đã được điền
|
|
57
|
+
Write-Host ""
|
|
58
|
+
Write-Host "### 2. Verdict Field"
|
|
59
|
+
if ($content -match "(?i)verdict\s*:\s*(VALIDATED|REJECTED|INCONCLUSIVE)") {
|
|
60
|
+
$verdict = $Matches[1].ToUpper()
|
|
61
|
+
Write-Host " ✅ verdict: $verdict" -ForegroundColor Green
|
|
62
|
+
} elseif ($content -match "(?i)verdict\s*:\s*(null|~|`"`")") {
|
|
63
|
+
Write-Host " ❌ verdict is empty/null — prototype not yet concluded" -ForegroundColor Red
|
|
64
|
+
$errors++
|
|
65
|
+
} else {
|
|
66
|
+
Write-Host " ⚠️ verdict field not found under prototype section" -ForegroundColor Yellow
|
|
67
|
+
$warnings++
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# 3. Branch đã được điền
|
|
71
|
+
Write-Host ""
|
|
72
|
+
Write-Host "### 3. Branch Field"
|
|
73
|
+
if ($content -match "(?i)branch\s*:\s*(LOGIC|UI)") {
|
|
74
|
+
$branch = $Matches[1].ToUpper()
|
|
75
|
+
Write-Host " ✅ branch: $branch" -ForegroundColor Green
|
|
76
|
+
} elseif ($content -match "(?i)branch\s*:\s*(null|~|`"`")") {
|
|
77
|
+
Write-Host " ⚠️ branch field empty/missing (should be LOGIC or UI)" -ForegroundColor Yellow
|
|
78
|
+
$warnings++
|
|
79
|
+
} else {
|
|
80
|
+
Write-Host " ⚠️ branch field not found (should be LOGIC or UI)" -ForegroundColor Yellow
|
|
81
|
+
$warnings++
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# 4. Phase hiện tại có tiến sang B.0 chưa
|
|
85
|
+
Write-Host ""
|
|
86
|
+
Write-Host "### 4. Pipeline Phase"
|
|
87
|
+
if ($content -match "(?i)(current_phase|phase)\s*:\s*[`"']?([SBR]\.\d+[\d.]*)[`"']?") {
|
|
88
|
+
$currentPhase = $Matches[2]
|
|
89
|
+
Write-Host " ℹ️ Current phase: $currentPhase"
|
|
90
|
+
if ($currentPhase -eq "S.1.5") {
|
|
91
|
+
Write-Host " ⚠️ Still at S.1.5 — have you routed to /v.plan yet?" -ForegroundColor Yellow
|
|
92
|
+
$warnings++
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
Write-Host " ⚠️ Cannot determine current phase" -ForegroundColor Yellow
|
|
96
|
+
$warnings++
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
Write-Host ""
|
|
100
|
+
Write-Host "════════════════════════════════════════════════════"
|
|
101
|
+
Write-Host "📊 Errors: $errors | Warnings: $warnings"
|
|
102
|
+
|
|
103
|
+
if ($errors -eq 0 -and $warnings -eq 0) {
|
|
104
|
+
Write-Host "✅ PASS — .flow-state.yaml correctly updated" -ForegroundColor Green
|
|
105
|
+
exit 0
|
|
106
|
+
} elseif ($errors -eq 0) {
|
|
107
|
+
Write-Host "⚠️ PASS WITH WARNINGS — check warnings above" -ForegroundColor Yellow
|
|
108
|
+
exit 0
|
|
109
|
+
} else {
|
|
110
|
+
Write-Host "❌ FAIL — .flow-state.yaml needs to be updated before continuing" -ForegroundColor Red
|
|
111
|
+
exit 1
|
|
112
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# check-flow-state.sh — Kiểm tra .flow-state.yaml đã được update sau prototype
|
|
3
|
+
# Usage: ./check-flow-state.sh <feature-number>
|
|
4
|
+
# ./check-flow-state.sh 005
|
|
5
|
+
#
|
|
6
|
+
# Checks: artifacts.prototype.* fields tồn tại và có giá trị
|
|
7
|
+
|
|
8
|
+
FEATURE_NUM="${1}"
|
|
9
|
+
|
|
10
|
+
if [ -z "$FEATURE_NUM" ]; then
|
|
11
|
+
# Auto-detect từ thư mục features có prototype-notes.md
|
|
12
|
+
FEATURE_DIR=$(ls -d .v-flow/features/*/ 2>/dev/null | while read d; do
|
|
13
|
+
[ -f "${d}prototype-notes.md" ] && echo "$d" && break
|
|
14
|
+
done)
|
|
15
|
+
if [ -z "$FEATURE_DIR" ]; then
|
|
16
|
+
echo "❌ Cannot find feature directory with prototype-notes.md"
|
|
17
|
+
echo " Usage: $0 <feature-number> (e.g. $0 005)"
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
FLOW_STATE="${FEATURE_DIR}.flow-state.yaml"
|
|
21
|
+
else
|
|
22
|
+
# Zero-pad nếu cần (005, 012, etc.)
|
|
23
|
+
PADDED=$(printf "%03d" "$FEATURE_NUM" 2>/dev/null || echo "$FEATURE_NUM")
|
|
24
|
+
FEATURE_DIR=$(ls -d .v-flow/features/${PADDED}-*/ 2>/dev/null | head -1)
|
|
25
|
+
if [ -z "$FEATURE_DIR" ]; then
|
|
26
|
+
FEATURE_DIR=".v-flow/features/${FEATURE_NUM}/"
|
|
27
|
+
fi
|
|
28
|
+
FLOW_STATE="${FEATURE_DIR}.flow-state.yaml"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
if [ ! -f "$FLOW_STATE" ]; then
|
|
32
|
+
echo "❌ .flow-state.yaml not found: $FLOW_STATE"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
echo "📋 Flow State Check (prototype section): $FLOW_STATE"
|
|
37
|
+
echo "════════════════════════════════════════════════════"
|
|
38
|
+
ERRORS=0
|
|
39
|
+
WARNINGS=0
|
|
40
|
+
|
|
41
|
+
# 1. Section artifacts.prototype tồn tại
|
|
42
|
+
echo ""
|
|
43
|
+
echo "### 1. Prototype Section Exists"
|
|
44
|
+
if grep -q "prototype" "$FLOW_STATE"; then
|
|
45
|
+
echo " ✅ 'prototype' section found"
|
|
46
|
+
else
|
|
47
|
+
echo " ❌ No 'prototype' section in .flow-state.yaml"
|
|
48
|
+
echo " Add: artifacts.prototype.verdict, artifacts.prototype.branch, etc."
|
|
49
|
+
ERRORS=$((ERRORS+1))
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# 2. Verdict đã được điền
|
|
53
|
+
echo ""
|
|
54
|
+
echo "### 2. Verdict Field"
|
|
55
|
+
VERDICT=$(grep -A5 "prototype" "$FLOW_STATE" | grep -i "verdict" | grep -oiE "VALIDATED|REJECTED|INCONCLUSIVE|null|~|\"\"" | head -1)
|
|
56
|
+
if [ -z "$VERDICT" ]; then
|
|
57
|
+
echo " ⚠️ verdict field not found under prototype section"
|
|
58
|
+
WARNINGS=$((WARNINGS+1))
|
|
59
|
+
elif echo "$VERDICT" | grep -qiE "null|~|\"\""; then
|
|
60
|
+
echo " ❌ verdict is empty/null — prototype not yet concluded"
|
|
61
|
+
ERRORS=$((ERRORS+1))
|
|
62
|
+
else
|
|
63
|
+
echo " ✅ verdict: $VERDICT"
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# 3. Branch đã được điền
|
|
67
|
+
echo ""
|
|
68
|
+
echo "### 3. Branch Field"
|
|
69
|
+
BRANCH=$(grep -A5 "prototype" "$FLOW_STATE" | grep -i "branch" | grep -oiE "LOGIC|UI|null|~|\"\"" | head -1)
|
|
70
|
+
if [ -z "$BRANCH" ] || echo "$BRANCH" | grep -qiE "null|~|\"\""; then
|
|
71
|
+
echo " ⚠️ branch field empty/missing (should be LOGIC or UI)"
|
|
72
|
+
WARNINGS=$((WARNINGS+1))
|
|
73
|
+
else
|
|
74
|
+
echo " ✅ branch: $BRANCH"
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# 4. Phase hiện tại có tiến sang B.0 chưa
|
|
78
|
+
echo ""
|
|
79
|
+
echo "### 4. Pipeline Phase"
|
|
80
|
+
CURRENT_PHASE=$(grep -i "current_phase\|phase:" "$FLOW_STATE" | head -1 | grep -oE "S\.[0-9.]+|B\.[0-9.]+|R\.[0-9.]+")
|
|
81
|
+
if [ -z "$CURRENT_PHASE" ]; then
|
|
82
|
+
echo " ⚠️ Cannot determine current phase"
|
|
83
|
+
WARNINGS=$((WARNINGS+1))
|
|
84
|
+
else
|
|
85
|
+
echo " ℹ️ Current phase: $CURRENT_PHASE"
|
|
86
|
+
if [[ "$CURRENT_PHASE" == "S.1.5" ]]; then
|
|
87
|
+
echo " ⚠️ Still at S.1.5 — have you routed to /v.plan yet?"
|
|
88
|
+
WARNINGS=$((WARNINGS+1))
|
|
89
|
+
fi
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
echo ""
|
|
93
|
+
echo "════════════════════════════════════════════════════"
|
|
94
|
+
echo "📊 Errors: $ERRORS | Warnings: $WARNINGS"
|
|
95
|
+
if [ "$ERRORS" -eq 0 ] && [ "$WARNINGS" -eq 0 ]; then
|
|
96
|
+
echo "✅ PASS — .flow-state.yaml correctly updated"
|
|
97
|
+
exit 0
|
|
98
|
+
elif [ "$ERRORS" -eq 0 ]; then
|
|
99
|
+
echo "⚠️ PASS WITH WARNINGS — check warnings above"
|
|
100
|
+
exit 0
|
|
101
|
+
else
|
|
102
|
+
echo "❌ FAIL — .flow-state.yaml needs to be updated before continuing"
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# check-prototype-cleanup.ps1 — Kiểm tra prototype code đã được cleanup chưa
|
|
2
|
+
# Usage: .\check-prototype-cleanup.ps1 [<feature-number>]
|
|
3
|
+
# .\check-prototype-cleanup.ps1 005
|
|
4
|
+
#
|
|
5
|
+
# Rule: Sau khi có verdict, thư mục prototype/ nên được xóa.
|
|
6
|
+
# Chỉ prototype-notes.md là được phép còn lại.
|
|
7
|
+
|
|
8
|
+
param(
|
|
9
|
+
[string]$FeatureNum = ""
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
function Check-SingleFeature {
|
|
13
|
+
param([string]$featureDir)
|
|
14
|
+
|
|
15
|
+
$prototypeDir = Join-Path $featureDir "prototype"
|
|
16
|
+
$notesFile = Join-Path $featureDir "prototype-notes.md"
|
|
17
|
+
$errors = 0
|
|
18
|
+
|
|
19
|
+
Write-Host "📋 Prototype Cleanup Check: $featureDir"
|
|
20
|
+
Write-Host "══════════════════════════════════════════"
|
|
21
|
+
|
|
22
|
+
# Check 1: prototype/ còn tồn tại không
|
|
23
|
+
Write-Host ""
|
|
24
|
+
Write-Host "### 1. Prototype Directory"
|
|
25
|
+
if (-not (Test-Path $prototypeDir)) {
|
|
26
|
+
Write-Host " ✅ prototype/ directory not found — already cleaned up" -ForegroundColor Green
|
|
27
|
+
} else {
|
|
28
|
+
if (Test-Path $notesFile) {
|
|
29
|
+
Write-Host " ❌ prototype/ still exists after verdict was captured" -ForegroundColor Red
|
|
30
|
+
Write-Host " Files:"
|
|
31
|
+
Get-ChildItem $prototypeDir | ForEach-Object { Write-Host " - $($_.Name)" }
|
|
32
|
+
Write-Host ""
|
|
33
|
+
Write-Host " → To cleanup:"
|
|
34
|
+
Write-Host " Remove-Item -Recurse -Force '$prototypeDir'"
|
|
35
|
+
$errors++
|
|
36
|
+
} else {
|
|
37
|
+
Write-Host " ⚠️ prototype/ exists but no prototype-notes.md yet" -ForegroundColor Yellow
|
|
38
|
+
Write-Host " → Capture verdict first before cleanup"
|
|
39
|
+
$errors++
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Check 2: prototype-notes.md tồn tại
|
|
44
|
+
Write-Host ""
|
|
45
|
+
Write-Host "### 2. Prototype Notes (the one thing to keep)"
|
|
46
|
+
if (Test-Path $notesFile) {
|
|
47
|
+
Write-Host " ✅ prototype-notes.md present" -ForegroundColor Green
|
|
48
|
+
$size = (Get-Item $notesFile).Length
|
|
49
|
+
if ($size -lt 200) {
|
|
50
|
+
Write-Host " ⚠️ File is very small ($size bytes) — may be incomplete" -ForegroundColor Yellow
|
|
51
|
+
$errors++
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
Write-Host " ⚠️ prototype-notes.md not found" -ForegroundColor Yellow
|
|
55
|
+
Write-Host " → If prototype is done, create notes before deleting prototype/"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
Write-Host ""
|
|
59
|
+
Write-Host "══════════════════════════════════════════"
|
|
60
|
+
Write-Host "📊 Errors: $errors"
|
|
61
|
+
if ($errors -eq 0) {
|
|
62
|
+
Write-Host "✅ PASS — prototype cleanup complete" -ForegroundColor Green
|
|
63
|
+
return 0
|
|
64
|
+
} else {
|
|
65
|
+
Write-Host "❌ FAIL — cleanup needed" -ForegroundColor Red
|
|
66
|
+
return 1
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
# ── Main ──────────────────────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
if (-not $FeatureNum) {
|
|
73
|
+
# Auto-detect: scan tất cả features
|
|
74
|
+
$allFeatureDirs = Get-Item ".v-flow/features/*/" -ErrorAction SilentlyContinue
|
|
75
|
+
if (-not $allFeatureDirs) {
|
|
76
|
+
Write-Host "❌ No feature directories found under .v-flow/features/" -ForegroundColor Red
|
|
77
|
+
exit 1
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
$foundAny = $false
|
|
81
|
+
$totalErrors = 0
|
|
82
|
+
|
|
83
|
+
foreach ($dir in $allFeatureDirs) {
|
|
84
|
+
$prototypeDir = Join-Path $dir.FullName "prototype"
|
|
85
|
+
$notesFile = Join-Path $dir.FullName "prototype-notes.md"
|
|
86
|
+
|
|
87
|
+
if ((Test-Path $notesFile) -and (Test-Path $prototypeDir)) {
|
|
88
|
+
$foundAny = $true
|
|
89
|
+
Write-Host "⚠️ STALE PROTOTYPE DETECTED: $($dir.FullName)" -ForegroundColor Yellow
|
|
90
|
+
Write-Host " prototype-notes.md exists (verdict captured) BUT prototype/ folder still present"
|
|
91
|
+
Write-Host " Files in prototype/:"
|
|
92
|
+
Get-ChildItem $prototypeDir | ForEach-Object { Write-Host " - $($_.Name)" }
|
|
93
|
+
Write-Host " → Run: Remove-Item -Recurse -Force '$prototypeDir'"
|
|
94
|
+
$totalErrors++
|
|
95
|
+
} elseif ((Test-Path $prototypeDir) -and -not (Test-Path $notesFile)) {
|
|
96
|
+
$foundAny = $true
|
|
97
|
+
Write-Host "⚠️ PROTOTYPE WITHOUT NOTES: $($dir.FullName)" -ForegroundColor Yellow
|
|
98
|
+
Write-Host " prototype/ folder exists but prototype-notes.md is missing"
|
|
99
|
+
Write-Host " → Capture verdict first, then cleanup"
|
|
100
|
+
$totalErrors++
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (-not $foundAny) {
|
|
105
|
+
Write-Host "✅ No active prototype directories found — all clean" -ForegroundColor Green
|
|
106
|
+
exit 0
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
Write-Host ""
|
|
110
|
+
Write-Host "📊 Total issues: $totalErrors"
|
|
111
|
+
if ($totalErrors -gt 0) { exit 1 } else { exit 0 }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
# Single feature mode
|
|
115
|
+
$padded = $FeatureNum.PadLeft(3, '0')
|
|
116
|
+
$featureDir = Get-Item ".v-flow/features/$padded-*/" -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
117
|
+
if (-not $featureDir) {
|
|
118
|
+
$featureDir = ".v-flow/features/$FeatureNum/"
|
|
119
|
+
} else {
|
|
120
|
+
$featureDir = $featureDir.FullName
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
$exitCode = Check-SingleFeature -featureDir $featureDir
|
|
124
|
+
exit $exitCode
|