Replaces a static SPA that shipped an Airtable PAT in the JS bundle.
The new architecture holds all secrets server-side, fronts the app
behind Apache on optical-dev with the shared-vhost split-build pattern,
and is designed for a later Azure AD/MSAL swap-in.
- backend/ FastAPI + uvicorn, local auth (Azure AD stub), Airtable
proxy with TTL cache, Zoho .xlsx/.csv parser, merge
service for utilisation summaries. 28 pytest tests.
- frontend/ React + Vite + TS + Tailwind + Recharts SPA. Login entry
chunk 12.83 KB gzipped; Recharts lazy-loaded. No tokens
or Airtable URLs in the built bundle.
- deploy/ Idempotent deploy.sh (port auto-pick 8200-8299,
.env-persisted) + split-build Apache include template.
- docker-compose.yml pins name: utilisation-dept and binds 127.0.0.1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
42 lines
1.6 KiB
Cheetah
42 lines
1.6 KiB
Cheetah
# Split-build include for utilisation-dept.
|
|
#
|
|
# Add ONCE inside </VirtualHost> of optical-dev.oliver.solutions.conf:
|
|
# Include /opt/utilisation-dept/deploy/apache-utilisation-dept.conf
|
|
#
|
|
# This file is generated from .conf.tmpl by deploy.sh — __APP_PORT__ is
|
|
# substituted with the chosen backend port. Do not edit the generated
|
|
# .conf directly; edit the .tmpl.
|
|
|
|
ProxyTimeout 300
|
|
TimeOut 300
|
|
|
|
# Backend API: only /utilisation-dept/api/ is proxied to the container.
|
|
ProxyPass /utilisation-dept/api/ http://127.0.0.1:__APP_PORT__/api/ timeout=300
|
|
ProxyPassReverse /utilisation-dept/api/ http://127.0.0.1:__APP_PORT__/api/
|
|
|
|
# Frontend SPA: Apache serves the Vite build directly from disk.
|
|
Alias /utilisation-dept /var/www/html/utilisation-dept
|
|
<Directory /var/www/html/utilisation-dept>
|
|
Options -Indexes +FollowSymLinks
|
|
AllowOverride None
|
|
Require all granted
|
|
|
|
# Long cache for hashed asset filenames (Vite emits content-hashed names).
|
|
<FilesMatch "\.(js|css|woff2?|svg|png|jpg|jpeg|webp|ico)$">
|
|
Header set Cache-Control "public, max-age=31536000, immutable"
|
|
</FilesMatch>
|
|
# No cache for index.html so deploys take effect immediately.
|
|
<FilesMatch "index\.html$">
|
|
Header set Cache-Control "no-cache, no-store, must-revalidate"
|
|
</FilesMatch>
|
|
|
|
# SPA fallback so deep links work.
|
|
RewriteEngine On
|
|
RewriteBase /utilisation-dept/
|
|
RewriteCond %{REQUEST_FILENAME} !-f
|
|
RewriteCond %{REQUEST_FILENAME} !-d
|
|
RewriteRule ^ index.html [L]
|
|
</Directory>
|
|
|
|
# Force trailing slash so relative asset paths in index.html resolve.
|
|
RedirectMatch ^/utilisation-dept$ /utilisation-dept/
|