@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
|
+
#!/bin/bash
|
|
2
|
+
# check-prototype-cleanup.sh — Kiểm tra prototype code đã được cleanup chưa
|
|
3
|
+
# Usage: ./check-prototype-cleanup.sh <feature-number>
|
|
4
|
+
# ./check-prototype-cleanup.sh 005
|
|
5
|
+
#
|
|
6
|
+
# Rule: Sau khi có verdict, thư mục prototype/ nên được xóa.
|
|
7
|
+
# Chỉ prototype-notes.md là được phép còn lại.
|
|
8
|
+
|
|
9
|
+
FEATURE_NUM="${1}"
|
|
10
|
+
|
|
11
|
+
if [ -z "$FEATURE_NUM" ]; then
|
|
12
|
+
# Auto-detect: tìm feature có prototype-notes.md
|
|
13
|
+
ALL_FEATURES=$(ls -d .v-flow/features/*/ 2>/dev/null)
|
|
14
|
+
if [ -z "$ALL_FEATURES" ]; then
|
|
15
|
+
echo "❌ No feature directories found under .v-flow/features/"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
# Scan tất cả features
|
|
19
|
+
FOUND_ANY=0
|
|
20
|
+
TOTAL_ERRORS=0
|
|
21
|
+
|
|
22
|
+
for FEATURE_DIR in $ALL_FEATURES; do
|
|
23
|
+
PROTOTYPE_DIR="${FEATURE_DIR}prototype/"
|
|
24
|
+
NOTES_FILE="${FEATURE_DIR}prototype-notes.md"
|
|
25
|
+
|
|
26
|
+
if [ -f "$NOTES_FILE" ] && [ -d "$PROTOTYPE_DIR" ]; then
|
|
27
|
+
FOUND_ANY=1
|
|
28
|
+
echo "⚠️ STALE PROTOTYPE DETECTED: $FEATURE_DIR"
|
|
29
|
+
echo " prototype-notes.md exists (verdict captured) BUT prototype/ folder still present"
|
|
30
|
+
echo " Files in prototype/:"
|
|
31
|
+
ls "$PROTOTYPE_DIR" | sed 's/^/ - /'
|
|
32
|
+
echo " → Run: rm -rf ${PROTOTYPE_DIR}"
|
|
33
|
+
TOTAL_ERRORS=$((TOTAL_ERRORS+1))
|
|
34
|
+
elif [ -d "$PROTOTYPE_DIR" ] && [ ! -f "$NOTES_FILE" ]; then
|
|
35
|
+
FOUND_ANY=1
|
|
36
|
+
echo "⚠️ PROTOTYPE WITHOUT NOTES: $FEATURE_DIR"
|
|
37
|
+
echo " prototype/ folder exists but prototype-notes.md is missing"
|
|
38
|
+
echo " → Capture verdict first, then cleanup"
|
|
39
|
+
TOTAL_ERRORS=$((TOTAL_ERRORS+1))
|
|
40
|
+
fi
|
|
41
|
+
done
|
|
42
|
+
|
|
43
|
+
if [ "$FOUND_ANY" -eq 0 ]; then
|
|
44
|
+
echo "✅ No active prototype directories found — all clean"
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
echo ""
|
|
49
|
+
echo "📊 Total issues: $TOTAL_ERRORS"
|
|
50
|
+
[ "$TOTAL_ERRORS" -gt 0 ] && exit 1 || exit 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Single feature mode
|
|
54
|
+
PADDED=$(printf "%03d" "$FEATURE_NUM" 2>/dev/null || echo "$FEATURE_NUM")
|
|
55
|
+
FEATURE_DIR=$(ls -d .v-flow/features/${PADDED}-*/ 2>/dev/null | head -1)
|
|
56
|
+
if [ -z "$FEATURE_DIR" ]; then
|
|
57
|
+
FEATURE_DIR=".v-flow/features/${FEATURE_NUM}/"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
PROTOTYPE_DIR="${FEATURE_DIR}prototype/"
|
|
61
|
+
NOTES_FILE="${FEATURE_DIR}prototype-notes.md"
|
|
62
|
+
|
|
63
|
+
echo "📋 Prototype Cleanup Check: $FEATURE_DIR"
|
|
64
|
+
echo "══════════════════════════════════════════"
|
|
65
|
+
ERRORS=0
|
|
66
|
+
|
|
67
|
+
# Check 1: prototype/ còn tồn tại không
|
|
68
|
+
echo ""
|
|
69
|
+
echo "### 1. Prototype Directory"
|
|
70
|
+
if [ ! -d "$PROTOTYPE_DIR" ]; then
|
|
71
|
+
echo " ✅ prototype/ directory not found — already cleaned up"
|
|
72
|
+
else
|
|
73
|
+
if [ -f "$NOTES_FILE" ]; then
|
|
74
|
+
echo " ❌ prototype/ still exists after verdict was captured"
|
|
75
|
+
echo " Files:"
|
|
76
|
+
ls "$PROTOTYPE_DIR" | sed 's/^/ - /'
|
|
77
|
+
echo ""
|
|
78
|
+
echo " → To cleanup:"
|
|
79
|
+
echo " rm -rf ${PROTOTYPE_DIR}"
|
|
80
|
+
ERRORS=$((ERRORS+1))
|
|
81
|
+
else
|
|
82
|
+
echo " ⚠️ prototype/ exists but no prototype-notes.md yet"
|
|
83
|
+
echo " → Capture verdict first before cleanup"
|
|
84
|
+
ERRORS=$((ERRORS+1))
|
|
85
|
+
fi
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Check 2: prototype-notes.md tồn tại
|
|
89
|
+
echo ""
|
|
90
|
+
echo "### 2. Prototype Notes (the one thing to keep)"
|
|
91
|
+
if [ -f "$NOTES_FILE" ]; then
|
|
92
|
+
echo " ✅ prototype-notes.md present"
|
|
93
|
+
SIZE=$(wc -c < "$NOTES_FILE" | tr -d ' ')
|
|
94
|
+
[ "$SIZE" -lt 200 ] && echo " ⚠️ File is very small (${SIZE} bytes) — may be incomplete" && ERRORS=$((ERRORS+1))
|
|
95
|
+
else
|
|
96
|
+
echo " ⚠️ prototype-notes.md not found"
|
|
97
|
+
echo " → If prototype is done, create notes before deleting prototype/"
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
echo ""
|
|
101
|
+
echo "══════════════════════════════════════════"
|
|
102
|
+
echo "📊 Errors: $ERRORS"
|
|
103
|
+
if [ "$ERRORS" -eq 0 ]; then
|
|
104
|
+
echo "✅ PASS — prototype cleanup complete"
|
|
105
|
+
exit 0
|
|
106
|
+
else
|
|
107
|
+
echo "❌ FAIL — cleanup needed"
|
|
108
|
+
exit 1
|
|
109
|
+
fi
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# check-prototype-notes.ps1 — Validate prototype-notes.md có đủ required fields
|
|
2
|
+
# Usage: .\check-prototype-notes.ps1 [<prototype-notes.md path>]
|
|
3
|
+
#
|
|
4
|
+
# Checks: required fields, verdict value, REQ refs, spec impact, routing
|
|
5
|
+
|
|
6
|
+
param(
|
|
7
|
+
[string]$Notes = ""
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
# Resolve path
|
|
11
|
+
if (-not $Notes) {
|
|
12
|
+
$found = Get-Item ".v-flow/features/*/prototype-notes.md" -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
13
|
+
if ($found) { $Notes = $found.FullName }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (-not $Notes -or -not (Test-Path $Notes)) {
|
|
17
|
+
Write-Host "❌ File not found: $Notes" -ForegroundColor Red
|
|
18
|
+
Write-Host " Usage: .\check-prototype-notes.ps1 <path/to/prototype-notes.md>"
|
|
19
|
+
exit 1
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
$content = Get-Content $Notes -Raw
|
|
23
|
+
Write-Host "📋 Prototype Notes Compliance Check: $Notes"
|
|
24
|
+
Write-Host "════════════════════════════════════════════"
|
|
25
|
+
$errors = 0
|
|
26
|
+
$warnings = 0
|
|
27
|
+
|
|
28
|
+
# 1. Required fields
|
|
29
|
+
Write-Host ""
|
|
30
|
+
Write-Host "### 1. Required Fields"
|
|
31
|
+
$requiredFields = @("Branch", "Question", "Verdict", "REQ refs", "Spec impact", "Routing")
|
|
32
|
+
foreach ($field in $requiredFields) {
|
|
33
|
+
if ($content -match "(?i)$field") {
|
|
34
|
+
Write-Host " ✅ '$field' present" -ForegroundColor Green
|
|
35
|
+
} else {
|
|
36
|
+
Write-Host " ❌ '$field' MISSING" -ForegroundColor Red
|
|
37
|
+
$errors++
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# 2. Verdict value phải hợp lệ
|
|
42
|
+
Write-Host ""
|
|
43
|
+
Write-Host "### 2. Verdict Value"
|
|
44
|
+
if ($content -match "(?i)(VALIDATED|REJECTED|INCONCLUSIVE)") {
|
|
45
|
+
$verdict = $Matches[1].ToUpper()
|
|
46
|
+
Write-Host " ✅ Verdict: $verdict" -ForegroundColor Green
|
|
47
|
+
} else {
|
|
48
|
+
Write-Host " ❌ No valid verdict found (must be VALIDATED | REJECTED | INCONCLUSIVE)" -ForegroundColor Red
|
|
49
|
+
$errors++
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# 3. REQ refs có format đúng không
|
|
53
|
+
Write-Host ""
|
|
54
|
+
Write-Host "### 3. REQ References"
|
|
55
|
+
$reqMatches = [regex]::Matches($content, "REQ-[UESO]\d+")
|
|
56
|
+
if ($reqMatches.Count -eq 0) {
|
|
57
|
+
Write-Host " ⚠️ No REQ-xxx references found (should link to spec requirements)" -ForegroundColor Yellow
|
|
58
|
+
$warnings++
|
|
59
|
+
} else {
|
|
60
|
+
$unique = $reqMatches | ForEach-Object { $_.Value } | Sort-Object -Unique
|
|
61
|
+
Write-Host " ✅ REQ refs found: $($reqMatches.Count) ($($unique -join ', '))" -ForegroundColor Green
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
# 4. Run command documented
|
|
65
|
+
Write-Host ""
|
|
66
|
+
Write-Host "### 4. Run Command"
|
|
67
|
+
if ($content -match "(?i)(run command|cách chạy|npm run|pnpm|tsx|python|bun)") {
|
|
68
|
+
Write-Host " ✅ Run command documented" -ForegroundColor Green
|
|
69
|
+
} else {
|
|
70
|
+
Write-Host " ⚠️ No run command found (user needs to know how to start the prototype)" -ForegroundColor Yellow
|
|
71
|
+
$warnings++
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# 5. Kết quả interact (evidence for verdict)
|
|
75
|
+
Write-Host ""
|
|
76
|
+
Write-Host "### 5. Interact Evidence"
|
|
77
|
+
if ($content -match "(?i)(\[x\]|\[✓\]|✅|✔|case|test|interact|kết quả|result|finding)") {
|
|
78
|
+
Write-Host " ✅ Interact results present" -ForegroundColor Green
|
|
79
|
+
} else {
|
|
80
|
+
Write-Host " ⚠️ No evidence of user interaction (verdict without evidence is unreliable)" -ForegroundColor Yellow
|
|
81
|
+
$warnings++
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# 6. Cleanup checklist
|
|
85
|
+
Write-Host ""
|
|
86
|
+
Write-Host "### 6. Cleanup Checklist"
|
|
87
|
+
if ($content -match "(?i)(cleanup|flow-state|_session|prototype/)") {
|
|
88
|
+
Write-Host " ✅ Cleanup references present" -ForegroundColor Green
|
|
89
|
+
} else {
|
|
90
|
+
Write-Host " ⚠️ No cleanup checklist (flow-state.yaml, _session.md may not be updated)" -ForegroundColor Yellow
|
|
91
|
+
$warnings++
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
Write-Host ""
|
|
95
|
+
Write-Host "════════════════════════════════════════════"
|
|
96
|
+
Write-Host "📊 Errors: $errors | Warnings: $warnings"
|
|
97
|
+
|
|
98
|
+
if ($errors -eq 0 -and $warnings -eq 0) {
|
|
99
|
+
Write-Host "✅ PASS — prototype-notes.md is complete" -ForegroundColor Green
|
|
100
|
+
exit 0
|
|
101
|
+
} elseif ($errors -eq 0) {
|
|
102
|
+
Write-Host "⚠️ PASS WITH WARNINGS — review warnings before routing to next phase" -ForegroundColor Yellow
|
|
103
|
+
exit 0
|
|
104
|
+
} else {
|
|
105
|
+
Write-Host "❌ FAIL — fix $errors error(s) before continuing pipeline" -ForegroundColor Red
|
|
106
|
+
exit 1
|
|
107
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# check-prototype-notes.sh — Validate prototype-notes.md có đủ required fields
|
|
3
|
+
# Usage: ./check-prototype-notes.sh <prototype-notes.md path>
|
|
4
|
+
#
|
|
5
|
+
# Checks: required fields, verdict value, REQ refs, spec impact, routing
|
|
6
|
+
|
|
7
|
+
NOTES="${1:-.v-flow/features/*/prototype-notes.md}"
|
|
8
|
+
|
|
9
|
+
# Nếu dùng glob, lấy file đầu tiên tìm được
|
|
10
|
+
if [[ "$NOTES" == *"*"* ]]; then
|
|
11
|
+
NOTES=$(ls .v-flow/features/*/prototype-notes.md 2>/dev/null | head -1)
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
if [ ! -f "$NOTES" ]; then
|
|
15
|
+
echo "❌ File not found: $NOTES"
|
|
16
|
+
echo " Usage: $0 <path/to/prototype-notes.md>"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
echo "📋 Prototype Notes Compliance Check: $NOTES"
|
|
21
|
+
echo "════════════════════════════════════════════"
|
|
22
|
+
ERRORS=0
|
|
23
|
+
WARNINGS=0
|
|
24
|
+
|
|
25
|
+
# 1. Required fields
|
|
26
|
+
echo ""
|
|
27
|
+
echo "### 1. Required Fields"
|
|
28
|
+
REQUIRED_FIELDS=("Branch" "Question" "Verdict" "REQ refs" "Spec impact" "Routing")
|
|
29
|
+
for field in "${REQUIRED_FIELDS[@]}"; do
|
|
30
|
+
if grep -qi "$field" "$NOTES"; then
|
|
31
|
+
echo " ✅ '$field' present"
|
|
32
|
+
else
|
|
33
|
+
echo " ❌ '$field' MISSING"
|
|
34
|
+
ERRORS=$((ERRORS+1))
|
|
35
|
+
fi
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
# 2. Verdict value phải hợp lệ
|
|
39
|
+
echo ""
|
|
40
|
+
echo "### 2. Verdict Value"
|
|
41
|
+
VERDICT=$(grep -i "verdict" "$NOTES" | grep -oiE "VALIDATED|REJECTED|INCONCLUSIVE" | head -1)
|
|
42
|
+
if [ -z "$VERDICT" ]; then
|
|
43
|
+
echo " ❌ No valid verdict found (must be VALIDATED | REJECTED | INCONCLUSIVE)"
|
|
44
|
+
ERRORS=$((ERRORS+1))
|
|
45
|
+
else
|
|
46
|
+
echo " ✅ Verdict: $VERDICT"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# 3. REQ refs có format đúng không
|
|
50
|
+
echo ""
|
|
51
|
+
echo "### 3. REQ References"
|
|
52
|
+
REQ_COUNT=$(grep -oE "REQ-[UESO][0-9]+" "$NOTES" | wc -l | tr -d ' ')
|
|
53
|
+
if [ "$REQ_COUNT" -eq 0 ]; then
|
|
54
|
+
echo " ⚠️ No REQ-xxx references found (should link to spec requirements)"
|
|
55
|
+
WARNINGS=$((WARNINGS+1))
|
|
56
|
+
else
|
|
57
|
+
echo " ✅ REQ refs found: $REQ_COUNT ($(grep -oE 'REQ-[UESO][0-9]+' "$NOTES" | sort -u | tr '\n' ' '))"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# 4. Run command documented
|
|
61
|
+
echo ""
|
|
62
|
+
echo "### 4. Run Command"
|
|
63
|
+
if grep -qiE "(run command|cách chạy|npm run|pnpm|tsx|python|bun)" "$NOTES"; then
|
|
64
|
+
echo " ✅ Run command documented"
|
|
65
|
+
else
|
|
66
|
+
echo " ⚠️ No run command found (user needs to know how to start the prototype)"
|
|
67
|
+
WARNINGS=$((WARNINGS+1))
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# 5. Kết quả interact (evidence for verdict)
|
|
71
|
+
echo ""
|
|
72
|
+
echo "### 5. Interact Evidence"
|
|
73
|
+
if grep -qiE "(\[x\]|\[✓\]|✅|✔|case|test|interact|kết quả|result|finding)" "$NOTES"; then
|
|
74
|
+
echo " ✅ Interact results present"
|
|
75
|
+
else
|
|
76
|
+
echo " ⚠️ No evidence of user interaction (verdict without evidence is unreliable)"
|
|
77
|
+
WARNINGS=$((WARNINGS+1))
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# 6. Cleanup checklist
|
|
81
|
+
echo ""
|
|
82
|
+
echo "### 6. Cleanup Checklist"
|
|
83
|
+
if grep -qiE "(cleanup|flow-state|_session|prototype/)" "$NOTES"; then
|
|
84
|
+
echo " ✅ Cleanup references present"
|
|
85
|
+
else
|
|
86
|
+
echo " ⚠️ No cleanup checklist (flow-state.yaml, _session.md may not be updated)"
|
|
87
|
+
WARNINGS=$((WARNINGS+1))
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
echo ""
|
|
91
|
+
echo "════════════════════════════════════════════"
|
|
92
|
+
echo "📊 Errors: $ERRORS | Warnings: $WARNINGS"
|
|
93
|
+
if [ "$ERRORS" -eq 0 ] && [ "$WARNINGS" -eq 0 ]; then
|
|
94
|
+
echo "✅ PASS — prototype-notes.md is complete"
|
|
95
|
+
exit 0
|
|
96
|
+
elif [ "$ERRORS" -eq 0 ]; then
|
|
97
|
+
echo "⚠️ PASS WITH WARNINGS — review warnings before routing to next phase"
|
|
98
|
+
exit 0
|
|
99
|
+
else
|
|
100
|
+
echo "❌ FAIL — fix $ERRORS error(s) before continuing pipeline"
|
|
101
|
+
exit 1
|
|
102
|
+
fi
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: adversarial-reviewer
|
|
3
|
+
description: "Hướng dẫn Review Agent tìm issues trong code. Agent PHẢI đọc skill này khi /v.review được gọi. Review đủ 5 chiều có bằng chứng — không ép số lượng issue, KHÔNG LGTM trống."
|
|
4
|
+
trigger: "Khi /v.review được gọi"
|
|
5
|
+
phase: "R.1"
|
|
6
|
+
used_by:
|
|
7
|
+
- /v.review
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Adversarial Reviewer — Review Không Nhân Nhượng
|
|
11
|
+
|
|
12
|
+
> ⚠️ Đây là **Skill bắt buộc** cho Review Agent.
|
|
13
|
+
> QUAN TRỌNG: Bắt buộc **review đủ 5 chiều có bằng chứng** — KHÔNG ép số lượng issue. "LGTM"/"Looks good" trống (không bằng chứng) BỊ CẤM; "no material findings" hợp lệ nếu kèm residual risk + test gap.
|
|
14
|
+
>
|
|
15
|
+
> → Xem `gotchas.md` cho issues hay gặp nhất (historical data).
|
|
16
|
+
> → Xem `examples/good/` cho mẫu review report chuẩn.
|
|
17
|
+
> → Xem `config.json` để customize (min_issues, review_depth).
|
|
18
|
+
> → Chạy `.v-flow/skills/review/adversarial-reviewer/scripts/quick-security-scan.sh <dir>` để pre-scan trước review.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Khi nào review KHÁC
|
|
23
|
+
|
|
24
|
+
- **Quick Fix** (`/v.quickfix`): Vẫn review đủ chiều nhưng scope nhỏ hơn.
|
|
25
|
+
- **Hotfix** (`/v.hotfix`): Focus correctness + security only. Có thể ≤3 nếu scope rất nhỏ.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 5 Chiều Review — Pattern Detection
|
|
30
|
+
|
|
31
|
+
> 💡 Phần này cung cấp **signals để tìm issues**, không phải step-by-step.
|
|
32
|
+
> Agent tự quyết thứ tự và depth dựa trên feature.
|
|
33
|
+
|
|
34
|
+
### 1. 🎯 Correctness — Code vs Spec alignment
|
|
35
|
+
|
|
36
|
+
**Signals cần tìm:**
|
|
37
|
+
- Function behavior khớp REQ-xxx description? → So sánh spec → code
|
|
38
|
+
- Edge cases trong test-cases.md có test code tương ứng?
|
|
39
|
+
- Return types/error codes match expected?
|
|
40
|
+
- Off-by-one errors (>, >=, <, <=)
|
|
41
|
+
- Null/undefined không được handle
|
|
42
|
+
|
|
43
|
+
### 2. 🏗️ Architecture — Constitution compliance
|
|
44
|
+
|
|
45
|
+
**Signals cần tìm:**
|
|
46
|
+
- Import direction vi phạm layer rules? (presentation → domain OK, domain → presentation ❌)
|
|
47
|
+
- Pattern mismatch? (constitution nói Repository, code dùng direct DB query)
|
|
48
|
+
- No-Go Zone violated?
|
|
49
|
+
- Naming convention bị mix? (camelCase + snake_case trong cùng module)
|
|
50
|
+
|
|
51
|
+
### 3. 🔒 Security — Attack surface check
|
|
52
|
+
|
|
53
|
+
**Grep patterns trong code review:**
|
|
54
|
+
```
|
|
55
|
+
String concatenation SQL: `+ variable`, `${variable}` trong SQL strings
|
|
56
|
+
Hardcoded secrets: `password`, `apiKey`, `secret`, `token` = literal value
|
|
57
|
+
Missing validation: req.body dùng trực tiếp không qua validation
|
|
58
|
+
Sensitive logging: console.log(password), console.log(token)
|
|
59
|
+
Missing auth check: Route handler không có auth middleware
|
|
60
|
+
XSS vectors: innerHTML =, dangerouslySetInnerHTML, v-html
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 4. 📊 Quality — Test & maintainability
|
|
64
|
+
|
|
65
|
+
**Signals cần tìm:**
|
|
66
|
+
- Test coverage gaps → file có logic nhưng không có test file tương ứng
|
|
67
|
+
- Error handling → try-catch thiếu hoặc swallow (`catch(e) {}`)
|
|
68
|
+
- Magic numbers → `if (count > 5)` thay vì `if (count > MAX_RETRIES)`
|
|
69
|
+
- Dead code → functions/variables defined but never used
|
|
70
|
+
- TODO/FIXME/HACK comments → tech debt indicators
|
|
71
|
+
|
|
72
|
+
### 5. ⚡ Performance — Resource efficiency
|
|
73
|
+
|
|
74
|
+
**Grep patterns:**
|
|
75
|
+
```
|
|
76
|
+
N+1 queries: `for ... await db.query()`
|
|
77
|
+
Missing index: WHERE clause on non-indexed column
|
|
78
|
+
Memory leak: addEventListener without removeEventListener
|
|
79
|
+
Large payload: SELECT * thay vì specific columns
|
|
80
|
+
Missing pagination: findAll() without limit
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Issue Severity Reference
|
|
86
|
+
|
|
87
|
+
| Severity | Criteria | Action Required |
|
|
88
|
+
|:--------:|---------|----------------|
|
|
89
|
+
| 🔴 **Critical** | Bug, security vuln, data loss, crash | **MUST fix** — block merge |
|
|
90
|
+
| 🟡 **Major** | Architecture violation, missing test, bad pattern | **SHOULD fix** — discuss if needed |
|
|
91
|
+
| 🟢 **Minor** | Style, naming, improvement, optimization | **CAN fix** — optional |
|
|
92
|
+
|
|
93
|
+
**Rule**: review đủ 5 chiều; mỗi finding có severity + `file:line` + bằng chứng. **Không ép số lượng** — nếu không có material finding, ghi rõ scope/assumptions/residual risk + test gap còn lại.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Concern Verification
|
|
98
|
+
|
|
99
|
+
> 💡 Phần này KHÔNG ĐƯỢC BỎ QUA.
|
|
100
|
+
|
|
101
|
+
Review Agent PHẢI verify W-xxx concerns từ R.0 (validation-report.md):
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
1. Đọc validation-report.md → §4 Concerns
|
|
105
|
+
2. Với mỗi W-xxx:
|
|
106
|
+
- Tìm code implementation giải quyết concern
|
|
107
|
+
- Verify implementation đúng và đủ
|
|
108
|
+
- Ghi kết quả vào review report
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Output Format
|
|
114
|
+
|
|
115
|
+
→ Xem `examples/good/review-report-template.md` cho format chuẩn.
|
|
116
|
+
|
|
117
|
+
Minimum required sections:
|
|
118
|
+
- **Summary**: Files reviewed, issues count, verdict
|
|
119
|
+
- **Issues**: Mỗi issue có CR-xxx ID, severity, file:line, description, suggestion
|
|
120
|
+
- **Concerns Verification**: Ma trận W-xxx → resolved?
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Reviewer Biases Cần Tránh
|
|
125
|
+
|
|
126
|
+
| Bias | Mô tả | Cách tránh |
|
|
127
|
+
|------|-------|----------|
|
|
128
|
+
| **Familiarity** | Ít critical với code style mình suggest | Review như người ngoài |
|
|
129
|
+
| **Nitpicking overload** | 20 minor issues che mất 1 critical | Sort by severity first |
|
|
130
|
+
| **Style wars** | Tranh cãi formatting khi không có convention | Skip nếu constitution không nói |
|
|
131
|
+
| **Recency** | Focus file cuối cùng, quên file đầu | Systematic — file by file |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Gotchas
|
|
136
|
+
|
|
137
|
+
→ Xem `gotchas.md` cho issues historical data — cập nhật sau MỖI review cycle.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"setup_questions": [
|
|
3
|
+
{
|
|
4
|
+
"id": "min_issues",
|
|
5
|
+
"question": "Số issues tối thiểu phải tìm?",
|
|
6
|
+
"type": "number",
|
|
7
|
+
"default": 3
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "review_depth",
|
|
11
|
+
"question": "Review depth?",
|
|
12
|
+
"options": ["quick", "standard", "deep"],
|
|
13
|
+
"default": "standard",
|
|
14
|
+
"description": "quick = correctness + security only. standard = 5 chiều. deep = + performance profiling."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "auto_grep_security",
|
|
18
|
+
"question": "Tự động grep security patterns?",
|
|
19
|
+
"type": "boolean",
|
|
20
|
+
"default": true
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"hooks": {
|
|
24
|
+
"pre_review": "Load spec.md + validation-report.md concerns (W-xxx) trước khi review",
|
|
25
|
+
"post_review": "Verify concern resolution count matches expected"
|
|
26
|
+
},
|
|
27
|
+
"memory": {
|
|
28
|
+
"file": "review-history.log",
|
|
29
|
+
"format": "[date] | [feature] | [issues_found] | [critical] | [major] | [minor] | [concerns_resolved]",
|
|
30
|
+
"purpose": "Track review quality over time — dùng cho /v.metrics"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Good Example — Code Review Report
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
- **Feature**: 002-legacy-crud (Refactor CRUD Products)
|
|
5
|
+
- **Files reviewed**: 7 files
|
|
6
|
+
- **Issues found**: 5 (1 critical, 2 major, 2 minor)
|
|
7
|
+
- **Verdict**: CHANGES REQUESTED
|
|
8
|
+
- **Concerns**: W-001 ✅ Resolved, W-002 ✅ Resolved
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Issues
|
|
13
|
+
|
|
14
|
+
### 🔴 CR-001: SQL injection risk in search query — Critical
|
|
15
|
+
**File**: `repositories/product.repo.js:45`
|
|
16
|
+
**Category**: Security
|
|
17
|
+
**Description**: `findByCategory()` uses template literal for category filter instead of parameterized query. This contradicts REQ-U01.
|
|
18
|
+
```javascript
|
|
19
|
+
// Current (vulnerable)
|
|
20
|
+
`SELECT * FROM products WHERE category = '${category}'`
|
|
21
|
+
// Fixed
|
|
22
|
+
'SELECT * FROM products WHERE category = $1', [category]
|
|
23
|
+
```
|
|
24
|
+
**REQ**: REQ-U01
|
|
25
|
+
|
|
26
|
+
### 🟡 CR-002: Missing error class for 503 — Major
|
|
27
|
+
**File**: `errors/app-error.js`
|
|
28
|
+
**Category**: Architecture
|
|
29
|
+
**Description**: Plan specified `ServiceUnavailableError` for REQ-S01 (DB connection fail → 503), but only `AppError`, `NotFoundError`, `ValidationError` exist.
|
|
30
|
+
**Suggestion**: Add `ServiceUnavailableError extends AppError` with status 503.
|
|
31
|
+
**REQ**: REQ-S01
|
|
32
|
+
|
|
33
|
+
### 🟡 CR-003: Validation schema allows negative page — Major
|
|
34
|
+
**File**: `validation/product.js:12`
|
|
35
|
+
**Category**: Correctness
|
|
36
|
+
**Description**: QuerySchema has `page: Joi.number().default(1)` but missing `.min(1)`. Negative page values accepted.
|
|
37
|
+
**REQ**: REQ-E03
|
|
38
|
+
|
|
39
|
+
### 🟢 CR-004: Magic number in pagination — Minor
|
|
40
|
+
**File**: `services/product.service.js:28`
|
|
41
|
+
**Category**: Quality
|
|
42
|
+
**Description**: `if (limit > 100) limit = 100` — hardcoded 100. Use constant `MAX_PAGE_SIZE`.
|
|
43
|
+
|
|
44
|
+
### 🟢 CR-005: Missing JSDoc on public methods — Minor
|
|
45
|
+
**File**: `repositories/product.repo.js`
|
|
46
|
+
**Category**: Standards
|
|
47
|
+
**Description**: Public methods `findAll`, `findById`, `create`, `update`, `softDelete` missing JSDoc.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Concerns Verification
|
|
52
|
+
|
|
53
|
+
| Concern | From R.0 | Resolution | Code Location | Verified? |
|
|
54
|
+
|---------|----------|-----------|---------------|:---------:|
|
|
55
|
+
| W-001 | Migration rollback missing | Added `rollback-deleted-at.sql` | `db/migrations/` | ✅ |
|
|
56
|
+
| W-002 | GET response format change | Tech Lead approved Option C (header-based) | `routes/products.js:15` | ✅ |
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Gotchas — Adversarial Reviewer
|
|
2
|
+
|
|
3
|
+
> Cập nhật liên tục sau MỖI review cycle.
|
|
4
|
+
> Đây là "institutional memory" — issues **THỰC SỰ** hay gặp nhất.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Top 10 Issues Phổ Biến (Historical)
|
|
9
|
+
|
|
10
|
+
1. ❌ **Missing error handling async** — `await doSomething()` không có try-catch.
|
|
11
|
+
- **Severity**: 🔴 Critical — unhandled promise rejection → crash.
|
|
12
|
+
|
|
13
|
+
2. ❌ **Hardcoded values** — Magic numbers, URLs, timeouts trong code.
|
|
14
|
+
- **VD**: `if (retries > 3)` → `MAX_RETRIES`, `setTimeout(5000)` → `TIMEOUT_MS`.
|
|
15
|
+
|
|
16
|
+
3. ❌ **Missing null/empty checks** — `.length` trên array có thể null.
|
|
17
|
+
- **VD**: `users.length` → crash nếu users = null. Check trước.
|
|
18
|
+
|
|
19
|
+
4. ❌ **N+1 queries** — `for (user of users) { await db.getOrders(user.id) }`.
|
|
20
|
+
- **Fix**: Batch query `WHERE user_id IN (...)`.
|
|
21
|
+
|
|
22
|
+
5. ❌ **Sensitive data logged** — `console.log('Login:', { email, password })`.
|
|
23
|
+
- **Fix**: Mask hoặc exclude sensitive fields.
|
|
24
|
+
|
|
25
|
+
6. ❌ **Missing input validation** — API chấp nhận mọi input, pass thẳng DB.
|
|
26
|
+
- **Check**: Trace req.body → db.query — có validation layer giữa?
|
|
27
|
+
|
|
28
|
+
7. ❌ **Race condition** — 2 concurrent requests modify same record.
|
|
29
|
+
- **Signal**: UPDATE without version check hoặc lock.
|
|
30
|
+
|
|
31
|
+
8. ❌ **Memory leak** — EventListener added nhưng không removeEventListener.
|
|
32
|
+
- **Check**: Trong React: useEffect return cleanup? Trong Node: .on() có .off()?
|
|
33
|
+
|
|
34
|
+
9. ❌ **Breaking backward compat** — Response format change không versioned.
|
|
35
|
+
- **Signal**: API response structure khác format cũ → consumer break.
|
|
36
|
+
|
|
37
|
+
10. ❌ **Test chỉ happy path** — Tests chỉ cover success, not error/edge.
|
|
38
|
+
- **Check**: Có test cho 400, 404, 500? Có test cho empty input?
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## False Positives Cần Tránh
|
|
43
|
+
|
|
44
|
+
- ✅ Console.log trong dev environment → OK nếu có log level control
|
|
45
|
+
- ✅ `any` type trong TypeScript → OK nếu có JSDoc comment giải thích
|
|
46
|
+
- ✅ Large function → OK nếu linear flow (không complex branching)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# quick-security-scan.sh — Quét code cho security issues phổ biến
|
|
3
|
+
# Usage: ./quick-security-scan.sh <directory>
|
|
4
|
+
#
|
|
5
|
+
# Output: Danh sách potential issues cho Review Agent xem xét
|
|
6
|
+
|
|
7
|
+
DIR="${1:-.}"
|
|
8
|
+
|
|
9
|
+
echo "🔒 Security Scan: $DIR"
|
|
10
|
+
echo "════════════════════════════════════════"
|
|
11
|
+
echo ""
|
|
12
|
+
|
|
13
|
+
# 1. SQL Injection — SQL keyword + nối chuỗi trên cùng dòng (BẤT KỂ thứ tự).
|
|
14
|
+
# Bug cũ: regex yêu cầu concat ĐỨNG TRƯỚC keyword nên bỏ sót `"SELECT...id=" + id`
|
|
15
|
+
# (keyword đứng trước). Nay tách 2 grep: lọc dòng có SQL keyword, rồi lọc dòng có concat.
|
|
16
|
+
echo "### 1. Potential SQL Injection"
|
|
17
|
+
SQLI=$(grep -rnI --include="*.js" --include="*.ts" --include="*.py" -iE "(select|insert|update|delete)" "$DIR" 2>/dev/null \
|
|
18
|
+
| grep -E "(\\\$\{|['\"][[:space:]]*\+|\+[[:space:]]*['\"])")
|
|
19
|
+
if [ -n "$SQLI" ]; then echo "$SQLI"; else echo " ✅ None found"; fi
|
|
20
|
+
echo ""
|
|
21
|
+
|
|
22
|
+
# 2. Hardcoded secrets
|
|
23
|
+
echo "### 2. Hardcoded Secrets"
|
|
24
|
+
grep -rnI --include="*.js" --include="*.ts" --include="*.py" --include="*.json" \
|
|
25
|
+
-E "(password|api_?key|secret|token)\s*[=:]\s*['\"][^'\"]{8,}" \
|
|
26
|
+
"$DIR" 2>/dev/null | grep -v "node_modules\|\.env\.example\|test\|spec\|mock" || echo " ✅ None found"
|
|
27
|
+
echo ""
|
|
28
|
+
|
|
29
|
+
# 3. Sensitive data in logs
|
|
30
|
+
echo "### 3. Sensitive Data in Logs"
|
|
31
|
+
grep -rnI --include="*.js" --include="*.ts" --include="*.py" \
|
|
32
|
+
-E "console\.(log|info|debug|warn)\(.*([Pp]assword|[Tt]oken|[Ss]ecret|[Cc]redential)" \
|
|
33
|
+
"$DIR" 2>/dev/null || echo " ✅ None found"
|
|
34
|
+
echo ""
|
|
35
|
+
|
|
36
|
+
# 4. Missing input validation
|
|
37
|
+
echo "### 4. Direct req.body Usage (potential missing validation)"
|
|
38
|
+
# Bug cũ: `grep | head || echo` — head luôn exit 0 (kể cả input rỗng) nên "None found"
|
|
39
|
+
# không bao giờ in. Nay bắt vào biến rồi mới quyết định.
|
|
40
|
+
REQBODY=$(grep -rnI --include="*.js" --include="*.ts" -E "req\.body\.[a-zA-Z]+" "$DIR" 2>/dev/null | head -20)
|
|
41
|
+
if [ -n "$REQBODY" ]; then echo "$REQBODY"; else echo " ✅ None found"; fi
|
|
42
|
+
echo ""
|
|
43
|
+
|
|
44
|
+
# 5. Dangerous functions
|
|
45
|
+
echo "### 5. Dangerous Functions"
|
|
46
|
+
grep -rnI --include="*.js" --include="*.ts" \
|
|
47
|
+
-E "(eval\(|innerHTML\s*=|dangerouslySetInnerHTML|exec\(|child_process)" \
|
|
48
|
+
"$DIR" 2>/dev/null || echo " ✅ None found"
|
|
49
|
+
echo ""
|
|
50
|
+
|
|
51
|
+
echo "════════════════════════════════════════"
|
|
52
|
+
echo "📊 Scan complete. Review findings above."
|