From f94fa6ba2f73ac31b9dd08738a36319788ede181 Mon Sep 17 00:00:00 2001 From: fs Date: Wed, 11 Mar 2026 20:11:01 +0100 Subject: [PATCH] Rename app branding from IMVS to CoreCore --- .env.example | 14 +- .env.prod.example | 10 +- AGENTS.md | 127 ++++++++++++++++++ CLAUDE.md | 2 +- README.md | 4 +- config/config.php.example | 2 +- docs/reference-konfiguration.md | 8 +- docs/tutorial-02-systemueberblick.md | 4 +- .../Branding/BrandingFaviconService.php | 2 +- lib/Support/helpers/app.php | 2 +- phpunit.xml | 2 +- tests/App/Bootstrap/EnvValidatorTest.php | 10 +- web/favicon/site.webmanifest | 4 +- 13 files changed, 159 insertions(+), 32 deletions(-) create mode 100644 AGENTS.md diff --git a/.env.example b/.env.example index 8b8fc00..a297edf 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -APP_NAME=IMVS +APP_NAME=CoreCore APP_URL=http://localhost:8080 APP_ENV=dev APP_DEBUG=true @@ -9,15 +9,15 @@ APP_LOCALE=de APP_LOCALES=de,en APP_I18N_DOMAIN=default APP_CRYPTO_KEY= -SESSION_NAME=IMVS +SESSION_NAME=CoreCore TENANT_SCOPE_STRICT=true DB_HOST=db DB_PORT=3306 -DB_NAME=imvs -DB_USER=imvs -DB_PASS=imvs -DB_ROOT_PASSWORD=imvs_root +DB_NAME=corecore +DB_USER=corecore +DB_PASS=corecore +DB_ROOT_PASSWORD=corecore_root CACHE_SERVERS=memcached:11211 @@ -32,5 +32,5 @@ SMTP_PORT=587 SMTP_USER=no-reply@example.com SMTP_PASS= SMTP_FROM=no-reply@example.com -SMTP_FROM_NAME=IMVS +SMTP_FROM_NAME=CoreCore SMTP_SECURE=tls diff --git a/.env.prod.example b/.env.prod.example index 3467706..48d6496 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -1,4 +1,4 @@ -APP_NAME=IMVS +APP_NAME=CoreCore APP_URL=https://example.com APP_ENV=prod APP_DEBUG=false @@ -9,13 +9,13 @@ APP_LOCALE=de APP_LOCALES=de,en APP_I18N_DOMAIN=default APP_CRYPTO_KEY=replace-with-64-char-hex-or-base64-key -SESSION_NAME=IMVS +SESSION_NAME=CoreCore TENANT_SCOPE_STRICT=true DB_HOST=db DB_PORT=3306 -DB_NAME=imvs -DB_USER=imvs +DB_NAME=corecore +DB_USER=corecore DB_PASS=replace-db-password DB_ROOT_PASSWORD=replace-db-root-password @@ -32,5 +32,5 @@ SMTP_PORT=587 SMTP_USER= SMTP_PASS= SMTP_FROM= -SMTP_FROM_NAME=IMVS +SMTP_FROM_NAME=CoreCore SMTP_SECURE=tls diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..6267049 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,127 @@ +# AGENTS.md + +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. + +## 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 `@layer` system — 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 + +```bash +# 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 + +# 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/) + 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) + Support/ # Crypto, flash, guard, search, helpers +pages/ # 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/ # Layouts and partials + partials/ # Reusable UI components + emails/ # Email HTML templates + pdfs/ # PDF templates (Dompdf) +config/ # App config (routes, assets, settings cache, themes) +web/ # Document root (entry point, CSS, JS, static assets) + js/core/ # DOM utilities, Grid.js factory + js/components/ # Reusable UI components + css/ # Layered CSS (base → components → layout → pages) +storage/ # Uploaded files (branding/, imports/, tenants/, users/) +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 scripts (scheduler, doctor.php health check) +tools/ # Dev tooling scripts +docker/ # Dockerfiles, Nginx configs, PHP configs +``` + +## Architecture Rules + +### Strict Layering (enforce in all changes) + +1. **App** (`lib/App/`): DI container bootstrap. Registers all service/repository factories. No business logic. +2. **Repository** (`lib/Repository/`): All SQL lives here. No HTTP, session, or rendering. +3. **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 inside `lib/Service/` that may call `new` on services/gateways/repositories. Registers via DI container. + - **Policy** (`*Policy.php` in `lib/Service/Access/`): Authorization decisions per resource type. Returns `AuthorizationDecision`. No HTTP, no business logic. +4. **Action** (`pages/**/*.php`): Reads input, checks permissions + tenant scope, calls services, sets view vars. +5. **View** (`pages/**/*.phtml`): Pure rendering. **No DB calls.** HTML escaping via `e(...)`. +6. **Template** (`templates/`): Layouts and partials. + +### Routing + +- File-based: `pages/admin/users/edit($id).php` → URL parameter `id` +- `...(none).phtml` → no template layout +- `data().php` suffix → data/AJAX endpoints +- Named aliases in `config/routes.php` with `public` flag for auth guard + +### PHP Conventions + +- PSR-4 autoload: `MintyPHP\` → `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.php` file 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` | optional `Danger 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 `settings` DB table (single source of truth); `config/settings.php` is a partial file cache for hot-path UI reads only + +## Quality Gates + +- **PHPStan level 5** — scans `config/`, `lib/`, `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.example` for dev, `.env.prod.example` for prod +- `config/config.php` (gitignored) — copy from `config/config.php.example` +- `APP_CRYPTO_KEY` (64-char hex) needed for AES-256-GCM encryption of SSO secrets diff --git a/CLAUDE.md b/CLAUDE.md index 97ce2e9..843a925 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,4 +1,4 @@ -# CLAUDE.md — IMVS (ImmobilienMaklerVerkaufssoftware) +# CLAUDE.md — CoreCore (ImmobilienMaklerVerkaufssoftware) 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. diff --git a/README.md b/README.md index de3efc2..4d8190e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# IMVS (MintyPHP) +# CoreCore (MintyPHP) -IMVS ist eine mandantenfaehige Admin-Anwendung auf Basis von MintyPHP. +CoreCore ist eine mandantenfaehige Admin-Anwendung auf Basis von MintyPHP. Der Fokus liegt auf klarer Rollen-/Rechtestruktur, Tenant-Scope und einer konsistenten Admin-UI. ## Funktionsumfang diff --git a/config/config.php.example b/config/config.php.example index 92105d3..0faa294 100644 --- a/config/config.php.example +++ b/config/config.php.example @@ -55,7 +55,7 @@ $envList = static function (string $key, array $default): array { return array_values(array_filter(array_map('trim', explode(',', (string) $value)))); }; -define('APP_NAME', $envString('APP_NAME', 'IMVS')); +define('APP_NAME', $envString('APP_NAME', 'CoreCore')); define('APP_TIMEZONE', $envString('APP_TIMEZONE', 'Europe/Berlin')); define('APP_STORAGE_PATH', $envString('APP_STORAGE_PATH', __DIR__ . '/../storage')); define('APP_CRYPTO_KEY', $envString('APP_CRYPTO_KEY', '')); diff --git a/docs/reference-konfiguration.md b/docs/reference-konfiguration.md index 0ccc8ea..967de3a 100644 --- a/docs/reference-konfiguration.md +++ b/docs/reference-konfiguration.md @@ -47,10 +47,10 @@ Vorlage: `.env.example` — niemals echte Credentials committen. |---|---|---| | `DB_HOST` | `db` | Hostname des MySQL/MariaDB-Servers (Docker-Service-Name oder IP) | | `DB_PORT` | `3306` | Port des Datenbankservers | -| `DB_NAME` | `imvs` | Name der Datenbank | -| `DB_USER` | `imvs` | Datenbankbenutzer | -| `DB_PASS` | `imvs` | Passwort des Datenbankbenutzers | -| `DB_ROOT_PASSWORD` | `imvs_root` | Root-Passwort für Docker-Compose (wird nur vom DB-Container genutzt, nicht von PHP) | +| `DB_NAME` | `corecore` | Name der Datenbank | +| `DB_USER` | `corecore` | Datenbankbenutzer | +| `DB_PASS` | `corecore` | Passwort des Datenbankbenutzers | +| `DB_ROOT_PASSWORD` | `corecore_root` | Root-Passwort für Docker-Compose (wird nur vom DB-Container genutzt, nicht von PHP) | --- diff --git a/docs/tutorial-02-systemueberblick.md b/docs/tutorial-02-systemueberblick.md index 37503f2..b93f25d 100644 --- a/docs/tutorial-02-systemueberblick.md +++ b/docs/tutorial-02-systemueberblick.md @@ -6,9 +6,9 @@ Letzte Aktualisierung: 2026-03-06 In 10 Minuten verstehen, was die Software tut, wie sie aufgebaut ist und welche Kernprinzipien immer gelten. -## Was ist IMVS? +## Was ist CoreCore? -IMVS ist eine mandantenfähige Admin-Software für Immobilienmakler-Prozesse mit klarer Rollen-/Rechtestruktur. +CoreCore ist eine mandantenfähige Admin-Software für Immobilienmakler-Prozesse mit klarer Rollen-/Rechtestruktur. Kernmodule: diff --git a/lib/Service/Branding/BrandingFaviconService.php b/lib/Service/Branding/BrandingFaviconService.php index a017ac4..0cdb48d 100644 --- a/lib/Service/Branding/BrandingFaviconService.php +++ b/lib/Service/Branding/BrandingFaviconService.php @@ -134,7 +134,7 @@ class BrandingFaviconService $title = $this->settingsAppGateway->getAppTitle(); if ($title === null || $title === '') { - $title = defined('APP_NAME') ? APP_NAME : 'IMVS'; + $title = defined('APP_NAME') ? APP_NAME : 'CoreCore'; } $data['name'] = $title; diff --git a/lib/Support/helpers/app.php b/lib/Support/helpers/app.php index 934e510..0d2d80c 100644 --- a/lib/Support/helpers/app.php +++ b/lib/Support/helpers/app.php @@ -115,7 +115,7 @@ function lurl(string $path = ''): string */ function appTitle(): string { - $default = defined('APP_NAME') ? APP_NAME : 'IMVS'; + $default = defined('APP_NAME') ? APP_NAME : 'CoreCore'; $title = appSetting('app_title'); if ($title !== null) { return $title; diff --git a/phpunit.xml b/phpunit.xml index 2f81b59..963e73e 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -4,7 +4,7 @@ bootstrap="tests/bootstrap.php" colors="true"> - + tests diff --git a/tests/App/Bootstrap/EnvValidatorTest.php b/tests/App/Bootstrap/EnvValidatorTest.php index 428ec91..5d5c9a9 100644 --- a/tests/App/Bootstrap/EnvValidatorTest.php +++ b/tests/App/Bootstrap/EnvValidatorTest.php @@ -122,7 +122,7 @@ final class EnvValidatorTest extends TestCase $storagePath = sys_get_temp_dir(); return array_merge([ - 'APP_NAME' => 'IMVS', + 'APP_NAME' => 'CoreCore', 'APP_ENV' => 'dev', 'APP_DEBUG' => 'true', 'APP_TIMEZONE' => 'Europe/Berlin', @@ -132,13 +132,13 @@ final class EnvValidatorTest extends TestCase 'APP_I18N_DOMAIN' => 'default', 'APP_URL' => 'http://localhost:8080', 'APP_CRYPTO_KEY' => '', - 'SESSION_NAME' => 'IMVS', + 'SESSION_NAME' => 'CoreCore', 'TENANT_SCOPE_STRICT' => 'true', 'DB_HOST' => 'db', 'DB_PORT' => '3306', - 'DB_NAME' => 'imvs', - 'DB_USER' => 'imvs', - 'DB_PASS' => 'imvs', + 'DB_NAME' => 'corecore', + 'DB_USER' => 'corecore', + 'DB_PASS' => 'corecore', 'CACHE_SERVERS' => 'memcached:11211', 'FIREWALL_CONCURRENCY' => '10', 'FIREWALL_SPINLOCK_SECONDS' => '0.15', diff --git a/web/favicon/site.webmanifest b/web/favicon/site.webmanifest index 2a08603..bebdeb3 100644 --- a/web/favicon/site.webmanifest +++ b/web/favicon/site.webmanifest @@ -1,6 +1,6 @@ { - "name": "IVMS", - "short_name": "IVMS", + "name": "CoreCore", + "short_name": "CC", "icons": [ { "src": "/favicon/web-app-manifest-192x192.png",