learning_ai_common_plat/dashboards/admin-web/src/lib/actiontrail-client.ts
saravanakumardb1 10b48a3800 feat(admin-web): add ActionTrail integration page
- New /actiontrail page with 4 tabs: Timeline, Agents, Alerts, Approvals
- Summary cards: total actions, critical/high count, pending approvals, active alerts
- Risk-level filtering on timeline, color-coded risk badges
- Server-side API proxy route (/api/actiontrail) to ActionTrail backend (port 4018)
- actiontrail-client.ts: typed API client using @bytelyst/api-client
- Sidebar nav item with Crosshair icon
- ACTIONTRAIL_SERVICE_URL added to .env.example
- Graceful fallback when ActionTrail service is unavailable
2026-03-21 13:20:15 -07:00

124 lines
3.2 KiB
TypeScript

/**
* ActionTrail backend API client (server-side).
* Used by Next.js API routes to proxy requests to the ActionTrail backend.
*/
import { createApiClient } from '@bytelyst/api-client';
const actiontrailApi = createApiClient({
baseUrl: `${process.env.ACTIONTRAIL_SERVICE_URL || 'http://localhost:4018'}/api`,
defaultHeaders: {
'x-product-id': 'actiontrail',
},
});
// ── Types ─────────────────────────────────────────────────────────
export interface ActionItem {
id: string;
userId: string;
agentId: string;
sourceProduct: string;
action: string;
category: string;
description: string;
riskLevel: 'low' | 'medium' | 'high' | 'critical';
riskScore: number;
status: string;
correlationId?: string;
tags: string[];
createdAt: string;
updatedAt: string;
}
export interface AgentItem {
id: string;
userId: string;
name: string;
description: string;
sourceProduct: string;
trustLevel: string;
status: string;
allowedCategories: string[];
maxRiskLevel: string;
actionCount: number;
createdAt: string;
}
export interface AlertItem {
id: string;
userId: string;
actionId: string;
agentId: string;
severity: string;
message: string;
reasons: string[];
riskScore: number;
acknowledged: boolean;
createdAt: string;
}
export interface ApprovalItem {
id: string;
userId: string;
actionId: string;
agentId: string;
action: string;
riskLevel: string;
riskScore: number;
status: string;
expiresAt: string;
createdAt: string;
}
export interface InsightSummary {
totalActions: number;
totalAgents: number;
totalAlerts: number;
riskDistribution: Record<string, number>;
categoryDistribution: Record<string, number>;
topAgents: Array<{ agentId: string; name: string; actionCount: number }>;
}
// ── API Functions ─────────────────────────────────────────────────
export async function getActions(userId: string, limit = 50) {
return actiontrailApi.fetch<{ items: ActionItem[]; cursor: string | null }>(
`/actions?limit=${limit}`,
{ headers: { 'x-user-id': userId } }
);
}
export async function getAgents(userId: string) {
return actiontrailApi.fetch<AgentItem[]>('/agents', { headers: { 'x-user-id': userId } });
}
export async function getAlerts(userId: string, limit = 50) {
return actiontrailApi.fetch<{ items: AlertItem[]; cursor: string | null }>(
`/alerts?limit=${limit}`,
{ headers: { 'x-user-id': userId } }
);
}
export async function getPendingApprovals(userId: string) {
return actiontrailApi.fetch<{ items: ApprovalItem[]; cursor: string | null }>(
'/approvals?status=pending',
{ headers: { 'x-user-id': userId } }
);
}
export async function getInsightsSummary(userId: string) {
return actiontrailApi.fetch<InsightSummary>('/insights/summary', {
headers: { 'x-user-id': userId },
});
}
export async function getBootstrap() {
return actiontrailApi.fetch<{
productId: string;
displayName: string;
domain: string;
surfaces: { primary: string; mobile: boolean };
}>('/bootstrap');
}