A quiet page each morning. A task app that resets each day at a time you choose.
pnpm installcp .env.example .env.localFill in all values. See details below.
Install the Supabase CLI if you haven't:
brew install supabase/tap/supabaseStart local Supabase and run migrations:
pnpm db:start
pnpm db:migrateCopy the local Supabase keys from pnpm db:status into .env.local.
pnpm devOpen http://localhost:3000.
| Variable | Description |
|---|---|
NEXTAUTH_SECRET |
Random secret for Auth.js. Generate: openssl rand -base64 32 |
NEXTAUTH_URL |
Base URL, e.g. http://localhost:3000 |
GOOGLE_CLIENT_ID |
From Google Cloud Console |
GOOGLE_CLIENT_SECRET |
From Google Cloud Console |
GITHUB_CLIENT_ID |
From GitHub developer settings |
GITHUB_CLIENT_SECRET |
From GitHub developer settings |
NEXT_PUBLIC_SUPABASE_URL |
From Supabase project settings → API |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
From Supabase project settings → API |
SUPABASE_SERVICE_ROLE_KEY |
From Supabase project settings → API. Never expose client-side. |
- Go to Google Cloud Console → APIs & Services → Credentials.
- Create OAuth 2.0 Client ID → Web application.
- Authorized redirect URIs:
http://localhost:3000/api/auth/callback/google(dev) and your production URL. - Copy Client ID and Secret into
.env.local.
- Go to GitHub Settings → OAuth Apps → New OAuth App.
- Homepage URL:
http://localhost:3000 - Authorization callback URL:
http://localhost:3000/api/auth/callback/github - Copy Client ID and generate a Client Secret into
.env.local.
pnpm dev # start Next.js dev server
pnpm build # production build
pnpm lint # lint
pnpm format # prettier
pnpm db:start # start local Supabase
pnpm db:stop # stop local Supabase
pnpm db:migrate # push migrations to remote
pnpm db:reset # reset local DB (re-runs all migrations)
pnpm db:status # show local Supabase connection details- Next.js 16 (App Router, Server Components, Server Actions)
- TypeScript strict mode
- Tailwind CSS v4 + shadcn/ui (Base components)
- Auth.js v5 — Google + GitHub OAuth only
- Supabase (Postgres, RLS on every user table)
- date-fns + date-fns-tz for all timezone-aware date math
- Zustand — client state (pomodoro, UI)
- @tanstack/react-query — server state cache
- Framer Motion, sonner, dnd-kit
- Auth.js v5 reads
NEXTAUTH_SECRET(legacy name also supported asAUTH_SECRET). - All server-side Supabase mutations use the service role key (bypasses RLS). Client-side RLS via Supabase JWTs will be wired up in Phase 02.
- The
tzcookie is set by a tiny client component on the landing/signin pages and read during OAuth sign-in to auto-populate the user's timezone setting.