Chợ beat VN-first: producer đăng beat → buyer mua license (3 SKU) → checkout VND → webhook xác nhận → PDF license + tải file.
Repo: dev-to2k/rap-app
MVP demo — payment là mock. Chưa gắn MoMo/VNPay thật.
| SKU | Lease MP3 · WAV + stems · Exclusive |
| Take-rate | 15% GMV (seed có promo 12% / 90 ngày) |
| Sample | clean | uncleared — uncleared cấm Exclusive |
| Exclusive | Atomic sold_exclusive, delist, lease cũ vẫn valid |
| Unlock | Chỉ sau webhook OK (signature + amount + order, idempotent) |
| Auth | Cookie session HMAC — role buyer | producer |
/— danh sách beat (search/empty CTA)/beats/[id]— chi tiết + 3 SKU/upload— đăng beat/checkout/[orderId]— thanh toán mock (MoMo / VNPay / CK)/orders/[orderId]/success·/license/[id]·/library— sau khi unlock/login·/support
- Next.js 14 (App Router) + TypeScript + Tailwind (mobile-first)
- Prisma + SQLite local (
file:./dev.db) — prod đổi Postgres/Neon - Storage local
storage/— prod private Cloudflare R2 (@aws-sdk/client-s3+ presigner) - PDF license (
pdf-lib) + signed download (R2 TTL 15m; HMAC fallback khi chưa có R2) - Health:
GET /api/health
Yêu cầu: Bun (hoặc Node 20+).
git clone https://github.com/dev-to2k/rap-app.git
cd rap-app
cp .env.example .env
bun install
bunx prisma db push
bun run db:seed
bun run dev| Lệnh | Việc |
|---|---|
bun run dev |
Dev server |
bun run build |
Production build |
bun run start |
Chạy build |
bun run db:push |
Sync schema |
bun run db:seed |
Seed user + beat demo |
bun run db:reset |
Reset DB + seed lại |
Copy từ .env.example (không commit .env):
| Key | Mục đích |
|---|---|
DATABASE_URL |
Postgres (Neon) |
SESSION_SECRET |
HMAC cookie session (≥32 ký tự) |
DOWNLOAD_HMAC_SECRET |
HMAC download tokens (local/dev khi chưa có R2) |
WEBHOOK_SECRET |
Verify webhook stub |
NEXT_PUBLIC_APP_URL |
Base URL app |
R2_ACCOUNT_ID |
Cloudflare R2 account (prod Seed bắt buộc) |
R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY |
R2 S3 API keys |
R2_BUCKET |
Private bucket (no public access) |
R2_ENDPOINT |
Optional; default https://{account}.r2.cloudflarestorage.com |
Prod Seed: set full R2_* — PDF/audio/stems chỉ qua signed R2 URL (TTL 15m). Local/dev có thể bỏ R2 → fallback /tmp + storage/ qua /api/download/[token].
Prod thêm: MOMO_*, VNPAY_* (xem note Security/DevOps).
Sau bun run db:seed — mật khẩu tất cả: password123
| Role | |
|---|---|
buyer@rap.app |
buyer |
producer@rap.app |
producer |
minhprod@rap.app |
producer |
- Login
buyer@rap.app - Mở beat → chọn SKU → Mua
- Checkout → chọn MoMo / VNPay / CK → Pay (mock webhook)
- Webhook verify → unlock PDF + file
- Vào Library / trang license để tải (URL có hạn)
Producer: login producer@rap.app → /upload đăng beat.
prisma/ schema + seed
src/app/ pages + API routes
src/components/ UI (SKU, checkout, upload…)
src/lib/ auth, webhook, unlock, pdf, signed-url
storage/ audio/licenses local (gitignore)
.env.example template secrets
src/lib/webhook.ts— HMAC verify stubsrc/app/api/webhooks/payment/route.ts— signature · amount · order · idempotentsrc/lib/unlock.ts— license + exclusive atomicsrc/lib/signed-url.ts— download TTL ngắn- Preview không leak WAV/stems trước pay
| Demo local | Production |
|---|---|
| SQLite | Postgres / Neon |
storage/ disk |
Cloudflare R2 / S3 + signed URL |
| Mock MoMo/VNPay/CK webhook | Gateway thật + IPN |
| Credentials login | Magic-link / OAuth (optional) |
| Vercel Preview / tunnel | Vercel + staging env tách |
Deploy tối giản (DevOps): Vercel (Next.js) · Neon/Supabase · R2 · webhook trên cùng app.
- Scaffold MVP + mock checkout trên
main - Waitlist
/waitlist(schemaWaitlistSignupđã có — page chưa) - MoMo/VNPay sandbox thật
- Vercel Preview URL public
Private — dev-to2k/rap-app. All rights reserved.