forked from fa/breadcrumb-the-shire
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>
This commit is contained in:
@@ -14,10 +14,6 @@ $canViewJobs = (bool) ($layoutAuth['can_view_jobs'] ?? false);
|
||||
$canViewApiDocs = (bool) ($layoutAuth['can_view_api_docs'] ?? false);
|
||||
$canViewDocs = (bool) ($layoutAuth['can_view_docs'] ?? false);
|
||||
$canViewMailLog = (bool) ($layoutAuth['can_view_mail_log'] ?? false);
|
||||
$canViewApiAudit = (bool) ($layoutAuth['can_view_api_audit'] ?? false);
|
||||
$canViewSystemAudit = (bool) ($layoutAuth['can_view_system_audit'] ?? false);
|
||||
$canViewImportsAudit = (bool) ($layoutAuth['can_view_imports_audit'] ?? false);
|
||||
$canViewUserLifecycleAudit = (bool) ($layoutAuth['can_view_user_lifecycle_audit'] ?? false);
|
||||
$canViewStats = (bool) ($layoutAuth['can_view_stats'] ?? false);
|
||||
$canViewSystemInfo = (bool) ($layoutAuth['can_view_system_info'] ?? false);
|
||||
$docsDefaultSlug = DocsCatalogService::defaultSlug();
|
||||
@@ -26,7 +22,7 @@ $hasOrganization = $canViewTenants || $canViewDepartments || $canViewUsers;
|
||||
$hasUsersSection = $canViewRoles || $canViewPermissions;
|
||||
$hasAutomationSection = $canViewImports || $canViewJobs || $canViewApiDocs;
|
||||
$hasMonitoringSection = $canViewStats;
|
||||
$hasLogsSection = $canViewMailLog || $canViewApiAudit || $canViewSystemAudit || $canViewImportsAudit || $canViewUserLifecycleAudit;
|
||||
$hasLogsSection = $canViewMailLog;
|
||||
$hasSystemSection = $canViewSettings || $canViewSystemInfo || $canViewDocs;
|
||||
$hasAdminPanel = layoutHasAdminPanel($layoutAuth);
|
||||
|
||||
@@ -140,34 +136,6 @@ $adminNavGroups = [
|
||||
'visible' => $canViewMailLog,
|
||||
'withTenant' => false,
|
||||
],
|
||||
[
|
||||
'label' => t('API audit'),
|
||||
'path' => 'admin/api-audit',
|
||||
'active' => navActive('admin/api-audit', true),
|
||||
'visible' => $canViewApiAudit,
|
||||
'withTenant' => false,
|
||||
],
|
||||
[
|
||||
'label' => t('System audit logs'),
|
||||
'path' => 'admin/system-audit',
|
||||
'active' => navActive('admin/system-audit', true),
|
||||
'visible' => $canViewSystemAudit,
|
||||
'withTenant' => false,
|
||||
],
|
||||
[
|
||||
'label' => t('Import logs'),
|
||||
'path' => 'admin/import-audit',
|
||||
'active' => navActive('admin/import-audit', true),
|
||||
'visible' => $canViewImportsAudit,
|
||||
'withTenant' => false,
|
||||
],
|
||||
[
|
||||
'label' => t('User lifecycle logs'),
|
||||
'path' => 'admin/user-lifecycle-audit',
|
||||
'active' => navActive('admin/user-lifecycle-audit', true),
|
||||
'visible' => $canViewUserLifecycleAudit,
|
||||
'withTenant' => false,
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
@@ -457,28 +425,6 @@ $moduleSearchSlots = is_array($moduleSlots['search.resource_item'] ?? null) ? $m
|
||||
<ul class="app-search-preview" data-search-preview></ul>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if ($canViewApiAudit): ?>
|
||||
<?php $apiAuditSearch = navActive('admin/api-audit', true); ?>
|
||||
<li data-search-key="api-audit" data-search-base="<?php e(lurl('admin/api-audit')); ?>">
|
||||
<a href="<?php e(lurl('admin/api-audit')); ?>" class="<?php e($apiAuditSearch['class']); ?>"
|
||||
<?php echo $apiAuditSearch['aria']; ?>>
|
||||
<span><?php e(t('API audit')); ?></span>
|
||||
<span class="badge" data-search-count>0</span>
|
||||
</a>
|
||||
<ul class="app-search-preview" data-search-preview></ul>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php if ($canViewSystemAudit): ?>
|
||||
<?php $systemAuditSearch = navActive('admin/system-audit', true); ?>
|
||||
<li data-search-key="system-audit" data-search-base="<?php e(lurl('admin/system-audit')); ?>">
|
||||
<a href="<?php e(lurl('admin/system-audit')); ?>" class="<?php e($systemAuditSearch['class']); ?>"
|
||||
<?php echo $systemAuditSearch['aria']; ?>>
|
||||
<span><?php e(t('System audit')); ?></span>
|
||||
<span class="badge" data-search-count>0</span>
|
||||
</a>
|
||||
<ul class="app-search-preview" data-search-preview></ul>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
$coreSearchKeys = [
|
||||
'users' => true,
|
||||
@@ -491,8 +437,6 @@ $moduleSearchSlots = is_array($moduleSlots['search.resource_item'] ?? null) ? $m
|
||||
'docs' => true,
|
||||
'hotkeys' => true,
|
||||
'mail-log' => true,
|
||||
'api-audit' => true,
|
||||
'system-audit' => true,
|
||||
];
|
||||
foreach ($moduleSearchSlots as $searchSlot):
|
||||
if (!is_array($searchSlot)) { continue; }
|
||||
|
||||
Reference in New Issue
Block a user