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,491 @@
|
|
|
1
|
+
# 02 — Tech Design Document (TDD)
|
|
2
|
+
> Dokumen teknis utama. AI merujuk file ini untuk setiap keputusan arsitektur.
|
|
3
|
+
> Update setiap kali ada keputusan teknis baru — catat di `06-DEVELOPMENT-LOG.md`.
|
|
4
|
+
> **Versi stack diverifikasi: Maret 2026**
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Tech Stack Final
|
|
9
|
+
|
|
10
|
+
### Runtime
|
|
11
|
+
| Layer | Teknologi | Versi | Keterangan |
|
|
12
|
+
|-------|-----------|-------|------------|
|
|
13
|
+
| Runtime | Node.js | **22 LTS (Jod)** | Active LTS s/d April 2027 — pakai di semua Dockerfile |
|
|
14
|
+
| Language | TypeScript | **5.x** | Strict mode wajib — no `any` |
|
|
15
|
+
|
|
16
|
+
### Frontend Web
|
|
17
|
+
| Layer | Teknologi | Versi | Keterangan |
|
|
18
|
+
|-------|-----------|-------|------------|
|
|
19
|
+
| Framework | Next.js | **16.1** | App Router, Turbopack default — wajib ≥16.1 (CVE di 16.0.x) |
|
|
20
|
+
| React | React | **19.x** | Bundled dengan Next.js 16 |
|
|
21
|
+
| UI Components | shadcn/ui | Latest | Source code di-copy ke `/components/ui/`, bukan dependency |
|
|
22
|
+
| Styling | Tailwind CSS | **3.x** | Mobile-first |
|
|
23
|
+
| State | Zustand | Latest | Client-side state |
|
|
24
|
+
| Form | React Hook Form + Zod | Latest | Validasi client + server |
|
|
25
|
+
| Data Fetching (default) | Server Components | built-in Next.js | Fetch di server — zero bundle, SEO |
|
|
26
|
+
| Data Fetching (client) | TanStack Query | Latest | Mutations, optimistic UI, realtime sync |
|
|
27
|
+
| Realtime | Socket.io Client | Latest | Connect ke Socket.io server |
|
|
28
|
+
|
|
29
|
+
### Mobile App
|
|
30
|
+
| Layer | Teknologi | Versi | Keterangan |
|
|
31
|
+
|-------|-----------|-------|------------|
|
|
32
|
+
| Framework | Flutter | **3.41.2** | Stable channel, Dart **3.10** |
|
|
33
|
+
| State | Riverpod | Latest | State management modern |
|
|
34
|
+
| HTTP | Dio | Latest | API calls + auth interceptors |
|
|
35
|
+
| Realtime | socket_io_client | Latest | Flutter Socket.io client |
|
|
36
|
+
| Push Notif | firebase_messaging | Latest | **HANYA package ini** — jangan tambah analytics/crashlytics |
|
|
37
|
+
| Local Cache | Hive | Latest | Offline data storage |
|
|
38
|
+
|
|
39
|
+
### Backend & Database
|
|
40
|
+
| Layer | Teknologi | Versi | Keterangan |
|
|
41
|
+
|-------|-----------|-------|------------|
|
|
42
|
+
| Database | PostgreSQL | **17** | Self-hosted Docker — VPS terpisah di production |
|
|
43
|
+
| ORM | Prisma | **7.x** | Rust-free — import dari `@/generated/prisma` |
|
|
44
|
+
| Auth | Better Auth | **1.5.x** | Email/password + Google OAuth |
|
|
45
|
+
| Background Jobs | BullMQ | **5.x** | Redis-backed queue |
|
|
46
|
+
| Realtime Server | Socket.io | Latest | WebSocket — shared Redis dengan BullMQ |
|
|
47
|
+
| Cache / PubSub | Redis | **7.4 LTS** | Shared BullMQ + Socket.io — Redis 8 hindari (beta) |
|
|
48
|
+
| Email | Resend | Latest | Transactional — free 3k/bulan |
|
|
49
|
+
| File Storage | NEO Object Storage | — | S3-compatible, Biznet Gio, Indonesia |
|
|
50
|
+
| Payment | Xendit | Latest | Split payment + disbursement |
|
|
51
|
+
| Push Notif | Firebase FCM | — | Hanya push notif — wajib accept Firebase DPT |
|
|
52
|
+
|
|
53
|
+
### Infrastructure
|
|
54
|
+
| Layer | Teknologi | Keterangan |
|
|
55
|
+
|-------|-----------|------------|
|
|
56
|
+
| VPS | Biznet Gio | Ubuntu **22.04 LTS** — Indonesia, comply UU PDP |
|
|
57
|
+
| Platform | Coolify | Self-hosted PaaS |
|
|
58
|
+
| Container | Docker + Compose | Semua service containerized |
|
|
59
|
+
| Proxy | Traefik (via Coolify) | Auto SSL + routing |
|
|
60
|
+
| CDN / DNS | Cloudflare Free | DDoS + cache — **wajib accept DPA** → Dashboard → Privacy |
|
|
61
|
+
| CI/CD | GitHub Actions → Coolify | Auto-deploy on push ke main |
|
|
62
|
+
| Monitoring | Uptime Kuma + Sentry | Uptime alert + error tracking |
|
|
63
|
+
| IDE | Antigravity | Skills + Workflows + MCP |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## ⚠️ Breaking Changes Wajib Diketahui
|
|
68
|
+
|
|
69
|
+
| Paket | Perubahan | Action |
|
|
70
|
+
|-------|-----------|--------|
|
|
71
|
+
| **Next.js 16** | `params`, `searchParams`, `headers()` sekarang async | Selalu `await params` dan `await headers()` |
|
|
72
|
+
| **Next.js 16** | Turbopack default bundler | Tidak perlu flag manual |
|
|
73
|
+
| **Next.js 16** | Tidak ada caching by default | Opt-in via `use cache` |
|
|
74
|
+
| **Next.js 16** | CVE di 16.0.x | Wajib pakai ≥16.1 — `npx @next/codemod@canary upgrade latest` |
|
|
75
|
+
| **Prisma 7** | Generator: `"prisma-client"` (bukan `"prisma-client-js"`) | Update `schema.prisma` |
|
|
76
|
+
| **Prisma 7** | Import dari `@/generated/prisma` | Update semua import |
|
|
77
|
+
| **Prisma 7** | Butuh `@prisma/adapter-pg` | Install adapter |
|
|
78
|
+
| **Flutter 3.41** | UIScene lifecycle default untuk iOS | Ikuti Apple UIScene migration guide |
|
|
79
|
+
| **Better Auth 1.5** | Semua deprecated API dihapus | Cek changelog jika upgrade dari <1.4 |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 2. Arsitektur Sistem
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
87
|
+
│ CLIENT LAYER │
|
|
88
|
+
│ Next.js Web App Flutter Mobile App │
|
|
89
|
+
└───────────────┬─────────────────────────┬───────────────────┘
|
|
90
|
+
│ HTTPS / WebSocket │ HTTPS / WebSocket
|
|
91
|
+
▼ ▼
|
|
92
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
93
|
+
│ Cloudflare (DNS + DDoS + Cache) [DPA ✓] │
|
|
94
|
+
└─────────────────────────┬───────────────────────────────────┘
|
|
95
|
+
▼
|
|
96
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
97
|
+
│ Traefik Reverse Proxy + Auto SSL │
|
|
98
|
+
│ [Coolify — VPS Biznet Gio] │
|
|
99
|
+
└──────────┬──────────────────────────────────────────────────┘
|
|
100
|
+
├─────────────────────┐
|
|
101
|
+
┌──────────▼────────┐ ┌────────▼────────────────┐
|
|
102
|
+
│ Next.js :3000 │ │ BullMQ Worker :3001 │
|
|
103
|
+
│ App Router │ │ Socket.io Server │
|
|
104
|
+
│ API Routes │ │ Background Jobs │
|
|
105
|
+
│ Better Auth │ └─────────────────────────┘
|
|
106
|
+
└──────────┬────────┘
|
|
107
|
+
└──────────────────┬──────────────────────
|
|
108
|
+
│
|
|
109
|
+
┌──────────────────┼──────────────────────┐
|
|
110
|
+
▼ ▼ ▼
|
|
111
|
+
┌────────────────┐ ┌────────────────┐ ┌──────────────────────┐
|
|
112
|
+
│ PostgreSQL :5432│ │ Redis :6379 │ │ NEO Object Storage │
|
|
113
|
+
│ (VPS terpisah) │ │ BullMQ + Socket│ │ nos.wjv-1.neo.id │
|
|
114
|
+
└────────────────┘ └────────────────┘ └──────────────────────┘
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 3. Struktur Folder
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
[project-root]/
|
|
123
|
+
├── AGENTS.md ← instruksi AI (root)
|
|
124
|
+
├── .antigravity/rules.md
|
|
125
|
+
├── .agent/
|
|
126
|
+
│ ├── skills/ ← 8 skills
|
|
127
|
+
│ ├── workflows/ ← 6 workflows
|
|
128
|
+
│ └── mcp_config.json
|
|
129
|
+
├── docs/
|
|
130
|
+
│ ├── 01-PRD.md
|
|
131
|
+
│ ├── 02-TECH-DESIGN.md
|
|
132
|
+
│ ├── 03-UI-GUIDELINES.md
|
|
133
|
+
│ ├── 04-BACKLOG.md
|
|
134
|
+
│ ├── 05-DEPLOYMENT.md
|
|
135
|
+
│ └── 06-DEVELOPMENT-LOG.md
|
|
136
|
+
├── specs/
|
|
137
|
+
├── apps/
|
|
138
|
+
│ ├── web/ ← Next.js 16
|
|
139
|
+
│ └── mobile/ ← Flutter 3.41
|
|
140
|
+
├── docker-compose.yml
|
|
141
|
+
└── README.md
|
|
142
|
+
|
|
143
|
+
apps/web/
|
|
144
|
+
├── app/
|
|
145
|
+
│ ├── (auth)/login/page.tsx
|
|
146
|
+
│ ├── (dashboard)/layout.tsx ← protected layout
|
|
147
|
+
│ ├── api/
|
|
148
|
+
│ │ ├── auth/[...all]/route.ts ← Better Auth handler
|
|
149
|
+
│ │ └── payment/webhook/route.ts
|
|
150
|
+
│ └── layout.tsx
|
|
151
|
+
├── components/
|
|
152
|
+
│ ├── ui/ ← shadcn (source code)
|
|
153
|
+
│ └── [feature]/
|
|
154
|
+
├── lib/
|
|
155
|
+
│ ├── auth/auth.ts ← Better Auth server
|
|
156
|
+
│ ├── auth/auth-client.ts ← Better Auth client
|
|
157
|
+
│ ├── db/index.ts ← Prisma singleton
|
|
158
|
+
│ ├── payment/xendit.ts
|
|
159
|
+
│ ├── queue/index.ts ← BullMQ + QUEUES konstanta
|
|
160
|
+
│ ├── socket/index.ts
|
|
161
|
+
│ ├── storage/index.ts ← NEO Object Storage
|
|
162
|
+
│ └── redis/index.ts
|
|
163
|
+
├── prisma/schema.prisma
|
|
164
|
+
└── src/generated/prisma/ ← generated client (jangan edit)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 4. Prisma 7 — Setup & Patterns
|
|
170
|
+
|
|
171
|
+
### schema.prisma
|
|
172
|
+
```prisma
|
|
173
|
+
generator client {
|
|
174
|
+
provider = "prisma-client"
|
|
175
|
+
output = "../src/generated/prisma"
|
|
176
|
+
}
|
|
177
|
+
datasource db {
|
|
178
|
+
provider = "postgresql"
|
|
179
|
+
url = env("DATABASE_URL")
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Singleton (`lib/db/index.ts`)
|
|
184
|
+
```typescript
|
|
185
|
+
import { PrismaClient } from '@/generated/prisma'
|
|
186
|
+
import { PrismaPg } from '@prisma/adapter-pg'
|
|
187
|
+
|
|
188
|
+
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL! })
|
|
189
|
+
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }
|
|
190
|
+
export const prisma = globalForPrisma.prisma ?? new PrismaClient({ adapter })
|
|
191
|
+
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Konvensi Schema
|
|
195
|
+
```prisma
|
|
196
|
+
model Order {
|
|
197
|
+
id String @id @default(cuid())
|
|
198
|
+
userId String
|
|
199
|
+
status OrderStatus @default(PENDING)
|
|
200
|
+
total Decimal @db.Decimal(12, 2)
|
|
201
|
+
createdAt DateTime @default(now())
|
|
202
|
+
updatedAt DateTime @updatedAt
|
|
203
|
+
deletedAt DateTime? // soft delete
|
|
204
|
+
user User @relation(fields: [userId], references: [id])
|
|
205
|
+
items OrderItem[]
|
|
206
|
+
@@map("orders")
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Migration Commands
|
|
211
|
+
```bash
|
|
212
|
+
npx prisma migrate dev --name nama_migration # development
|
|
213
|
+
npx prisma migrate deploy # production (JANGAN pakai dev)
|
|
214
|
+
npx prisma generate # setelah ubah schema
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 5. Better Auth 1.5
|
|
220
|
+
|
|
221
|
+
### Server Config (`lib/auth/auth.ts`)
|
|
222
|
+
```typescript
|
|
223
|
+
import { betterAuth } from 'better-auth'
|
|
224
|
+
import { prismaAdapter } from 'better-auth/adapters/prisma'
|
|
225
|
+
import { prisma } from '@/lib/db'
|
|
226
|
+
|
|
227
|
+
export const auth = betterAuth({
|
|
228
|
+
database: prismaAdapter(prisma, { provider: 'postgresql' }),
|
|
229
|
+
emailAndPassword: { enabled: true, requireEmailVerification: true },
|
|
230
|
+
socialProviders: {
|
|
231
|
+
google: {
|
|
232
|
+
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
233
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
session: { expiresIn: 60 * 60 * 24 * 7, updateAge: 60 * 60 * 24 },
|
|
237
|
+
})
|
|
238
|
+
export type Session = typeof auth.$Infer.Session
|
|
239
|
+
export type User = typeof auth.$Infer.Session.user
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Client (`lib/auth/auth-client.ts`)
|
|
243
|
+
```typescript
|
|
244
|
+
import { createAuthClient } from 'better-auth/react'
|
|
245
|
+
export const authClient = createAuthClient({ baseURL: process.env.NEXT_PUBLIC_APP_URL })
|
|
246
|
+
export const { signIn, signOut, signUp, useSession } = authClient
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Cek Session (Next.js 16 — wajib await headers())
|
|
250
|
+
```typescript
|
|
251
|
+
import { auth } from '@/lib/auth/auth'
|
|
252
|
+
import { headers } from 'next/headers'
|
|
253
|
+
|
|
254
|
+
// ✅ Next.js 16: headers() harus di-await
|
|
255
|
+
const session = await auth.api.getSession({ headers: await headers() })
|
|
256
|
+
if (!session) redirect('/login')
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Route Handler
|
|
260
|
+
```typescript
|
|
261
|
+
import { auth } from '@/lib/auth/auth'
|
|
262
|
+
import { toNextJsHandler } from 'better-auth/next-js'
|
|
263
|
+
export const { GET, POST } = toNextJsHandler(auth)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## 6. Xendit Payment (Split Payment)
|
|
269
|
+
|
|
270
|
+
### Client (`lib/payment/xendit.ts`)
|
|
271
|
+
```typescript
|
|
272
|
+
import Xendit from 'xendit-node'
|
|
273
|
+
export const xendit = new Xendit({ secretKey: process.env.XENDIT_SECRET_KEY! })
|
|
274
|
+
|
|
275
|
+
export async function createPayment(params: {
|
|
276
|
+
orderId: string; amount: number; email: string
|
|
277
|
+
description: string; subMerchantId?: string
|
|
278
|
+
}) {
|
|
279
|
+
return xendit.Invoice.create({
|
|
280
|
+
externalID: params.orderId,
|
|
281
|
+
amount: params.amount,
|
|
282
|
+
payerEmail: params.email,
|
|
283
|
+
description: params.description,
|
|
284
|
+
...(params.subMerchantId && {
|
|
285
|
+
forUserID: params.subMerchantId,
|
|
286
|
+
withFeeRule: process.env.XENDIT_FEE_RULE_ID,
|
|
287
|
+
}),
|
|
288
|
+
successRedirectURL: `${process.env.NEXT_PUBLIC_APP_URL}/payment/success`,
|
|
289
|
+
failureRedirectURL: `${process.env.NEXT_PUBLIC_APP_URL}/payment/failed`,
|
|
290
|
+
})
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Webhook Handler (Next.js 16 — wajib await headers())
|
|
295
|
+
```typescript
|
|
296
|
+
import { headers } from 'next/headers'
|
|
297
|
+
import { paymentQueue } from '@/lib/queue'
|
|
298
|
+
|
|
299
|
+
export async function POST(req: Request) {
|
|
300
|
+
// ✅ Next.js 16: await headers()
|
|
301
|
+
const callbackToken = (await headers()).get('x-callback-token')
|
|
302
|
+
if (callbackToken !== process.env.XENDIT_CALLBACK_TOKEN) {
|
|
303
|
+
return Response.json({ error: 'Unauthorized' }, { status: 403 })
|
|
304
|
+
}
|
|
305
|
+
const payload = await req.json()
|
|
306
|
+
await paymentQueue.add('process-webhook', payload, {
|
|
307
|
+
attempts: 3, backoff: { type: 'exponential', delay: 1000 },
|
|
308
|
+
})
|
|
309
|
+
return Response.json({ received: true }) // return 200 segera ke Xendit
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Alur Split Payment
|
|
314
|
+
```
|
|
315
|
+
Buyer bayar →
|
|
316
|
+
Xendit split: fee → rekening platform, sisa → sub-merchant
|
|
317
|
+
Xendit kirim webhook → BullMQ worker →
|
|
318
|
+
Update order status → Socket.io notify client → FCM push notif
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## 7. BullMQ + Redis + Socket.io
|
|
324
|
+
|
|
325
|
+
### Queue Definitions (`lib/queue/index.ts`)
|
|
326
|
+
```typescript
|
|
327
|
+
import { Queue } from 'bullmq'
|
|
328
|
+
import { redis } from '@/lib/redis'
|
|
329
|
+
|
|
330
|
+
export const QUEUES = {
|
|
331
|
+
EMAIL: 'email', PAYMENT: 'payment',
|
|
332
|
+
NOTIFICATION: 'notification', FILE: 'file',
|
|
333
|
+
} as const
|
|
334
|
+
|
|
335
|
+
export const emailQueue = new Queue(QUEUES.EMAIL, { connection: redis })
|
|
336
|
+
export const paymentQueue = new Queue(QUEUES.PAYMENT, { connection: redis })
|
|
337
|
+
export const notifQueue = new Queue(QUEUES.NOTIFICATION, { connection: redis })
|
|
338
|
+
export const fileQueue = new Queue(QUEUES.FILE, { connection: redis })
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Redis (`lib/redis/index.ts`)
|
|
342
|
+
```typescript
|
|
343
|
+
import { Redis } from 'ioredis'
|
|
344
|
+
export const redis = new Redis(process.env.REDIS_URL!, {
|
|
345
|
+
maxRetriesPerRequest: null, // required untuk BullMQ
|
|
346
|
+
enableReadyCheck: false,
|
|
347
|
+
})
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Worker Pattern
|
|
351
|
+
```typescript
|
|
352
|
+
import { Worker } from 'bullmq'
|
|
353
|
+
import { io } from '@/lib/socket'
|
|
354
|
+
|
|
355
|
+
const worker = new Worker(QUEUES.PAYMENT, async (job) => {
|
|
356
|
+
return await processXenditWebhook(job.data)
|
|
357
|
+
}, { connection: redis, concurrency: 5 })
|
|
358
|
+
|
|
359
|
+
worker.on('completed', (job, result) => {
|
|
360
|
+
io.to(`user_${result.userId}`).emit('payment:updated', result)
|
|
361
|
+
})
|
|
362
|
+
worker.on('failed', (job, error) => {
|
|
363
|
+
console.error(`[${QUEUES.PAYMENT}] Job ${job?.id} failed:`, error)
|
|
364
|
+
})
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## 8. Docker Compose (Local Dev)
|
|
370
|
+
|
|
371
|
+
```yaml
|
|
372
|
+
version: '3.8'
|
|
373
|
+
services:
|
|
374
|
+
postgres:
|
|
375
|
+
image: postgres:17-alpine
|
|
376
|
+
environment:
|
|
377
|
+
POSTGRES_USER: devuser
|
|
378
|
+
POSTGRES_PASSWORD: devpassword
|
|
379
|
+
POSTGRES_DB: myapp_dev
|
|
380
|
+
ports: ["5432:5432"]
|
|
381
|
+
volumes: [postgres_data:/var/lib/postgresql/data]
|
|
382
|
+
healthcheck:
|
|
383
|
+
test: ["CMD-SHELL", "pg_isready -U devuser"]
|
|
384
|
+
interval: 5s
|
|
385
|
+
retries: 5
|
|
386
|
+
|
|
387
|
+
redis:
|
|
388
|
+
image: redis:7.4-alpine
|
|
389
|
+
ports: ["6379:6379"]
|
|
390
|
+
volumes: [redis_data:/data]
|
|
391
|
+
|
|
392
|
+
volumes:
|
|
393
|
+
postgres_data:
|
|
394
|
+
redis_data:
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## 9. Environment Variables
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
# App
|
|
403
|
+
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
|
404
|
+
NODE_ENV=development
|
|
405
|
+
|
|
406
|
+
# Database
|
|
407
|
+
DATABASE_URL=postgresql://devuser:devpassword@localhost:5432/myapp_dev
|
|
408
|
+
|
|
409
|
+
# Redis
|
|
410
|
+
REDIS_URL=redis://localhost:6379
|
|
411
|
+
|
|
412
|
+
# Better Auth
|
|
413
|
+
BETTER_AUTH_SECRET= # openssl rand -base64 32
|
|
414
|
+
BETTER_AUTH_URL=http://localhost:3000
|
|
415
|
+
|
|
416
|
+
# Google OAuth
|
|
417
|
+
GOOGLE_CLIENT_ID=
|
|
418
|
+
GOOGLE_CLIENT_SECRET=
|
|
419
|
+
|
|
420
|
+
# Xendit
|
|
421
|
+
XENDIT_SECRET_KEY=xnd_development_...
|
|
422
|
+
XENDIT_CALLBACK_TOKEN=
|
|
423
|
+
XENDIT_FEE_RULE_ID=
|
|
424
|
+
NEXT_PUBLIC_XENDIT_PUBLIC_KEY=xnd_public_development_...
|
|
425
|
+
|
|
426
|
+
# NEO Object Storage
|
|
427
|
+
NEO_ENDPOINT=https://nos.wjv-1.neo.id
|
|
428
|
+
NEO_ACCESS_KEY=
|
|
429
|
+
NEO_SECRET_KEY=
|
|
430
|
+
NEO_BUCKET_NAME=myapp-dev
|
|
431
|
+
|
|
432
|
+
# Resend
|
|
433
|
+
RESEND_API_KEY=re_...
|
|
434
|
+
EMAIL_FROM=noreply@[domain].com
|
|
435
|
+
|
|
436
|
+
# Firebase FCM (server-side only)
|
|
437
|
+
FIREBASE_PROJECT_ID=
|
|
438
|
+
FIREBASE_PRIVATE_KEY=
|
|
439
|
+
FIREBASE_CLIENT_EMAIL=
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## 10. UU PDP — Sub-Processor Eksternal
|
|
445
|
+
|
|
446
|
+
| Layanan | Peran | Data Dikirim | Aksi Wajib |
|
|
447
|
+
|---------|-------|-------------|------------|
|
|
448
|
+
| **Cloudflare** | Sub-processor (CDN) | IP address, headers | Accept DPA → Dashboard → Privacy |
|
|
449
|
+
| **Firebase FCM** | Sub-processor (notif) | Device token, payload | Accept DPT → Firebase Console → Project Settings |
|
|
450
|
+
| **Resend** | Sub-processor (email) | Email address, isi email | Cantumkan di Privacy Policy |
|
|
451
|
+
| **Xendit** | Processor (payment) | Data transaksi | Sudah comply (OJK-registered) |
|
|
452
|
+
|
|
453
|
+
### Aturan Firebase
|
|
454
|
+
```
|
|
455
|
+
✅ Aktifkan HANYA: firebase_messaging
|
|
456
|
+
❌ JANGAN: Firebase Analytics, Crashlytics, Performance, Remote Config
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## 11. Coding Standards
|
|
462
|
+
|
|
463
|
+
### Naming Conventions
|
|
464
|
+
| Hal | Konvensi | Contoh |
|
|
465
|
+
|-----|----------|--------|
|
|
466
|
+
| File React | PascalCase | `ProductCard.tsx` |
|
|
467
|
+
| File utils | camelCase | `formatCurrency.ts` |
|
|
468
|
+
| Variabel/fungsi | camelCase | `totalPrice`, `createOrder()` |
|
|
469
|
+
| Konstanta | SCREAMING_SNAKE | `MAX_FILE_SIZE` |
|
|
470
|
+
| Prisma model | PascalCase | `model Order` |
|
|
471
|
+
| DB table | snake_case via `@@map` | `@@map("order_item")` |
|
|
472
|
+
| Flutter file | snake_case | `product_card.dart` |
|
|
473
|
+
| API endpoint | kebab-case | `/api/order-items` |
|
|
474
|
+
|
|
475
|
+
### Next.js 16 Patterns Wajib
|
|
476
|
+
```typescript
|
|
477
|
+
// ✅ params — async
|
|
478
|
+
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
|
|
479
|
+
const { id } = await params
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// ✅ headers() — async
|
|
483
|
+
const session = await auth.api.getSession({ headers: await headers() })
|
|
484
|
+
|
|
485
|
+
// ✅ webhook headers — async
|
|
486
|
+
const token = (await headers()).get('x-callback-token')
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### Flutter 3.41
|
|
490
|
+
- UIScene lifecycle wajib untuk iOS — ikuti migration guide Apple
|
|
491
|
+
- Dart 3.10 dot shorthands: `.center` bukan `MainAxisAlignment.center`
|