From 1c94234996c6acce6d0d4bdd0a916c38b69c09fc Mon Sep 17 00:00:00 2001 From: Till JS Date: Sat, 11 Apr 2026 17:12:36 +0200 Subject: [PATCH] fix(web): point credits/sync API client at credits.mana.how The frontend was calling /api/v1/credits/* and /api/v1/sync/* on auth.mana.how, but those routes live on credits.mana.how (mana-credits service). Add getManaCreditsUrl() helper, inject the URL via hooks.server.ts, allow it in the CSP connect-src, and update both API clients (credits.ts + sync.ts) to use it. Also: pass MANA_CREDITS_URL + MANA_SERVICE_KEY to mana-sync so its billing middleware can reach mana-credits at http://mana-credits:3002. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/mana/apps/web/src/hooks.server.ts | 4 ++++ apps/mana/apps/web/src/lib/api/config.ts | 13 +++++++++++++ apps/mana/apps/web/src/lib/api/credits.ts | 6 +++--- apps/mana/apps/web/src/lib/api/sync.ts | 4 ++-- docker-compose.macmini.yml | 4 ++++ 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/apps/mana/apps/web/src/hooks.server.ts b/apps/mana/apps/web/src/hooks.server.ts index 0ab749241..906453ecf 100644 --- a/apps/mana/apps/web/src/hooks.server.ts +++ b/apps/mana/apps/web/src/hooks.server.ts @@ -45,6 +45,8 @@ const PUBLIC_MANA_EVENTS_URL_CLIENT = process.env.PUBLIC_MANA_EVENTS_URL_CLIENT || process.env.PUBLIC_MANA_EVENTS_URL || ''; const PUBLIC_MANA_API_URL_CLIENT = process.env.PUBLIC_MANA_API_URL_CLIENT || process.env.PUBLIC_MANA_API_URL || ''; +const PUBLIC_MANA_CREDITS_URL_CLIENT = + process.env.PUBLIC_MANA_CREDITS_URL_CLIENT || process.env.PUBLIC_MANA_CREDITS_URL || ''; // Map of app subdomains to internal paths const APP_SUBDOMAINS = new Set([ @@ -95,6 +97,7 @@ window.__PUBLIC_MANA_MEDIA_URL__ = ${JSON.stringify(PUBLIC_MANA_MEDIA_URL_CLIENT window.__PUBLIC_MANA_LLM_URL__ = ${JSON.stringify(PUBLIC_MANA_LLM_URL_CLIENT)}; window.__PUBLIC_MANA_EVENTS_URL__ = ${JSON.stringify(PUBLIC_MANA_EVENTS_URL_CLIENT)}; window.__PUBLIC_MANA_API_URL__ = ${JSON.stringify(PUBLIC_MANA_API_URL_CLIENT)}; +window.__PUBLIC_MANA_CREDITS_URL__ = ${JSON.stringify(PUBLIC_MANA_CREDITS_URL_CLIENT)}; window.__PUBLIC_GLITCHTIP_DSN__ = ${JSON.stringify(PUBLIC_GLITCHTIP_DSN)}; `; return injectUmamiAnalytics(html.replace('', `${envScript}`)); @@ -123,6 +126,7 @@ window.__PUBLIC_GLITCHTIP_DSN__ = ${JSON.stringify(PUBLIC_GLITCHTIP_DSN)}; PUBLIC_MANA_LLM_URL_CLIENT, PUBLIC_MANA_EVENTS_URL_CLIENT, PUBLIC_MANA_API_URL_CLIENT, + PUBLIC_MANA_CREDITS_URL_CLIENT, 'wss://sync.mana.how', // transformers.js *also* fetch()es the .wasm binary and the .mjs // loader factory directly to pre-warm the runtime — those go diff --git a/apps/mana/apps/web/src/lib/api/config.ts b/apps/mana/apps/web/src/lib/api/config.ts index 456ec2d54..f257743f8 100644 --- a/apps/mana/apps/web/src/lib/api/config.ts +++ b/apps/mana/apps/web/src/lib/api/config.ts @@ -46,3 +46,16 @@ export function getManaApiUrl(): string { } return process.env.PUBLIC_MANA_API_URL || 'http://localhost:3060'; } + +/** + * Get the mana-credits service URL. + * Hosts credit balance, packages, transactions, gift codes, sync billing. + */ +export function getManaCreditsUrl(): string { + if (browser && typeof window !== 'undefined') { + const injected = (window as unknown as { __PUBLIC_MANA_CREDITS_URL__?: string }) + .__PUBLIC_MANA_CREDITS_URL__; + return injected || 'http://localhost:3061'; + } + return process.env.PUBLIC_MANA_CREDITS_URL || 'http://localhost:3061'; +} diff --git a/apps/mana/apps/web/src/lib/api/credits.ts b/apps/mana/apps/web/src/lib/api/credits.ts index b1425caf9..fb87744b3 100644 --- a/apps/mana/apps/web/src/lib/api/credits.ts +++ b/apps/mana/apps/web/src/lib/api/credits.ts @@ -4,7 +4,7 @@ */ import { authStore } from '$lib/stores/auth.svelte'; -import { getManaAuthUrl } from './config'; +import { getManaCreditsUrl } from './config'; // Types export interface CreditBalance { @@ -58,7 +58,7 @@ export interface CreditPurchase { async function fetchWithAuth(endpoint: string, options: RequestInit = {}): Promise { const token = await authStore.getAccessToken(); - const response = await fetch(`${getManaAuthUrl()}${endpoint}`, { + const response = await fetch(`${getManaCreditsUrl()}${endpoint}`, { ...options, headers: { 'Content-Type': 'application/json', @@ -104,7 +104,7 @@ export const creditsService = { * Get available credit packages (public endpoint) */ async getPackages(): Promise { - const response = await fetch(`${getManaAuthUrl()}/api/v1/credits/packages`); + const response = await fetch(`${getManaCreditsUrl()}/api/v1/credits/packages`); if (!response.ok) { throw new Error('Failed to fetch packages'); } diff --git a/apps/mana/apps/web/src/lib/api/sync.ts b/apps/mana/apps/web/src/lib/api/sync.ts index 6bf487126..5ca12deda 100644 --- a/apps/mana/apps/web/src/lib/api/sync.ts +++ b/apps/mana/apps/web/src/lib/api/sync.ts @@ -4,7 +4,7 @@ */ import { authStore } from '$lib/stores/auth.svelte'; -import { getManaAuthUrl } from './config'; +import { getManaCreditsUrl } from './config'; // Types export type BillingInterval = 'monthly' | 'quarterly' | 'yearly'; @@ -28,7 +28,7 @@ export interface SyncActivateResponse { async function fetchWithAuth(endpoint: string, options: RequestInit = {}): Promise { const token = await authStore.getAccessToken(); - const response = await fetch(`${getManaAuthUrl()}${endpoint}`, { + const response = await fetch(`${getManaCreditsUrl()}${endpoint}`, { ...options, headers: { 'Content-Type': 'application/json', diff --git a/docker-compose.macmini.yml b/docker-compose.macmini.yml index f650e0af2..78a4d8687 100644 --- a/docker-compose.macmini.yml +++ b/docker-compose.macmini.yml @@ -583,6 +583,8 @@ services: DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD:-mana123}@postgres:5432/mana_sync?sslmode=disable JWKS_URL: http://mana-auth:3001/api/v1/auth/jwks CORS_ORIGINS: "https://mana.how,https://*.mana.how" + MANA_CREDITS_URL: http://mana-credits:3002 + MANA_SERVICE_KEY: ${MANA_SERVICE_KEY} ports: - "3010:3010" healthcheck: @@ -800,6 +802,8 @@ services: # mana-api.* subdomain is the unambiguous new home. PUBLIC_MANA_API_URL: http://mana-api:3060 PUBLIC_MANA_API_URL_CLIENT: https://mana-api.mana.how + PUBLIC_MANA_CREDITS_URL: http://mana-credits:3002 + PUBLIC_MANA_CREDITS_URL_CLIENT: https://credits.mana.how # Per-app HTTP backend URLs (todo-api, calendar-api, contacts-api, # chat-api, storage-api, cards-api, music-api, nutriphi-api, # picture-api, presi-api, zitare-api, clock-api, context-api) and