Record what a change was, not only which field it touched
The audit log said "Adresse, wirksam ab 30.07.2026". That names the field
and hides the answer: what did it say before? For a personnel record that is
the question the log exists to answer.
Both values are in hand at the moment of the change — v_old holds the row as
it was, the payload holds what is being written. change_employee_data
already compared them to decide whether to mention the field at all, then
dropped them. It now keeps them in audit_log.changes as
[{feld, vorher, nachher}], and derives the old one-line text from the same
array so existing views are unaffected.
Clicking a row opens the detail. Fields with no previous value read "leer"
rather than showing an empty cell, because "was not set" is itself a
statement.
Two honest limits, both stated in the panel rather than left to look like a
bug:
- Existing entries cannot be enriched. The values were never captured;
there is nothing to recover.
- Hire, exit and import record no individual fields, so they show none.
The rewritten function also drops auth.uid() for app_current_user_id(),
which works on either system — one of the last few call sites before #23.
Caught while writing this: my scripted edit of types.ts silently did nothing
and my own check reported success, because the pattern matched
pending_org_changes. Redone with the editor. That is the second time a
regex-driven edit has lied about its result in this project.
Not verified end to end: the migration needs privileges I no longer hold
after the database password was rotated. Until it is applied the audit page
will not load, since it selects a column that does not exist yet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import Link from "next/link";
|
||||
import { Suspense } from "react";
|
||||
import { AuditDetail } from "@/components/audit/AuditDetail";
|
||||
import { AuditFilters } from "@/components/audit/AuditFilters";
|
||||
import { CARD_CLASS } from "@/components/ui/Card";
|
||||
import { Pagination } from "@/components/ui/Pagination";
|
||||
@@ -54,7 +55,7 @@ export default async function AuditPage({ searchParams }: { searchParams: Promis
|
||||
|
||||
const [entries, total] = await Promise.all([
|
||||
base()
|
||||
.select(["id", "occurred_at", "actor_name", "action", "target_label", "target_employee_id", "details"])
|
||||
.select(["id", "occurred_at", "actor_name", "action", "target_label", "target_employee_id", "details", "changes"])
|
||||
// Nach id als zweitem Kriterium: bei gleichem Zeitstempel wäre die
|
||||
// Reihenfolge sonst unbestimmt und ein Eintrag könnte auf zwei Seiten
|
||||
// erscheinen oder auf keiner.
|
||||
@@ -115,7 +116,9 @@ export default async function AuditPage({ searchParams }: { searchParams: Promis
|
||||
entry.target_label
|
||||
)}
|
||||
</td>
|
||||
<td className="px-4 py-2.5 text-ink-muted">{entry.details ?? "–"}</td>
|
||||
<td className="px-2 py-1.5">
|
||||
<AuditDetail eintrag={entry} />
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user