candle-annotator/openspec/changes/archive/2026-02-20-user-accounts/tasks.md
Marko Djordjevic 5fb9733bd6 Archive user-accounts change to openspec/changes/archive/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 18:50:36 +01:00

93 lines
6.7 KiB
Markdown

## 1. Dependencies & Configuration
- [x] 1.1 `[haiku]` Install npm dependencies: `next-auth@5`, `bcryptjs`, `@types/bcryptjs`
- [x] 1.2 `[haiku]` Add environment variables to `.env.example`: `AUTH_SECRET`, `AUTH_GOOGLE_ID`, `AUTH_GOOGLE_SECRET`, `AUTH_TRUST_HOST`, `DEFAULT_ADMIN_EMAIL`, `DEFAULT_ADMIN_PASSWORD`
- [x] 1.3 `[haiku]` Update `docker-compose.yml` to pass new auth env vars to the candle-annotator service
## 2. Database Schema & Migration
- [x] 2.1 `[sonnet]` Add `users` table to Drizzle schema (`src/lib/db/schema.ts`) with UUID PK, email, password_hash, name, image, provider, provider_account_id, email_verified, created_at, updated_at
- [x] 2.2 `[sonnet]` Add `user_id` (uuid, FK to users.id) column to `charts`, `annotations`, `annotation_types`, `span_annotations`, `span_label_types` in schema
- [x] 2.3 `[sonnet]` Replace unique constraints: `charts.name``(user_id, name)`, `annotation_types.name``(user_id, name)`, `span_label_types.name``(user_id, name)`
- [x] 2.4 `[haiku]` Generate Drizzle migration with `drizzle-kit generate`
- [x] 2.5 `[opus]` Create data migration script (`scripts/migrate-users.ts`): create default admin user, backfill `user_id` on all existing rows, alter columns to NOT NULL
## 3. Auth.js Configuration
- [x] 3.1 `[sonnet]` Create `src/auth.ts` with Auth.js v5 config: JWT strategy, Credentials provider (email/password with bcryptjs verify), Google OAuth provider
- [x] 3.2 `[sonnet]` Add JWT callback to embed `user.id` in token and session callback to expose `session.user.id`
- [x] 3.3 `[sonnet]` Handle Google OAuth sign-in callback: create user on first sign-in, find existing user on returning sign-in
- [x] 3.4 `[haiku]` Create `src/app/api/auth/[...nextauth]/route.ts` exporting GET/POST handlers
## 4. Registration API
- [x] 4.1 `[sonnet]` Create `POST /api/auth/register` endpoint: validate input (email required, password 8+ chars), check email uniqueness, hash password with bcryptjs, insert user, return 201
- [x] 4.2 `[sonnet]` Add default data seeding function: on new user creation, insert default annotation_types (break_up, break_down, line) and default span_label_types for the new user
## 5. Auth Middleware & Helpers
- [x] 5.1 `[sonnet]` Create `proxy.ts` at project root: protect `/app/*` routes (redirect to `/login`), protect `/api/*` except `/api/auth/*` and `/api/health` (return 401), redirect authenticated users from `/login` and `/register` to `/app`
- [x] 5.2 `[haiku]` Create `src/lib/auth.ts` with `getAuthUser()` helper that extracts user from Auth.js session
## 6. User Settings API
- [x] 6.1 `[haiku]` Create `PUT /api/auth/profile` endpoint: update user display name
- [x] 6.2 `[sonnet]` Create `PUT /api/auth/password` endpoint: verify current password, hash new password, update; reject for OAuth users
- [x] 6.3 `[sonnet]` Create `DELETE /api/auth/account` endpoint: delete all user data (cascade) and user record
## 7. Update Existing API Routes
- [x] 7.1 `[sonnet]` Add `getAuthUser()` check to all data API routes: `/api/upload`, `/api/candles`, `/api/charts`, `/api/annotations`, `/api/annotation-types`, `/api/span-annotations`, `/api/span-label-types`, `/api/export`
- [x] 7.2 `[opus]` Update all Drizzle queries to filter by `user_id` from authenticated session (SELECT, INSERT, DELETE)
- [x] 7.3 `[sonnet]` Add `getAuthUser()` check to all proxy API routes: `/api/predict`, `/api/predict/batch`, `/api/model/info`, `/api/model/load`, `/api/patterns/detect`, `/api/patterns/available`, `/api/training/start`, `/api/training/runs`
- [x] 7.4 `[haiku]` Add `X-User-ID` header to all fetch calls from proxy routes to the FastAPI ML service
## 8. Frontend Routing Restructure
- [x] 8.1 `[haiku]` Create `src/app/(public)/layout.tsx` — minimal layout for public pages (shared fonts/theme, no sidebar)
- [x] 8.2 `[haiku]` Move current `src/app/page.tsx` to `src/app/app/page.tsx` (workspace at `/app`)
- [x] 8.3 `[sonnet]` Create `src/app/app/layout.tsx` — protected layout with `SessionProvider`, user menu nav bar, sidebar with settings link
- [x] 8.4 `[haiku]` Update any hardcoded `/` links in existing components to `/app`
## 9. Landing Page
- [x] 9.1 `[sonnet]` Create `src/app/(public)/page.tsx` — landing page matching Lovable design: navbar with login/register links, hero section, features grid (6 cards), stats bar, footer CTA
- [x] 9.2 `[haiku]` Add auth-aware navbar: show "Log in"/"Get Started" when unauthenticated, "Go to App" when authenticated
## 10. Login Page
- [x] 10.1 `[sonnet]` Create `src/app/(public)/login/page.tsx` — login form matching Lovable design: email/password inputs, "Sign In" button calling `signIn("credentials")`, "Continue with Google" button calling `signIn("google")`
- [x] 10.2 `[haiku]` Add error state display for invalid credentials
- [x] 10.3 `[haiku]` Add "Forgot password?" link (shows toast: "Not yet available"), "Sign up" link to `/register`
## 11. Register Page
- [x] 11.1 `[sonnet]` Create `src/app/(public)/register/page.tsx` — register form matching Lovable design: name/email/password inputs, "Create Account" button posting to `/api/auth/register` then auto-signing in
- [x] 11.2 `[haiku]` Add error state display for duplicate email, short password
- [x] 11.3 `[haiku]` Add "Continue with Google" button, "Sign in" link to `/login`
## 12. Settings Page
- [x] 12.1 `[sonnet]` Create `src/app/app/settings/page.tsx` — Profile section: display name input with save, read-only email
- [x] 12.2 `[sonnet]` Add Security section: change password form (current/new/confirm) for credentials users, "Signed in via Google" for OAuth users
- [x] 12.3 `[sonnet]` Add Danger Zone section: delete account button with confirmation dialog (type "DELETE" to confirm)
- [x] 12.4 `[haiku]` Add back navigation link to `/app`
## 13. App Layout & User Menu
- [x] 13.1 `[sonnet]` Create user menu component: avatar/initial, dropdown with "Settings" and "Sign Out" links
- [x] 13.2 `[haiku]` Add settings gear icon to sidebar (near theme toggle)
- [x] 13.3 `[haiku]` Wire `signOut()` in user menu to destroy session and redirect to `/login`
## 14. ML Service User Scoping
- [x] 14.1 `[haiku]` Update FastAPI service to read `X-User-ID` header from incoming requests
- [x] 14.2 `[haiku]` Scope MLflow experiment names to include user ID (e.g., `user_{uuid}_training`)
- [x] 14.3 `[sonnet]` Scope training run queries in FastAPI to filter by user ID
## 15. Documentation & Deployment
- [x] 15.1 `[haiku]` Update `DEPLOYMENT.md` with new env vars, migration steps, Google OAuth setup instructions
- [x] 15.2 `[haiku]` Update `README.md` with user accounts feature description
- [x] 15.3 `[haiku]` Update `CLAUDE_DESCRIPTION.md` with new routing, auth system, and schema changes
- [x] 15.4 `[haiku]` Update `.env.example` with all new environment variables and comments