From f95c8022a27015331a0ab7467f2ae3b0e6508403 Mon Sep 17 00:00:00 2001 From: deepsikha-dash Date: Mon, 6 Jul 2026 18:38:48 +0530 Subject: [PATCH] fix: tighten API client response types --- frontend/src/api.ts | 69 +++++++++++++++---- .../unit/hooks/useTaskSubscription.test.ts | 2 +- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 3271c79bd..58c6aae78 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -391,8 +391,15 @@ export function getPluginSchema(id: string) { return request(`/plugin/${id}/schema`) } -export function getSettings() { - return request(`/settings`) +export interface SettingsResponse { + execution_context?: { + default?: ExecutionContext + } + [key: string]: unknown +} + +export function getSettings(): Promise { + return request('/settings') } export function getDashboardSummary() { @@ -453,7 +460,7 @@ export interface NotificationRuleUpdatePayload { } export async function listNotificationRules(): Promise { - const data: any = await request('/notifications/rules') + const data = await request('/notifications/rules') const rules = Array.isArray(data) ? data : data?.rules return Array.isArray(rules) ? (rules as NotificationRule[]) : [] } @@ -490,7 +497,12 @@ export async function listNotificationHistory(params?: { if (typeof params?.limit === 'number') sp.set('limit', String(params.limit)) if (typeof params?.offset === 'number') sp.set('offset', String(params.offset)) const suffix = sp.toString() ? `?${sp.toString()}` : '' - const data: any = await request(`/notifications/history${suffix}`) + const data = await request<{ + history?: NotificationHistoryRow[] + total?: number + limit?: number + offset?: number + }>(`/notifications/history${suffix}`) return { history: Array.isArray(data?.history) ? (data.history as NotificationHistoryRow[]) : [], total: Number(data?.total ?? 0), @@ -532,12 +544,21 @@ export function getTasks(params?: URLSearchParams) { export type ScanPhase = 'queued' | 'running_command' | 'parsing' | 'reporting' | 'finished' -export function getTaskStatus(taskId: string): Promise { - return request(`/task/${taskId}/status`) +export interface TaskStatusResponse { + task_id?: string + status: string + phase?: ScanPhase + progress?: number + message?: string + error_message?: string | null +} + +export function getTaskStatus(taskId: string): Promise { + return request(`/task/${taskId}/status`) } -export function getTaskResult(taskId: string): Promise { - return request(`/task/${taskId}/result`) +export function getTaskResult(taskId: string): Promise { + return request(`/task/${taskId}/result`) } export function getTaskDiff(taskId: string): Promise { @@ -636,10 +657,28 @@ export interface WorkflowUpdatePayload { } interface WorkflowListResponse { - workflows: unknown[] + workflows: RawWorkflow[] total: number } +interface RawWorkflow { + id: unknown + name?: unknown + schedule_seconds?: unknown + enabled?: unknown + steps?: unknown + steps_json?: unknown + last_run_at?: string | null + queued_task_ids?: unknown + queued_tasks?: unknown + created_at?: string +} + +interface WorkflowRunResponse { + queued_task_ids?: string[] + queued_tasks?: string[] +} + function parseWorkflowSteps(value: unknown): WorkflowStep[] { if (Array.isArray(value)) return value as WorkflowStep[] if (typeof value !== 'string' || value.trim() === '') return [] @@ -658,7 +697,7 @@ function parseScheduleSeconds(value: unknown): number | null { return Number.isFinite(parsed) ? parsed : null } -function normalizeWorkflow(raw: any): Workflow { +function normalizeWorkflow(raw: RawWorkflow): Workflow { return { id: String(raw.id), name: String(raw.name ?? ''), @@ -676,13 +715,13 @@ function normalizeWorkflow(raw: any): Workflow { } export async function getWorkflows(): Promise { - const data = await request('/workflows') + const data = await request('/workflows') const workflows = Array.isArray(data) ? data : data.workflows return Array.isArray(workflows) ? workflows.map(normalizeWorkflow) : [] } export async function createWorkflow(data: WorkflowCreatePayload): Promise { - const workflow = await request('/workflows', { + const workflow = await request('/workflows', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), @@ -691,7 +730,7 @@ export async function createWorkflow(data: WorkflowCreatePayload): Promise { - const result: any = await request(`/workflows/${workflowId}/run`, { + const result = await request(`/workflows/${workflowId}/run`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, }) @@ -705,7 +744,7 @@ export async function runWorkflow(workflowId: string): Promise<{ queued_task_ids } export async function updateWorkflow(workflowId: string, data: WorkflowUpdatePayload): Promise { - const workflow = await request(`/workflows/${workflowId}`, { + const workflow = await request(`/workflows/${workflowId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), @@ -764,7 +803,7 @@ export async function rollbackWorkflow(workflowId: string, versionNumber: number workflow_id: string rolled_back_to_version: number new_version_number: number - workflow: any + workflow: RawWorkflow }>(`/workflows/${workflowId}/rollback/${versionNumber}`, { method: 'POST', }) diff --git a/frontend/testing/unit/hooks/useTaskSubscription.test.ts b/frontend/testing/unit/hooks/useTaskSubscription.test.ts index 09efd8bb5..e92a48ea2 100644 --- a/frontend/testing/unit/hooks/useTaskSubscription.test.ts +++ b/frontend/testing/unit/hooks/useTaskSubscription.test.ts @@ -153,7 +153,7 @@ describe('useTaskSubscription', () => { }) it('stops polling on terminal status', async () => { - let resolveGetTaskStatus: (value: unknown) => void + let resolveGetTaskStatus: (value: Awaited>) => void vi.mocked(getTaskStatus).mockImplementation(() => new Promise(resolve => { resolveGetTaskStatus = resolve }))