Commit Graph

27 Commits

Author SHA1 Message Date
fs
d6be536fbf refactor(departments-create): migrate to actionCreateContext (step 9)
First production use of actionCreateContext — the second aggregator
introduced in step 1 and unit-tested at the building-block level, but
not yet exercised against a real caller. Helper file stays 0-diff for
the sixth consecutive migration.

The migration uncovers one real API gap and resolves it at the policy
layer rather than at the helper:

* actionCreateContext always calls actionEnforceCanViewPage. The
  Departments create-decision was the only Departments authorize
  branch that did not emit can_view_page (View and EditContext both
  did). Adding 'can_view_page' => true to the create-capabilities
  map is tautological — every actor that survives the deny() guards
  at lines 69-70 and 75-76 can by definition see the page. No new
  forbidden path is created. View, Create, and EditContext now share
  the same capability shape.

Three drift decisions reproduced where applicable:
* notFoundFlashScopeKey is N/A (no model lookup in create flow).
* t() consistency: all three Flash::success('Department created', …)
  calls now flow through t().
* Defensive scope consumption: $canManageAllTenants reads
  $tenantScope['scope'] === 'all', mirroring the edit-action pattern.
  The GET tenant filter rewrites from is_array($allowedTenantIds) to
  the three-way scope-tuple form.

AuthzAdminMasterDataContractTest gets a single-line assertion update
(AuthorizationService::class → actionCreateContext() pattern). The
aggregator wraps the same authorize call internally, so this is a
pattern-rename, not a semantic shift.

ActionContextCsrfPairingContractTest now covers six callers (five
edits + departments-create) and stays green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 14:44:09 +02:00
fs
5378209fed refactor(departments-edit): migrate to actionEditContext (step 2)
Pilot migration of pages/admin/departments/edit($id).php onto the
actionEditContext aggregator introduced in step 1. The CONTEXT-stage
vorspiel (lookup → authorize → tenant-scope → can_view_page → viewAuth)
collapses into a single declarative call; the POST branch (CSRF →
SUBMIT-authorize → can_update gate → service call → PRG) stays
callsite-specific as planned.

Three deliberate touches beyond a 1:1 lift:

* Additive aggregator extension: actionEditContext gains an optional
  notFoundFlashScopeKey arg so the dedup scope-key 'department_not_found'
  is preserved without widening the frozen actionResolveModelOrFail
  building-block signature. Pattern is documented as the
  forward-compatibility mechanism for future cluster migrations.
* t() consistency: the not-found message now flows through t() via the
  aggregator. To avoid a partial-translation mix, Flash::success calls
  for 'Department updated' (×2) are also wrapped — German users now see
  fully translated messages instead of a German/English mix.
* Defensive scope consumption: the action now consults
  $tenantScope['scope'] before falling through to the strict-mode
  fallback. The Departments policy never emits can_manage_all_tenants
  today (so behavior is identical), but the action is now resilient to
  future policies that might.

New ActionContextCsrfPairingContractTest enforces actionRequireCsrf()
before any POST body access for actions that use the aggregators —
preventing CSRF-pairing regressions during the cluster-wide rollout
(step 3). The step-1 testNoProductionCallSitesYet guard is removed,
since departments-edit is now the first legitimate caller; the new
pairing test takes over its protective role with a more substantive
guarantee.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 23:52:27 +02:00
fs
6c99c040b2 refactor(support): centralize ID-array normalization in toIntIds()
Consolidates the scattered `array_values(array_unique(array_map('intval',
$x)))` + manual positive-filter pattern behind a single lenient helper
`toIntIds(mixed $value): array` in core/Support/helpers/array.php.

- `RepositoryArrayHelper::sanitizePositiveIds()` now delegates (keeps
  strict array-input contract + existing tests intact).
- Drops two private duplicates: `UserProfileViewService::normalizeIds()`
  and `AddressBookService::normalizeIds()`.
- Replaces 12 inline occurrences across admin action pages with the
  helper, cutting boilerplate by 3-5 lines per site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 19:11:53 +02:00
fs
da7e7c593e refactor(actions): centralize wave-2 post/csrf guards 2026-04-24 18:31:17 +02:00
fs
b749b5d192 feat: centralize breadcrumbs in topbar and remove history navigation
Move breadcrumb rendering from individual page templates into the core
topbar. Each page now sets $breadcrumbs in its action .php file; the
topbar renders it automatically via the shared partial.

- Remove global back/forward buttons and app-nav-history.js component
- Remove Alt+Arrow keyboard shortcuts for history navigation
- Render breadcrumb in topbar-left section (replaces button area)
- Clean up breadcrumb CSS: context-neutral base (flex, no margin)
- Recalculate sticky titlebar offset in details container
- Migrate all 41 pages (core + helpdesk, audit, addressbook, api-docs)
- Add missing breadcrumbs to addressbook detail view
- Update architecture contract tests (nav-history references removed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 17:17:06 +02:00
fs
7a222f0b1f fix(audit): harden module isolation and fix post-extraction drift
Fix 5 broken FQCN references (runtime errors) where core pages referenced
non-existent MintyPHP\Service\Audit\AuditMetadataEnricher and SystemAuditService.
Add AuditMetadataEnricherInterface with NullAuditMetadataEnricher fallback so
deactivating the audit module no longer crashes core edit pages.

Move audit search resources from core Search*Provider files into the module
via a new AuditSearchResourceProvider implementing the existing
SearchResourceProvider contract. Add module-specific purge permissions
(audit.api.purge, audit.imports.purge) replacing core ABILITY_ADMIN_SETTINGS_UPDATE.

Also fixes: session key prefix convention, hardcoded English string, $_SERVER
superglobal fallback, and manifest schema drift (i18n_path, group in ui_slots).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 10:03:27 +01:00
fs
06e619f26c feat: show "View X" instead of "Edit X" for read-only users
Titlebar, breadcrumbs, and page title now reflect the user's actual
permission level across all 6 edit pages (roles, users, departments,
tenants, permissions, scheduled jobs). Added i18n keys for de and en.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:28:19 +01:00
fs
c429ff43cd refactor: fix 7 CRUD system inconsistencies for robustness and maintainability
- Add user-assignment dependency check to DepartmentService.deleteByUuid (409 when users assigned)
- Standardize POST detection to isMethod('POST') in 10 create/edit actions
- Align RoleService code uniqueness to warning pattern (matching departments)
- Normalize repository create() return types from mixed to int|false (3 repos + 3 interfaces)
- Add JSON response branches to 4 non-user delete actions
- Document delete authorization ordering pattern
- Decompose AdminSettingsService.updateFromAdmin into domain-scoped private methods

Workflow: .agents/runs/CRUD-CONSISTENCY-001/
Reviewed by: Code Reviewer (pass), Security Reviewer (pass), Acceptance Tester (pass)
Quality gates: QG-001 PHPUnit pass, QG-002 PHPStan pass, QG-003 Architecture pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 18:25:33 +01:00
fs
c7b8fd516a feat: extend module platform with UI slots, runtime components, CLI tooling and {{userId}} search support
Completes the generic module platform that enables modules to contribute
UI elements, runtime JS components, and search resources without any
core hardcoding.

New generic UI slot types:
- topbar.right_item: module-contributed topbar buttons
- layout.body_end_template: module-contributed dialog/overlay templates
- layout.head_style: module-contributed global CSS
- runtime.component: declarative JS component registration with phase ordering

New infrastructure:
- ModuleAutoloader: PSR-4 autoloading for module-local PHP classes
- ModuleRuntimePageBuilder: symlinks module pages into runtime directory
- ModuleRuntimeAssetPublisher: publishes module CSS/JS to web/modules/
- ModulePermissionSynchronizer: syncs module permissions to DB
- CLI scripts: module-runtime-sync, module-build, module-migrate,
  module-permissions-sync, module-assets-sync
- {{userId}} placeholder in SearchDataService for user-scoped search queries
- Component runtime with phased initialization (early/default/late)
- AppContainer.protectExistingBindings() to prevent module→core overwrites
- Architecture tests: ModuleStructureContractTest, CoreTemplateIsolationTest,
  FrontendComponentRuntimeContractTest, AppContainerIsolationContractTest

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 22:19:56 +01:00
fs
921977bdd3 create without tab storage local 2026-03-14 16:08:19 +01:00
fs
010690de19 refactor(actions): deduplicate audit metadata and grid user count enrichment 2026-03-13 12:05:11 +01:00
fs
892da0048d refactor(arch): enforce gateway compliance and remove service-wrapping gateways 2026-03-13 11:31:33 +01:00
fs
082fa4c9a5 empty states 2026-03-13 09:49:11 +01:00
fs
cb7256aebc variablen und empty states 2026-03-12 16:47:53 +01:00
fs
17a72af5f2 guard permission fix 2026-03-12 13:01:06 +01:00
fs
277168f7e8 feat(admin): preserve list return target for back and close actions 2026-03-11 23:32:11 +01:00
fs
fd90065048 fix(security): add CSRF protection to all POST endpoints + contract tests (B2)
CSRF guards added to 16 admin pages that previously accepted POST requests
without token verification (GR-SEC-001): departments, permissions, roles,
settings, tenants, users (create/edit/bulk/tokens), and lang switch.

New contract tests:
- PostEndpointCsrfContractTest: scans all pages/ for POST handlers and
  verifies checkCsrfToken is present (API/data endpoints exempt).
- DatabaseUpdatesContractTest: validates db/updates/ scripts follow naming
  convention and use idempotent SQL patterns (GR-CORE-010).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:40:07 +01:00
fs
205da203cc refactor(pages): replace superglobals with request/session abstractions 2026-03-06 11:28:22 +01:00
fs
9a08f96c11 agent foundation 2026-03-06 00:44:52 +01:00
fs
c5f657c8c8 listen ansichten verbessert 2026-03-05 11:17:42 +01:00
fs
4b31fc7664 Repo Interface für tests 2026-03-05 08:26:51 +01:00
fs
8f4dd5840d major update 2026-03-04 15:56:58 +01:00
fs
16759a2732 weitere updates für instanzierbarkeit und sauberes testing 2026-02-24 08:49:40 +01:00
fs
99db252f60 instances added god may help 2026-02-23 12:58:19 +01:00
fs
25370a1a55 add composer-unused, comprehensive docs, and project restructure
- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks
- Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists
- Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services
- Add Microsoft OIDC SSO, API token management, and user lifecycle features
- Add swagger-ui vendor integration and OpenAPI spec
- Add production Docker setup and bin/ scripts
- Update composer dependencies, config, templates, and frontend assets throughout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 15:27:35 +01:00
fs
3eb9cc0ac4 big restructure 2026-02-11 19:28:12 +01:00
fs
cd59ccd99b baseline 2026-02-04 23:31:53 +01:00