WebVNWrite/progress.txt

121 lines
6.5 KiB
Plaintext

## Codebase Patterns
- Project uses Next.js 16 with App Router, TypeScript, and TailwindCSS 4
- Source files are in `src/` directory (app, components, lib, types)
- Supabase is configured with @supabase/supabase-js and @supabase/ssr packages
- Environment variables follow NEXT_PUBLIC_* convention for client-side access
- Use `npm run typecheck` to run TypeScript type checking (tsc --noEmit)
- Flowchart types exported from `src/types/flowchart.ts`
- Supabase migrations go in `supabase/migrations/` with timestamp prefix (YYYYMMDDHHMMSS_*.sql)
- Database has profiles table (linked to auth.users) and projects table (with flowchart_data JSONB)
- RLS policies enforce user_id = auth.uid() for project access
- Supabase client utilities in `src/lib/supabase/`: client.ts (browser), server.ts (App Router), middleware.ts (route protection)
- Next.js middleware.ts at project root handles route protection using updateSession helper
- Public auth routes: /login, /signup, /forgot-password, /reset-password
- Protected routes: /dashboard, /editor/* (redirect to /login if unauthenticated)
- Auth pages use 'use client' with useState, createClient() from lib/supabase/client.ts, and useRouter for redirects
---
## 2026-01-21 - US-001
- What was implemented: Project scaffolding and configuration
- Files changed:
- package.json - project dependencies and scripts
- tsconfig.json - TypeScript configuration
- next.config.ts - Next.js configuration
- postcss.config.mjs - PostCSS with TailwindCSS
- eslint.config.mjs - ESLint configuration
- .env.example - environment variables template
- .gitignore - git ignore rules
- src/app/ - Next.js App Router pages
- src/components/.gitkeep - components directory placeholder
- src/lib/.gitkeep - lib directory placeholder
- src/types/.gitkeep - types directory placeholder
- **Learnings for future iterations:**
- Next.js 16 uses `@tailwindcss/postcss` for TailwindCSS 4 integration
- Use --src-dir flag for create-next-app to put source in src/ folder
- npm package names can't have capital letters (use lowercase)
- .gitignore needs explicit exclusion for .env files, but include .env.example
---
## 2026-01-21 - US-002
- What was implemented: TypeScript types for flowchart data structures
- Files changed:
- src/types/flowchart.ts - new file with all flowchart type definitions
- package.json - added typecheck script (tsc --noEmit)
- **Learnings for future iterations:**
- Position is a helper type for {x, y} coordinates used by nodes
- FlowchartNode is a union type of DialogueNode | ChoiceNode | VariableNode
- ChoiceOption is a separate type to make options array cleaner
- All types use `export type` for TypeScript isolatedModules compatibility
---
## 2026-01-21 - US-003
- What was implemented: Supabase schema for users and projects
- Files changed:
- supabase/migrations/20260121000000_create_profiles_and_projects.sql - new file with all database schema
- **Learnings for future iterations:**
- Supabase migrations are plain SQL files in supabase/migrations/ directory
- Migration filenames use timestamp prefix (YYYYMMDDHHMMSS_description.sql)
- RLS policies need separate policies for SELECT, INSERT, UPDATE, DELETE operations
- Admin check policy uses EXISTS subquery to check is_admin flag on profiles table
- projects table references profiles.id (not auth.users.id directly) for proper FK relationships
- flowchart_data column uses JSONB type with default empty structure
- Added auto-update trigger for updated_at timestamp on projects table
---
## 2026-01-21 - US-004
- What was implemented: Supabase client configuration utilities
- Files changed:
- src/lib/supabase/client.ts - browser client using createBrowserClient from @supabase/ssr
- src/lib/supabase/server.ts - server client for App Router with async cookies() API
- src/lib/supabase/middleware.ts - middleware helper with updateSession function
- src/lib/.gitkeep - removed (no longer needed)
- **Learnings for future iterations:**
- @supabase/ssr package provides createBrowserClient and createServerClient functions
- Server client requires async cookies() from next/headers in Next.js 16
- Middleware client returns both user object and supabaseResponse for route protection
- Cookie handling uses getAll/setAll pattern for proper session management
- setAll in server.ts wrapped in try/catch to handle Server Component limitations
---
## 2026-01-21 - US-005
- What was implemented: Protected routes middleware for authentication
- Files changed:
- middleware.ts - new file at project root for route protection
- **Learnings for future iterations:**
- Next.js middleware.ts must be at project root (not in src/)
- updateSession helper from lib/supabase/middleware.ts returns { user, supabaseResponse }
- Use startsWith() for route matching to handle nested routes (e.g., /editor/*)
- Matcher config excludes static files and images to avoid unnecessary middleware calls
- Clone nextUrl before modifying pathname for redirects
---
## 2026-01-21 - US-006
- What was implemented: Login page with email/password authentication
- Files changed:
- src/app/login/page.tsx - new file with login form and Supabase auth
- **Learnings for future iterations:**
- Auth pages use 'use client' directive since they need useState and form handling
- Use createClient() from lib/supabase/client.ts for browser-side auth operations
- supabase.auth.signInWithPassword returns { error } object for handling failures
- useRouter from next/navigation for programmatic redirects after auth
- Error state displayed in red alert box with dark mode support
- Loading state disables submit button and shows "Signing in..." text
- TailwindCSS dark mode uses dark: prefix (e.g., dark:bg-zinc-950)
---
## 2026-01-21 - US-007
- What was implemented: Sign up page for invite-only account setup
- Files changed:
- src/app/signup/page.tsx - new file with signup form and Supabase auth
- **Learnings for future iterations:**
- Supabase invite tokens come via URL hash fragment (window.location.hash)
- Parse hash with URLSearchParams after removing leading '#'
- Check for type=invite or type=signup to detect invite flow
- Use setSession() with access_token and refresh_token to establish session from invite link
- For invited users, update password with updateUser() then create profile with upsert()
- Use upsert() instead of insert() for profiles to handle edge cases
- Validate password confirmation before submission (passwords match check)
- display_name defaults to email prefix (split('@')[0])
---