Release v0.1.7

This commit is contained in:
2026-07-11 02:34:56 +02:00
parent ae70cac70f
commit 7ffb16d981
9 changed files with 399 additions and 8 deletions

74
webui/src/api/audit.ts Normal file
View File

@@ -0,0 +1,74 @@
import { apiFetch, type ApiSettings, type DeltaDeletedItem } from "@govoplan/core-webui";
export type AuditAdminItem = {
id: string;
scope: "tenant" | "system";
tenant_id?: string | null;
actor_email?: string | null;
action: string;
object_type?: string | null;
object_id?: string | null;
details: Record<string, unknown>;
created_at: string;
};
export type AuditSortBy = "time" | "actor" | "action" | "object" | "tenant";
export type AuditQueryOptions = {
tenantId?: string | null;
allTenants?: boolean;
scope?: "tenant" | "system";
limit?: number;
offset?: number;
page?: number;
pageSize?: number;
cursor?: string | null;
sortBy?: AuditSortBy;
sortDirection?: "asc" | "desc";
filters?: Partial<Record<AuditSortBy, string>>;
};
export type AuditAdminListResponse = {
items: AuditAdminItem[];
total: number;
page: number;
page_size: number;
pages: number;
cursor?: string | null;
next_cursor?: string | null;
};
export type AuditAdminDeltaResponse = AuditAdminListResponse & {
deleted: DeltaDeletedItem[];
watermark?: string | null;
has_more: boolean;
full: boolean;
};
function auditQuery(options: AuditQueryOptions & { since?: string | null } = {}): string {
const params = new URLSearchParams();
if (options.tenantId) params.set("tenant_id", options.tenantId);
if (options.allTenants) params.set("all_tenants", "true");
if (options.scope) params.set("scope", options.scope);
if (options.limit) params.set("limit", String(options.limit));
if (options.offset) params.set("offset", String(options.offset));
if (options.page) params.set("page", String(options.page));
if (options.pageSize) params.set("page_size", String(options.pageSize));
if (options.cursor) params.set("cursor", options.cursor);
if (options.sortBy) params.set("sort_by", options.sortBy);
if (options.sortDirection) params.set("sort_direction", options.sortDirection);
if (options.since) params.set("since", options.since);
for (const [column, value] of Object.entries(options.filters ?? {})) {
if (value?.trim()) params.set(`filter_${column}`, value);
}
const suffix = params.toString();
return suffix ? `?${suffix}` : "";
}
export function fetchAdminAudit(settings: ApiSettings, options: AuditQueryOptions = {}): Promise<AuditAdminListResponse> {
return apiFetch(settings, `/api/v1/admin/audit${auditQuery(options)}`);
}
export function fetchAdminAuditDelta(settings: ApiSettings, options: AuditQueryOptions & { since?: string | null } = {}): Promise<AuditAdminDeltaResponse> {
return apiFetch(settings, `/api/v1/admin/audit/delta${auditQuery(options)}`);
}