diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index dc84d19..bee7a1b 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -34,14 +34,79 @@ psql -c "GRANT ALL PRIVILEGES ON DATABASE candle_annotator TO ml_user;" #### Environment Configuration -Create a `.env` file in the project root: +Create a `.env` file in the project root based on `.env.example`: + +```bash +cp .env.example .env +``` + +Edit `.env` to customize: ```env DATABASE_URL=postgresql://ml_user:ml_password@localhost:5432/candle_annotator NODE_ENV=development PORT=3000 + +# Authentication (Auth.js v5) +AUTH_SECRET=your_strong_random_secret_here +AUTH_TRUST_HOST=true + +# Google OAuth +AUTH_GOOGLE_ID=your_google_oauth_client_id +AUTH_GOOGLE_SECRET=your_google_oauth_client_secret + +# Default admin user +DEFAULT_ADMIN_EMAIL=admin@example.com +DEFAULT_ADMIN_PASSWORD=your_strong_password_here ``` +#### Google OAuth Setup + +To enable Google OAuth sign-in: + +1. **Create a Google OAuth Application**: + - Go to [Google Cloud Console](https://console.cloud.google.com/) + - Create a new project + - Enable the "Google+ API" + - Go to "Credentials" and click "Create Credentials" → "OAuth 2.0 Client IDs" + - Select "Web application" + - Add authorized redirect URIs: + - `http://localhost:3000/api/auth/callback/google` (local development) + - `https://yourdomain.com/api/auth/callback/google` (production) + - Copy the Client ID and Client Secret + +2. **Set Environment Variables**: + ```env + AUTH_GOOGLE_ID= + AUTH_GOOGLE_SECRET= + ``` + +3. **Generate AUTH_SECRET**: + ```bash + openssl rand -hex 32 + ``` + +#### Database Migrations + +After setting up the database and environment variables, run the migrations: + +1. **Run Drizzle migrations** (creates schema): + ```bash + npm run db:migrate + ``` + +2. **Run the user migration script** (creates default admin user, backfills user_id): + ```bash + DEFAULT_ADMIN_EMAIL=admin@example.com \ + DEFAULT_ADMIN_PASSWORD=your_password \ + npx tsx scripts/migrate-users.ts + ``` + + This script: + - Creates a default admin user with the specified email and password (hashed with bcryptjs) + - Backfills `user_id` on all existing rows in: `charts`, `annotations`, `annotation_types`, `span_annotations`, `span_label_types` + - Is idempotent (safe to run multiple times) + #### Run Migrations Database migrations run automatically on application startup. To run manually: @@ -159,19 +224,34 @@ PORT=3001 npm run dev ## Environment Variables -Required environment variables: +### Required Variables - `DATABASE_URL` - PostgreSQL connection string (e.g., `postgresql://ml_user:ml_password@localhost:5432/candle_annotator`) - `NODE_ENV` - Environment (`development` or `production`) - `PORT` - Server port (default: 3000) +- `AUTH_SECRET` - Random secret for Auth.js JWT signing (generate with `openssl rand -hex 32`) +- `AUTH_GOOGLE_ID` - Google OAuth Client ID +- `AUTH_GOOGLE_SECRET` - Google OAuth Client Secret +- `DEFAULT_ADMIN_EMAIL` - Default admin user email (used by migration script) +- `DEFAULT_ADMIN_PASSWORD` - Default admin user password (used by migration script) -Optional variables for ML inference: +### Authentication Variables + +- `AUTH_TRUST_HOST` - Set to `true` when using HTTP (localhost development), `false` for HTTPS production with proper domain +- `AUTH_GOOGLE_ID` - Google OAuth Client ID from Google Cloud Console +- `AUTH_GOOGLE_SECRET` - Google OAuth Client Secret from Google Cloud Console + +### Optional Variables for ML Inference - `INFERENCE_API_URL` - ML service endpoint (default: `http://localhost:8001`) - `INFERENCE_API_TIMEOUT` - Request timeout in ms (default: 30000) - `INFERENCE_BATCH_TIMEOUT` - Batch processing timeout in ms (default: 120000) - `NEXT_PUBLIC_PREDICTIONS_ENABLED` - Enable predictions UI (default: true) +### API Key Variable + +- `API_KEY` - Strong random key for authenticating requests between Next.js and ML service (generate with `openssl rand -hex 32`) + ## File Structure ``` @@ -406,7 +486,7 @@ docker run -d \ candle-annotator ``` -### Environment Configuration +### Environment Configuration for Docker Create a `.env` file in the project root based on `.env.example`: @@ -414,11 +494,30 @@ Create a `.env` file in the project root based on `.env.example`: cp .env.example .env ``` -Edit `.env` to customize: -``` +Edit `.env` to customize for your deployment: +```env NODE_ENV=production PORT=3000 DATABASE_URL=postgresql://ml_user:ml_password@postgres:5432/candle_annotator + +# Authentication +AUTH_SECRET=your_strong_random_secret_here +AUTH_TRUST_HOST=false +AUTH_GOOGLE_ID=your_google_oauth_client_id +AUTH_GOOGLE_SECRET=your_google_oauth_client_secret + +# Default admin user +DEFAULT_ADMIN_EMAIL=admin@example.com +DEFAULT_ADMIN_PASSWORD=your_strong_password_here + +# API Key +API_KEY=your_strong_random_api_key_here + +# ML Inference (optional) +INFERENCE_API_URL=http://ml-service:8001 +INFERENCE_API_TIMEOUT=30000 +INFERENCE_BATCH_TIMEOUT=120000 +NEXT_PUBLIC_PREDICTIONS_ENABLED=true ``` Pass environment variables to docker-compose: @@ -427,6 +526,8 @@ Pass environment variables to docker-compose: docker-compose --env-file .env up -d ``` +After containers are running, the user migration will run automatically during startup. + ### Data Persistence The application stores all data in PostgreSQL using the Docker named volume `postgres-data`. This ensures data persists across container restarts: @@ -664,9 +765,12 @@ For production deployments, consider: ## Notes -- This application is designed for **single-user local use** only -- There is no authentication or user management +- The application now includes **user authentication and multi-user support** +- Users can sign up with email/password or use Google OAuth +- A default admin user is created during the migration phase (see Database Migrations section) +- Each user's data (charts, annotations, etc.) is isolated and scoped by `user_id` - PostgreSQL is used for all application data (frontend and ML service) -- The shared database enables the ML service to directly query candle and annotation data +- The shared database enables the ML service to directly query candle and annotation data with user scoping - Docker deployment provides lightweight containerization ideal for standalone instances - The multi-stage Dockerfile keeps image size minimal (~100MB) +- Auth.js v5 is used for authentication with JWT strategy and 30-day session expiry