Skip to content

Repository files navigation

ProblemVault

ProblemVault adalah knowledge base teknis untuk menyimpan masalah, investigasi, dan solusi developer agar dapat dicari dan digunakan kembali.

Stack

  • 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

Prerequisites

  • Node.js 20+
  • pnpm 9+
  • Supabase project

Local setup

pnpm install
cp .env.example .env
pnpm dev

Isi .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:3000

Jangan commit .env atau menaruh service-role key di client.

Supabase setup

  1. Buat Supabase project.

  2. Aktifkan Authentication → Providers → Email.

  3. Tentukan apakah email confirmation diperlukan untuk development dan production.

  4. Tambahkan URL aplikasi pada Authentication → URL Configuration:

    • Site URL: http://localhost:3000
    • Redirect URL: http://localhost:3000/dashboard
  5. Jalankan migration:

    supabase link --project-ref YOUR_PROJECT_REF
    supabase db push
  6. 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_at trigger
  • indexes dan RLS policies
  • function atomic untuk menyimpan problem beserta tags dalam satu transaksi
  • Supabase Cron keepalive

Keepalive cron

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');

Commands

pnpm dev
pnpm build
pnpm preview
pnpm format
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test

Deploy ke Vercel

Nuxt terdeteksi otomatis oleh Vercel. Tidak perlu vercel.json atau dedicated backend service.

  1. Push repository ke GitHub lalu import project di Vercel.

  2. Set Framework Preset ke Nuxt.js jika tidak terdeteksi otomatis.

  3. Gunakan konfigurasi berikut:

    • Install Command: pnpm install --frozen-lockfile
    • Build Command: pnpm build
    • Node.js: 20.x atau lebih baru
  4. 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
  5. Di Supabase, tambahkan domain Vercel pada Authentication → URL Configuration:

    • Site URL untuk production: domain production
    • Redirect URL: https://your-domain.vercel.app/dashboard
  6. 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.

Routes

/                         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

Architecture

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 PRIVATE tidak tersedia lewat public route;
  • mutation problems dan problem_tags diverifikasi oleh ownership policy.

MVP decisions

  • 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_tags dalam 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.

About

ProblemVault adalah knowledge base teknis untuk menyimpan masalah, investigasi, dan solusi developer agar dapat dicari dan digunakan kembali.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages