Files
breadcrumb-the-shire/modules/security/CLAUDE.md

113 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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:
1. A **fixed 7-step internal process** (`SecurityCheckProcess`, identical for every check), and
2. 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 15 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.