This commit is contained in:
Manish Tanwar 2026-01-27 18:36:53 +05:30
parent 361e476d2c
commit e1067b551e
11 changed files with 536 additions and 1646 deletions

7
.gitignore vendored
View file

@ -67,3 +67,10 @@ debug*.php
# Session files
sess_*
# Development server files (created by setup.sh)
.backend.pid
.frontend.pid
backend-server.log
frontend-server.log
stop.sh

View file

@ -183,7 +183,7 @@ All managed by `useProjects.js` hook.
- Reference images (up to 2: first frame + optional last frame for interpolation)
- Veo 3.1 Standard or Fast model selection
- Creative Freedom levels (auto-adjusts guidance strength)
- Duration constraints: 4s (any), 6s (T2V only), 8s (T2V only)
- Duration options: 4s, 6s, 8s (all available for both T2V and I2V)
- Async polling for video completion
- Frame extraction from generated videos
@ -376,13 +376,8 @@ if ((tabId === 'image' || tabId === 'video') && !activeProjectId) {
}
```
### 4. Video Duration Constraints
Veo 3.1 I2V (image-to-video) only supports 4 seconds:
```javascript
if (referenceImages.length > 0 && duration > 4) {
duration = 4; // Force to 4s for I2V
}
```
### 4. Video Generation Settings
All durations (4s, 6s, 8s) work for both T2V and I2V modes. Resolution (720p/1080p) is a UI-only setting - only aspectRatio and durationSeconds are sent to the Veo 3.1 API.
### 5. MIME Type Handling
Always store and use dynamic MIME type from API response:

View file

@ -12,6 +12,13 @@
# Start backend with: php -S localhost:${BACKEND_PORT}
BACKEND_PORT=5015
# ----------------------------------------------------------------------------
# API Base Path (for video/file streaming URLs)
# ----------------------------------------------------------------------------
# For LOCAL development: Use /lux-studio-back (matches Vite proxy)
# For PRODUCTION: Set to your Apache proxy path (e.g., /lux-studio-back)
API_BASE_PATH=/lux-studio-back
# ----------------------------------------------------------------------------
# Google Gemini API Key (REQUIRED)
# ----------------------------------------------------------------------------

View file

@ -11,6 +11,13 @@
# Start backend with: php -S localhost:5015
BACKEND_PORT=5015
# ----------------------------------------------------------------------------
# API Base Path (for video/file streaming URLs)
# ----------------------------------------------------------------------------
# For LOCAL development: Use /lux-studio-back (matches Vite proxy)
# For PRODUCTION: Set to your Apache proxy path (e.g., /lux-studio-back)
API_BASE_PATH=/lux-studio-back
# ----------------------------------------------------------------------------
# Google Gemini API Key (REQUIRED)
# ----------------------------------------------------------------------------

View file

@ -14,11 +14,19 @@
# Port is hardcoded in lux-studio-backend.service, this is for reference only
BACKEND_PORT=5015
# ----------------------------------------------------------------------------
# API Base Path (for video/file streaming URLs)
# ----------------------------------------------------------------------------
# Apache proxy path - MUST match ProxyPass configuration in apache2.conf
# Used by video_api.php to generate correct video streaming URLs
API_BASE_PATH=/lux-studio-back
# ----------------------------------------------------------------------------
# Google Gemini API Key (REQUIRED)
# ----------------------------------------------------------------------------
# Get your API key from: https://aistudio.google.com/app/apikey
GEMINI_API_KEY=AIzaSyCMKLSJJYEx4c6-TtBACnjdULrLzsr_fts
GEMINI_API_KEY=AIzaSyDs7EKdC9NLM5UqWlGUqeQO96TmSA-kos8
# AIzaSyCMKLSJJYEx4c6-TtBACnjdULrLzsr_fts
# ----------------------------------------------------------------------------
# Frontend URL for CORS (REQUIRED)

View file

@ -1,8 +1,8 @@
# ==============================================================================
# VIDEO OPTIMIZER - FRONTEND SECURITY CONFIGURATION
# LUX STUDIO BACKEND - SECURITY CONFIGURATION
# ==============================================================================
# Location: /var/www/html/lux-studio/.htaccess
# Purpose: Security hardening for frontend static files
# Location: /opt/lux-studio-back/.htaccess
# Purpose: Prevent direct browser access, allow only API endpoints
# ==============================================================================
# ------------------------------------------------------------------------------
@ -12,20 +12,68 @@
# Disable directory browsing
Options -Indexes
# Follow symbolic links (required for some servers)
Options +FollowSymLinks
# Disable server signature
ServerSignature Off
# ------------------------------------------------------------------------------
# FILE ACCESS CONTROL
# BLOCK ROOT AND INDEX ACCESS
# ------------------------------------------------------------------------------
# Default: Allow access to all files (will be restricted below)
# Block access to index.php (prevents browsing backend UI)
<Files "index.php">
Require all denied
</Files>
# Deny access to sensitive files and patterns
<FilesMatch "^\.">
# Block access to test files
<FilesMatch "^(test|auth-test|server-check)\.php$">
Require all denied
</FilesMatch>
# Block access to configuration files
<FilesMatch "^(config|config\.example)\.php$">
Require all denied
</FilesMatch>
# ------------------------------------------------------------------------------
# API ENDPOINT ACCESS CONTROL
# ------------------------------------------------------------------------------
# Only allow POST requests to API endpoints
# GET is allowed only for stream_video.php (video streaming)
<FilesMatch "^(api|video_api|enhance_prompt|auth|webhook_logger)\.php$">
<RequireAll>
Require all granted
<RequireAny>
Require method POST OPTIONS
</RequireAny>
</RequireAll>
</FilesMatch>
# Allow GET and POST for video streaming
<Files "stream_video.php">
Require all granted
</Files>
# Allow POST for cleanup and session management
<FilesMatch "^(cleanup|clear_session|session_manager)\.php$">
<RequireAll>
Require all granted
Require method POST OPTIONS
</RequireAll>
</FilesMatch>
# Allow get_config.php and get_logs.php for debugging (consider disabling in production)
<FilesMatch "^(get_config|get_logs|get_current_image)\.php$">
Require all granted
</FilesMatch>
# ------------------------------------------------------------------------------
# PROTECT SENSITIVE FILES
# ------------------------------------------------------------------------------
# Deny access to environment files
<FilesMatch "^\.env">
Require all denied
</FilesMatch>
@ -34,86 +82,60 @@ ServerSignature Off
Require all denied
</FilesMatch>
# Deny access to version control files
<FilesMatch "(^\.git|^\.svn|^\.hg|^\.bzr)">
# Deny access to version control
<FilesMatch "(^\.git|^\.svn|^\.hg|composer\.)">
Require all denied
</FilesMatch>
# Deny access to environment and configuration files
<FilesMatch "^(\.env|\.env\.|config\.json|package\.json|package-lock\.json|composer\.json|composer\.lock)">
# Deny access to class files (should only be included, not accessed directly)
<FilesMatch "^(AuthMiddleware|JWTValidator|SessionManager)\.php$">
Require all denied
</FilesMatch>
# Deny access to PHP files (if any exist - security measure)
<FilesMatch "\.php">
Require all denied
</FilesMatch>
# <FilesMatch "\.php$">
# Require all denied
# </FilesMatch>
# Deny access to Python files (should not be in frontend)
<FilesMatch "\.py$">
Require all denied
</FilesMatch>
# Deny access to README and documentation that shouldn't be public
<FilesMatch "^(README|INSTALL|CHANGELOG|LICENSE|CONTRIBUTING)">
Require all denied
</FilesMatch>
# ------------------------------------------------------------------------------
# ALLOWED FILE TYPES (Explicitly allow necessary files)
# ------------------------------------------------------------------------------
# Allow HTML files (main application pages)
<FilesMatch "\.(html|htm)$">
Require all granted
</FilesMatch>
# Allow JavaScript files
<FilesMatch "\.(js|mjs)$">
Require all granted
</FilesMatch>
# Allow CSS files
<FilesMatch "\.css$">
Require all granted
</FilesMatch>
# Allow images
<FilesMatch "\.(jpg|jpeg|png|gif|ico|svg|webp)$">
Require all granted
</FilesMatch>
# Allow fonts
<FilesMatch "\.(woff|woff2|ttf|otf|eot)$">
Require all granted
</FilesMatch>
# Allow JSON files (only if needed for app functionality)
<FilesMatch "\.json$">
Require all denied
</FilesMatch>
# ------------------------------------------------------------------------------
# ERROR DOCUMENTS
# ------------------------------------------------------------------------------
# Custom error pages (optional - create these files if needed)
# ErrorDocument 403 /video-optimizer/error/403.html
# ErrorDocument 404 /video-optimizer/error/404.html
# ErrorDocument 500 /video-optimizer/error/500.html
# ------------------------------------------------------------------------------
# ADDITIONAL SECURITY
# ------------------------------------------------------------------------------
# Prevent access to .htaccess itself
# Deny access to .htaccess itself
<Files ".htaccess">
Require all denied
</Files>
# ------------------------------------------------------------------------------
# UPLOADS DIRECTORY PROTECTION
# ------------------------------------------------------------------------------
# Block direct access to uploads directory (videos/images should be streamed via PHP)
<IfModule mod_rewrite.c>
RewriteEngine On
# Block direct access to uploads folder
RewriteRule ^uploads/ - [F,L]
</IfModule>
# ------------------------------------------------------------------------------
# SECURITY HEADERS (if not set by Apache)
# ------------------------------------------------------------------------------
<IfModule mod_headers.c>
# Prevent MIME type sniffing
Header set X-Content-Type-Options "nosniff"
# Prevent clickjacking
Header set X-Frame-Options "DENY"
# XSS Protection
Header set X-XSS-Protection "1; mode=block"
</IfModule>
# ------------------------------------------------------------------------------
# ERROR HANDLING
# ------------------------------------------------------------------------------
# Return 403 Forbidden instead of showing file listings
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
# Custom error document (returns JSON for API errors)
ErrorDocument 403 "Forbidden: Direct access to backend is not allowed. Use API endpoints only."
ErrorDocument 404 "Not Found: API endpoint does not exist."
# ==============================================================================
# END OF CONFIGURATION

File diff suppressed because it is too large Load diff

View file

@ -439,7 +439,7 @@ try {
'video' => [
'filename' => $filename,
'mime_type' => $videoData['mime_type'],
'url' => '/api/stream_video.php?file=' . urlencode($filename)
'url' => ($_ENV['API_BASE_PATH'] ?? '') . '/stream_video.php?file=' . urlencode($filename)
]
]);
} else if ($videoData['type'] === 'uri') {
@ -481,7 +481,7 @@ try {
'video' => [
'filename' => $filename,
'mime_type' => $videoData['mime_type'],
'url' => '/api/stream_video.php?file=' . urlencode($filename)
'url' => ($_ENV['API_BASE_PATH'] ?? '') . '/stream_video.php?file=' . urlencode($filename)
]
]);
} else {
@ -561,7 +561,7 @@ try {
echo json_encode([
'success' => true,
'video' => [
'url' => '/api/stream_video.php?file=' . urlencode($filename),
'url' => ($_ENV['API_BASE_PATH'] ?? '') . '/stream_video.php?file=' . urlencode($filename),
'filename' => $filename,
'mime_type' => 'video/mp4'
]

View file

@ -129,10 +129,9 @@ const VideoGenTab = ({ activeProjectId, rerunData, onRerunLoaded }) => {
// Check if already added
if (referenceImages.some(img => img.projectItemId === item.id)) return;
// Auto-set constraints when adding first reference image (I2V requirements)
// Auto-set aspect ratio when adding first reference image
if (referenceImages.length === 0) {
setDuration(8);
setAspectRatio('16:9'); // Reference images only support 16:9
setAspectRatio('16:9');
}
setReferenceImages(prev => [...prev, {
@ -185,10 +184,9 @@ const VideoGenTab = ({ activeProjectId, rerunData, onRerunLoaded }) => {
const reader = new FileReader();
reader.onload = () => {
setReferenceImages(prev => {
// Auto-set constraints when adding first reference image (I2V requirements)
// Auto-set aspect ratio when adding first reference image
if (prev.length === 0) {
setDuration(8);
setAspectRatio('16:9'); // Reference images only support 16:9
setAspectRatio('16:9');
}
return [...prev, {
data: reader.result.split(',')[1],
@ -615,25 +613,16 @@ OUTPUT ONLY THE PROMPT - no explanations, no labels, no formatting.`;
</label>
<div className="flex gap-2">
{durationOptions.map((opt) => {
const isDisabledByI2V = referenceImages.length > 0 && opt.value !== 8;
const isDisabledByI2V = false;
return (
<button
key={opt.value}
onClick={() => {
if (isDisabledByI2V) return;
setDuration(opt.value);
// Auto-downgrade resolution if not 8s (1080p requires 8s)
if (opt.value !== 8 && resolution === '1080p') {
setResolution('720p');
}
}}
disabled={isDisabledByI2V}
title={isDisabledByI2V ? 'I2V requires 8s duration' : ''}
onClick={() => setDuration(opt.value)}
className={`flex-1 px-3 py-2 rounded-lg font-medium transition-all text-sm ${
duration === opt.value
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
} ${isDisabledByI2V ? 'opacity-50 cursor-not-allowed' : ''}`}
}`}
>
<div>{opt.label}</div>
<div className="text-xs opacity-70">{getDurationCost(opt.value)}</div>
@ -641,9 +630,6 @@ OUTPUT ONLY THE PROMPT - no explanations, no labels, no formatting.`;
);
})}
</div>
{referenceImages.length > 0 && (
<p className="text-xs text-slate-500">I2V mode requires 8s duration</p>
)}
</div>
{/* Aspect Ratio */}
@ -655,13 +641,7 @@ OUTPUT ONLY THE PROMPT - no explanations, no labels, no formatting.`;
{['16:9', '9:16'].map((ratio) => (
<button
key={ratio}
onClick={() => {
setAspectRatio(ratio);
if (ratio === '9:16') {
// Auto-downgrade resolution (1080p not supported in portrait)
setResolution('720p');
}
}}
onClick={() => setAspectRatio(ratio)}
className={`flex-1 px-4 py-2 rounded-lg font-medium transition-all ${
aspectRatio === ratio
? 'bg-cinema-gold text-slate-950'
@ -681,27 +661,22 @@ OUTPUT ONLY THE PROMPT - no explanations, no labels, no formatting.`;
</label>
<div className="flex gap-2">
{['720p', '1080p'].map((res) => {
const is1080pDisabled = res === '1080p' && (duration !== 8 || aspectRatio !== '16:9');
const is1080pDisabled = false;
return (
<button
key={res}
onClick={() => !is1080pDisabled && setResolution(res)}
disabled={is1080pDisabled}
title={is1080pDisabled ? '1080p requires 8s duration + 16:9 aspect ratio' : ''}
onClick={() => setResolution(res)}
className={`flex-1 px-4 py-2 rounded-lg font-medium transition-all ${
resolution === res
? 'bg-cinema-gold text-slate-950'
: 'bg-slate-800 text-slate-400 hover:bg-slate-700'
} ${is1080pDisabled ? 'opacity-50 cursor-not-allowed' : ''}`}
}`}
>
{res}
</button>
);
})}
</div>
{(duration !== 8 || aspectRatio !== '16:9') && (
<p className="text-xs text-slate-500">1080p requires 8s + 16:9</p>
)}
</div>
{/* Audio Toggle */}

284
setup.sh
View file

@ -1,9 +1,9 @@
#!/bin/bash
# ============================================================================
# Lux Studio - Local Development Setup Script
# Lux Studio - Local Development Setup & Start Script
# ============================================================================
# This script sets up both frontend and backend for LOCAL development
# This script sets up AND starts both frontend and backend for LOCAL development
# For production deployment, use deploy.sh instead
# ============================================================================
@ -19,6 +19,9 @@ YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Get the absolute path of the project root
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ============================================================================
# 1. CHECK PREREQUISITES
# ============================================================================
@ -125,7 +128,20 @@ cd ..
echo ""
# ============================================================================
# 4. READ PORT CONFIGURATION
# 4. CREATE REQUIRED DIRECTORIES
# ============================================================================
echo "${BLUE}Step 4: Creating required directories...${NC}"
# Create backend upload directory with proper permissions
mkdir -p backend/uploads/sessions
chmod -R 755 backend/uploads 2>/dev/null || true
echo "${GREEN}✓ Required directories created${NC}"
echo ""
# ============================================================================
# 5. READ PORT CONFIGURATION
# ============================================================================
# Read ports from .env files
@ -145,38 +161,262 @@ BACKEND_PORT=${BACKEND_PORT:-5015}
FRONTEND_PORT=${FRONTEND_PORT:-3000}
# ============================================================================
# 5. FINAL INSTRUCTIONS
# 6. CHECK FOR PORT CONFLICTS
# ============================================================================
echo "${BLUE}Step 5: Checking for port conflicts...${NC}"
# Function to check if a port is in use
check_port() {
local port=$1
if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1 ; then
return 0 # Port is in use
else
return 1 # Port is free
fi
}
# Function to kill process on port
kill_port() {
local port=$1
local pid=$(lsof -ti:$port)
if [ ! -z "$pid" ]; then
echo " → Killing process $pid on port $port..."
kill -9 $pid 2>/dev/null || true
sleep 1
fi
}
# Check backend port
if check_port $BACKEND_PORT; then
echo "${YELLOW} ⚠ Port $BACKEND_PORT is already in use${NC}"
read -p " Kill the process and continue? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
kill_port $BACKEND_PORT
echo "${GREEN} ✓ Port $BACKEND_PORT is now free${NC}"
else
echo "${RED} ✗ Cannot start backend - port in use${NC}"
exit 1
fi
else
echo "${GREEN} ✓ Port $BACKEND_PORT is available${NC}"
fi
# Check frontend port
if check_port $FRONTEND_PORT; then
echo "${YELLOW} ⚠ Port $FRONTEND_PORT is already in use${NC}"
read -p " Kill the process and continue? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
kill_port $FRONTEND_PORT
echo "${GREEN} ✓ Port $FRONTEND_PORT is now free${NC}"
else
echo "${RED} ✗ Cannot start frontend - port in use${NC}"
exit 1
fi
else
echo "${GREEN} ✓ Port $FRONTEND_PORT is available${NC}"
fi
echo ""
# ============================================================================
# 7. START BACKEND SERVER
# ============================================================================
echo "${BLUE}Step 6: Starting backend server...${NC}"
cd "$PROJECT_ROOT/backend"
# Start PHP server in background
nohup php -S localhost:${BACKEND_PORT} > "${PROJECT_ROOT}/backend-server.log" 2>&1 &
BACKEND_PID=$!
# Wait a moment and check if server started
sleep 2
if ps -p $BACKEND_PID > /dev/null; then
echo "${GREEN}✓ Backend server started on port ${BACKEND_PORT}${NC}"
echo " PID: $BACKEND_PID"
echo " Logs: ${PROJECT_ROOT}/backend-server.log"
# Save PID for later shutdown
echo $BACKEND_PID > "${PROJECT_ROOT}/.backend.pid"
else
echo "${RED}✗ Failed to start backend server${NC}"
echo " Check ${PROJECT_ROOT}/backend-server.log for errors"
exit 1
fi
cd "$PROJECT_ROOT"
echo ""
# ============================================================================
# 8. START FRONTEND SERVER
# ============================================================================
echo "${BLUE}Step 7: Starting frontend dev server...${NC}"
cd "$PROJECT_ROOT/frontend"
# Start Vite dev server in background
nohup npm run dev > "${PROJECT_ROOT}/frontend-server.log" 2>&1 &
FRONTEND_PID=$!
# Wait for Vite to start (it takes a bit longer)
echo " → Waiting for Vite dev server to start..."
sleep 5
if ps -p $FRONTEND_PID > /dev/null; then
echo "${GREEN}✓ Frontend server started on port ${FRONTEND_PORT}${NC}"
echo " PID: $FRONTEND_PID"
echo " Logs: ${PROJECT_ROOT}/frontend-server.log"
# Save PID for later shutdown
echo $FRONTEND_PID > "${PROJECT_ROOT}/.frontend.pid"
else
echo "${RED}✗ Failed to start frontend server${NC}"
echo " Check ${PROJECT_ROOT}/frontend-server.log for errors"
# Clean up backend server
kill $BACKEND_PID 2>/dev/null || true
exit 1
fi
cd "$PROJECT_ROOT"
echo ""
# ============================================================================
# 9. VERIFY SERVERS ARE RUNNING
# ============================================================================
echo "${BLUE}Step 8: Verifying servers...${NC}"
# Wait a moment for servers to fully initialize
sleep 3
# Check if backend responds
if curl -s http://localhost:${BACKEND_PORT}/server-check.php > /dev/null 2>&1; then
echo "${GREEN} ✓ Backend is responding${NC}"
else
echo "${YELLOW} ⚠ Backend may not be fully ready yet${NC}"
fi
# Check if frontend responds
if curl -s http://localhost:${FRONTEND_PORT} > /dev/null 2>&1; then
echo "${GREEN} ✓ Frontend is responding${NC}"
else
echo "${YELLOW} ⚠ Frontend may not be fully ready yet${NC}"
fi
echo ""
# ============================================================================
# 10. CREATE STOP SCRIPT
# ============================================================================
# Create a stop script for easy shutdown
cat > "${PROJECT_ROOT}/stop.sh" << 'EOF'
#!/bin/bash
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${YELLOW}🛑 Stopping Lux Studio servers...${NC}"
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Stop backend
if [ -f "${PROJECT_ROOT}/.backend.pid" ]; then
BACKEND_PID=$(cat "${PROJECT_ROOT}/.backend.pid")
if ps -p $BACKEND_PID > /dev/null 2>&1; then
kill $BACKEND_PID 2>/dev/null
echo -e "${GREEN}✓ Backend server stopped (PID: $BACKEND_PID)${NC}"
else
echo -e "${YELLOW}⚠ Backend server not running${NC}"
fi
rm "${PROJECT_ROOT}/.backend.pid"
fi
# Stop frontend
if [ -f "${PROJECT_ROOT}/.frontend.pid" ]; then
FRONTEND_PID=$(cat "${PROJECT_ROOT}/.frontend.pid")
if ps -p $FRONTEND_PID > /dev/null 2>&1; then
kill $FRONTEND_PID 2>/dev/null
echo -e "${GREEN}✓ Frontend server stopped (PID: $FRONTEND_PID)${NC}"
else
echo -e "${YELLOW}⚠ Frontend server not running${NC}"
fi
rm "${PROJECT_ROOT}/.frontend.pid"
fi
# Also kill any remaining processes on the ports (cleanup)
BACKEND_PORT=$(grep -E "^BACKEND_PORT=" backend/.env 2>/dev/null | cut -d'=' -f2 | tr -d ' ')
FRONTEND_PORT=$(grep -E "^FRONTEND_PORT=" frontend/.env 2>/dev/null | cut -d'=' -f2 | tr -d ' ')
BACKEND_PORT=${BACKEND_PORT:-5015}
FRONTEND_PORT=${FRONTEND_PORT:-3000}
# Kill any remaining processes on ports
for port in $BACKEND_PORT $FRONTEND_PORT; do
pid=$(lsof -ti:$port 2>/dev/null)
if [ ! -z "$pid" ]; then
kill -9 $pid 2>/dev/null || true
echo -e "${GREEN}✓ Cleaned up process on port $port${NC}"
fi
done
echo -e "${GREEN}✅ All servers stopped${NC}"
EOF
chmod +x "${PROJECT_ROOT}/stop.sh"
# ============================================================================
# 11. SUCCESS MESSAGE
# ============================================================================
echo "${GREEN}════════════════════════════════════════════════════════════${NC}"
echo "${GREEN}🎉 Setup Complete! Ready for Local Development${NC}"
echo "${GREEN}🎉 Lux Studio is Running!${NC}"
echo "${GREEN}════════════════════════════════════════════════════════════${NC}"
echo ""
echo "${BLUE}📋 Next Steps:${NC}"
echo "${BLUE}🌐 Application URLs:${NC}"
echo " • Frontend: ${GREEN}http://localhost:${FRONTEND_PORT}${NC}"
echo " • Backend API: ${GREEN}http://localhost:${BACKEND_PORT}${NC}"
echo ""
echo "1. ${YELLOW}Start Backend Server${NC} (Terminal 1):"
echo " ${GREEN}cd backend && php -S localhost:${BACKEND_PORT}${NC}"
echo "${BLUE}📊 Server Status:${NC}"
echo " • Backend PID: $BACKEND_PID (port $BACKEND_PORT)"
echo " • Frontend PID: $FRONTEND_PID (port $FRONTEND_PORT)"
echo ""
echo "2. ${YELLOW}Start Frontend Dev Server${NC} (Terminal 2):"
echo " ${GREEN}cd frontend && npm run dev${NC}"
echo "${BLUE}📝 Log Files:${NC}"
echo " • Backend: ${PROJECT_ROOT}/backend-server.log"
echo " • Frontend: ${PROJECT_ROOT}/frontend-server.log"
echo " • View backend: ${GREEN}tail -f ${PROJECT_ROOT}/backend-server.log${NC}"
echo " • View frontend: ${GREEN}tail -f ${PROJECT_ROOT}/frontend-server.log${NC}"
echo ""
echo "3. ${YELLOW}Open in Browser:${NC}"
echo " ${GREEN}http://localhost:${FRONTEND_PORT}${NC}"
echo "${BLUE}🛑 Stop Servers:${NC}"
echo " ${GREEN}./stop.sh${NC}"
echo ""
echo "${BLUE}⚙️ Configuration:${NC}"
echo " • Backend Port: ${BACKEND_PORT} (change in backend/.env)"
echo " • Frontend Port: ${FRONTEND_PORT} (change in frontend/.env)"
echo " • SSO: Enabled (disable by setting VITE_SSO_ENABLED=false in frontend/.env)"
echo " • SSO: Enabled with LOCAL credentials"
echo " • SSO Client ID: 15c0c4e2-bac0-4564-a3a6-c2717f00a6d9 (local dev)"
echo " • API Key: Configured in .env files"
echo ""
echo "${BLUE}📚 Documentation:${NC}"
echo " • README.md - User guide and features"
echo " • CLAUDE.md - Developer guide for AI assistants"
echo " • DEPLOYMENT.md - Production deployment guide"
echo " • CLAUDE.md - Developer guide"
echo " • MDFiles/README.md - User guide"
echo " • MDFiles/AUTH_README.md - SSO guide"
echo ""
echo "${BLUE}💡 Useful Commands:${NC}"
echo " • Build for production: ${GREEN}cd frontend && npm run build${NC}"
echo " • Run linter: ${GREEN}cd frontend && npm run lint${NC}"
echo " • View logs: Check terminal output and browser console (F12)"
echo "${YELLOW}💡 Tip: Open http://localhost:${FRONTEND_PORT} in your browser!${NC}"
echo ""
echo "Happy coding! 🚀"

108
status.sh Normal file
View file

@ -0,0 +1,108 @@
#!/bin/bash
# ============================================================================
# Lux Studio - Server Status Check Script
# ============================================================================
# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Read ports from .env files
BACKEND_PORT=5015
FRONTEND_PORT=3000
if [ -f "backend/.env" ]; then
BACKEND_PORT=$(grep -E "^BACKEND_PORT=" backend/.env | cut -d'=' -f2 | tr -d ' ')
fi
if [ -f "frontend/.env" ]; then
FRONTEND_PORT=$(grep -E "^FRONTEND_PORT=" frontend/.env | cut -d'=' -f2 | tr -d ' ')
fi
BACKEND_PORT=${BACKEND_PORT:-5015}
FRONTEND_PORT=${FRONTEND_PORT:-3000}
echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}📊 Lux Studio Server Status${NC}"
echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
echo ""
# Check Backend
echo -e "${BLUE}🔧 Backend Server (Port ${BACKEND_PORT}):${NC}"
if [ -f "${PROJECT_ROOT}/.backend.pid" ]; then
BACKEND_PID=$(cat "${PROJECT_ROOT}/.backend.pid")
if ps -p $BACKEND_PID > /dev/null 2>&1; then
echo -e " Status: ${GREEN}✓ Running${NC}"
echo -e " PID: $BACKEND_PID"
if curl -s http://localhost:${BACKEND_PORT}/server-check.php > /dev/null 2>&1; then
echo -e " Health: ${GREEN}✓ Responding${NC}"
else
echo -e " Health: ${YELLOW}⚠ Not responding${NC}"
fi
else
echo -e " Status: ${RED}✗ Not running (stale PID file)${NC}"
fi
else
echo -e " Status: ${RED}✗ Not running${NC}"
fi
echo ""
# Check Frontend
echo -e "${BLUE}🎨 Frontend Server (Port ${FRONTEND_PORT}):${NC}"
if [ -f "${PROJECT_ROOT}/.frontend.pid" ]; then
FRONTEND_PID=$(cat "${PROJECT_ROOT}/.frontend.pid")
if ps -p $FRONTEND_PID > /dev/null 2>&1; then
echo -e " Status: ${GREEN}✓ Running${NC}"
echo -e " PID: $FRONTEND_PID"
if curl -s http://localhost:${FRONTEND_PORT} > /dev/null 2>&1; then
echo -e " Health: ${GREEN}✓ Responding${NC}"
else
echo -e " Health: ${YELLOW}⚠ Not responding${NC}"
fi
else
echo -e " Status: ${RED}✗ Not running (stale PID file)${NC}"
fi
else
echo -e " Status: ${RED}✗ Not running${NC}"
fi
echo ""
# URLs
echo -e "${BLUE}🌐 Application URLs:${NC}"
echo -e " • Frontend: ${GREEN}http://localhost:${FRONTEND_PORT}${NC}"
echo -e " • Backend API: ${GREEN}http://localhost:${BACKEND_PORT}${NC}"
echo ""
# Log files
echo -e "${BLUE}📝 Log Files:${NC}"
if [ -f "${PROJECT_ROOT}/backend-server.log" ]; then
echo -e " • Backend: ${GREEN}${PROJECT_ROOT}/backend-server.log${NC}"
echo -e " Last 3 lines:"
tail -3 "${PROJECT_ROOT}/backend-server.log" | sed 's/^/ /'
else
echo -e " • Backend: ${YELLOW}No log file${NC}"
fi
echo ""
if [ -f "${PROJECT_ROOT}/frontend-server.log" ]; then
echo -e " • Frontend: ${GREEN}${PROJECT_ROOT}/frontend-server.log${NC}"
echo -e " Last 3 lines:"
tail -3 "${PROJECT_ROOT}/frontend-server.log" | sed 's/^/ /'
else
echo -e " • Frontend: ${YELLOW}No log file${NC}"
fi
echo ""
# Commands
echo -e "${BLUE}💡 Useful Commands:${NC}"
echo -e " • View backend logs: ${GREEN}tail -f backend-server.log${NC}"
echo -e " • View frontend logs: ${GREEN}tail -f frontend-server.log${NC}"
echo -e " • Stop servers: ${GREEN}./stop.sh${NC}"
echo -e " • Restart: ${GREEN}./stop.sh && ./setup.sh${NC}"
echo ""