5.4 KiB
CLAUDE.md — Security Module
Self-contained MintyPHP module. Namespace: MintyPHP\Module\Security\*. Standalone —
requires: [], no dependency on helpdesk. All changes stay inside modules/security/.
After any manifest change (route, permission, slot): docker compose exec php php bin/console module:sync
What it does
Lets the security officer run security checks for customers. A check is created via a wizard (select customer → domain → software product), then tracked on a checklist workspace that combines:
- A fixed 7-step internal process (
SecurityCheckProcess, identical for every check), and - A per-product technical checklist defined as a reusable template (the product catalog is owned by this module — the templates are the product list).
Overall status (open → in_progress → completed, plus manual archived) is derived from
checklist progress. Each step/item records who completed it and when (completion log).
Architecture
lib/Module/Security/
SecurityAuthorizationPolicy.php — ability/permission constants + authorize()
SecurityContainerRegistrar.php — all DI bindings (add new services here)
Providers/SecurityLayoutProvider.php — resolves can_* flags for the sidebar
Repository/ — SQL only (tenant-scoped, prepared statements)
Service/
SecurityCheckProcess.php — fixed 7-step process + progress/status math (pure, no DI)
SecurityCheckService.php — check CRUD, saveState, status derivation, archive
SecurityCheckTemplateService.php— template CRUD + tech-schema validation/slugify
SecurityBcSettingsGateway.php — global BC connection settings (core settings table, encrypted)
SecurityOAuthTokenService.php — OAuth2 token acquire + encrypted cache
SecurityBcGateway.php — thin BC OData (ONLY customer-search + domains-for-customer)
SecurityReportPdfService.php — customer PDF report (Dompdf); pure context builder + render
pages/security/ — actions (*.php) + views (*.phtml)
checks/report($id).php — streams the customer report PDF (gated on steps 1–5 complete)
templates/aside-security-panel.phtml— sidebar navigation
templates/pdf/customer-report.phtml — customer report PDF template (hydrated by SecurityReportPdfService)
i18n/default_de.json + default_en.json — keep both in sync (identical key sets)
migrations/ — 003 SQL files (module:migrate)
web/css/security.css | web/js/ — module styles + runtime components + page scripts
tests/Module/Security/Service/ — 7 test files (happy path + edge case)
Permissions (6)
All constants in SecurityAuthorizationPolicy:
| Constant | Key |
|---|---|
ABILITY_ACCESS |
security.access — gates the main-menu entry |
ABILITY_CHECKS_VIEW |
security.checks.view |
ABILITY_CHECKS_CREATE |
security.checks.create — create + edit the checklist |
ABILITY_CHECKS_MANAGE |
security.checks.manage — archive, delete |
ABILITY_TEMPLATES_MANAGE |
security.templates.manage |
ABILITY_SETTINGS_MANAGE |
security.settings.manage |
Gate every action with Guard::requireAbilityOrForbidden(...); tenant scope enforced in repositories.
DB schema
| Table | Key columns |
|---|---|
security_check_templates |
tenant_id, product_code (uniq), product_name, tech_schema_json, active, version |
security_checks |
tenant_id, debitor_no, domain_no, product_code, template_id, owner_user_id, status, process_state_json, tech_schema_snapshot_json, tech_state_json |
security_oauth_token_cache |
tenant_id, access_token_encrypted, expires_at |
tech_schema_snapshot_json freezes the template's checklist onto the check at creation time, so later
template edits never mutate in-flight checks. JSON state shapes:
- tech schema:
{version, items:[ {type:"section",label}, {type:"check",key,label,hint?} ]} - process_state:
{<stepKey>: {done, by, at, note, fields?}} - tech_state:
{<itemKey>: {done, by, at, note}}
Routes / pages
Main menu entry via the aside.tab_panel slot (icon bi-shield-check, permission security.access).
Pages: security/checks (list), security/checks/create (wizard), security/checks/edit/{id}
(workspace), security/checks/report/{id} (streams the customer PDF report),
security/templates (+create/edit/{id}), security/settings, plus data endpoints
security/checks-data, security/templates-data, security/customer-search-data,
security/customer-domains-data, security/settings/test-connection-data.
JS runtime components
data-app-component on the container: security-customer-domain-select (wizard domain picker),
security-check-workspace (live progress), security-template-schema-editor (checklist editor),
security-settings (auth-mode toggle + connection test). List pages load their own
web/js/pages/*-index.js via <script type="module">.
Tests
docker compose exec php vendor/bin/phpunit modules/security/tests/
Pattern: mock repositories, ->willReturn(...) / ->willReturnCallback(...) to capture args
(avoid ->with()). Every new/changed Service or Gateway needs happy path + edge case.
Deferred (not built)
Internal report PDF (the customer report is built — see SecurityReportPdfService),
per-tenant BC connection overrides, per-step assignment, revision history.