- Auto pull latest code before deployment
- Clean old Docker images before building new ones
- Add comprehensive cleanup commands documentation
- Add production deployment guide
- Fix frontend serving from /var/www/html for production
- Preserve build cache for faster deployments
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Remove .env from .gitignore
- Add backend/.env with all configuration
- Add frontend/.env with Vite variables
- Match APAC Ops Bot pattern
Environment files now tracked in git for easier deployment.
Update SECRET_KEY, OPENAI_API_KEY, AZURE_CLIENT_SECRET on server.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Change to OPENAI_MODEL (original variable name)
- Add OPENAI_API_BASE
- Use gpt-5.2 model as specified
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Add volume mount for /var/www/html/solventum-image-metadata
- Read-only mount (ro) for security
- Allows FastAPI to serve React static files
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Serve index.html on root /
- Mount /assets for React static files
- Backend now serves both frontend and API
- Works with simple ProxyPass config
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Rename app/api/import.py to import_api.py
- Update imports in main.py
- Fixes SyntaxError: 'import' is a reserved keyword in Python
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Add VITE_AZURE_* variables for SSO
- Use relative /api URL for Apache proxy
- Match APAC Ops Bot env pattern
- Production and development configs
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Change FRONTEND_URL to full URL with /solventum-image-metadata path
- Ensures CORS allows requests from correct origin
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Add DEPLOYMENT-CHECKLIST.md with step-by-step guide
- Add frontend/.env.production for build
- Update .env.fastapi.example with correct REDIRECT_URI
- Include all verification steps and troubleshooting
Ready for production deployment!
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Update .env: REDIRECT_URI without /api/ prefix
- Add OAuth handler in App.tsx for SSO callback
- Add basename to BrowserRouter: /solventum-image-metadata
- Add .env.production for server deployment
Matches Azure AD config:
https://ai-sandbox.oliver.solutions/solventum-image-metadata/
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Add prominent "Login with Microsoft" button
- Match original Flask design with Microsoft icon
- Add divider between SSO and local login
- Update styling to match gold theme
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Add Montserrat font from Google Fonts
- Use original color scheme (gold #FFC407, dark gradients)
- Add glass morphism effect with backdrop blur
- Add shimmer animation on header
- Style upload zone with hover/drag states
- Match all original design elements from Flask version
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Copy utils.py from src/ (required by extractors)
- Fixes ModuleNotFoundError: No module named 'app.processors.utils'
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- cd back to SCRIPT_DIR before running docker-compose logs/ps
- Fixes "no such file" error when running from frontend/ directory
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- FileUploadZone: Drag-drop with metadata source selector
- FileList: Batch operations (select, download, process more)
- FileItem: File card with expandable metadata editor
These were created but not committed previously.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Add Redis container back (no external port exposure)
- Redis only accessible within Docker network
- Backend connects via redis://redis:6379/0
- Simplify Redis health check in deploy.sh
This avoids port conflicts while keeping Redis in Docker.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Remove postgres service (port 5432 conflict)
- Using SQLite by default (simpler for single-server deployment)
- Remove postgres-data volume
- PostgreSQL can be added later if needed
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Comment out Excel file volume mount by default
- Excel lookup will be disabled if file not present
- Prevents deployment error when file doesn't exist
- Users can uncomment the line if they have the Excel file
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Change BACKEND_PORT from 8001 to 5001 (same as Flask)
- Keeps existing Azure AD redirect URI working
- No need to update Azure AD app registration
- Apache proxy can use same port configuration
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Make BACKEND_PORT configurable via .env
- Update docker-compose to use ${BACKEND_PORT:-8001}
- Update deploy.sh to read port from .env
- Update Apache config examples to use port 8001
- Update all documentation with correct port
Apache config must proxy:
/solventum-image-metadata/api → http://localhost:8001
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Update REDIRECT_URI to include /api/auth/microsoft/callback path
- Add production Azure AD credentials to .env.fastapi.example
- Create Apache migration guide with correct configuration
BREAKING CHANGE: Apache proxy must change from port 5001 to 8000
- Old: ProxyPass /solventum-image-metadata/ http://localhost:5001/
- New: ProxyPass /solventum-image-metadata/api http://localhost:8000
Frontend now served as static files, not proxied.
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Create idempotent deploy.sh for production deployment
- Add docker-compose.fastapi.yml with Redis + Backend
- Configure health checks for all services
- Add .env.fastapi.example with all configuration
- Remove old Flask deployment script (docker-run.sh)
Deployment features:
- Pre-flight checks (Docker, Node, permissions)
- Frontend build with Vite
- Deploy to /var/www/html/solventum-image-metadata
- Graceful container restart
- Health checks (backend + Redis)
- Auto-cleanup old Docker images
Usage:
cd /opt/solventum-image-metadata
git pull origin main
sudo ./deploy.sh
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
Fixed three critical issues:
1. Session persistence - Cookies not saved after page refresh
- Replaced APPLICATION_ROOT with SESSION_COOKIE_PATH
- Added proper cookie settings for reverse proxy (HttpOnly, SameSite)
- Set correct cookie path matching URL_PREFIX
2. AJAX detection for FormData uploads (JPG, etc.)
- Enhanced @login_required to detect POST/PUT/DELETE as AJAX
- Added Content-Type check for JSON requests
- Added path prefix check for API endpoints
3. JavaScript AJAX identification
- Updated fetchWithAuth() to add X-Requested-With header
- Properly handles both JSON and FormData requests using Headers API
- Ensures all fetch calls are identified as AJAX by server
Changes:
- web_app.py: Fixed Flask session cookie configuration
- src/auth.py: Improved AJAX detection logic in login_required decorator
- templates/index.html: Enhanced fetchWithAuth() with proper headers
This fixes:
- Users having to re-login on every page refresh
- "Unexpected token '<'" errors when uploading JPG files
- Session cookies not persisting through reverse proxy
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
Fixed two critical issues with API authentication on production server:
1. Modified @login_required decorator to detect AJAX/API requests and return
JSON error with 401 status instead of HTML redirect. This prevents
"Unexpected token '<'" errors when session expires.
2. Created fetchWithAuth() helper function in JavaScript that automatically
handles 401 responses by redirecting to login page. Updated all 11 API
fetch calls to use this wrapper.
Changes:
- src/auth.py: Added AJAX detection and JSON error responses to login_required
- templates/index.html: Added fetchWithAuth() and updated all fetch() calls
This fixes the console errors:
- "Failed to load templates: SyntaxError: Unexpected token '<'"
- 502 Bad Gateway errors now properly handled with session checks
Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Login button now uses MSAL.js loginRedirect() for PKCE
- oauth_callback uses MSAL.js handleRedirectPromise() to complete token exchange
- PKCE flow is now entirely in browser (SPA compatible)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Render oauth_callback.html with MSAL.js for browser token exchange
- Add /auth/token endpoint to receive token from JavaScript
- Token exchange happens in browser (cross-origin) for SPA compatibility
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Check for OAuth code in query params on main page
- Process SSO login without requiring /auth/callback route
- Redirect to clean URL after successful login
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use initiate_auth_code_flow for PKCE (required by Azure AD for public clients)
- Store auth flow in session for token exchange
- Fix AADSTS9002325 error
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove -back suffix, use single path for monolithic Flask app
- All routes now use /solventum-image-metadata/ prefix
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add URL_PREFIX for all redirect URLs
- Redirects now go to /solventum-image-metadata-back/login instead of /login
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add deploy.sh for idempotent Docker deployments
- Configure API_BASE for /solventum-image-metadata-back/ reverse proxy
- Enable Azure AD SSO with public client flow (no secret required)
- Remove hardcoded tester user for production security
- Add ProxyFix middleware for reverse proxy header handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GPT-5, GPT-5-mini, and GPT-5-nano to valid models list
- Add model validation with automatic fallback to gpt-4o-mini
- Update _is_new_model() to recognize GPT-5 as new generation
- Add detailed API response logging (model used, tokens, content preview)
- Add empty content detection with helpful error messages
- Fix API parameter selection for GPT-5 models
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>