171 lines
5.3 KiB
Markdown
171 lines
5.3 KiB
Markdown
# Supabase Setup Guide for Gantt Board
|
|
|
|
## Step 1: Create a Supabase Project
|
|
|
|
Since Supabase CLI is not installed, we'll use the Supabase Dashboard:
|
|
|
|
1. Go to https://supabase.com/dashboard
|
|
2. Click "New Project"
|
|
3. Choose your organization
|
|
4. 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-1` for US East Coast)
|
|
5. Click "Create New Project"
|
|
6. Wait for the project to be created (~2 minutes)
|
|
|
|
## Step 2: Get Your Credentials
|
|
|
|
Once the project is created:
|
|
|
|
1. Go to **Project Settings** → **API**
|
|
2. 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!)
|
|
|
|
## Step 3: Create the Database Schema
|
|
|
|
1. Go to the **SQL Editor** in the left sidebar
|
|
2. Click "New Query"
|
|
3. Copy and paste the contents of `supabase/schema.sql` (created below)
|
|
4. 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:
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
npm install @supabase/supabase-js
|
|
```
|
|
|
|
## Step 6: Migrate Data from SQLite
|
|
|
|
Run the migration script to copy your existing data:
|
|
|
|
```bash
|
|
npx tsx scripts/migrate-to-supabase.ts
|
|
```
|
|
|
|
This will:
|
|
1. Read all data from your local SQLite database
|
|
2. Insert it into Supabase
|
|
3. Handle conflicts and dependencies (users first, then projects, etc.)
|
|
|
|
## Step 7: Test Locally
|
|
|
|
```bash
|
|
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`/`endDate` from date inputs (for example `2026-02-16` to `2026-02-22`).
|
|
- Confirm UI displays the same calendar dates without shifting a day earlier in local timezone.
|
|
- Confirm `sprints.start_date` and `sprints.end_date` are stored as `YYYY-MM-DD` in Supabase.
|
|
|
|
## Step 8: Deploy to Vercel
|
|
|
|
### Add Environment Variables in Vercel:
|
|
|
|
1. Go to your Vercel dashboard
|
|
2. Select the gantt-board project
|
|
3. Go to **Settings** → **Environment Variables**
|
|
4. Add all variables from `.env.local`:
|
|
- `NEXT_PUBLIC_SUPABASE_URL`
|
|
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
|
|
- `SUPABASE_SERVICE_ROLE_KEY`
|
|
|
|
### Deploy:
|
|
|
|
```bash
|
|
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 AM` for selected day.
|
|
- Sprint end date = local `11:59:59.999 PM` for selected day.
|
|
- API behavior:
|
|
- `/api/sprints` normalizes `startDate` and `endDate` to `YYYY-MM-DD` before persistence.
|
|
- Invalid date format on `PATCH /api/sprints` returns `400`.
|
|
- 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 `DATE` columns
|
|
|
|
## 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_session` cookie sessions
|
|
- Works on multiple servers/Vercel edge functions
|
|
- Real-time subscriptions possible (future enhancement)
|
|
|
|
## Security Notes
|
|
|
|
1. **Never expose `SUPABASE_SERVICE_ROLE_KEY` to 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_`)
|
|
|
|
2. **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
|
|
|
|
3. **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.
|