@echo off setlocal EnableDelayedExpansion set "SELF=%~f0" if /i "%~1"=="__run__" ( set "ACTION=%~2" ) else ( set "ACTION=%~1" echo %CMDCMDLINE% | find /i " /c " >nul if not errorlevel 1 ( cmd /k "%SELF%" __run__ %* exit /b ) ) set "ROOT=%~dp0.." for %%I in ("%ROOT%") do set "ROOT=%%~fI" cd /d "%ROOT%" || goto :fail_cd set "COMPOSE=docker\docker-compose.yml" set "ENV_FILE=docker\.env" set "COMPOSE_PROJECT=soondesign" set "WEB_PORT=8100" set "ELECTRON_PORT=8101" set "BACKEND_PORT=8102" if /i "%ACTION%"=="stop" goto :do_stop if /i "%ACTION%"=="reset" goto :do_reset if /i "%ACTION%"=="rebuild" goto :do_rebuild if /i "%ACTION%"=="logs" goto :do_logs if /i "%ACTION%"=="status" goto :do_status goto :do_start :compose docker compose -p "%COMPOSE_PROJECT%" -f "%COMPOSE%" --env-file "%ENV_FILE%" %* exit /b !ERRORLEVEL! :compose_noenv docker compose -p "%COMPOSE_PROJECT%" -f "%COMPOSE%" %* exit /b !ERRORLEVEL! :load_ports for /f "usebackq eol=# tokens=1,* delims==" %%A in ("%ENV_FILE%") do ( if /i "%%A"=="WEB_PORT" set "WEB_PORT=%%B" if /i "%%A"=="ELECTRON_PORT" set "ELECTRON_PORT=%%B" if /i "%%A"=="BACKEND_PORT" set "BACKEND_PORT=%%B" ) exit /b 0 :ensure_env if not exist "%ROOT%\docker\docker-compose.yml" ( echo [ERROR] Missing docker\docker-compose.yml under %ROOT% exit /b 1 ) if not exist "%ROOT%\soonModels\" mkdir "%ROOT%\soonModels" if not exist "%ENV_FILE%" ( if not exist "docker\.env.example" ( echo [ERROR] Missing docker\.env.example exit /b 1 ) copy /Y "docker\.env.example" "%ENV_FILE%" >nul ) powershell -NoProfile -ExecutionPolicy Bypass -File "docker\sync-config.ps1" -EnvFile "%ENV_FILE%" if errorlevel 1 ( echo [ERROR] Config sync failed. exit /b 1 ) call :load_ports exit /b 0 :wait_api echo [INFO] Waiting for API http://localhost:%BACKEND_PORT%/health ... set /a RETRY=0 :wait_health set /a RETRY+=1 curl.exe -sf "http://localhost:%BACKEND_PORT%/health" >nul 2>&1 if not errorlevel 1 exit /b 0 if !RETRY! GEQ 90 ( echo [WARN] API not ready after ~3 min. Run: scripts\start.bat logs exit /b 1 ) set /a MOD=!RETRY! %% 5 if !MOD!==0 echo ... still waiting (!RETRY!/90) ping -n 3 127.0.0.1 >nul goto :wait_health :print_urls echo. echo ======================================== echo Project: %COMPOSE_PROJECT% echo Web: http://localhost:%WEB_PORT%/pages/index.web.html echo Admin: http://localhost:%WEB_PORT%/pages/admin/index.html echo Electron: http://localhost:%ELECTRON_PORT%/pages/index.html echo API: http://localhost:%BACKEND_PORT%/health echo ======================================== echo Login: admin@local.test / admin123 echo Desktop: cd frontend-electron ^&^& npm start echo Stop: scripts\start.bat stop echo Logs: scripts\start.bat logs exit /b 0 :do_stop if exist "%ENV_FILE%" (call :compose down) else (call :compose_noenv down) echo. echo [OK] Stopped project %COMPOSE_PROJECT%. DB volume kept. exit /b 0 :do_reset if exist "%ENV_FILE%" (call :compose down -v) else (call :compose_noenv down -v) echo. echo [OK] Project %COMPOSE_PROJECT% stopped. DB volume removed. exit /b 0 :do_logs docker logs -f --tail 80 soondesign-api exit /b 0 :do_status call :ensure_env if errorlevel 1 goto :fail docker ps --filter name=soondesign --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" echo. curl.exe -sf "http://localhost:%BACKEND_PORT%/health" >nul 2>&1 if errorlevel 1 ( echo [WARN] API health check failed. ) else ( echo [OK] API health check passed. ) exit /b 0 :do_rebuild echo [SoonDesign] Rebuilding API image and restarting... call :ensure_env if errorlevel 1 goto :fail if exist "%ENV_FILE%" (call :compose up -d --build --force-recreate api) else (call :compose_noenv up -d --build --force-recreate api) if errorlevel 1 goto :fail call :wait_api call :print_urls goto :done_ok :do_start echo [SoonDesign] Starting local Docker environment... echo [INFO] Compose project: %COMPOSE_PROJECT% echo. docker info >nul 2>&1 if errorlevel 1 ( echo [ERROR] Docker is not running. Please start Docker Desktop first. goto :fail ) call :ensure_env if errorlevel 1 goto :fail echo [INFO] Ports: Web=%WEB_PORT% Electron=%ELECTRON_PORT% API=%BACKEND_PORT% echo [INFO] docker compose up -d (keeps running containers; use rebuild for fresh API image) if exist "%ENV_FILE%" (call :compose up -d) else (call :compose_noenv up -d) if errorlevel 1 ( echo [ERROR] docker compose failed. Is Docker Desktop running? goto :fail ) call :wait_api if errorlevel 1 goto :show_urls_warn echo [OK] Backend is ready. curl.exe -sf "http://localhost:%BACKEND_PORT%/api/v1/settings" >nul 2>&1 if errorlevel 1 ( echo [WARN] API routes not responding. Run: scripts\start.bat logs ) else ( echo [OK] API routes verified. ) call :print_urls goto :done_ok :show_urls_warn call :print_urls goto :done_ok :fail_cd echo [ERROR] Cannot cd to project root: %ROOT% goto :fail :fail echo. echo [FAILED] See messages above. exit /b 1 :done_ok echo. echo [DONE] SoonDesign dev stack is up (project %COMPOSE_PROJECT%). exit /b 0