feat(parafering-audit-trail): apply spec#396
Merged
Merged
Conversation
Manifest-first implementation of the regulator-grade, append-only audit
trail for the parafeerroute lifecycle.
- Schema: add paraferingAuditEntry to procest_register.json (action,
actor, actorRole, timestamp, reason, contentSnapshot, ipAddress,
auditEntryHash) + register slug list + new x-pages index page at
/voorstellen/:voorstelId/audit-trail (sorted by timestamp desc).
- Service: lib/Service/Parafering/AuditTrailService.php — record() builds
the canonical entry + SHA-256 hash and persists via ObjectService;
export() returns the MDTO 1.0 envelope with 20yr/7yr retention;
assertAppendOnly() rejects UPDATE/DELETE with OCSForbiddenException
"Audit entries are append-only".
- Domain event: lib/Event/ParafeerTransitionEvent.php — emitted by
ParafeerRouteService (startParafering, completeStep, skipStep,
addAdhocStep, completed) and ParafeerActieService.recordAction.
- Listener: lib/Listener/ParaferingAuditListener.php subscribes to the
event and persists one entry per transition; failures are swallowed
so audit outages never block operational transitions.
- Validator: lib/Validator/ParaferingAuditAppendOnlyValidator.php hooks
OR pre-save (ObjectCreating/Updating/Deleting) events to enforce
append-only on the audit schema.
- Endpoint: GET /api/voorstellen/{id}/audit-trail/export (action, not
CRUD) — RBAC via auditors/secretariaat/beheerders groups; returns
metadata + entries envelope.
- Registry: SettingsService gets the parafering_audit_entry_schema
config key and slug→key mapping.
CRUD listing is served by OpenRegister's auto-exposed
/api/objects/<register>/<schema> endpoint via the manifest index page;
no bespoke CRUD controller introduced.
7dce54d to
44cb3b5
Compare
Contributor
Quality Report — ConductionNL/procest @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ❌ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 419/419 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ |
Spec coverage: 3% (21 tests / 673 specs)
Quality workflow — 2026-05-11 12:22 UTC
Download the full PDF report from the workflow artifacts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Applies the parafering-audit-trail spec: a regulator-grade, append-only audit trail for every parafeerroute lifecycle transition (started, paraferd, terugsturen, advised, route-changed, completed). Manifest-first — listing is served by OpenRegister's auto-exposed CRUD endpoint via a new x-pages index page; only the Archiefwet-aligned export is exposed as an action endpoint.
Changes
Strict watchdog
Validated with php -l (all 10 files clean) + jq (schema/registers/x-pages structure). No i18n keys, no composer check per the 25-minute budget.
Test plan