import { authFetch } from "./client"; export type WorkspaceLogSection = | "workspace" | "workspace_members" | "clients" | "projects" | "tags" | "time_entries" | "rates" | "report_exports"; export type WorkspaceLogEvent = | "create" | "update" | "delete" | "restore" | "archive" | "unarchive" | "activate" | "deactivate"; export interface WorkspaceLogActor { id: string; full_name: string; mobile?: string | null; profile_picture?: string | null; } export interface WorkspaceLogTarget { id: string; name: string; section: WorkspaceLogSection; workspace_id: string; } export interface WorkspaceLogPreviewChange { field: string; label: string; summary: string; } export interface WorkspaceLogItem { id: number; timestamp: string; section: WorkspaceLogSection; model: string | null; event: WorkspaceLogEvent; audit_action: string; actor: WorkspaceLogActor | null; target: WorkspaceLogTarget; changed_fields: string[]; preview_changes: WorkspaceLogPreviewChange[]; } export interface WorkspaceLogChangeRow { field: string; label: string; change_type: "field" | "m2m"; operation: string; old_value: string | null; new_value: string | null; summary: string; } export interface WorkspaceLogDetail extends WorkspaceLogItem { remote_addr?: string | null; changes: WorkspaceLogChangeRow[]; raw_changes: Record; serialized_snapshot?: unknown; additional_data: Record; } export interface WorkspaceLogFilters { workspace: string; section?: WorkspaceLogSection | ""; actor?: string; event?: WorkspaceLogEvent | ""; search?: string; from?: string; to?: string; ordering?: "-timestamp" | "timestamp"; } interface PaginatedResponse { count: number; next: string | null; previous: string | null; results: T[]; } const toQueryString = (params: Record) => { const query = new URLSearchParams(); Object.entries(params).forEach(([key, value]) => { if (value !== undefined && value !== null && value !== "") { query.set(key, String(value)); } }); return query.toString(); }; export const listWorkspaceLogs = async ( filters: WorkspaceLogFilters, pagination?: { limit?: number; offset?: number }, ): Promise> => { const query = toQueryString({ workspace: filters.workspace, section: filters.section || undefined, actor: filters.actor || undefined, event: filters.event || undefined, search: filters.search || undefined, from: filters.from || undefined, to: filters.to || undefined, ordering: filters.ordering || "-timestamp", limit: pagination?.limit, offset: pagination?.offset, }); const response = await authFetch(`/api/logs/${query ? `?${query}` : ""}`); if (!response.ok) { throw new Error("Failed to fetch workspace logs."); } const data = await response.json(); return { count: data.count || 0, next: data.next || null, previous: data.previous || null, results: data.results || [], }; }; export const getWorkspaceLogDetail = async (id: number): Promise => { const response = await authFetch(`/api/logs/${id}/`); if (!response.ok) { throw new Error("Failed to fetch workspace log detail."); } return await response.json(); };