API and Runtime Config
Introduction
This document describes the frontend API client, runtime configuration system, endpoint groups, response contracts, and query parameter conventions.
Runtime Configuration
Runtime configuration is implemented in src/config/appConfig.ts.
The config source priority is:
- Global Configuration:
globalThis.__APP_CONFIG__ - Environment Variables:
import.meta.env - Defaults: Hardcoded fallbacks in downstream modules
Global Shape
interface AppRuntimeConfig {
VITE_API_BASE_URL?: string;
VITE_ANALYTICS_AI_CHAT_ENABLED?: string | boolean;
}
Exported Config
interface AppConfig {
VITE_API_BASE_URL: string;
VITE_ANALYTICS_AI_CHAT_ENABLED: boolean;
}
appConfig is frozen after parsing to prevent accidental runtime mutation.
URL Validation
validateUrl() accepts only http: and https: URLs. Invalid values return an empty string and trigger the API fallback.
VITE_API_BASE_URL should be configured without /api.
Examples:
VITE_API_BASE_URL=http://localhost:5144
VITE_API_BASE_URL=https://defense-center.example.com
src/lib/api.ts derives the final base:
export const API_BASE = appConfig.VITE_API_BASE_URL
? `${appConfig.VITE_API_BASE_URL}/api`
: 'http://localhost:5009/api';
Boolean Parsing
VITE_ANALYTICS_AI_CHAT_ENABLED is considered true only for the following values:
true1yeson
All other string values, missing values, and unknown values resolve to false.
Production Runtime Injection
docker-entrypoint.sh writes this file before starting Nginx:
window.__APP_CONFIG__ = {
VITE_API_BASE_URL: "${VITE_API_BASE_URL:-}",
VITE_ANALYTICS_AI_CHAT_ENABLED: "${VITE_ANALYTICS_AI_CHAT_ENABLED:-false}",
};
Nginx serves /config.js with no-cache headers so runtime config changes are applied immediately upon refresh.
Axios Client
src/lib/api.ts creates apiClient through createApiInstance(API_BASE).
Axios Defaults:
| Setting | Value |
|---|---|
baseURL | API_BASE |
timeout | 10000 ms |
Content-Type | application/json |
Interceptors:
- Request: Reads access token from
auth.getToken()and adds theAuthorizationheader. - Response: On HTTP
401, clears auth and redirects to login. Rejects errors for caller-specific handling.
API Endpoint Groups
The exported api object is grouped by backend domain:
| Group | Purpose |
|---|---|
auth | Login, register, current user, logout |
user | User CRUD and pagination |
organization | Organization CRUD and listing |
sensor | Sensor CRUD, heartbeat, metrics, install token/script, counts |
virtualSensor | Virtual sensor CRUD and activate/deactivate |
sensorSetup | Legacy alias for virtual sensor endpoints |
role | Role CRUD and pagination |
permission | Permission catalog |
location | Province and city lookup |
dashboard | Dashboard stats, logs, sensor overview |
opensearch | Security analytics aggregations and alert listing |
analyticsChat | AI chat status and saved conversations |
analyticsVirtualSensors | Virtual sensors for analytics filtering |
Query Parameter Conventions
Most endpoints pass object params directly through Axios. Some analytics endpoints use buildRepeatedQueryParams() to serialize arrays with repeated keys:
Example: priority=High&priority=Low&protocol=TCP
Used by endpoints such as:
/opensearch/dashboard/summary/opensearch/alerts/ip-flow/opensearch/alerts/list
Shared Response Types
The frontend models standard backend wrappers:
Base Wrapper
interface ApiResponse<T> {
success: boolean;
data: T;
errors: string[];
traceId?: string | null;
}
Payloads
interface ListPayload<T> {
items: T[];
count: number;
}
interface PaginatedPayload<T> {
items: T[];
pagination: {
currentPage: number;
pageSize: number;
totalCount: number;
totalPages: number;
};
}
Streaming API
Analytics AI chat streaming uses fetch and Server-Sent Events style chunks.
Endpoint: POST /api/analytics/chat/conversations/:conversationId/stream
Handled Events:
start(onStart)chunk(onChunk)complete(onComplete)error(onError)
The stream parser reads event: and data: lines, parses JSON payloads, and handles cleanup in finally.