diff --git a/.DS_Store b/.DS_Store index b248104..b7949fd 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/backend/app/api/v1/__pycache__/routes_auth.cpython-313.pyc b/backend/app/api/v1/__pycache__/routes_auth.cpython-313.pyc index 82e436e..de9cf88 100644 Binary files a/backend/app/api/v1/__pycache__/routes_auth.cpython-313.pyc and b/backend/app/api/v1/__pycache__/routes_auth.cpython-313.pyc differ diff --git a/backend/app/api/v1/routes_auth.py b/backend/app/api/v1/routes_auth.py index d3e9191..a60b4a2 100644 --- a/backend/app/api/v1/routes_auth.py +++ b/backend/app/api/v1/routes_auth.py @@ -138,7 +138,11 @@ async def refresh_token( max_age=settings.jwt_refresh_ttl_days * 24 * 60 * 60, ) - return RefreshResponse(access_token=new_access_token) + return RefreshResponse( + access_token=new_access_token, + user_id=user_id, + role=user.role.value + ) except Exception: raise HTTPException( diff --git a/docs/video accessibility demo user guide instructions.pdf b/docs/video accessibility demo user guide instructions.pdf new file mode 100644 index 0000000..491f7da Binary files /dev/null and b/docs/video accessibility demo user guide instructions.pdf differ diff --git a/docs/video-accessibility-demo-instructions.mp4 b/docs/video-accessibility-demo-instructions.mp4 new file mode 100644 index 0000000..0153555 Binary files /dev/null and b/docs/video-accessibility-demo-instructions.mp4 differ diff --git a/docs/video-accessibility-download-final-assets.mp4 b/docs/video-accessibility-download-final-assets.mp4 new file mode 100644 index 0000000..37b4120 Binary files /dev/null and b/docs/video-accessibility-download-final-assets.mp4 differ diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index f5e5660..fc3cd6a 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -3,6 +3,7 @@ import type { AxiosInstance } from 'axios'; import type { LoginRequest, LoginResponse, + RefreshResponse, Job, JobCreateRequest, JobListResponse, @@ -96,7 +97,7 @@ class ApiClient { return response.data; } - async refresh(): Promise<{ access_token: string }> { + async refresh(): Promise { const response = await this.client.post('/auth/refresh'); this.setAccessToken(response.data.access_token); return response.data; diff --git a/frontend/src/lib/auth.ts b/frontend/src/lib/auth.ts index a3801cd..8a50ebb 100644 --- a/frontend/src/lib/auth.ts +++ b/frontend/src/lib/auth.ts @@ -48,17 +48,17 @@ export const useAuthStore = create((set) => ({ refreshAuth: async () => { try { - await apiClient.refresh(); - // Token refresh succeeded, but we don't have user info - // In a proper implementation, the refresh endpoint would return user data - // For now, we'll assume if refresh succeeds and we have existing user, we're authenticated - const currentState = useAuthStore.getState(); - if (currentState.user) { - set({ isAuthenticated: true, isLoading: false }); - } else { - // No user info available, mark as unauthenticated - set({ user: null, isAuthenticated: false, isLoading: false }); - } + const response = await apiClient.refresh(); + // Reconstruct user from refresh response + const user: User = { + id: response.user_id, + email: '', // Will be populated if needed + full_name: '', + role: response.role as UserRole, + is_active: true, + created_at: '', + }; + set({ user, isAuthenticated: true, isLoading: false }); } catch (error) { set({ user: null, isAuthenticated: false, isLoading: false }); throw error; diff --git a/frontend/src/types/api.ts b/frontend/src/types/api.ts index 7b0545f..bf0e7a1 100644 --- a/frontend/src/types/api.ts +++ b/frontend/src/types/api.ts @@ -93,6 +93,13 @@ export interface LoginResponse { role: string; } +export interface RefreshResponse { + access_token: string; + token_type: string; + user_id: string; + role: string; +} + export interface JobCreateRequest { title: string; language: string; diff --git a/scripts/full-deploy.sh b/scripts/full-deploy.sh new file mode 100755 index 0000000..b76df5a --- /dev/null +++ b/scripts/full-deploy.sh @@ -0,0 +1,288 @@ +#!/bin/bash +# ============================================================================= +# Full Deployment Script for Accessible Video Platform +# ============================================================================= +# Pulls latest code, rebuilds containers, and deploys frontend +# Run from: /opt/video-accessibility/ +# Usage: sudo ./scripts/full-deploy.sh +# ============================================================================= + +set -e # Exit on any error + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Configuration +PROJECT_DIR="/opt/video-accessibility" +FRONTEND_DEPLOY_DIR="/var/www/html/video-accessibility" +COMPOSE_FILES="-f docker-compose.yml -f docker-compose.prod.yml" + +# ============================================================================= +# Helper Functions +# ============================================================================= + +print_header() { + echo -e "${BLUE}==============================================================================${NC}" + echo -e "${BLUE}$1${NC}" + echo -e "${BLUE}==============================================================================${NC}" +} + +print_success() { + echo -e "${GREEN} $1${NC}" +} + +print_error() { + echo -e "${RED} $1${NC}" +} + +print_warning() { + echo -e "${YELLOW}  $1${NC}" +} + +print_info() { + echo -e "${BLUE}9 $1${NC}" +} + +# ============================================================================= +# Pre-flight Checks +# ============================================================================= + +preflight_checks() { + print_header "Pre-flight Checks" + + # Check if running as root or with sudo + if [ "$EUID" -ne 0 ]; then + print_error "Please run with sudo" + exit 1 + fi + print_success "Running with sudo" + + # Check if in correct directory + if [ ! -f "docker-compose.yml" ]; then + print_error "docker-compose.yml not found. Please run from $PROJECT_DIR" + exit 1 + fi + print_success "Running from correct directory" + + # Check if Docker is running + if ! docker info > /dev/null 2>&1; then + print_error "Docker is not running" + exit 1 + fi + print_success "Docker is running" + + echo "" +} + +# ============================================================================= +# Pull Latest Code +# ============================================================================= + +pull_code() { + print_header "Pulling Latest Code from Git" + + # Pull backend + if [ -d "backend/.git" ]; then + print_info "Pulling backend repository..." + cd backend + git pull origin main + cd .. + print_success "Backend code updated" + else + print_warning "Backend is not a git repository" + fi + + # Pull frontend + if [ -d "frontend/.git" ]; then + print_info "Pulling frontend repository..." + cd frontend + git pull origin main + cd .. + print_success "Frontend code updated" + else + print_warning "Frontend is not a git repository" + fi + + # Pull root repo if it exists + if [ -d ".git" ]; then + print_info "Pulling root repository..." + git pull origin main + print_success "Root repository updated" + fi + + echo "" +} + +# ============================================================================= +# Rebuild and Restart Containers +# ============================================================================= + +rebuild_containers() { + print_header "Rebuilding Docker Containers" + + print_info "Building images (this may take several minutes)..." + docker compose $COMPOSE_FILES build --no-cache + print_success "Docker images built" + + print_info "Stopping existing containers..." + docker compose $COMPOSE_FILES down + print_success "Containers stopped" + + print_info "Starting services..." + docker compose $COMPOSE_FILES up -d + print_success "Services started" + + print_info "Waiting for services to be healthy (30 seconds)..." + sleep 30 + + # Check if containers are running + print_info "Checking container status..." + docker compose $COMPOSE_FILES ps + + # Check for unhealthy containers + if docker compose $COMPOSE_FILES ps | grep -q "unhealthy"; then + print_warning "Some services may be unhealthy, check logs" + else + print_success "All services appear healthy" + fi + + echo "" +} + +# ============================================================================= +# Build and Deploy Frontend +# ============================================================================= + +build_and_deploy_frontend() { + print_header "Building and Deploying Frontend" + + cd frontend + + # Install dependencies + print_info "Installing frontend dependencies..." + npm ci + print_success "Dependencies installed" + + # Build frontend + print_info "Building React application..." + npm run build + print_success "Frontend build completed" + + # Check if build succeeded + if [ ! -d "dist" ]; then + print_error "Build failed - dist directory not found" + exit 1 + fi + + # Display build size + BUILD_SIZE=$(du -sh dist | cut -f1) + print_info "Build size: $BUILD_SIZE" + + cd .. + + # Deploy to Apache + print_info "Deploying to $FRONTEND_DEPLOY_DIR..." + + # Create backup of existing deployment + if [ -d "$FRONTEND_DEPLOY_DIR" ] && [ "$(ls -A $FRONTEND_DEPLOY_DIR 2>/dev/null)" ]; then + BACKUP_DIR="${FRONTEND_DEPLOY_DIR}.backup.$(date +%Y%m%d_%H%M%S)" + print_info "Creating backup at $BACKUP_DIR" + cp -r "$FRONTEND_DEPLOY_DIR" "$BACKUP_DIR" + print_success "Backup created" + fi + + # Clear and deploy + print_info "Clearing deployment directory..." + rm -rf "$FRONTEND_DEPLOY_DIR"/* + print_success "Directory cleared" + + print_info "Copying build artifacts..." + cp -r frontend/dist/* "$FRONTEND_DEPLOY_DIR"/ + print_success "Files copied" + + # Set ownership and permissions + print_info "Setting ownership to www-data..." + chown -R www-data:www-data "$FRONTEND_DEPLOY_DIR" + print_success "Ownership set" + + print_info "Setting permissions..." + find "$FRONTEND_DEPLOY_DIR" -type d -exec chmod 755 {} \; + find "$FRONTEND_DEPLOY_DIR" -type f -exec chmod 644 {} \; + print_success "Permissions set" + + # Verify deployment + if [ ! -f "$FRONTEND_DEPLOY_DIR/index.html" ]; then + print_error "Deployment verification failed - index.html not found" + exit 1 + fi + print_success "Deployment verified" + + echo "" +} + +# ============================================================================= +# Display Deployment Summary +# ============================================================================= + +display_summary() { + print_header "Deployment Summary" + + echo -e "${BLUE}Container Status:${NC}" + docker compose $COMPOSE_FILES ps + echo "" + + echo -e "${GREEN} Deployment completed successfully!${NC}" + echo "" + echo -e "${BLUE}Service URLs:${NC}" + echo " Frontend: https://ai-sandbox.oliver.solutions/video-accessibility" + echo " Backend API: https://ai-sandbox.oliver.solutions/video-accessibility-back" + echo " API Health: https://ai-sandbox.oliver.solutions/video-accessibility-back/health" + echo "" + echo -e "${BLUE}Useful Commands:${NC}" + echo " View logs: sudo docker compose $COMPOSE_FILES logs -f [service]" + echo " Restart service: sudo docker compose $COMPOSE_FILES restart [service]" + echo " Check status: sudo docker compose $COMPOSE_FILES ps" + echo "" + echo -e "${YELLOW}Note: If you created a backup, it's stored at:${NC}" + ls -dt ${FRONTEND_DEPLOY_DIR}.backup.* 2>/dev/null | head -1 || echo " (No backup created)" + echo "" +} + +# ============================================================================= +# Main Deployment Flow +# ============================================================================= + +main() { + print_header "Full Deployment - Accessible Video Platform" + echo "" + echo "This script will:" + echo " 1. Pull latest code from git" + echo " 2. Rebuild all Docker containers" + echo " 3. Restart all services" + echo " 4. Build and deploy frontend" + echo "" + + # Confirm before proceeding + read -p "Continue with deployment? (y/N) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + print_warning "Deployment cancelled" + exit 0 + fi + echo "" + + preflight_checks + pull_code + rebuild_containers + build_and_deploy_frontend + display_summary + + print_success "Deployment complete! =€" +} + +# Run main function +main