refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Audit module manifest.
|
|
|
|
|
*
|
|
|
|
|
* Provides four audit streams: system audit, API audit, import audit,
|
|
|
|
|
* and user lifecycle audit. Includes frontend telemetry ingestion,
|
|
|
|
|
* PII redaction, encrypted snapshots, and retention-based cleanup.
|
|
|
|
|
*/
|
|
|
|
|
return [
|
|
|
|
|
'id' => 'audit',
|
|
|
|
|
'version' => '1.0.0',
|
|
|
|
|
'enabled_by_default' => true,
|
|
|
|
|
'load_order' => 5,
|
|
|
|
|
'requires' => [],
|
|
|
|
|
|
|
|
|
|
'routes' => [
|
|
|
|
|
// API audit pages
|
2026-03-26 08:13:37 +01:00
|
|
|
['path' => 'admin/api-audit', 'target' => 'audit/api-audit/index'],
|
|
|
|
|
['path' => 'admin/api-audit/view', 'target' => 'audit/api-audit/view'],
|
|
|
|
|
['path' => 'admin/api-audit/data', 'target' => 'audit/api-audit/data'],
|
|
|
|
|
['path' => 'admin/api-audit/purge', 'target' => 'audit/api-audit/purge'],
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
// System audit pages
|
2026-03-26 08:13:37 +01:00
|
|
|
['path' => 'admin/system-audit', 'target' => 'audit/system-audit/index'],
|
|
|
|
|
['path' => 'admin/system-audit/view', 'target' => 'audit/system-audit/view'],
|
|
|
|
|
['path' => 'admin/system-audit/data', 'target' => 'audit/system-audit/data'],
|
feat(audit): CSV/Excel export for system-audit via core primitive
Third consumer of the generic export primitive. Adds a
GET /admin/system-audit/export endpoint, the reusable export dropdown
to the list titlebar, and wires initListExport() into the page JS.
- pages/audit/system-audit/export().php: guard + ABILITY_SYSTEM_AUDIT_VIEW,
reuses the existing filter-schema.php via gridParseFiltersFromSchemaFile
so exported rows match the grid under the same filters, caps the limit
at 5000, and declares 11 ExportColumns (ID, created, event, status,
channel, actor, actor email, target type/uuid, request id, error code)
with translated enum labels for outcome/channel.
- module.php: new admin/system-audit/export route.
- index(default).phtml: app-list-export-dropdown partial placed above the
existing purge action; exportUrl added to pageConfig via
lurl('admin/system-audit/export').
- admin-system-audit-index.js: imports initListExport and invokes it
whenever config.exportUrl is present.
- i18n de/en: new "Actor email" key (required by TranslationKeysTest).
Gates: PHPUnit 1880 OK, PHPStan 0 errors, module:sync ok.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 22:15:43 +02:00
|
|
|
['path' => 'admin/system-audit/export', 'target' => 'audit/system-audit/export'],
|
2026-03-26 08:13:37 +01:00
|
|
|
['path' => 'admin/system-audit/purge', 'target' => 'audit/system-audit/purge'],
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
// Import audit pages
|
2026-03-26 08:13:37 +01:00
|
|
|
['path' => 'admin/import-audit', 'target' => 'audit/import-audit/index'],
|
|
|
|
|
['path' => 'admin/import-audit/view', 'target' => 'audit/import-audit/view'],
|
|
|
|
|
['path' => 'admin/import-audit/data', 'target' => 'audit/import-audit/data'],
|
|
|
|
|
['path' => 'admin/import-audit/purge', 'target' => 'audit/import-audit/purge'],
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
// User lifecycle audit pages
|
2026-03-26 08:13:37 +01:00
|
|
|
['path' => 'admin/user-lifecycle-audit', 'target' => 'audit/user-lifecycle-audit/index'],
|
|
|
|
|
['path' => 'admin/user-lifecycle-audit/view', 'target' => 'audit/user-lifecycle-audit/view'],
|
|
|
|
|
['path' => 'admin/user-lifecycle-audit/data', 'target' => 'audit/user-lifecycle-audit/data'],
|
|
|
|
|
['path' => 'admin/user-lifecycle-audit/purge', 'target' => 'audit/user-lifecycle-audit/purge'],
|
|
|
|
|
['path' => 'admin/user-lifecycle-audit/restore', 'target' => 'audit/user-lifecycle-audit/restore'],
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
// Frontend telemetry
|
2026-03-26 08:13:37 +01:00
|
|
|
['path' => 'admin/frontend-telemetry/ingest', 'target' => 'audit/frontend-telemetry/ingest'],
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
],
|
|
|
|
|
'public_paths' => [],
|
|
|
|
|
|
|
|
|
|
'container_registrars' => [
|
|
|
|
|
\MintyPHP\Module\Audit\AuditContainerRegistrar::class,
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
'ui_slots' => [
|
|
|
|
|
'sidebar.admin_nav_item' => [
|
|
|
|
|
[
|
|
|
|
|
'key' => 'audit-api-audit',
|
|
|
|
|
'group' => 'admin-logs',
|
2026-03-26 15:09:55 +01:00
|
|
|
'label' => 'nav.audit.api',
|
2026-03-26 09:14:25 +01:00
|
|
|
'path' => 'audit/api-audit',
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
'permission' => 'audit.api.view',
|
|
|
|
|
'order' => 200,
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'key' => 'audit-system-audit',
|
|
|
|
|
'group' => 'admin-logs',
|
2026-03-26 15:09:55 +01:00
|
|
|
'label' => 'nav.audit.system',
|
2026-03-26 09:14:25 +01:00
|
|
|
'path' => 'audit/system-audit',
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
'permission' => 'audit.system.view',
|
|
|
|
|
'order' => 210,
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'key' => 'audit-import-audit',
|
|
|
|
|
'group' => 'admin-logs',
|
2026-03-26 15:09:55 +01:00
|
|
|
'label' => 'nav.audit.imports',
|
2026-03-26 09:14:25 +01:00
|
|
|
'path' => 'audit/import-audit',
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
'permission' => 'audit.imports.view',
|
|
|
|
|
'order' => 220,
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'key' => 'audit-user-lifecycle-audit',
|
|
|
|
|
'group' => 'admin-logs',
|
2026-03-26 15:09:55 +01:00
|
|
|
'label' => 'nav.audit.user_lifecycle',
|
2026-03-26 09:14:25 +01:00
|
|
|
'path' => 'audit/user-lifecycle-audit',
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
'permission' => 'audit.user_lifecycle.view',
|
|
|
|
|
'order' => 230,
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
'authorization_policies' => [
|
|
|
|
|
\MintyPHP\Module\Audit\AuditAuthorizationPolicy::class,
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
'permissions' => [
|
|
|
|
|
[
|
|
|
|
|
'key' => 'audit.api.view',
|
|
|
|
|
'description' => 'View API audit logs',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'key' => 'audit.system.view',
|
|
|
|
|
'description' => 'View system audit logs',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'key' => 'audit.system.purge',
|
|
|
|
|
'description' => 'Purge system audit logs',
|
|
|
|
|
],
|
2026-03-26 10:03:27 +01:00
|
|
|
[
|
|
|
|
|
'key' => 'audit.api.purge',
|
|
|
|
|
'description' => 'Purge API audit logs',
|
|
|
|
|
],
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
[
|
|
|
|
|
'key' => 'audit.imports.view',
|
|
|
|
|
'description' => 'View import audit logs',
|
|
|
|
|
],
|
2026-03-26 10:03:27 +01:00
|
|
|
[
|
|
|
|
|
'key' => 'audit.imports.purge',
|
|
|
|
|
'description' => 'Purge import audit logs',
|
|
|
|
|
],
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
[
|
|
|
|
|
'key' => 'audit.user_lifecycle.view',
|
|
|
|
|
'description' => 'View user lifecycle audit logs',
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'key' => 'audit.user_lifecycle.restore',
|
|
|
|
|
'description' => 'Restore deleted users from lifecycle audit',
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
'scheduler_jobs' => [
|
|
|
|
|
[
|
2026-04-06 12:26:54 +02:00
|
|
|
'job_key' => 'system_audit_purge',
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
'handler' => \MintyPHP\Module\Audit\Handler\SystemAuditPurgeJobHandler::class,
|
|
|
|
|
'label' => 'System audit log cleanup',
|
|
|
|
|
'description' => 'Purges system audit log entries older than the configured retention period',
|
|
|
|
|
'default_enabled' => 1,
|
|
|
|
|
'default_timezone' => 'UTC',
|
|
|
|
|
'default_schedule_type' => 'daily',
|
|
|
|
|
'default_schedule_interval' => 1,
|
|
|
|
|
'default_schedule_time' => '03:00',
|
|
|
|
|
'default_schedule_weekdays_csv' => null,
|
|
|
|
|
'default_catchup_once' => 1,
|
|
|
|
|
'allowed_schedule_types' => ['daily', 'weekly'],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'job_key' => 'audit_api_purge',
|
|
|
|
|
'handler' => \MintyPHP\Module\Audit\Handler\ApiAuditPurgeJobHandler::class,
|
|
|
|
|
'label' => 'API audit log cleanup',
|
|
|
|
|
'description' => 'Purges API audit log entries older than 90 days',
|
|
|
|
|
'default_enabled' => 1,
|
|
|
|
|
'default_timezone' => 'UTC',
|
|
|
|
|
'default_schedule_type' => 'daily',
|
|
|
|
|
'default_schedule_interval' => 1,
|
|
|
|
|
'default_schedule_time' => '03:15',
|
|
|
|
|
'default_schedule_weekdays_csv' => null,
|
|
|
|
|
'default_catchup_once' => 1,
|
|
|
|
|
'allowed_schedule_types' => ['daily', 'weekly'],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'job_key' => 'audit_import_purge',
|
|
|
|
|
'handler' => \MintyPHP\Module\Audit\Handler\ImportAuditPurgeJobHandler::class,
|
|
|
|
|
'label' => 'Import audit log cleanup',
|
|
|
|
|
'description' => 'Purges import audit run records older than 90 days',
|
|
|
|
|
'default_enabled' => 1,
|
|
|
|
|
'default_timezone' => 'UTC',
|
|
|
|
|
'default_schedule_type' => 'daily',
|
|
|
|
|
'default_schedule_interval' => 1,
|
|
|
|
|
'default_schedule_time' => '03:30',
|
|
|
|
|
'default_schedule_weekdays_csv' => null,
|
|
|
|
|
'default_catchup_once' => 1,
|
|
|
|
|
'allowed_schedule_types' => ['daily', 'weekly'],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'job_key' => 'audit_user_lifecycle_purge',
|
|
|
|
|
'handler' => \MintyPHP\Module\Audit\Handler\UserLifecycleAuditPurgeJobHandler::class,
|
|
|
|
|
'label' => 'User lifecycle audit log cleanup',
|
|
|
|
|
'description' => 'Purges user lifecycle audit entries older than 365 days',
|
|
|
|
|
'default_enabled' => 1,
|
|
|
|
|
'default_timezone' => 'UTC',
|
|
|
|
|
'default_schedule_type' => 'daily',
|
|
|
|
|
'default_schedule_interval' => 1,
|
|
|
|
|
'default_schedule_time' => '03:45',
|
|
|
|
|
'default_schedule_weekdays_csv' => null,
|
|
|
|
|
'default_catchup_once' => 1,
|
|
|
|
|
'allowed_schedule_types' => ['daily', 'weekly'],
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
'layout_context_providers' => [
|
|
|
|
|
\MintyPHP\Module\Audit\Providers\AuditLayoutProvider::class,
|
|
|
|
|
],
|
|
|
|
|
'session_providers' => [],
|
|
|
|
|
|
|
|
|
|
'event_listeners' => [],
|
2026-03-26 10:03:27 +01:00
|
|
|
'search_resources' => [
|
|
|
|
|
\MintyPHP\Module\Audit\Providers\AuditSearchResourceProvider::class,
|
|
|
|
|
],
|
refactor(audit): extract audit domain into self-contained module
Move the entire audit subsystem (system audit, API audit, import audit,
user lifecycle audit, frontend telemetry) from core into modules/audit/.
Core decoupling via interface-based injection:
- AuditRecorderInterface replaces SystemAuditService in 10+ core services
- UserLifecycleAuditInterface / ImportAuditInterface for specialized flows
- NullAuditRecorder fallback when audit module is disabled
- ApiBootstrap/ApiResponse use null-safe callable resolvers
Module structure (modules/audit/):
- Manifest with routes, permissions, scheduler jobs, authorization policy
- 9 services, 8 repositories, 6 domain enums, 4 job handlers
- 33 page files, 4 JS files, 8 test files, migration scripts, i18n
Core cleanup:
- OperationsAuthorizationPolicy, UiCapabilityMap, PermissionService
surgically cleaned of audit-specific constants
- Sidebar template cleared of hardcoded audit navigation
- AuditModuleIsolationContractTest ensures no future core→module coupling
All quality gates pass: 1346 tests (19,276 assertions), PHPStan level 5
clean, architecture contracts verified.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:12:49 +01:00
|
|
|
'asset_groups' => [],
|
|
|
|
|
'migrations_path' => 'db/updates',
|
|
|
|
|
'i18n_path' => 'i18n',
|
|
|
|
|
];
|