candle-annotator/openspec/changes/user-accounts/proposal.md
Marko Djordjevic c36ab7c146 Implement task 6.1: Create PUT /api/auth/profile endpoint for updating user display name
- Create src/app/api/auth/profile/route.ts with PUT handler
- Validates user is authenticated (returns 401 if not)
- Validates request body has a non-empty name field
- Updates user's name in the database
- Returns 200 with updated user data

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 10:20:20 +01:00

3.4 KiB

Why

CandleAnnotator is currently a single-user application with no authentication — all data (charts, annotations, models, settings) is global. To support multiple users, each with their own isolated workspace, we need user accounts with registration, login, and per-user data isolation. This unlocks the ability to deploy as a multi-tenant SaaS.

What Changes

  • Add user accounts with email/password registration and Google OAuth login
  • Add NextAuth.js authentication with JWT sessions
  • Add landing page (public, from Lovable design) at /
  • Add login page at /login (from Lovable design)
  • Add register page at /register (from Lovable design)
  • Move the existing app workspace to /app (protected route)
  • Add users table to PostgreSQL schema
  • Add user_id foreign key to all existing data tables: charts, annotations, span_annotations, annotation_types, span_label_types
  • Filter all API queries by authenticated user's ID
  • Add user settings page at /app/settings with: change password, display name, email preferences, delete account
  • Add Google OAuth provider configuration
  • Add auth middleware to protect /app/* and /api/* routes
  • Seed default annotation types per user on registration

Capabilities

New Capabilities

  • user-auth: User registration (email+password), login, Google OAuth, JWT sessions, password hashing, auth middleware, protected routes
  • landing-page: Public landing page at / with Lovable design, nav links to login/register
  • login-page: Login page at /login with email/password form and Google OAuth button (Lovable design)
  • register-page: Registration page at /register with name/email/password form (Lovable design)
  • user-settings: Settings page at /app/settings — change password, update display name, manage email, delete account
  • user-data-isolation: Per-user data scoping — all existing tables get user_id FK, all queries filtered by authenticated user, default data seeded on registration

Modified Capabilities

  • postgres-data-layer: Add users table, add user_id column to all existing tables, update schema and migrations
  • backend-api: All API routes require authentication, filter queries by user_id from session
  • ui-shell: Move app to /app route, add auth-aware navigation (show login/register when unauthenticated, show user menu when authenticated)

Impact

  • Database: New users table. Migration adds user_id to charts, annotations, span_annotations, annotation_types, span_label_types. Existing data needs migration strategy (assign to a default user or require re-import).
  • Frontend routing: Current single-page app at / moves to /app. New public pages: /, /login, /register. New protected page: /app/settings.
  • API routes: All 13 existing API endpoints need auth middleware and user-scoped queries.
  • Dependencies: Add next-auth (v5/beta for App Router), bcryptjs for password hashing, @auth/drizzle-adapter for database sessions.
  • Environment variables: New env vars for NEXTAUTH_SECRET, NEXTAUTH_URL, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET.
  • ML Service: Python FastAPI service needs user context passed via API key or header — training runs and model storage become user-scoped.
  • Docker: No new services, but env vars need updating in docker-compose.yml.
  • Breaking: Existing single-user data will need migration to a default user account. BREAKING for any existing deployments.