refactor(api): resolve the backend URL in one place

VITE_BASE_API_URL with a localhost:3001/api fallback was re-derived in six
files across libs/api, libs/auth, the portal and the backoffice — and a seventh
site (UserManagementPage) read the env raw with no fallback at all, handing the
IAM user-management app an undefined apiUrl whenever no .env was present.

BASE_API_URL in base-query-with-reauth.ts is now the single definition,
exported from @ema-platform/api; every other site imports it. Trims the env
value and treats blank as unset, matching how the backend reads its own keys.
This commit is contained in:
mihretue
2026-08-26 09:09:25 +00:00
parent baea9f2b57
commit c753009ed9
8 changed files with 16 additions and 19 deletions

View File

@@ -1,9 +1,9 @@
import type { Bilingual, LicenseCategory, LicenseTemplate, LicenseType } from '@ema-platform/api'; import type { Bilingual, LicenseCategory, LicenseTemplate, LicenseType } from '@ema-platform/api';
import { BASE_API_URL } from '@ema-platform/api';
/** Same resolution — and same fallback — the shared RTK Query baseQuery uses. */ /** Same resolution — and same fallback — the shared RTK Query baseQuery uses. */
export const API_BASE_URL = export const API_BASE_URL = BASE_API_URL;
(import.meta as { env?: Record<string, string> }).env?.['VITE_BASE_API_URL'] ??
'http://localhost:3001/api';
export const STATUS_COLOR: Record<LicenseTemplate['status'], string> = { export const STATUS_COLOR: Record<LicenseTemplate['status'], string> = {
DRAFT: 'gray', DRAFT: 'gray',

View File

@@ -3,6 +3,7 @@ import { useCallback, useEffect, useRef } from 'react';
import { createRoot, type Root } from 'react-dom/client'; import { createRoot, type Root } from 'react-dom/client';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { UserManagementApp } from '@tria-plc/iamui'; import { UserManagementApp } from '@tria-plc/iamui';
import { BASE_API_URL } from '@ema-platform/api';
import type { DesignConfig, UserManagementSessionOptions } from '@tria-plc/iamui'; import type { DesignConfig, UserManagementSessionOptions } from '@tria-plc/iamui';
import '@tria-plc/iamui/style.css'; import '@tria-plc/iamui/style.css';
@@ -99,7 +100,7 @@ const UM_CONFIG: DesignConfig = {
const UM_RUNTIME = { const UM_RUNTIME = {
basename: '/um', basename: '/um',
apiUrl: import.meta.env.VITE_BASE_API_URL, apiUrl: BASE_API_URL,
}; };
const buttonStyle: React.CSSProperties = { const buttonStyle: React.CSSProperties = {

View File

@@ -120,9 +120,7 @@ function formatDate(value: string | null | undefined): string {
}); });
} }
const API_BASE = import { BASE_API_URL as API_BASE } from '@ema-platform/api';
(import.meta as { env?: Record<string, string> }).env?.['VITE_BASE_API_URL'] ??
'http://localhost:3001/api';
async function generateCertificate(profileId: string): Promise<Blob> { async function generateCertificate(profileId: string): Promise<Blob> {
const token = authStorage.getToken(); const token = authStorage.getToken();

View File

@@ -7,5 +7,5 @@ export * from './lib/features/seafarer';
export * from './lib/features/seafarer-registration'; export * from './lib/features/seafarer-registration';
export * from './lib/features/seafarer-document'; export * from './lib/features/seafarer-document';
export * from './lib/features/vessel'; export * from './lib/features/vessel';
export { baseQueryWithReauth, configureTokenRefresh } from './lib/base-api/base-query-with-reauth'; export { BASE_API_URL, baseQueryWithReauth, configureTokenRefresh } from './lib/base-api/base-query-with-reauth';
export { openAuthedDocument, downloadAuthedFile } from './lib/base-api/download'; export { openAuthedDocument, downloadAuthedFile } from './lib/base-api/download';

View File

@@ -2,10 +2,15 @@ import { fetchBaseQuery, type BaseQueryFn } from "@reduxjs/toolkit/query/react";
import type { FetchArgs, FetchBaseQueryError } from "@reduxjs/toolkit/query"; import type { FetchArgs, FetchBaseQueryError } from "@reduxjs/toolkit/query";
import { resolveSessionContext } from "../session"; import { resolveSessionContext } from "../session";
/**
* The one place the backend URL is resolved: VITE_BASE_API_URL from the env,
* falling back to the local dev API (3001 — the portal itself owns 3000 for
* the Fayda redirect). Import this; do not re-derive it.
*/
export const BASE_API_URL = export const BASE_API_URL =
(import.meta as { env?: Record<string, string> }).env?.[ (import.meta as { env?: Record<string, string> }).env?.[
"VITE_BASE_API_URL" "VITE_BASE_API_URL"
] ?? "http://localhost:3001/api"; ]?.trim() || "http://localhost:3001/api";
let _onTokenExpired: (() => Promise<string>) | null = null; let _onTokenExpired: (() => Promise<string>) | null = null;
let _onAuthFailure: (() => void) | null = null; let _onAuthFailure: (() => void) | null = null;

View File

@@ -10,9 +10,7 @@ import type {
ValidationIssue, ValidationIssue,
} from './licensing.types'; } from './licensing.types';
const BASE_API_URL = import { BASE_API_URL } from '../../base-api/base-query-with-reauth';
(import.meta as { env?: Record<string, string> }).env?.['VITE_BASE_API_URL'] ??
'http://localhost:3001/api';
/** /**
* Uploads a document straight to the API. * Uploads a document straight to the API.

View File

@@ -6,9 +6,7 @@ import { hydrateAuth, logout, setToken, setUser } from '../store/auth.slice';
import { refreshAccessToken } from '../utils/refresh-token'; import { refreshAccessToken } from '../utils/refresh-token';
import type { AuthUser } from '../types/auth.types'; import type { AuthUser } from '../types/auth.types';
const BASE_API_URL = import { BASE_API_URL } from '@ema-platform/api';
(import.meta as { env?: Record<string, string> }).env?.['VITE_BASE_API_URL'] ??
'http://localhost:3001/api';
/** /**
* Restores the signed-in session before the router renders. * Restores the signed-in session before the router renders.

View File

@@ -1,9 +1,6 @@
import { authStorage } from "./auth-storage"; import { authStorage } from "./auth-storage";
const BASE_API_URL = import { BASE_API_URL } from "@ema-platform/api";
(import.meta as { env?: Record<string, string> }).env?.[
"VITE_BASE_API_URL"
] ?? "http://localhost:3001/api";
interface RefreshResponse { interface RefreshResponse {
token: string; token: string;