import { getApiClient } from './client'; import { listWorkspaces } from './workspaces'; export type MobileApprovalItem = { id: string; workspaceId: string; noteId: string; title: string; summary: string; status: 'pending' | 'approved' | 'rejected'; }; export type MobileActivityItem = { id: string; workspaceId: string; noteId: string; title: string; summary: string; kind: 'note' | 'task' | 'agent'; }; type NoteAgentActionDoc = { id: string; workspaceId: string; noteId: string; actorId: string; actionType: 'create' | 'update' | 'summarize' | 'extract_tasks' | 'attach_citation'; state: 'draft' | 'proposed' | 'approved' | 'rejected' | 'applied'; reason?: string; afterSummary?: string; updatedAt: string; }; type NoteAgentActionListResponse = { items: NoteAgentActionDoc[]; }; function toApprovalStatus(action: NoteAgentActionDoc): MobileApprovalItem['status'] { if (action.state === 'approved' || action.state === 'applied') { return 'approved'; } if (action.state === 'rejected') { return 'rejected'; } return 'pending'; } function toApprovalItem(action: NoteAgentActionDoc): MobileApprovalItem { return { id: action.id, workspaceId: action.workspaceId, noteId: action.noteId, title: action.afterSummary ?? action.reason ?? `${action.actionType} proposal`, summary: action.reason ?? action.afterSummary ?? `Agent proposed a ${action.actionType.replaceAll('_', ' ')} change.`, status: toApprovalStatus(action), }; } function toActivityKind(actionType: NoteAgentActionDoc['actionType']): MobileActivityItem['kind'] { if (actionType === 'extract_tasks') { return 'task'; } if (actionType === 'attach_citation') { return 'note'; } return 'agent'; } function toActivityItem(action: NoteAgentActionDoc): MobileActivityItem { return { id: action.id, workspaceId: action.workspaceId, noteId: action.noteId, title: action.afterSummary ?? `${action.actionType.replaceAll('_', ' ')} update`, summary: action.reason ?? action.afterSummary ?? `State: ${action.state}`, kind: toActivityKind(action.actionType), }; } async function listAgentActionsForWorkspace(workspaceId: string): Promise { const response = await getApiClient().fetch( `/note-agent-actions?workspaceId=${encodeURIComponent(workspaceId)}`, ); return response.items; } export async function listApprovalQueue(): Promise { const workspaces = await listWorkspaces(); const actionGroups = await Promise.all(workspaces.map((workspace) => listAgentActionsForWorkspace(workspace.id))); return actionGroups .flat() .filter((action) => action.state === 'draft' || action.state === 'proposed') .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)) .map(toApprovalItem); } export async function listActivityFeed(): Promise { const workspaces = await listWorkspaces(); const actionGroups = await Promise.all(workspaces.map((workspace) => listAgentActionsForWorkspace(workspace.id))); return actionGroups .flat() .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)) .slice(0, 10) .map(toActivityItem); } export async function updateApprovalState( id: string, workspaceId: string, state: 'approved' | 'rejected', reviewNote?: string, ): Promise { const updated = await getApiClient().fetch( `/note-agent-actions/${encodeURIComponent(id)}?workspaceId=${encodeURIComponent(workspaceId)}`, { method: 'PATCH', body: JSON.stringify({ state, reviewedAt: new Date().toISOString(), ...(reviewNote ? { reviewNote } : {}), }), }, ); return toApprovalItem(updated); }