ProblemVault adalah knowledge base teknis untuk menyimpan masalah, investigasi, dan solusi developer agar dapat dicari dan digunakan kembali.
- Nuxt 3, Vue 3, TypeScript, Vite
- pnpm
- Supabase Auth email/password
- PostgreSQL, migrations, triggers, dan RLS
- Nuxt composables untuk state, business logic, dan Supabase access
- Node.js 20+
- pnpm 9+
- Supabase project
pnpm install
cp .env.example .env
pnpm devIsi .env:
NUXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NUXT_PUBLIC_SUPABASE_KEY=your-anon-or-publishable-key
NUXT_PUBLIC_SITE_URL=http://localhost:3000Jangan commit .env atau menaruh service-role key di client.
-
Buat Supabase project.
-
Aktifkan Authentication → Providers → Email.
-
Tentukan apakah email confirmation diperlukan untuk development dan production.
-
Tambahkan URL aplikasi pada Authentication → URL Configuration:
- Site URL:
http://localhost:3000 - Redirect URL:
http://localhost:3000/dashboard
- Site URL:
-
Jalankan migration:
supabase link --project-ref YOUR_PROJECT_REF supabase db push
-
Jalankan supabase/seed.sql dari SQL Editor untuk data development.
Migration membuat:
profiles,problems,tags,problem_tags- enum visibility
- profile trigger dari
auth.users updated_attrigger- indexes dan RLS policies
- function atomic untuk menyimpan problem beserta tags dalam satu transaksi
- Supabase Cron keepalive
Migration membuat job problemvault-daily-keepalive:
Waktu: 23:59 Asia/Jakarta
Cron: 59 16 * * * (UTC)
Query: select 1;
Job menggunakan pg_cron dan tidak membutuhkan endpoint publik atau service-role key. Cek statusnya:
select jobid, jobname, schedule, command
from cron.job
where jobname = 'problemvault-daily-keepalive';Ini hanya best-effort activity signal untuk Free project. Supabase tetap dapat melakukan auto-pause jika aktivitas dianggap tidak cukup. Paid plan adalah opsi platform-level yang tidak terkena auto-pause karena inactivity.
Untuk menghapus job:
select cron.unschedule('problemvault-daily-keepalive');pnpm dev
pnpm build
pnpm preview
pnpm format
pnpm format:check
pnpm lint
pnpm typecheck
pnpm testNuxt terdeteksi otomatis oleh Vercel. Tidak perlu vercel.json atau dedicated backend service.
-
Push repository ke GitHub lalu import project di Vercel.
-
Set Framework Preset ke
Nuxt.jsjika tidak terdeteksi otomatis. -
Gunakan konfigurasi berikut:
- Install Command:
pnpm install --frozen-lockfile - Build Command:
pnpm build - Node.js:
20.xatau lebih baru
- Install Command:
-
Tambahkan environment variables pada Vercel untuk environment yang sesuai:
NUXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co NUXT_PUBLIC_SUPABASE_KEY=your-anon-or-publishable-key NUXT_PUBLIC_SITE_URL=https://your-domain.vercel.app
-
Di Supabase, tambahkan domain Vercel pada Authentication → URL Configuration:
- Site URL untuk production: domain production
- Redirect URL:
https://your-domain.vercel.app/dashboard
-
Deploy dan pastikan migration sudah dijalankan pada Supabase production project.
Untuk preview deployment, gunakan URL preview Vercel sebagai redirect URL tambahan jika email confirmation digunakan. Jangan menaruh service-role key di Vercel environment variables yang dibaca client.
/ Landing page
/login Email/password sign in dan sign up
/dashboard Workspace overview
/problems Problem milik user
/problems/new Create problem
/problems/:id Detail problem private/owner
/problems/:id/edit Edit problem
/public/problems Explore dokumentasi public
/public/problems/:slug Dokumentasi public
/settings Profile, account, password, logout
pages/ File-based routes dan page composition
components/ Reusable Vue UI components
composables/ Auto-imported state, logic, dan data access
layouts/ Shared page shells
middleware/ Route guards
assets/ CSS dan asset yang diproses bundler
infrastructure/supabase/types/ Typed database schema
shared/ Domain types, validation, dan utilities
supabase/migrations/ Schema, trigger, indexes, RLS, cron, RPC
Page dan component tidak melakukan query Supabase langsung. Logic aplikasi berada di composables, mengikuti struktur default Nuxt. RLS menjadi authorization boundary:
- owner dapat membaca dan mengubah problem miliknya;
- anonymous user hanya dapat membaca problem
PUBLIC; - problem
PRIVATEtidak tersedia lewat public route; - mutation
problemsdanproblem_tagsdiverifikasi oleh ownership policy.
- Slug dibuat sekali saat problem dibuat dan tidak berubah ketika title diedit.
- Tag adalah shared vocabulary. User terautentikasi dapat menambah tag, tetapi tidak dapat mengubah atau menghapus tag existing dari client.
- Create/update problem dan tags dijalankan oleh
save_problem_with_tagsdalam satu transaksi database. Jika salah satu langkah gagal, seluruh perubahan di-rollback. - Delete problem menggunakan satu operasi database; relasi tags ikut terhapus lewat foreign key cascade.
- Public documentation hanya merender plain text, bukan raw HTML.