- compute_total_cost: read token_input/token_output/char (new keys)
with fallback to old input_tokens/output_tokens/chars for compat
- _PROVIDER_ALIAS: google/gemini → vertex_ai-language-models
- _infer_provider: gemini → vertex_ai-language-models
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend:
- routes_auth: POST /v1/auth/dev-login — bypass Azure AD (disabled in production),
creates admin in DB and sets JWT cookie; takes email + full_name
- routes_auth: use settings.frontend_callback_url instead of parsing CORS origins
for SSO post-login redirect — configurable per environment
- config: add frontend_callback_url setting
- dependencies: fix get_current_admin — was querying _id as string (ObjectId bug)
and filtering is_active:True (never set by SSO flow)
Frontend:
- Login.tsx: dev login form shown in non-production builds below SSO button
- api.ts: use import.meta.env.BASE_URL so API paths work under any subpath prefix
- main.tsx: pass BASE_URL as BrowserRouter basename for correct SPA routing
- vite.config.ts: read VITE_BASE_PATH env var to set Vite base (default /)
- nginx.conf: serve app at /cost-tracker/ prefix, proxy API routes internally
- Dockerfile: accept VITE_BASE_PATH build arg, copy build to /cost-tracker/ subdir
Infra:
- docker-compose.yml: API host port 8003 (8001 taken by ppt-tool on optical-dev)
- infra/deploy/apache-cost-tracker.conf: Apache include for optical-dev routing
- infra/deploy/deploy.sh: one-shot deploy script (clone/pull, build, Apache config)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>