codehava-agent-kit 1.0.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/README.md +56 -0
- package/bin/cli.js +56 -0
- package/package.json +26 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/templates/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/templates/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/templates/.agent/agents/backend-specialist.md +263 -0
- package/templates/.agent/agents/code-archaeologist.md +106 -0
- package/templates/.agent/agents/database-architect.md +226 -0
- package/templates/.agent/agents/debugger.md +225 -0
- package/templates/.agent/agents/devops-engineer.md +242 -0
- package/templates/.agent/agents/documentation-writer.md +104 -0
- package/templates/.agent/agents/explorer-agent.md +73 -0
- package/templates/.agent/agents/frontend-specialist.md +593 -0
- package/templates/.agent/agents/game-developer.md +162 -0
- package/templates/.agent/agents/mobile-developer.md +377 -0
- package/templates/.agent/agents/orchestrator.md +416 -0
- package/templates/.agent/agents/penetration-tester.md +188 -0
- package/templates/.agent/agents/performance-optimizer.md +187 -0
- package/templates/.agent/agents/product-manager.md +112 -0
- package/templates/.agent/agents/product-owner.md +95 -0
- package/templates/.agent/agents/project-planner.md +406 -0
- package/templates/.agent/agents/qa-automation-engineer.md +103 -0
- package/templates/.agent/agents/security-auditor.md +170 -0
- package/templates/.agent/agents/seo-specialist.md +111 -0
- package/templates/.agent/agents/test-engineer.md +158 -0
- package/templates/.agent/mcp_config.json +129 -0
- package/templates/.agent/rules/GEMINI.md +273 -0
- package/templates/.agent/scripts/auto_preview.py +148 -0
- package/templates/.agent/scripts/checklist.py +217 -0
- package/templates/.agent/scripts/session_manager.py +120 -0
- package/templates/.agent/scripts/verify_all.py +327 -0
- package/templates/.agent/skills/api-patterns/SKILL.md +81 -0
- package/templates/.agent/skills/api-patterns/api-style.md +42 -0
- package/templates/.agent/skills/api-patterns/auth.md +24 -0
- package/templates/.agent/skills/api-patterns/documentation.md +26 -0
- package/templates/.agent/skills/api-patterns/graphql.md +41 -0
- package/templates/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/templates/.agent/skills/api-patterns/response.md +37 -0
- package/templates/.agent/skills/api-patterns/rest.md +40 -0
- package/templates/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/templates/.agent/skills/api-patterns/security-testing.md +122 -0
- package/templates/.agent/skills/api-patterns/trpc.md +41 -0
- package/templates/.agent/skills/api-patterns/versioning.md +22 -0
- package/templates/.agent/skills/app-builder/SKILL.md +75 -0
- package/templates/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/templates/.agent/skills/app-builder/feature-building.md +53 -0
- package/templates/.agent/skills/app-builder/project-detection.md +34 -0
- package/templates/.agent/skills/app-builder/scaffolding.md +118 -0
- package/templates/.agent/skills/app-builder/tech-stack.md +41 -0
- package/templates/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/templates/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/templates/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/templates/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/templates/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/templates/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/templates/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/templates/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/templates/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/templates/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/templates/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/templates/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/templates/.agent/skills/architecture/SKILL.md +55 -0
- package/templates/.agent/skills/architecture/context-discovery.md +43 -0
- package/templates/.agent/skills/architecture/examples.md +94 -0
- package/templates/.agent/skills/architecture/pattern-selection.md +68 -0
- package/templates/.agent/skills/architecture/patterns-reference.md +50 -0
- package/templates/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/templates/.agent/skills/bash-linux/SKILL.md +199 -0
- package/templates/.agent/skills/behavioral-modes/SKILL.md +242 -0
- package/templates/.agent/skills/better-auth-patterns/SKILL.md +121 -0
- package/templates/.agent/skills/brainstorming/SKILL.md +163 -0
- package/templates/.agent/skills/brainstorming/dynamic-questioning.md +350 -0
- package/templates/.agent/skills/bullmq-worker/SKILL.md +124 -0
- package/templates/.agent/skills/clean-code/SKILL.md +201 -0
- package/templates/.agent/skills/code-review-checklist/SKILL.md +109 -0
- package/templates/.agent/skills/database-design/SKILL.md +52 -0
- package/templates/.agent/skills/database-design/database-selection.md +43 -0
- package/templates/.agent/skills/database-design/indexing.md +39 -0
- package/templates/.agent/skills/database-design/migrations.md +48 -0
- package/templates/.agent/skills/database-design/optimization.md +36 -0
- package/templates/.agent/skills/database-design/orm-selection.md +30 -0
- package/templates/.agent/skills/database-design/schema-design.md +56 -0
- package/templates/.agent/skills/database-design/scripts/schema_validator.py +172 -0
- package/templates/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/templates/.agent/skills/doc.md +177 -0
- package/templates/.agent/skills/documentation-templates/SKILL.md +194 -0
- package/templates/.agent/skills/feature-spec-writer/SKILL.md +76 -0
- package/templates/.agent/skills/frontend-design/SKILL.md +452 -0
- package/templates/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/templates/.agent/skills/frontend-design/color-system.md +311 -0
- package/templates/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/templates/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/templates/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/templates/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/templates/.agent/skills/frontend-design/typography-system.md +345 -0
- package/templates/.agent/skills/frontend-design/ux-psychology.md +1116 -0
- package/templates/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/templates/.agent/skills/game-development/2d-games/SKILL.md +119 -0
- package/templates/.agent/skills/game-development/3d-games/SKILL.md +135 -0
- package/templates/.agent/skills/game-development/SKILL.md +167 -0
- package/templates/.agent/skills/game-development/game-art/SKILL.md +185 -0
- package/templates/.agent/skills/game-development/game-audio/SKILL.md +190 -0
- package/templates/.agent/skills/game-development/game-design/SKILL.md +129 -0
- package/templates/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
- package/templates/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
- package/templates/.agent/skills/game-development/pc-games/SKILL.md +144 -0
- package/templates/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
- package/templates/.agent/skills/game-development/web-games/SKILL.md +150 -0
- package/templates/.agent/skills/geo-fundamentals/SKILL.md +156 -0
- package/templates/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
- package/templates/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/templates/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/templates/.agent/skills/intelligent-routing/SKILL.md +335 -0
- package/templates/.agent/skills/lint-and-validate/SKILL.md +45 -0
- package/templates/.agent/skills/lint-and-validate/scripts/lint_runner.py +184 -0
- package/templates/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
- package/templates/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/templates/.agent/skills/mobile-design/SKILL.md +394 -0
- package/templates/.agent/skills/mobile-design/decision-trees.md +516 -0
- package/templates/.agent/skills/mobile-design/mobile-backend.md +491 -0
- package/templates/.agent/skills/mobile-design/mobile-color-system.md +420 -0
- package/templates/.agent/skills/mobile-design/mobile-debugging.md +122 -0
- package/templates/.agent/skills/mobile-design/mobile-design-thinking.md +357 -0
- package/templates/.agent/skills/mobile-design/mobile-navigation.md +458 -0
- package/templates/.agent/skills/mobile-design/mobile-performance.md +767 -0
- package/templates/.agent/skills/mobile-design/mobile-testing.md +356 -0
- package/templates/.agent/skills/mobile-design/mobile-typography.md +433 -0
- package/templates/.agent/skills/mobile-design/platform-android.md +666 -0
- package/templates/.agent/skills/mobile-design/platform-ios.md +561 -0
- package/templates/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
- package/templates/.agent/skills/mobile-design/touch-psychology.md +537 -0
- package/templates/.agent/skills/neo-storage/SKILL.md +115 -0
- package/templates/.agent/skills/nextjs-api-route/SKILL.md +134 -0
- package/templates/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +351 -0
- package/templates/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +240 -0
- package/templates/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +490 -0
- package/templates/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +264 -0
- package/templates/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +581 -0
- package/templates/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +432 -0
- package/templates/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +684 -0
- package/templates/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +150 -0
- package/templates/.agent/skills/nextjs-react-expert/9-cache-components.md +103 -0
- package/templates/.agent/skills/nextjs-react-expert/SKILL.md +293 -0
- package/templates/.agent/skills/nextjs-react-expert/scripts/convert_rules.py +222 -0
- package/templates/.agent/skills/nextjs-react-expert/scripts/react_performance_checker.py +252 -0
- package/templates/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
- package/templates/.agent/skills/parallel-agents/SKILL.md +175 -0
- package/templates/.agent/skills/performance-profiling/SKILL.md +143 -0
- package/templates/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
- package/templates/.agent/skills/plan-writing/SKILL.md +152 -0
- package/templates/.agent/skills/powershell-windows/SKILL.md +167 -0
- package/templates/.agent/skills/prisma-7-patterns/SKILL.md +91 -0
- package/templates/.agent/skills/python-patterns/SKILL.md +441 -0
- package/templates/.agent/skills/red-team-tactics/SKILL.md +199 -0
- package/templates/.agent/skills/rust-pro/SKILL.md +176 -0
- package/templates/.agent/skills/seo-fundamentals/SKILL.md +129 -0
- package/templates/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
- package/templates/.agent/skills/server-management/SKILL.md +161 -0
- package/templates/.agent/skills/systematic-debugging/SKILL.md +109 -0
- package/templates/.agent/skills/tailwind-patterns/SKILL.md +269 -0
- package/templates/.agent/skills/tdd-workflow/SKILL.md +149 -0
- package/templates/.agent/skills/testing-patterns/SKILL.md +178 -0
- package/templates/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
- package/templates/.agent/skills/uu-pdp-feature-check/SKILL.md +116 -0
- package/templates/.agent/skills/vibe-buildplan/SKILL.md +232 -0
- package/templates/.agent/skills/vibe-prd/SKILL.md +226 -0
- package/templates/.agent/skills/vibe-research/SKILL.md +162 -0
- package/templates/.agent/skills/vibe-techdesign/SKILL.md +195 -0
- package/templates/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
- package/templates/.agent/skills/vulnerability-scanner/checklists.md +121 -0
- package/templates/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
- package/templates/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/templates/.agent/skills/webapp-testing/SKILL.md +187 -0
- package/templates/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
- package/templates/.agent/skills/xendit-integration/SKILL.md +100 -0
- package/templates/.agent/snippets/@react-component-template.tsx +29 -0
- package/templates/.agent/workflows/brainstorm.md +113 -0
- package/templates/.agent/workflows/create.md +59 -0
- package/templates/.agent/workflows/db-migrate.md +26 -0
- package/templates/.agent/workflows/debug.md +103 -0
- package/templates/.agent/workflows/deploy.md +35 -0
- package/templates/.agent/workflows/dev-reset.md +40 -0
- package/templates/.agent/workflows/enhance.md +63 -0
- package/templates/.agent/workflows/git-commit.md +24 -0
- package/templates/.agent/workflows/health-check.md +34 -0
- package/templates/.agent/workflows/new-feature.md +32 -0
- package/templates/.agent/workflows/orchestrate.md +237 -0
- package/templates/.agent/workflows/plan.md +89 -0
- package/templates/.agent/workflows/preview.md +81 -0
- package/templates/.agent/workflows/status.md +86 -0
- package/templates/.agent/workflows/test.md +144 -0
- package/templates/.agent/workflows/ui-ux-pro-max.md +296 -0
- package/templates/.agent/workflows/vibe-plan.md +133 -0
- package/templates/.agent/workflows/vibe-recap.md +17 -0
- package/templates/.antigravity/rules.md +64 -0
- package/templates/AGENTS.md +268 -0
- package/templates/docs/00A-PROJECT-CHARTER.md +33 -0
- package/templates/docs/00B-BRD.md +25 -0
- package/templates/docs/01-PRD.md +122 -0
- package/templates/docs/01B-SRS-LENGKAP.md +60 -0
- package/templates/docs/02-TECH-DESIGN.md +491 -0
- package/templates/docs/03-UI-GUIDELINES.md +301 -0
- package/templates/docs/04-BACKLOG.md +127 -0
- package/templates/docs/05-DEPLOYMENT.md +363 -0
- package/templates/docs/06-DEVELOPMENT-LOG.md +78 -0
- package/templates/specs/README.md +54 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Test Runner - Unified test execution and coverage reporting
|
|
4
|
+
Runs tests and generates coverage report based on project type.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
python test_runner.py <project_path> [--coverage]
|
|
8
|
+
|
|
9
|
+
Supports:
|
|
10
|
+
- Node.js: npm test, jest, vitest
|
|
11
|
+
- Python: pytest, unittest
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
import json
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
|
|
20
|
+
# Fix Windows console encoding
|
|
21
|
+
try:
|
|
22
|
+
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
|
|
23
|
+
except:
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def detect_test_framework(project_path: Path) -> dict:
|
|
28
|
+
"""Detect test framework and commands."""
|
|
29
|
+
result = {
|
|
30
|
+
"type": "unknown",
|
|
31
|
+
"framework": None,
|
|
32
|
+
"cmd": None,
|
|
33
|
+
"coverage_cmd": None
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# Node.js project
|
|
37
|
+
package_json = project_path / "package.json"
|
|
38
|
+
if package_json.exists():
|
|
39
|
+
result["type"] = "node"
|
|
40
|
+
try:
|
|
41
|
+
pkg = json.loads(package_json.read_text(encoding='utf-8'))
|
|
42
|
+
scripts = pkg.get("scripts", {})
|
|
43
|
+
deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}
|
|
44
|
+
|
|
45
|
+
# Check for test script
|
|
46
|
+
if "test" in scripts:
|
|
47
|
+
result["framework"] = "npm test"
|
|
48
|
+
result["cmd"] = ["npm", "test"]
|
|
49
|
+
|
|
50
|
+
# Try to detect specific framework for coverage
|
|
51
|
+
if "vitest" in deps:
|
|
52
|
+
result["framework"] = "vitest"
|
|
53
|
+
result["coverage_cmd"] = ["npx", "vitest", "run", "--coverage"]
|
|
54
|
+
elif "jest" in deps:
|
|
55
|
+
result["framework"] = "jest"
|
|
56
|
+
result["coverage_cmd"] = ["npx", "jest", "--coverage"]
|
|
57
|
+
elif "vitest" in deps:
|
|
58
|
+
result["framework"] = "vitest"
|
|
59
|
+
result["cmd"] = ["npx", "vitest", "run"]
|
|
60
|
+
result["coverage_cmd"] = ["npx", "vitest", "run", "--coverage"]
|
|
61
|
+
elif "jest" in deps:
|
|
62
|
+
result["framework"] = "jest"
|
|
63
|
+
result["cmd"] = ["npx", "jest"]
|
|
64
|
+
result["coverage_cmd"] = ["npx", "jest", "--coverage"]
|
|
65
|
+
|
|
66
|
+
except:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
# Python project
|
|
70
|
+
if (project_path / "pyproject.toml").exists() or (project_path / "requirements.txt").exists():
|
|
71
|
+
result["type"] = "python"
|
|
72
|
+
result["framework"] = "pytest"
|
|
73
|
+
result["cmd"] = ["python", "-m", "pytest", "-v"]
|
|
74
|
+
result["coverage_cmd"] = ["python", "-m", "pytest", "--cov", "--cov-report=term-missing"]
|
|
75
|
+
|
|
76
|
+
return result
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def run_tests(cmd: list, cwd: Path) -> dict:
|
|
80
|
+
"""Run tests and return results."""
|
|
81
|
+
result = {
|
|
82
|
+
"passed": False,
|
|
83
|
+
"output": "",
|
|
84
|
+
"error": "",
|
|
85
|
+
"tests_run": 0,
|
|
86
|
+
"tests_passed": 0,
|
|
87
|
+
"tests_failed": 0
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
proc = subprocess.run(
|
|
92
|
+
cmd,
|
|
93
|
+
cwd=str(cwd),
|
|
94
|
+
capture_output=True,
|
|
95
|
+
text=True,
|
|
96
|
+
encoding='utf-8',
|
|
97
|
+
errors='replace',
|
|
98
|
+
timeout=300 # 5 min timeout for tests
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
result["output"] = proc.stdout[:3000] if proc.stdout else ""
|
|
102
|
+
result["error"] = proc.stderr[:500] if proc.stderr else ""
|
|
103
|
+
result["passed"] = proc.returncode == 0
|
|
104
|
+
|
|
105
|
+
# Try to parse test counts from output
|
|
106
|
+
output = proc.stdout or ""
|
|
107
|
+
|
|
108
|
+
# Jest/Vitest pattern: "Tests: X passed, Y failed, Z total"
|
|
109
|
+
if "passed" in output.lower() and "failed" in output.lower():
|
|
110
|
+
import re
|
|
111
|
+
match = re.search(r'(\d+)\s+passed', output, re.IGNORECASE)
|
|
112
|
+
if match:
|
|
113
|
+
result["tests_passed"] = int(match.group(1))
|
|
114
|
+
match = re.search(r'(\d+)\s+failed', output, re.IGNORECASE)
|
|
115
|
+
if match:
|
|
116
|
+
result["tests_failed"] = int(match.group(1))
|
|
117
|
+
result["tests_run"] = result["tests_passed"] + result["tests_failed"]
|
|
118
|
+
|
|
119
|
+
# Pytest pattern: "X passed, Y failed"
|
|
120
|
+
if "pytest" in str(cmd):
|
|
121
|
+
import re
|
|
122
|
+
match = re.search(r'(\d+)\s+passed', output)
|
|
123
|
+
if match:
|
|
124
|
+
result["tests_passed"] = int(match.group(1))
|
|
125
|
+
match = re.search(r'(\d+)\s+failed', output)
|
|
126
|
+
if match:
|
|
127
|
+
result["tests_failed"] = int(match.group(1))
|
|
128
|
+
result["tests_run"] = result["tests_passed"] + result["tests_failed"]
|
|
129
|
+
|
|
130
|
+
except FileNotFoundError:
|
|
131
|
+
result["error"] = f"Command not found: {cmd[0]}"
|
|
132
|
+
except subprocess.TimeoutExpired:
|
|
133
|
+
result["error"] = "Timeout after 300s"
|
|
134
|
+
except Exception as e:
|
|
135
|
+
result["error"] = str(e)
|
|
136
|
+
|
|
137
|
+
return result
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def main():
|
|
141
|
+
project_path = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
|
|
142
|
+
with_coverage = "--coverage" in sys.argv
|
|
143
|
+
|
|
144
|
+
print(f"\n{'='*60}")
|
|
145
|
+
print(f"[TEST RUNNER] Unified Test Execution")
|
|
146
|
+
print(f"{'='*60}")
|
|
147
|
+
print(f"Project: {project_path}")
|
|
148
|
+
print(f"Coverage: {'enabled' if with_coverage else 'disabled'}")
|
|
149
|
+
print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
|
150
|
+
|
|
151
|
+
# Detect test framework
|
|
152
|
+
test_info = detect_test_framework(project_path)
|
|
153
|
+
print(f"Type: {test_info['type']}")
|
|
154
|
+
print(f"Framework: {test_info['framework']}")
|
|
155
|
+
print("-"*60)
|
|
156
|
+
|
|
157
|
+
if not test_info["cmd"]:
|
|
158
|
+
print("No test framework found for this project.")
|
|
159
|
+
output = {
|
|
160
|
+
"script": "test_runner",
|
|
161
|
+
"project": str(project_path),
|
|
162
|
+
"type": test_info["type"],
|
|
163
|
+
"framework": None,
|
|
164
|
+
"passed": True,
|
|
165
|
+
"message": "No tests configured"
|
|
166
|
+
}
|
|
167
|
+
print(json.dumps(output, indent=2))
|
|
168
|
+
sys.exit(0)
|
|
169
|
+
|
|
170
|
+
# Choose command
|
|
171
|
+
cmd = test_info["coverage_cmd"] if with_coverage and test_info["coverage_cmd"] else test_info["cmd"]
|
|
172
|
+
|
|
173
|
+
print(f"Running: {' '.join(cmd)}")
|
|
174
|
+
print("-"*60)
|
|
175
|
+
|
|
176
|
+
# Run tests
|
|
177
|
+
result = run_tests(cmd, project_path)
|
|
178
|
+
|
|
179
|
+
# Print output (truncated)
|
|
180
|
+
if result["output"]:
|
|
181
|
+
lines = result["output"].split("\n")
|
|
182
|
+
for line in lines[:30]:
|
|
183
|
+
print(line)
|
|
184
|
+
if len(lines) > 30:
|
|
185
|
+
print(f"... ({len(lines) - 30} more lines)")
|
|
186
|
+
|
|
187
|
+
# Summary
|
|
188
|
+
print("\n" + "="*60)
|
|
189
|
+
print("SUMMARY")
|
|
190
|
+
print("="*60)
|
|
191
|
+
|
|
192
|
+
if result["passed"]:
|
|
193
|
+
print("[PASS] All tests passed")
|
|
194
|
+
else:
|
|
195
|
+
print("[FAIL] Some tests failed")
|
|
196
|
+
if result["error"]:
|
|
197
|
+
print(f"Error: {result['error'][:200]}")
|
|
198
|
+
|
|
199
|
+
if result["tests_run"] > 0:
|
|
200
|
+
print(f"Tests: {result['tests_run']} total, {result['tests_passed']} passed, {result['tests_failed']} failed")
|
|
201
|
+
|
|
202
|
+
output = {
|
|
203
|
+
"script": "test_runner",
|
|
204
|
+
"project": str(project_path),
|
|
205
|
+
"type": test_info["type"],
|
|
206
|
+
"framework": test_info["framework"],
|
|
207
|
+
"tests_run": result["tests_run"],
|
|
208
|
+
"tests_passed": result["tests_passed"],
|
|
209
|
+
"tests_failed": result["tests_failed"],
|
|
210
|
+
"passed": result["passed"]
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
print("\n" + json.dumps(output, indent=2))
|
|
214
|
+
|
|
215
|
+
sys.exit(0 if result["passed"] else 1)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
if __name__ == "__main__":
|
|
219
|
+
main()
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uu-pdp-feature-check
|
|
3
|
+
description: |
|
|
4
|
+
Use when building any feature that collects, stores, displays, or processes
|
|
5
|
+
user personal data. Triggers on "user data", "personal info", "profile",
|
|
6
|
+
"upload", "store user", "collect", "privacy", "consent", or when creating
|
|
7
|
+
new database models with user-related fields. Do NOT use for pure UI/styling tasks.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# UU PDP Compliance — Checklist Fitur Baru
|
|
11
|
+
|
|
12
|
+
Setiap fitur yang menyentuh data pribadi pengguna WAJIB melewati checklist ini.
|
|
13
|
+
|
|
14
|
+
## 1. Identifikasi Data
|
|
15
|
+
|
|
16
|
+
Sebelum coding, tentukan:
|
|
17
|
+
- **Data apa** yang dikumpulkan fitur ini?
|
|
18
|
+
- **Kategori mana**: Data Umum (nama, email, HP, alamat) atau Data Spesifik/Sensitif (NIK, rekening, kesehatan, biometrik, data anak)?
|
|
19
|
+
- **Tujuan**: untuk apa data ini dipakai?
|
|
20
|
+
- **Retensi**: berapa lama data disimpan?
|
|
21
|
+
|
|
22
|
+
## 2. Checklist Implementasi
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
□ Consent tersedia sebelum data dikumpulkan
|
|
26
|
+
→ Jika data baru yang belum ada consent-nya, update consent flow
|
|
27
|
+
|
|
28
|
+
□ Data minimization — hanya kumpulkan yang benar-benar dibutuhkan
|
|
29
|
+
→ Hapus field yang "nice to have" tapi tidak essential
|
|
30
|
+
|
|
31
|
+
□ Data sensitif dienkripsi di kolom database
|
|
32
|
+
→ NIK, nomor rekening, data kesehatan: gunakan pgcrypto
|
|
33
|
+
|
|
34
|
+
□ Audit log tersedia untuk akses ke data ini
|
|
35
|
+
→ Siapa mengakses, kapan, dari IP mana
|
|
36
|
+
|
|
37
|
+
□ User bisa lihat/edit/hapus data ini dari settings
|
|
38
|
+
→ Terhubung ke fitur "Unduh Data" dan "Hapus Akun"
|
|
39
|
+
|
|
40
|
+
□ Data TIDAK dikirim ke layanan luar negeri dalam bentuk raw
|
|
41
|
+
→ Cloudflare/Firebase/Resend: pastikan hanya metadata, bukan data sensitif
|
|
42
|
+
|
|
43
|
+
□ Log tidak mengandung data PII
|
|
44
|
+
→ console.log TIDAK boleh print NIK, password, nomor rekening, token
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 3. Pola Enkripsi Kolom Sensitif (PostgreSQL)
|
|
48
|
+
|
|
49
|
+
```sql
|
|
50
|
+
-- Aktifkan pgcrypto (sekali saja)
|
|
51
|
+
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
|
52
|
+
|
|
53
|
+
-- Simpan data terenkripsi
|
|
54
|
+
UPDATE users
|
|
55
|
+
SET nik_encrypted = pgp_sym_encrypt(nik_plaintext, current_setting('app.encryption_key'))
|
|
56
|
+
WHERE id = $1;
|
|
57
|
+
|
|
58
|
+
-- Baca data terenkripsi
|
|
59
|
+
SELECT pgp_sym_decrypt(nik_encrypted::bytea, current_setting('app.encryption_key'))
|
|
60
|
+
FROM users WHERE id = $1;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```prisma
|
|
64
|
+
// Di schema.prisma: simpan sebagai Bytes untuk data terenkripsi
|
|
65
|
+
model User {
|
|
66
|
+
nikEncrypted Bytes? // Terenkripsi via pgcrypto
|
|
67
|
+
// JANGAN buat field nikPlaintext
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 4. Audit Log Pattern
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// lib/audit/index.ts
|
|
75
|
+
export async function logDataAccess(params: {
|
|
76
|
+
actorId: string
|
|
77
|
+
action: 'VIEW' | 'EDIT' | 'DELETE' | 'EXPORT'
|
|
78
|
+
resourceType: string
|
|
79
|
+
resourceId: string
|
|
80
|
+
ipAddress: string
|
|
81
|
+
}) {
|
|
82
|
+
await prisma.auditLog.create({
|
|
83
|
+
data: {
|
|
84
|
+
...params,
|
|
85
|
+
createdAt: new Date(),
|
|
86
|
+
// Audit log: append-only, tidak ada updatedAt
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 5. Yang TIDAK BOLEH Dilakukan
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// ❌ Log data sensitif
|
|
96
|
+
console.log('User NIK:', user.nik)
|
|
97
|
+
console.log('Payment token:', token)
|
|
98
|
+
|
|
99
|
+
// ❌ Kirim data sensitif ke Resend sebagai email content
|
|
100
|
+
await resend.emails.send({ html: `NIK kamu: ${user.nik}` })
|
|
101
|
+
|
|
102
|
+
// ❌ Simpan PII di URL/query params
|
|
103
|
+
router.push(`/verify?nik=${nik}`)
|
|
104
|
+
|
|
105
|
+
// ❌ Hard-code data sensitif di kode
|
|
106
|
+
const adminNIK = '3201...'
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 6. Layanan Luar Negeri — Batasan
|
|
110
|
+
|
|
111
|
+
| Layanan | Boleh Kirim | JANGAN Kirim |
|
|
112
|
+
|---------|-------------|--------------|
|
|
113
|
+
| Cloudflare | Headers, IP (sudah ada DPA) | Konten body yang terenkripsi |
|
|
114
|
+
| Firebase FCM | Device token, notif payload | NIK, data rekening, data kesehatan |
|
|
115
|
+
| Resend | Alamat email, teks notifikasi umum | NIK, nomor rekening, data medis |
|
|
116
|
+
| Sentry | Error message, stack trace | Password, token auth, NIK |
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vibe-buildplan
|
|
3
|
+
description: |
|
|
4
|
+
Use after vibe-techdesign. Generates sprint plan and initial backlog from PRD.
|
|
5
|
+
Triggers on "buat sprint plan", "breakdown task", "berapa sprint",
|
|
6
|
+
"buat backlog dari PRD", "rencana build", "mulai sprint pertama",
|
|
7
|
+
or /vibe-plan step 4.
|
|
8
|
+
Requires: docs/01-PRD.md + docs/02-TECH-DESIGN.md
|
|
9
|
+
Output: docs/04-BACKLOG.md (terisi) + BUILD_PLAN.md
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Vibe Build Plan — Sprint Planner dari PRD
|
|
13
|
+
|
|
14
|
+
Skill ini mengubah PRD + Tech Design menjadi sprint plan yang konkret dan siap dikerjakan.
|
|
15
|
+
Output: backlog terisi + BUILD_PLAN.md sebagai panduan build phase.
|
|
16
|
+
|
|
17
|
+
## Persiapan
|
|
18
|
+
|
|
19
|
+
Baca kedua file ini sebelum mulai:
|
|
20
|
+
- `docs/01-PRD.md` — untuk user stories dan fitur
|
|
21
|
+
- `docs/02-TECH-DESIGN.md` — untuk stack dan ERD
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Pertanyaan yang Diajukan
|
|
26
|
+
|
|
27
|
+
**Q1:** "Berapa lama satu sprint? (1 minggu / 2 minggu)"
|
|
28
|
+
|
|
29
|
+
**Q2:** "Berapa jam per hari yang bisa dialokasikan untuk coding?
|
|
30
|
+
(termasuk semua anggota tim — contoh: 2 developer × 4 jam/hari = 8 jam/hari)"
|
|
31
|
+
|
|
32
|
+
**Q3:** "Target berapa sprint untuk MVP yang bisa di-launch?"
|
|
33
|
+
|
|
34
|
+
**Q4:** "Ada task teknis yang sudah harus ada sebelum coding fitur?
|
|
35
|
+
(setup Docker, CI/CD, domain, SSL, dll)"
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Logic: Kalkulasi Kapasitas
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
Total jam per sprint = jam/hari × hari kerja per sprint
|
|
43
|
+
Buffer factor = 0.7 (ambil 70% kapasitas untuk hal tak terduga)
|
|
44
|
+
Efektif per sprint = total jam × 0.7
|
|
45
|
+
|
|
46
|
+
Size → jam estimasi:
|
|
47
|
+
XS = 1 jam
|
|
48
|
+
S = 2 jam
|
|
49
|
+
M = 4 jam
|
|
50
|
+
L = 8 jam
|
|
51
|
+
XL = 16 jam (harus dipecah)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Output 1: `docs/04-BACKLOG.md` (TERISI dari PRD)
|
|
57
|
+
|
|
58
|
+
Generate backlog dengan task konkret dari setiap REQ di PRD:
|
|
59
|
+
|
|
60
|
+
```markdown
|
|
61
|
+
# 04 — Sprint Backlog — [Nama Aplikasi]
|
|
62
|
+
> Dibuat dari PRD [tanggal] | Update setiap sprint
|
|
63
|
+
|
|
64
|
+
## 📋 Sprint 1 — Setup & Foundation
|
|
65
|
+
|
|
66
|
+
**Goal:** Environment siap, auth berfungsi, dapat login
|
|
67
|
+
**Kapasitas:** [X] jam efektif
|
|
68
|
+
|
|
69
|
+
### 🔴 In Progress
|
|
70
|
+
| ID | Task | PIC | Notes |
|
|
71
|
+
|----|------|-----|-------|
|
|
72
|
+
| — | — | — | — |
|
|
73
|
+
|
|
74
|
+
### 🟡 Todo
|
|
75
|
+
| ID | Task | Size | Estimasi | REQ ref |
|
|
76
|
+
|----|------|------|----------|---------|
|
|
77
|
+
| T001 | Setup monorepo + Docker Compose (postgres:17, redis:7.4) | S | 2j | — |
|
|
78
|
+
| T002 | Setup Next.js 16.1 + Prisma 7 + schema awal | S | 2j | — |
|
|
79
|
+
| T003 | Better Auth 1.5 — login email + Google OAuth | M | 4j | REQ-001, REQ-002 |
|
|
80
|
+
| T004 | Layout dashboard + protected routes | M | 4j | REQ-001 |
|
|
81
|
+
| T005 | Halaman login + register (web) | M | 4j | REQ-001 |
|
|
82
|
+
| T006 | Setup GitHub Actions → Coolify CI/CD | S | 2j | — |
|
|
83
|
+
| [T00X] | [task lain dari PRD jika muat] | [size] | [jam] | [REQ] |
|
|
84
|
+
|
|
85
|
+
**Total estimasi Sprint 1:** [X] jam
|
|
86
|
+
|
|
87
|
+
### 🟢 Done
|
|
88
|
+
| ID | Task | Selesai |
|
|
89
|
+
|----|------|---------|
|
|
90
|
+
| — | — | — |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 📋 Sprint 2 — [Core Feature Utama dari PRD]
|
|
95
|
+
|
|
96
|
+
**Goal:** [fitur P0 pertama berjalan end-to-end]
|
|
97
|
+
**Kapasitas:** [X] jam efektif
|
|
98
|
+
|
|
99
|
+
### 🟡 Todo
|
|
100
|
+
| ID | Task | Size | Estimasi | REQ ref |
|
|
101
|
+
|----|------|------|----------|---------|
|
|
102
|
+
| T010 | [task dari F02 di PRD] | M | 4j | REQ-010 |
|
|
103
|
+
| T011 | [task dari F02 lanjutan] | M | 4j | REQ-011 |
|
|
104
|
+
| T012 | [task dari F03 di PRD] | L | 8j | REQ-012 |
|
|
105
|
+
| [dst berdasarkan PRD] | | | | |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## 📋 Sprint 3 — [Payment + Notifikasi jika ada]
|
|
110
|
+
|
|
111
|
+
[Generate berdasarkan P0 yang tersisa di PRD]
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 📦 Product Backlog (P1 — Sprint Berikutnya)
|
|
116
|
+
|
|
117
|
+
[Semua fitur P1 dari PRD, dipecah jadi task]
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 🐛 Bug Log
|
|
122
|
+
| ID | Deskripsi | Severity | Status | Ditemukan |
|
|
123
|
+
|----|-----------|----------|--------|-----------|
|
|
124
|
+
| — | — | — | — | — |
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Output 2: `BUILD_PLAN.md` (baru, di root)
|
|
130
|
+
|
|
131
|
+
```markdown
|
|
132
|
+
# BUILD_PLAN — [Nama Aplikasi]
|
|
133
|
+
> Panduan build phase untuk agent dan developer
|
|
134
|
+
> Dibuat: [tanggal] | Berdasarkan: PRD v0.1 + Tech Design
|
|
135
|
+
|
|
136
|
+
## Overview
|
|
137
|
+
|
|
138
|
+
| Sprint | Goal | Deliverable |
|
|
139
|
+
|--------|------|-------------|
|
|
140
|
+
| Sprint 1 | Setup + Auth | App bisa login, deploy ke staging |
|
|
141
|
+
| Sprint 2 | [core feature] | [deliverable konkret] |
|
|
142
|
+
| Sprint 3 | [feature lanjut] | [deliverable] |
|
|
143
|
+
| Sprint N | Polish + Launch | App siap production |
|
|
144
|
+
|
|
145
|
+
**Total estimasi:** [N] sprint × [X] minggu = [Y] minggu
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Cara Pakai Build Plan ini dengan Antigravity
|
|
150
|
+
|
|
151
|
+
### Per Fitur Baru (size M/L)
|
|
152
|
+
```
|
|
153
|
+
1. Jalankan /new-feature
|
|
154
|
+
2. Agent buat spec di specs/NNN-nama-fitur.md
|
|
155
|
+
3. Review spec → approve
|
|
156
|
+
4. Agent implementasi sesuai acceptance criteria
|
|
157
|
+
5. /git-commit → /deploy
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Urutan Build yang Benar
|
|
161
|
+
|
|
162
|
+
**Phase 1: Foundation (Sprint 1)**
|
|
163
|
+
Jangan coding fitur sebelum ini selesai:
|
|
164
|
+
- [ ] Docker Compose jalan (postgres + redis)
|
|
165
|
+
- [ ] Prisma migrate berhasil
|
|
166
|
+
- [ ] Auth berjalan (bisa login + logout)
|
|
167
|
+
- [ ] Deploy ke staging berhasil
|
|
168
|
+
- [ ] Health check endpoint aktif
|
|
169
|
+
|
|
170
|
+
**Phase 2: Core Features (Sprint 2-3)**
|
|
171
|
+
Build fitur berdasarkan urutan REQ di PRD:
|
|
172
|
+
- [ ] [REQ-010] — [nama fitur]
|
|
173
|
+
- [ ] [REQ-011] — [nama fitur]
|
|
174
|
+
- [ ] dst berdasarkan PRD
|
|
175
|
+
|
|
176
|
+
**Phase 3: Payment & Notifikasi (jika ada)**
|
|
177
|
+
- [ ] Xendit sandbox setup
|
|
178
|
+
- [ ] Webhook handler + BullMQ
|
|
179
|
+
- [ ] FCM push notif
|
|
180
|
+
- [ ] Email via Resend
|
|
181
|
+
|
|
182
|
+
**Phase 4: UU PDP & Security**
|
|
183
|
+
Wajib sebelum launch:
|
|
184
|
+
- [ ] Fitur hapus akun
|
|
185
|
+
- [ ] Fitur unduh data
|
|
186
|
+
- [ ] Privacy Policy live
|
|
187
|
+
- [ ] Cloudflare DPA accepted
|
|
188
|
+
- [ ] Firebase DPT accepted
|
|
189
|
+
|
|
190
|
+
**Phase 5: Launch Preparation**
|
|
191
|
+
- [ ] Load testing
|
|
192
|
+
- [ ] Security review
|
|
193
|
+
- [ ] Monitoring aktif (Uptime Kuma + Sentry)
|
|
194
|
+
- [ ] Backup strategy running
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Prompt Template untuk Build Phase
|
|
199
|
+
|
|
200
|
+
Gunakan format ini di Antigravity untuk setiap task:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
[KONTEKS] Sprint [N] — Task T0XX: [nama task]
|
|
204
|
+
[REQ] REQ-XXX dari PRD
|
|
205
|
+
[TUGAS] [deskripsi spesifik sesuai acceptance criteria]
|
|
206
|
+
[CONSTRAINT] Jangan ubah: [files yang tidak boleh diubah]
|
|
207
|
+
use context7
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Definition of Done per Task
|
|
213
|
+
|
|
214
|
+
Task dianggap selesai jika:
|
|
215
|
+
- [ ] Kode ter-commit dengan format benar
|
|
216
|
+
- [ ] TypeScript strict — tidak ada error
|
|
217
|
+
- [ ] Loading/Empty/Error state ada (untuk komponen UI)
|
|
218
|
+
- [ ] Input divalidasi dengan Zod
|
|
219
|
+
- [ ] Error handling ada di setiap async function
|
|
220
|
+
- [ ] Di-test manual di browser/device
|
|
221
|
+
- [ ] Di-update di backlog (pindah ke Done)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Aturan Penting
|
|
227
|
+
|
|
228
|
+
- Task harus konkret dan bisa selesai dalam satu sesi coding (≤ 4 jam)
|
|
229
|
+
- XL task harus dipecah sebelum masuk sprint — jangan taruh di backlog sebagai XL
|
|
230
|
+
- Sprint 1 selalu: setup infrastruktur + auth — jangan ada fitur business logic di sprint 1
|
|
231
|
+
- Urutan task harus memperhatikan dependency: DB schema dulu, baru UI
|
|
232
|
+
- Setelah generate, reminder: "Build plan siap. Mulai dengan Sprint 1 Task T001 — ketik `/new-feature` jika siap."
|