import { api as client } from "../auth/http"; import { unwrap } from "@/utils/endpoint"; import { URL_CONSTANTS } from "@/constants/URLS"; const A = URL_CONSTANTS.AUDIT; // Shape from @tria-plc/auditlog's AuditLogCommandController — see // local-packages/FRONTEND_GUIDE.md. export type AuditQueryMethod = | "INSERT" | "UPDATE" | "DELETE" | "INSERT_CHILD" | "DELETE_CHILD"; export interface AuditFieldChange { field: string; from: unknown; to: unknown; } // IAM entities (users, orgs, positions, ...) name themselves bilingually — // see edr-org.seeder.ts. Any `name`/`title` field lifted from a raw audited // entity (auditLog.user, payload) can come back as either a plain string or // this shape; both `name` fields below reflect that. export type LocalizedText = string | { am?: string; en?: string }; // The vendored interceptor's own broken template produces a plain string // ("undefined undefined") when no user was attached at all (unauthenticated/ // customer flows) — that's the non-bilingual string case for `name` here. export interface AuditUser { id?: string; name?: LocalizedText; organizationId?: string; organizationName?: string; [key: string]: unknown; } export interface AuditLogRow { id?: string; createdAt: string; deletedAt?: string | null; entityName: string; queryMethod: AuditQueryMethod; changes?: AuditFieldChange[] | null; payload?: { name?: LocalizedText; title?: LocalizedText; id?: string } | null; auditLog?: { id?: string; user?: AuditUser | null }; } export interface AuditLogListFilter { skip?: number; take?: number; } export interface PaginatedAuditLogs { items: AuditLogRow[]; count: number; } export const auditService = { list: async (filter?: AuditLogListFilter): Promise => { const params: Record = { skip: filter?.skip, take: filter?.take, }; const response = await client.get(A.LOGS, { params }); const data = unwrap(response.data) as PaginatedAuditLogs; return { items: data.items ?? [], count: data.count ?? 0 }; }, };