feat(audit): archive retention and superseded stale-archive cleanup (ScadaBridge#109)
Owner decisions recorded: the archive destination stays a directory/UNC (no object-storage client; share + permissions named at enablement), parquet-tools-only reading (no re-import), unsigned like the chain (#107). AuditLog:Archive:RetentionDays (default 0 = never delete; else must exceed AuditLog:RetentionDays, counted from the archived month's end) and DeleteSupersededStaleArchives (default true) run after every purge tick. A retried purge's stale Archived archive is deleted only when a later, verifying, Purged archive of the same partition provably holds every row: same prior anchor and the stale chain-end hash at its chain-end sequence (row or tombstone), every unchained row present by EventId; otherwise it is reported KeptStale. A sole copy left at Archived is never touched. Deletion removes only the archive name's own three files in its folder, manifest first, never a manifest-supplied path. `audit archive cleanup [--dry-run]` = CleanupAuditArchives (Administrator). AuditLogArchiveCleanupTests (MSSQL) cover retried purge, kept stale copy, sole copy, retention and the path guard; each safety rule mutation-checked. Follow-ups filed: #113, #114, #115. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -24,8 +24,8 @@ Management commands use `POST /management`. Audit query, export, and tree use
|
||||
`GET /api/audit/query`, `/api/audit/export`, and `/api/audit/tree`; source-node
|
||||
backfill uses `POST /api/audit/backfill-source-node`. `audit verify-chain` sends the
|
||||
`VerifyAuditChain` management command (ScadaBridge#41); `audit verify-heads` reads off-box
|
||||
exported chain heads and sends `VerifyAuditChainHeads` (ScadaBridge#107); `audit archive list|verify` send
|
||||
`ListAuditArchives` / `VerifyAuditArchive` (ScadaBridge#42). `debug stream` uses a persistent
|
||||
exported chain heads and sends `VerifyAuditChainHeads` (ScadaBridge#107); `audit archive list|verify|cleanup` send
|
||||
`ListAuditArchives` / `VerifyAuditArchive` (ScadaBridge#42) / `CleanupAuditArchives` (ScadaBridge#109). `debug stream` uses a persistent
|
||||
SignalR connection. Audit export streams the response without buffering it all.
|
||||
|
||||
### Authentication and roles
|
||||
@@ -122,7 +122,7 @@ scadabridge instance deploy --id 7
|
||||
| `db-connection` | `list`, `get`, `create`, `update`, `delete` | `Designer` |
|
||||
| `api-method` | `list`, `get`, `create`, `update`, `delete`, `validate`, `recompile` | `Designer` |
|
||||
| `bundle` | `export`, `preview`, `import` | Designer export; Administrator preview/import |
|
||||
| `audit` | `query`, `export`, `tree`, `backfill-source-node`, `verify-chain`, `verify-heads`, `archive list`, `archive verify` | Audit roles; Administrator backfill; verify-chain, verify-heads and archive need an unscoped audit role |
|
||||
| `audit` | `query`, `export`, `tree`, `backfill-source-node`, `verify-chain`, `verify-heads`, `archive list`, `archive verify`, `archive cleanup` | Audit roles; Administrator backfill and archive cleanup; verify-chain, verify-heads and archive need an unscoped audit role |
|
||||
| `audit-config` | `query` (config-change audit trail; was `audit-log` pre-M8) | `Admin` |
|
||||
| `health` | `summary`, `pending-updates`, `site`, `event-log`, `parked-messages` | Authenticated reads with server-side scope checks |
|
||||
| `debug` | `snapshot`, `stream` | `Deployer` |
|
||||
|
||||
Reference in New Issue
Block a user