Thanks for helping out. This document covers the dev setup, repo structure, and conventions.
Before filing, check existing issues. A good bug report includes:
- A clear title
- Exact reproduction steps
- Expected vs. actual behavior
- Any error messages or screenshots
- Browser / Node version if relevant
File a GitHub issue with the motivation, the proposed behavior, and any alternatives you considered.
- Fork and branch off
main - Keep changes focused β atomic commits are easier to review
- Update relevant documentation if you change behavior, env vars, or APIs
- Make sure
pnpm buildsucceeds andpnpm exec tsc --noEmitdoesn't introduce new errors - Open the PR with a short description of what changed and why
- Node.js 18+ and pnpm 10+
- A Supabase project (free tier is fine) β the schema lives in
supabase/migrations/(apply in order) - A GitHub OAuth app for local sign-in (callback URL:
http://localhost:3000/api/auth/callback/github)
git clone https://github.com/sculptdotfun/viberank.git
cd viberank
pnpm install
cp .env.example .env.localFill in .env.local with your Supabase project URL, anon key, service role key, GitHub OAuth credentials, and a generated NEXTAUTH_SECRET.
Run the SQL files in supabase/migrations/ (in order: 001_initial_schema.sql, then 002_multi_tool.sql) against your Supabase project, either via the SQL editor in the dashboard or the supabase CLI.
pnpm devOpens on http://localhost:3000.
viberank/
βββ src/
β βββ app/ # Next.js App Router
β β βββ api/
β β β βββ submit/ # POST /api/submit (normalize + validate + store)
β β β βββ claim/ # POST /api/claim (authenticated merge)
β β β βββ admin/flag/ # POST /api/admin/flag (admin-only)
β β β βββ auth/ # NextAuth handlers
β β β βββ health/ # GET /api/health
β β βββ page.tsx # Home (server: SSR first page + FAQ schema)
β β βββ HomeClient.tsx # Home interactivity (hero, board, modals)
β β βββ tool/[tool]/ # Per-tool leaderboards (SSR, ISR hourly)
β β βββ profile/[username]/ # SSR profile (+ getProfile cache, UsageChart)
β β βββ blog/ # Blog posts (static)
β β βββ admin/ # Flag-review dashboard
β βββ components/ # Leaderboard, NavBar, Footer, ShareCard, β¦
β βββ lib/
β β βββ ccusage.ts # ccusage normalization + validation (unit-tested)
β β βββ admin.ts # Admin allowlist (client gate + server enforcement)
β β βββ home-faqs.ts # Homepage FAQ content (visible copy + JSON-LD)
β β βββ auth.ts # Shared NextAuth options
β β βββ env.ts # Server env validation
β β βββ utils.ts # Formatters, tool labels, FEATURED_TOOLS
β β βββ data/ # Data layer (Supabase)
β β βββ index.ts # Data-layer factory
β β βββ types.ts
β β βββ hooks/ # React hooks (client)
β β βββ supabase/ # Supabase client + services
β βββ types/ # Shared TS types
βββ supabase/
β βββ migrations/ # SQL migrations (apply in order)
βββ test/ # ccusage tests (`pnpm test`)
βββ packages/
β βββ viberank-cli/ # `npx viberank-cli` (npm: viberank-cli)
β βββ viberank-mcp-server/ # MCP server (npm: viberank-mcp)
βββ public/ # Static assets
The data layer (src/lib/data/) is backed by Supabase (Postgres). ccusage input is normalized and validated in src/lib/ccusage.ts before it reaches the data layer β run pnpm test after touching it.
- No
any. Use explicit types orunknownand narrow. import type { ... }for type-only imports.- The build currently has
typescript.ignoreBuildErrors: trueinnext.config.ts(because of pre-existing implicit-anys in admin pages). Don't introduce new errors β runpnpm exec tsc --noEmitlocally before pushing.
- Functional components with hooks
- Small, focused components β extract when a single component does too much
- Destructure props at the parameter level
- Tailwind CSS 4. Use existing tokens / utilities; check
src/app/globals.cssandtailwind.configfor theme overrides. - Test mobile layouts when you touch anything in
src/components/
We use Conventional Commits:
feat: add time-range filter to leaderboardfix: correct token math for merged submissionsrefactor: extract auth options to lib/auth.tschore: update env exampledocs: refresh README
Keep the subject under ~72 characters. Use the body for the why.
pnpm exec tsc --noEmit # type-check
pnpm lint # next lint
pnpm test # ccusage normalization/validation tests
pnpm build # full production buildManually verify in the browser:
- Sign-in flow works
- A web upload completes
- The leaderboard renders with and without date filters
- Mobile layout doesn't break
Open an issue or reach out to a maintainer. Thanks for contributing π§‘.