Historie filtruje audit přes existující entity — smazaný záznam „zmizí beze stopy“
import { Aside } from ‘@astrojs/starlight/components’;
Symptom
Sekce “Symptom”Klient nahlásil, že „záznam zmizel bez stopy” — v kartě nadřazené entity nebyla po smazání ani položka, ani žádná událost v historii. Vyvolalo to podezření na nedostatečný audit, případně na obcházení oprávnění.
Root cause
Sekce “Root cause”Audit byl v pořádku (CREATE, UPDATE i DELETE s aktérem, IP a snapshotem). Vada byla ve čtecí cestě — timeline skládala události takto:
{ entity: "record", entityId: { in: (await db.record.findMany({ where: { parentId }, select: { id: true } })).map(r => r.id) } }entityId IN (žijící záznamy) — smazaný záznam v seznamu není, takže
z historie zmizí celý jeho auditní řetěz včetně DELETE události.
Tentýž vzor byl na všech větvích dotazu (více typů entit).
Fix
Sekce “Fix”// DELETE/ARCHIVE události nesou v details identifikátor nadřazené entity// (zapisuje ho mazací routa) — historie je dohledá i po zániku záznamu:OR: [ { entity: "record", entityId: { in: livingIds } }, { entity: { in: KNOWN_ENTITIES }, // jen známé typy… action: { in: ["DELETE", "ARCHIVE", "RESTORE"] }, // …a akce details: { path: ["parentId"], equals: parentId } },]Omezení na známé entity a akce je důležité — jinak větev přes details
přimíchá nesouvisející auditní záznamy.
Jak se tomu vyvarovat v jiných systémech
Sekce “Jak se tomu vyvarovat v jiných systémech”- Detection: smaž testovací záznam a otevři historii nadřazené
entity — pokud DELETE událost není vidět, čtecí cesta filtruje přes
živé entity. V kódu grep na
entityId: { in:plněné zfindMany. - Anti-pattern: audit trail JOINovaný na aktuální stav dat; mazací routa, která do details nezapíše vazbu na nadřazenou entitu.
- Lepší přístup: soft delete/archivace místo hard delete (historie zůstává plnohodnotná) + audit události vždy samonosné (obsahují vše potřebné k zobrazení bez JOINu na smazaná data).
Sister bugs / související
Sekce “Sister bugs / související”- Vjemová past: „chybí stopa” ≠ „chybí audit” — před závěrem o díře v auditech ověř čtecí cestu, kterou uživatel na stopu kouká.