export type CommonAuditLog = { event_id: string; timestamp: string; user_id: string; event_type: string; status: string; ip_address: string; user_agent: string; device_id?: string; details?: string; }; export type AuditDetails = { request_id?: string; method?: string; path?: string; status?: number; latency_ms?: number; error?: string; tenant_id?: string; actor_id?: string; action?: string; target?: string; target_id?: string; before?: unknown; after?: unknown; }; export function parseAuditDetails(details?: string): AuditDetails { if (!details) { return {}; } try { const parsed = JSON.parse(details); if (parsed && typeof parsed === "object") { return parsed as AuditDetails; } } catch {} return {}; } export function formatAuditValue(value: unknown) { if (value === null || value === undefined || value === "") { return "-"; } if (typeof value === "string") { return value; } try { return JSON.stringify(value); } catch { return String(value); } } export function formatAuditDateParts(value: string) { if (!value) { return { date: "-", time: "-" }; } const parsed = new Date(value); if (Number.isNaN(parsed.getTime())) { return { date: value, time: "-" }; } return { date: parsed.toISOString().slice(0, 10), time: parsed.toLocaleTimeString("ko-KR", { hour12: false }), }; } export function resolveAuditActor( log: Pick, details: AuditDetails, ) { return log.user_id || details.actor_id || "-"; } export function resolveAuditAction( log: Pick, details: AuditDetails, ) { if (details.action) { return details.action; } if (details.method && details.path) { return `${details.method} ${details.path}`; } return log.event_type; } export function resolveAuditTarget(details: AuditDetails) { return details.target || details.target_id || "-"; }