5.3 KiB
5.3 KiB
Supabase Setup Guide for Gantt Board
Step 1: Create a Supabase Project
Since Supabase CLI is not installed, we'll use the Supabase Dashboard:
- Go to https://supabase.com/dashboard
- Click "New Project"
- Choose your organization
- Enter project details:
- Name:
gantt-board(or your preferred name) - Database Password: Generate a strong password (save this!)
- Region: Choose closest to your users (e.g.,
us-east-1for US East Coast)
- Name:
- Click "Create New Project"
- Wait for the project to be created (~2 minutes)
Step 2: Get Your Credentials
Once the project is created:
- Go to Project Settings → API
- Copy these values:
- Project URL (e.g.,
https://xxxxxx.supabase.co) - anon/public key (under "Project API keys")
- service_role key (under "Project API keys" - keep this secret!)
- Project URL (e.g.,
Step 3: Create the Database Schema
- Go to the SQL Editor in the left sidebar
- Click "New Query"
- Copy and paste the contents of
supabase/schema.sql(created below) - Click "Run"
This creates all tables with proper:
- Primary keys (using UUID)
- Foreign key constraints
- Indexes for performance
- Row Level Security (RLS) policies
Step 4: Set Environment Variables
Create a .env.local file in your project root with the credentials from Step 2:
# Supabase Configuration
NEXT_PUBLIC_SUPABASE_URL=https://your-project-url.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key-here
Important: Never commit .env.local to git. It's already in .gitignore.
Step 5: Install Supabase Client
npm install @supabase/supabase-js
Step 6: Migrate Data from SQLite
Run the migration script to copy your existing data:
npx tsx scripts/migrate-to-supabase.ts
This will:
- Read all data from your local SQLite database
- Insert it into Supabase
- Handle conflicts and dependencies (users first, then projects, etc.)
Step 7: Test Locally
npm run dev
Test all functionality:
- Login/logout
- Create/edit tasks
- Create/edit projects
- Create/edit sprints
- User management
Sprint date verification:
- Create a sprint with
startDate/endDatefrom date inputs (for example2026-02-16to2026-02-22). - Confirm UI displays the same calendar dates without shifting a day earlier in local timezone.
- Confirm
sprints.start_dateandsprints.end_dateare stored asYYYY-MM-DDin Supabase.
Step 8: Deploy to Vercel
Add Environment Variables in Vercel:
- Go to your Vercel dashboard
- Select the gantt-board project
- Go to Settings → Environment Variables
- Add all variables from
.env.local:NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEY
Deploy:
vercel --prod
Or push to git and let Vercel auto-deploy.
Troubleshooting
Connection Issues
- Verify your Supabase URL and keys are correct
- Check if your Supabase project is active (not paused)
- Ensure your IP is not blocked in Supabase settings
Row Level Security Errors
- The schema includes RLS policies
- Anonymous users can only read public data
- Authenticated users can only modify their own data
- Service role bypasses RLS (used for admin operations)
Data Migration Issues
- If migration fails mid-way, you can re-run it
- The script uses upsert, so existing data won't be duplicated
- Check the error message for specific constraint violations
Off-by-One Sprint Date Display
- Root cause: using
new Date("YYYY-MM-DD")directly can parse as UTC and render as the previous day in some local time zones. - Expected behavior in this app:
- Sprint start date = local
12:00:00 AMfor selected day. - Sprint end date = local
11:59:59.999 PMfor selected day.
- Sprint start date = local
- API behavior:
/api/sprintsnormalizesstartDateandendDatetoYYYY-MM-DDbefore persistence.- Invalid date format on
PATCH /api/sprintsreturns400.
- API payload examples:
POST /api/sprints{ "name": "Sprint 1", "startDate": "2026-02-16", "endDate": "2026-02-22", "status": "active", "projectId": "<uuid>" }
PATCH /api/sprints{ "id": "<sprint-id>", "startDate": "2026-02-16T00:00:00.000Z", "endDate": "2026-02-22T23:59:59.999Z" }- stored as date-only values in Supabase
DATEcolumns
Architecture Changes
Before (SQLite):
- File-based database stored in
data/tasks.db - Sessions stored in SQLite
- Works only on single server
After (Supabase):
- PostgreSQL database hosted by Supabase
- Supabase Auth credentials + app-managed
gantt_sessioncookie sessions - Works on multiple servers/Vercel edge functions
- Real-time subscriptions possible (future enhancement)
Security Notes
-
Never expose
SUPABASE_SERVICE_ROLE_KEYto the client- Only use it in server-side code (API routes, server actions)
- The anon key is safe to expose (it's in
NEXT_PUBLIC_)
-
Row Level Security is enabled
- Tables have policies that restrict access
- Users can only see/modify their own data
- Admin operations use service role key
-
Password handling
- Passwords are managed by Supabase Auth.
- Do not add
public.users.password_hash; keep password data out of public tables. - App login state uses secure, HTTP-only session cookies.