feat: add audit log functionality to OrganizationSettings, including filters and loading states for improved organization activity tracking

This commit is contained in:
Usman Baig
2026-02-05 12:23:06 +01:00
parent 7072049b5f
commit 54578d00ca
2 changed files with 243 additions and 4 deletions

69
lib/api/audit.ts Normal file
View File

@@ -0,0 +1,69 @@
/**
* Audit log API client (org-scoped; requires org admin role)
*/
import { API_URL } from './client'
export interface AuditLogEntry {
id: string
org_id: string
actor_id?: string
action: string
resource_type: string
resource_id?: string
occurred_at: string
payload?: Record<string, unknown>
}
export interface GetAuditLogParams {
limit?: number
offset?: number
action?: string
start_date?: string
end_date?: string
}
export interface GetAuditLogResponse {
entries: AuditLogEntry[]
total: number
}
async function auditFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
const url = `${API_URL}${endpoint}`
const headers: HeadersInit = {
'Content-Type': 'application/json',
...options.headers,
}
const response = await fetch(url, {
...options,
headers,
credentials: 'include',
})
if (!response.ok) {
const errorBody = await response.json().catch(() => ({
error: 'Unknown error',
message: `HTTP ${response.status}: ${response.statusText}`,
}))
throw new Error(errorBody.message || errorBody.error || 'Request failed')
}
return response.json()
}
/**
* Fetches paginated audit log entries for the current org (org from JWT; admin-only on backend).
*/
export async function getAuditLog(params: GetAuditLogParams = {}): Promise<GetAuditLogResponse> {
const search = new URLSearchParams()
if (params.limit != null) search.set('limit', String(params.limit))
if (params.offset != null) search.set('offset', String(params.offset))
if (params.action) search.set('action', params.action)
if (params.start_date) search.set('start_date', params.start_date)
if (params.end_date) search.set('end_date', params.end_date)
const qs = search.toString()
const url = qs ? `/api/audit?${qs}` : '/api/audit'
return await auditFetch<GetAuditLogResponse>(url, { method: 'GET' })
}