forked from fa/breadcrumb-the-shire
9.0 KiB
9.0 KiB
CLAUDE.md — CoreCore
Multi-tenant admin application built on MintyPHP. Manages tenants, users, departments, roles, permissions, address books, mail, CSV imports, scheduled jobs, and Microsoft Entra ID SSO.
Agent workflow: guards, quality gates, role prompts, contracts, and skills live in
.agents/— start with.agents/README.md.
Tech Stack
- Runtime: PHP 8.5 (FPM) on MintyPHP framework (
mintyphp/core) - Web server: Nginx 1.25 (Alpine)
- Database: MariaDB 11.4
- Cache: Memcached 1.6
- Frontend: Vanilla JS (ES2022 modules), vanilla CSS with
@layersystem — no build step - Key PHP libs: PHPMailer 7, Dompdf 3, endroid/qr-code 6, league/commonmark 2
- Containerized: Docker Compose (dev + prod variants)
Quick Commands
# Start dev environment
docker compose up --build -d
# App: http://localhost:8080 | phpMyAdmin: http://localhost:8081
# Run PHPUnit tests (phpunit.xml configures bootstrap + testsuite)
docker compose exec php vendor/bin/phpunit
# Run PHPStan (level 5)
docker compose exec php vendor/bin/phpstan analyse -c phpstan.neon --no-progress
# CLI commands (single entry point)
docker compose exec php php bin/console list
docker compose exec php php bin/console module:sync # full module runtime sync
docker compose exec php php bin/console module:migrate # apply module SQL migrations
docker compose exec php php bin/console module:permissions-sync # sync + deactivate orphaned
docker compose exec php php bin/console module:build # build runtime page root
docker compose exec php php bin/console module:assets-sync # publish module web assets
docker compose exec php php bin/console module:deactivate <id> --confirm
docker compose exec php php bin/console scheduler:run
docker compose exec php php bin/console doctor
# Check unused Composer packages
docker compose exec php vendor/bin/composer-unused
Project Structure
lib/ # All backend PHP (namespace MintyPHP\)
App/ # DI container + bootstrap (AppContainer, Container/Registrars/)
Module/ # Module platform (Registry, Manifest, Autoloader, Builder)
Repository/ # SQL queries, prepared statements, filters/paging
Service/ # Business logic, validation, orchestration
Http/ # Auth guards, API auth, request helpers
Input/ # Request input handling (RequestInput, FormErrors)
Console/ # CLI command framework (ConsoleApplication, Command base class)
Commands/ # Command classes (Module/, Scheduler/, Tools/)
Support/ # Crypto, flash, guard, search, helpers
modules/ # Self-contained feature modules (namespace MintyPHP\Module\<Name>\)
<id>/module.php # Module manifest (routes, slots, providers, permissions)
<id>/lib/ # Module PHP classes (Service, Repository, Providers)
<id>/pages/ # Module actions + views (symlinked into runtime)
<id>/templates/ # Module-specific templates
<id>/web/ # Module CSS/JS (published to web/modules/<id>/)
<id>/tests/ # Module PHPUnit tests
pages/ # Core actions (controllers) — file-based routing
pages/**/*.php # Action files (read input, check permissions, call services)
pages/**/*.phtml # View files (rendering only, no DB calls)
templates/ # Core layouts and partials
partials/ # Reusable UI components
emails/ # Email HTML templates
pdfs/ # PDF templates (Dompdf)
config/ # App config (routes, assets, settings cache, themes, modules)
web/ # Document root (entry point, CSS, JS, static assets)
js/core/ # DOM utilities, Grid.js factory, component runtime
js/components/ # Reusable UI components
css/ # Layered CSS (base → components → layout → pages)
modules/ # Published module assets (symlinks to modules/<id>/web/)
storage/ # Uploaded files + runtime state
runtime/pages/ # Symlinked page tree (core + modules, built by module-build)
db/init/init.sql # Full schema + seed data (no migration framework)
db/updates/ # Idempotent SQL update scripts for existing installs
tests/ # PHPUnit tests (namespace MintyPHP\Tests\)
docs/ # German-language documentation (Markdown)
i18n/ # Translation files (de, en)
bin/ # CLI entry point (bin/console) + legacy scripts + shell tools
docker/ # Dockerfiles, Nginx configs, PHP configs
.agents/ # Agent workflow system (contracts, prompts, checks, skills, runs)
Architecture Rules
Strict Layering (enforce in all changes)
- App (
lib/App/): DI container bootstrap. Registers all service/repository factories. No business logic. - Repository (
lib/Repository/): All SQL lives here. No HTTP, session, or rendering. - Service (
lib/Service/): Business rules and validation. No HTML. Four internal sub-types:- Service (
*Service.php): Business logic + orchestration. Coordinates repositories and gateways. - Gateway (
*Gateway.php): Adapter for a single external dependency (repository, settings, HTTP API, scope). No orchestration flow. - Factory (
*Factory.php): Only place insidelib/Service/that may callnewon services/gateways/repositories. Registers via DI container. - Policy (
*Policy.phpinlib/Service/Access/): Authorization decisions per resource type. ReturnsAuthorizationDecision. No HTTP, no business logic.
- Service (
- Action (
pages/**/*.php): Reads input, checks permissions + tenant scope, calls services, sets view vars. - View (
pages/**/*.phtml): Pure rendering. No DB calls. HTML escaping viae(...). - Template (
templates/): Layouts and partials.
Modules
- Modules are self-contained feature packages under
modules/<id>/ - Namespace:
MintyPHP\Module\<Name>\*— never use core namespaces (MintyPHP\Service\*,MintyPHP\Repository\*) - Manifest:
module.phpdeclares routes, UI slots, providers, permissions, scheduler jobs - UI integration: Only via platform slots (
aside.tab_panel,topbar.right_item,layout.head_style,runtime.component, etc.) — no core template hardcoding - Session keys: Prefixed with
module.<id>.* - Activation:
config/modules.phporAPP_ENABLED_MODULESenv override - Runtime sync:
php bin/module-runtime-sync.phpafter any module/manifest change (builds page symlinks, syncs permissions, publishes assets) - Fingerprint guard:
web/index.phpvalidates runtime state matches active modules; fails fast if stale - API isolation: API requests (
api/prefix) skip session/auth/cookie flows entirely; modules using API endpoints rely onApiBootstrap.php
Routing
- File-based:
pages/admin/users/edit($id).php→ URL parameterid - Module pages:
modules/<id>/pages/symlinked intostorage/runtime/pages/at build time ...(none).phtml→ no template layoutdata().phpsuffix → data/AJAX endpoints- Named aliases in
config/routes.phpwithpublicflag for auth guard - Module routes declared in manifest, merged at boot (fail-fast on collision)
PHP Conventions
- PSR-4 autoload:
MintyPHP\→lib/,MintyPHP\Module\*→modules/*/lib/,MintyPHP\Tests\→tests/ - All user-facing text uses
t('key')translation helper - Permissions + tenant scope enforced in actions/services, never just in UI
- Security/integration settings stay in DB, not in
config/settings.phpfile cache
Frontend Conventions
- Vanilla ES2022 modules, no bundler
- CSS classes prefixed with
app- - Defensive DOM checks (elements may not exist on every page)
- No business logic in frontend
- Assets served raw with
assetVersion()cache-busting (filemtime-based)
UI Patterns
- Edit pages: tabs →
Master data|Visibility| optionalDanger zone - Titlebar partial for primary actions (Save, Save & close)
- Secondary actions in Aside block via
app-details-aside-actions.phtml - Lists use Grid.js
- All visible text wrapped in
t('...')
Database
- Schema defined in
db/init/init.sql(applied once on container init) - No migration framework — schema changes for existing installs are idempotent SQL scripts
- Settings stored in
settingsDB table (single source of truth);config/settings.phpis a partial file cache for hot-path UI reads only
Quality Gates
- PHPStan level 5 — scans
config/,lib/,modules/,pages/,tests/ - PHPUnit 11 — bootstrap:
tests/bootstrap.php - Frontend Smoke-Check — browser console bleibt fehlerfrei in Kernflows
- composer-unused — periodic check for unused dependencies
Environment
- Config via
.env(gitignored) — copy from.env.examplefor dev,.env.prod.examplefor prod config/config.php(gitignored) — copy fromconfig/config.php.exampleAPP_CRYPTO_KEY(64-char hex) needed for AES-256-GCM encryption of SSO secrets