From ff1c8092493ed1d2117095f5effbbe1e1399745d Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Fri, 6 Mar 2026 11:54:00 +0000 Subject: [PATCH] Prepare production deployment for baic.oliver.solutions/modcomms - Add VITE_BASE_PATH support to vite.config.ts so assets resolve correctly under /modcomms/ subpath - Fix home URL in urlState.ts to use BASE_URL instead of hardcoded '/' - Fix sidebar logo src to use BASE_URL prefix (Vite doesn't rewrite TSX src attributes) - Fix Azure AD redirect/logout URIs to include BASE_URL subpath in authConfig.ts and App.tsx - Add migration 009 to remove Mindshare/Zenith and add Rapp agency - Update .env.deploy.example with production values for baic.oliver.solutions Co-Authored-By: Claude Sonnet 4.6 --- .env.deploy.example | 19 ++++++++---- .../versions/009_production_agencies.py | 29 +++++++++++++++++++ frontend/App.tsx | 2 +- frontend/components/Sidebar.tsx | 2 +- frontend/services/authConfig.ts | 4 +-- frontend/utils/urlState.ts | 2 +- frontend/vite.config.ts | 1 + 7 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 backend/alembic/versions/009_production_agencies.py diff --git a/.env.deploy.example b/.env.deploy.example index d545c79..bcdce83 100644 --- a/.env.deploy.example +++ b/.env.deploy.example @@ -24,17 +24,24 @@ POSTGRES_PASSWORD=change_this_in_production POSTGRES_DB=modcomms # Frontend deployment directory (Apache document root) -# Examples: /var/www/modcomms-prod, /var/www/modcomms-dev -FRONTEND_DEPLOY_DIR=/var/www/html/modcomms +# Production: /var/vhosts/baic.oliver.solutions/htdocs/modcomms +# Dev/staging: /var/www/html/modcomms +FRONTEND_DEPLOY_DIR=/var/vhosts/baic.oliver.solutions/htdocs/modcomms # CORS origins (should match your frontend domain) # Multiple origins can be comma-separated -CORS_ORIGINS=https://your-domain.com +CORS_ORIGINS=https://baic.oliver.solutions # NOTE: Frontend environment variables (VITE_*) are NOT configured here. # Create frontend/.env.local manually with: -# VITE_BACKEND_WS_URL=wss://your-domain.com/ws/analyze -# VITE_BACKEND_URL=https://your-domain.com +# VITE_BASE_PATH=/modcomms/ +# VITE_BACKEND_URL=https://baic.oliver.solutions/back +# VITE_BACKEND_WS_URL=wss://baic.oliver.solutions/back/ws/analyze # VITE_AZURE_CLIENT_ID=your_azure_client_id # VITE_AZURE_TENANT_ID=your_azure_tenant_id -# VITE_AZURE_REDIRECT_URI=https://your-domain.com +# VITE_AZURE_REDIRECT_URI=https://baic.oliver.solutions/modcomms/ +# +# Apache proxy config (production, port 8000): +# ProxyPass /back/ws/analyze ws://localhost:8000/ws/analyze +# ProxyPass /back/ http://localhost:8000/ +# ProxyPassReverse /back/ http://localhost:8000/ diff --git a/backend/alembic/versions/009_production_agencies.py b/backend/alembic/versions/009_production_agencies.py new file mode 100644 index 0000000..9c92f79 --- /dev/null +++ b/backend/alembic/versions/009_production_agencies.py @@ -0,0 +1,29 @@ +"""Production agencies: add Rapp, remove Mindshare and Zenith + +Revision ID: 009_production_agencies +Revises: 008_add_user_change_log +Create Date: 2026-03-06 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + +revision: str = '009_production_agencies' +down_revision: Union[str, None] = '008_add_user_change_log' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Remove agencies not used in production + op.execute("DELETE FROM agencies WHERE name IN ('Mindshare', 'Zenith')") + # Add Rapp (idempotent) + op.execute("INSERT INTO agencies (name) VALUES ('Rapp') ON CONFLICT (name) DO NOTHING") + + +def downgrade() -> None: + op.execute("DELETE FROM agencies WHERE name = 'Rapp'") + op.execute("INSERT INTO agencies (name) VALUES ('Mindshare') ON CONFLICT (name) DO NOTHING") + op.execute("INSERT INTO agencies (name) VALUES ('Zenith') ON CONFLICT (name) DO NOTHING") diff --git a/frontend/App.tsx b/frontend/App.tsx index 897063f..a01bfa0 100755 --- a/frontend/App.tsx +++ b/frontend/App.tsx @@ -848,7 +848,7 @@ const AppContent: React.FC<{ msalInstance: any }> = ({ msalInstance }) => { const handleLogout = async () => { try { await msalInstance.logoutPopup({ - postLogoutRedirectUri: window.location.origin, + postLogoutRedirectUri: window.location.origin + import.meta.env.BASE_URL, }); } catch (error) { console.error('Logout failed:', error); diff --git a/frontend/components/Sidebar.tsx b/frontend/components/Sidebar.tsx index 613960e..004f310 100755 --- a/frontend/components/Sidebar.tsx +++ b/frontend/components/Sidebar.tsx @@ -38,7 +38,7 @@ export const Sidebar: React.FC = ({ activeItem, onNavigate, userNa