From 0c78dc4355bfa6da54585c03730ba50c719f1204 Mon Sep 17 00:00:00 2001 From: fs Date: Wed, 29 Apr 2026 08:37:45 +0200 Subject: [PATCH] chore(setup): track config.php directly, slim README to setup checklist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit config/config.php was gitignored and devs had to copy it from config/config.php.example on every fresh clone. Since the bootstrap config reads everything from .env via $envString() / $envInt() / $envBool() defaults, there is nothing developer-specific in the file — the cp step was dead ceremony. - Remove config/config.php from .gitignore and track it directly - Delete config/config.php.example - Drop the example-existence + per-doc reference checks from bin/docs-drift-check.sh; add a legacy-pattern check that flags any new mention of the removed example file - Update ConfigContractsTest to require config.php and forbid the example - Clean stale references in CLAUDE.md, README.md, six docs files, and the core-guardrails skill Same commit slims README down from 294 to 47 lines: one setup checklist (now 3 commands instead of 4), the seeded login table, the three quality-gate commands, and pointers to CLAUDE.md and docs/index.md for everything else. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../references/quality-gates.md | 1 - .gitignore | 1 - CLAUDE.md | 3 +- README.md | 316 ++---------------- bin/docs-drift-check.sh | 21 +- config/{config.php.example => config.php} | 0 docs/howto-docker-lokal.md | 12 +- docs/howto-lokale-entwicklung.md | 10 - docs/reference-cli-commands.md | 2 - docs/reference-konfiguration.md | 2 +- docs/tutorial-01-erste-schritte.md | 2 - docs/tutorial-03-setup-und-erster-login.md | 1 - tests/Architecture/ConfigContractsTest.php | 7 +- 13 files changed, 47 insertions(+), 331 deletions(-) rename config/{config.php.example => config.php} (100%) diff --git a/.agents/skills/core-guardrails/references/quality-gates.md b/.agents/skills/core-guardrails/references/quality-gates.md index ecf0456..ff543c9 100644 --- a/.agents/skills/core-guardrails/references/quality-gates.md +++ b/.agents/skills/core-guardrails/references/quality-gates.md @@ -39,7 +39,6 @@ Erwartung: jeweils `0`. - `.agents/runs/**` ist standardmaessig ausgeschlossen (historische Artefakte) 2. `bin/docs-drift-check.sh` - prueft bekannte Legacy-Drifts (entfernte Config-Pfade/Constants, obsolete Search-Marker) - - prueft Setup-Vertrag fuer `config/config.php.example` in den Kern-Onboarding-Dokus 3. `bin/codex-skills-sync.sh --check` - prueft Drift zwischen Repo-Skills und `~/.codex/skills` diff --git a/.gitignore b/.gitignore index 0081e78..df08c0a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ composer.phar /vendor/ # Secrets / local config -config/config.php .env # Agent workflow runs (ephemeral artifacts) diff --git a/CLAUDE.md b/CLAUDE.md index 8c7d6c8..42492b9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,7 +26,6 @@ Full workflow definition: `.agents/workflow.md` | Guard catalog: `.agents/checks ```bash # Start dev environment -cp config/config.php.example config/config.php docker compose up --build -d # App: http://localhost:8080 | phpMyAdmin: http://localhost:8081 @@ -251,5 +250,5 @@ Additional non-blocking gates: QG-004 structural checks, QG-005 JS smoke, QG-007 ## 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` +- `config/config.php` is tracked; all environment-specific values come from `.env` via `$envString()` defaults — edit only when adding new bootstrap settings - `APP_CRYPTO_KEY` (64-char hex) needed for AES-256-GCM encryption of SSO secrets diff --git a/README.md b/README.md index df410d9..73cef37 100644 --- a/README.md +++ b/README.md @@ -1,293 +1,51 @@ -# CoreCore (MintyPHP) +# CoreCore -CoreCore ist eine mandantenfaehige Admin-Anwendung auf Basis von MintyPHP. -Der Fokus liegt auf klarer Rollen-/Rechtestruktur, Tenant-Scope und einer konsistenten Admin-UI. +Mandantenfaehige Admin-Anwendung auf MintyPHP (PHP 8.5, MariaDB 11, Nginx, Memcached, Docker). +Liefert Tenants, User, Rollen, Adressbuch, Mail, Scheduler, Microsoft SSO und ein Helpdesk-Modul mit Business-Central-Anbindung. -## Funktionsumfang - -- Mandantenverwaltung (inkl. Branding/Farbe/Favicon) -- Abteilungen pro Mandant -- Benutzerverwaltung mit Rollen, Sichtbarkeit und Stammdaten -- Rollen- und Berechtigungsverwaltung -- Adressbuch (tenant-scoped, read-only Profilansicht) -- Globale Suche (Admin + Address Book) -- Mail-Versand (SMTP/PHPMailer) inkl. Mail-Log -- Onboarding-PDF fuer Zugangsdaten (Single inline, Bulk als ZIP) -- Passwort-Reset und Remember-Login-Tokens -- Geplante Aufgaben (Scheduler mit Ausfuehrungshistorie) - -## Tech Stack - -- PHP 8.5 (Runtime im Docker-Container) -- MintyPHP Core -- MariaDB 11 -- Memcached -- Nginx -- Grid.js (Tabellen) -- PHPMailer -- Dompdf (PDF Rendering) -- endroid/qr-code (QR-Code Rendering) - -## Webserver-Policy - -- Docker-Betrieb ist Nginx-only (Dev + Prod). -- Apache-/`.htaccess`-Regeln werden nicht ausgewertet und sind kein Teil des Laufzeit-Contracts. -- Routing und Front-Controller-Verhalten werden ausschliesslich in `/docker/nginx/default.conf` und `/docker/nginx/prod.conf` gepflegt. - -## Schnellstart (Docker) - -1. Umgebungsdatei anlegen +## Setup (frischer Clone) ```bash -cp .env.example .env +cp .env.example .env # 1. ENV (enthaelt APP_CRYPTO_KEY fuer Test-Secrets) +docker compose up --build -d # 2. Container starten + init.sql einspielen +docker compose exec php php bin/console module:sync # 3. Modul-Migrationen + Asset-Publish ``` -2. Config-Template fuer den App-Bootstrap anlegen +App: · phpMyAdmin: + +> `APP_CRYPTO_KEY` aus `.env.example` nicht aendern — sonst lassen sich die geseeded Microsoft-SSO- und BC-Test-Secrets nicht entschluesseln. + +### Login + +Alle Demo-User haben das Passwort `Demo123`: + +| E-Mail | Rolle | +|---|---| +| `demo@user.com` | Admin | +| `max@user.com` | Manager | +| `bernd@user.com` | User | +| `petra@user.com` | Auditor | +| `hilde@user.com` | Support | + +Plus der Live-User `fs@breadcrumb-solutions.de` (alle Rollen, Passwort nur per Reset). +Microsoft SSO ist fuer den Tenant `breadcrumb mediasolutions GmbH` vorkonfiguriert (Domain `breadcrumb-solutions.de`). + +## Quality Gates ```bash -cp config/config.php.example config/config.php +docker compose exec php vendor/bin/phpunit # Tests +docker compose exec php vendor/bin/phpstan analyse -c phpstan.neon # Static Analysis +docker compose exec php composer cs:fix # Code Style autofix ``` -3. Container starten +## Wo was steht -```bash -docker compose up --build -d -``` - -4. App oeffnen - -- App: [http://localhost:8080](http://localhost:8080) -- phpMyAdmin: [http://localhost:8081](http://localhost:8081) - -5. Container stoppen - -```bash -docker compose down -``` - -Alternativ ueber den Dev-Orchestrator: - -```bash -cp config/config.php.example config/config.php -bin/dev init -bin/dev up -bin/dev down -bin/dev console list -bin/dev qa -``` - -## Produktion (Docker) - -Es gibt eine getrennte Produktions-Compose: - -- Dev: `/docker-compose.yml` -- Prod: `/docker-compose.prod.yml` - -Grundschritte: - -1. `.env` auf Produktionswerte setzen (siehe `/.env.prod.example`) -2. Domain und TLS in `/docker/nginx/prod.conf` anpassen -3. Zertifikate unter `/docker/nginx/certs/` bereitstellen -4. Starten: - -```bash -docker compose -f docker-compose.prod.yml up --build -d -``` - -Details stehen in: - -- `/docs/howto-docker-lokal.md` -- `/docs/howto-docker-produktiv.md` -- `/docs/explanation-docker-betrieb.md` (Übersicht) - -## Seed-Daten - -Die Initialisierung liegt in `/db/init/init.sql`. - -Standard-Demo-User: - -- E-Mail: `demo@user.com` -- Passwort: `Demo123` -- Tenant: `MusterMandant` -- Abteilung: `Musterabteilung` -- Rollen: `Admin`, `User` - -Initiale DB-Settings (Seed): - -- `app_title` -> `CoreCore` -- `app_locale` -> `de` -- `app_theme` -> `light` -- `app_theme_user` -> `1` -- `app_registration` -> `1` (aktiv) -- `app_primary_color` -> `#105433` -- `api_token_default_ttl_days` -> `90` -- `api_token_max_ttl_days` -> `365` -- `api_cors_allowed_origins` -> `http://localhost:8080`, `http://127.0.0.1:8080` -- `session_idle_timeout_minutes` -> `30` -- `session_absolute_timeout_hours` -> `8` -- `user_inactivity_deactivate_days` -> `180` -- `user_inactivity_delete_days` -> `365` -- `default_tenant_id` -> `MusterMandant` -- `default_department_id` -> Abteilungscode `MUSTER` (`Musterabteilung`) -- `default_role_id` -> Rolle `USER` (`User`) -- `frontend_telemetry_enabled` -> `1` -- `frontend_telemetry_sample_rate` -> `0.2` -- `frontend_telemetry_allowed_events` -> `ajax_error,warn_once` - -## Projektstruktur - -- `/config` Konfiguration (Routen, Assets, Themes, Module + ENV-Bootstrap) -- `/db/init` Datenbankschema + Seeds -- `/lib` Backend-Code (`Repository`, `Service`, `Http`, `Support`) -- `/pages` Action-Layer + Views pro Route -- `/templates` Layouts + wiederverwendbare Partials -- `/web` oeffentliche Assets (CSS/JS/Vendor) -- `/i18n` Uebersetzungen -- `/tests` PHPUnit-Tests -- `/docs` Projekt-Dokumentation - -## Architektur-Kurzregeln - -- Keine DB-Zugriffe in `.phtml`-Views. -- SQL bleibt in Repositories. -- Geschaeftslogik bleibt in Services. -- `pages/.../*.php` fungiert als Action-/Controller-Schicht. -- Service-Aufloesung in Actions/Helpern ueber `app(Foo::class)`. -- `new ...Factory()` nur im Composition Root (`web/index.php` + `core/App/registerContainer.php`) oder in `*Factory.php`. -- `pages/**/data().php` sind GET-only (`gridRequireGetRequest()`) und normalisieren `limit`/`offset`/`order`/`dir` ueber Grid-Helper. -- Permissions + Tenant-Scope werden in Actions/Services erzwungen. -- Wiederkehrende UI-Bloecke als Partials zentralisieren. - -## UI-Konventionen - -Edit-Seiten verwenden einheitliche Tab-Struktur: - -- erster Tab: `Master data` -- letzter Tab: `Visibility` -- optional letzter Tab: `Danger zone` - -User-Organisation: - -- Departments werden tenantweise angezeigt (ein Multi-Select je ausgewaehltem Tenant). -- Nach Tenant-Aenderungen im selben Formular werden Department-Optionen nach Speichern/Reload aktualisiert (kein Live-Update). - -Zentrale Partials: - -- `/templates/partials/app-details-titlebar.phtml` -- `/templates/partials/app-visibility-status-field.phtml` -- `/templates/partials/app-danger-zone-delete-field.phtml` -- `/templates/partials/app-details-aside-audit.phtml` -- `/templates/partials/app-details-aside-ids.phtml` - -## Onboarding-PDF (User) - -- Permission: `users.access_pdf` -- Single: `admin/users/access-pdf/{uuid}` (inline im neuen Tab) -- Bulk: `admin/users/access-pdf-bulk` (POST, ZIP mit einer PDF pro User) -- Hard limit: maximal 100 User pro Bulk-Request -- Benoetigte Extensions: `ext-zip`, `ext-dom`, `ext-mbstring` -- Bestehende Installationen: Schema-/Permission-Updates als idempotentes SQL-Update ausfuehren - -## Microsoft SSO (Tenant, Entra ID) - -- Zentraler Einstieg: `login` (optional mit Tenant-Hint `login?tenant={tenant-slug}`) -- OIDC-Endpunkte: `auth/microsoft/start` und `auth/microsoft/callback` -- Tenant-Config liegt in `tenant_auth_microsoft` -- Externe User-Linkung liegt in `user_external_identities` -- Optionaler Profil-Sync pro Tenant: - - `sync_profile_on_login` aktiviert Sync bei jedem Microsoft-Login - - `sync_profile_fields`: `first_name`, `last_name`, `phone`, `mobile`, `avatar` - - Default-Felder bei aktivem Sync ohne Auswahl: `first_name,last_name` - - `phone/mobile/avatar` nutzen Microsoft Graph (`User.Read`) -- Shared App Credentials werden in Settings gepflegt (optional Tenant-Overrides) -- Permission fuer Tenant-SSO-Konfiguration: `tenants.sso_manage` -- Bestandsinstallationen: Schema-/Permission-Updates als idempotentes SQL-Update ausfuehren -- Wichtig: `APP_CRYPTO_KEY` in `.env` setzen, sonst koennen SSO-Secrets nicht gespeichert/verwendet werden - -## Asset- und Frontend-System - -- Core-CSS-Entrypoint: `/web/css/core.css` -- CSS-Layer/Vendor-Basis: `/web/css/app-layers.css` -- Vendor-Overrides: `/web/css/vendor-overrides` -- Asset-Gruppen: `/config/assets.php` -- Template-Styles: `renderTemplateStyles('default'|'login')` -- Seiten-Styles per Action: `Buffer::set('style_groups', ...)` -- CSS-Contract-Check: `bin/css-contract-check.sh` -- JS-Bootstrap: - - `/web/js/app-boot.js` (frueh, ohne Module) - - `/web/js/app-init.js` (Standardseiten) - - `/web/js/app-login-init.js` (Loginseiten) - -## Qualitaetschecks - -Alle Befehle aus dem Projekt-Root ausfuehren. - -### PHPUnit - -```bash -docker compose exec php vendor/bin/phpunit --bootstrap vendor/autoload.php -``` - -Gezielt: - -```bash -docker compose exec php vendor/bin/phpunit --bootstrap vendor/autoload.php tests/I18n/TranslationKeysTest.php -docker compose exec php vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Repository/RepoQueryTest.php -``` - -### PHPStan - -```bash -docker compose exec php vendor/bin/phpstan analyse -c phpstan.neon --no-progress -``` - -### Coding Style (PHP CS Fixer) - -CI-Check (ohne Dateien zu aendern): - -```bash -docker compose exec php vendor/bin/php-cs-fixer fix --config=tools/php-cs-fixer/.php-cs-fixer.dist.php --dry-run --diff --verbose -``` - -Lokal automatisch formatieren: - -```bash -docker compose exec php composer cs:fix -``` - -### Frontend-JS Smoke-Check (ohne Node) - -- Browser-DevTools öffnen (Console + Preserve log) -- Kernflows klicken: Users, Address-Book, Audit-Listen, Filter setzen/zurücksetzen -- Keine JavaScript-Errors/Unhandled-Rejections in der Console - -## Dokumentation - -- `/docs/index.md` Dokumentationsstart mit chronologischem Lernpfad und Referenzbereichen -- `/docs/tutorial-02-systemueberblick.md` Einstieg in Produktbild und Kernprinzipien -- `/docs/tutorial-03-setup-und-erster-login.md` lokales Setup und erster Smoke-Test -- `/docs/reference-domain-glossar.md` zentrale Begriffe fuer Tenant/Role/Scope -- `/docs/tutorial-04-architektur-request-flow.md` Request-Flow und Schichtmodell -- `/docs/tutorial-07-security-tenant-scope.md` Security-Grundlagen vor Feature-Arbeit -- `/docs/tutorial-08-api-erweitern.md` verbindlicher API-Aenderungsablauf inkl. OpenAPI - -## Troubleshooting - -- Verhalten wirkt stale nach groesseren Refactors: - -```bash -docker compose restart php nginx -``` - -- Uebersetzungs-Keys fehlen: - -```bash -docker compose exec php vendor/bin/phpunit --bootstrap vendor/autoload.php tests/I18n/TranslationKeysTest.php -``` - -- Favicon/Logo aus Storage fehlt: - - Symlink und Tenant-Kontext pruefen (`web/favicon/tenants -> storage/tenants`). +- **Architektur, Konventionen, Guards** — `CLAUDE.md` +- **Tutorials, How-Tos, Referenzen** — `docs/index.md` +- **Production-Deployment** — `docs/howto-docker-produktiv.md` +- **Schema + Seed** — `db/init/init.sql`, idempotente Updates in `db/updates/` +- **Module** — `modules//` (eigene Migrationen unter `modules//migrations/`) ## Lizenz -MIT (siehe `/LICENSE.md`) +MIT (siehe `LICENSE.md`) diff --git a/bin/docs-drift-check.sh b/bin/docs-drift-check.sh index c4e6a20..a1b5657 100755 --- a/bin/docs-drift-check.sh +++ b/bin/docs-drift-check.sh @@ -27,26 +27,7 @@ check_legacy_pattern 'config/router\.php' 'Legacy docs reference to config/route check_legacy_pattern '\bAPP_ROUTE_DEFINITIONS\b' 'Legacy docs reference to APP_ROUTE_DEFINITIONS found' check_legacy_pattern '\bAPP_PUBLIC_PATHS\b' 'Legacy docs reference to APP_PUBLIC_PATHS found' check_legacy_pattern 'data-search-key' 'Legacy global-search aside marker (data-search-key) found' - -if [[ ! -f config/config.php.example ]]; then - echo "[FAIL] Missing setup template: config/config.php.example" - fail=1 -fi - -required_setup_docs=( - README.md - docs/howto-docker-lokal.md - docs/tutorial-01-erste-schritte.md - docs/tutorial-03-setup-und-erster-login.md - docs/howto-lokale-entwicklung.md -) - -for doc in "${required_setup_docs[@]}"; do - if ! rg -q 'config/config\.php\.example' "${doc}"; then - echo "[FAIL] Missing setup contract reference in ${doc}: config/config.php.example" - fail=1 - fi -done +check_legacy_pattern 'config/config\.php\.example' 'Legacy docs reference to config/config.php.example (file removed; config.php is now tracked)' if [[ ${fail} -ne 0 ]]; then echo "[FAIL] docs drift checks failed" diff --git a/config/config.php.example b/config/config.php similarity index 100% rename from config/config.php.example rename to config/config.php diff --git a/docs/howto-docker-lokal.md b/docs/howto-docker-lokal.md index 640ecce..0924e8d 100644 --- a/docs/howto-docker-lokal.md +++ b/docs/howto-docker-lokal.md @@ -20,23 +20,17 @@ Diese Anleitung bringt die Anwendung lokal schnell und stabil zum Laufen. cp .env.example .env ``` -2. Config-Template fuer den App-Bootstrap anlegen: - -```bash -cp config/config.php.example config/config.php -``` - -3. Container bauen und starten: +2. Container bauen und starten: ```bash docker compose up --build -d ``` -4. Anwendung öffnen: +3. Anwendung öffnen: - App: `http://localhost:8080` - phpMyAdmin: `http://localhost:8081` -5. Logs prüfen (optional): +4. Logs prüfen (optional): ```bash docker compose logs -f nginx php diff --git a/docs/howto-lokale-entwicklung.md b/docs/howto-lokale-entwicklung.md index bb5ea3e..51546b0 100644 --- a/docs/howto-lokale-entwicklung.md +++ b/docs/howto-lokale-entwicklung.md @@ -8,14 +8,6 @@ Kompakter Tagesworkflow für Entwicklung, Tests und schema-nahe Änderungen. ## First-Time Workflow -Einmalig vor dem ersten Start: - -```bash -cp config/config.php.example config/config.php -``` - -Dann: - ```bash bin/dev init ``` @@ -27,8 +19,6 @@ bin/dev init 3. `module:sync` 4. `doctor` -Hinweis: `bin/dev init` erzeugt aktuell **nicht** automatisch `config/config.php`. - ## Start/Stop ```bash diff --git a/docs/reference-cli-commands.md b/docs/reference-cli-commands.md index c421cf9..3ee8c5c 100644 --- a/docs/reference-cli-commands.md +++ b/docs/reference-cli-commands.md @@ -147,8 +147,6 @@ bin/dev qa-required bin/dev qa-extended ``` -Voraussetzung fuer den ersten App-Start: `config/config.php` muss vorhanden sein (einmalig aus `config/config.php.example` kopieren). - `bin/dev console ...` delegiert intern auf `docker compose exec -T php php bin/console ...`. `bin/dev qa` ist ein Alias fuer `bin/dev qa-required`. diff --git a/docs/reference-konfiguration.md b/docs/reference-konfiguration.md index 5e08b8c..911f38f 100644 --- a/docs/reference-konfiguration.md +++ b/docs/reference-konfiguration.md @@ -5,7 +5,7 @@ Letzte Aktualisierung: 2026-04-01 Alle Konfiguration erfolgt über Umgebungsvariablen in der `.env`-Datei. Vorlage: `.env.example` — niemals echte Credentials committen. -Setup-Vertrag (Source of Truth): Fuer den Boot wird `config/config.php` benoetigt; die Datei wird aus `config/config.php.example` abgeleitet. Diese Seite und `web/index.php` sind die massgeblichen Referenzen dafuer. +Setup-Vertrag (Source of Truth): `config/config.php` ist im Repository getrackt und liest alle Werte über `$envString()`/`$envInt()`/`$envBool()` aus den ENV-Variablen. Diese Seite und `web/index.php` sind die massgeblichen Referenzen dafuer. --- diff --git a/docs/tutorial-01-erste-schritte.md b/docs/tutorial-01-erste-schritte.md index fe20d94..034375b 100644 --- a/docs/tutorial-01-erste-schritte.md +++ b/docs/tutorial-01-erste-schritte.md @@ -16,12 +16,10 @@ Diese Seite bringt neue Entwickler in unter 45 Minuten zu einem lauffähigen lok ```bash cp .env.example .env -cp config/config.php.example config/config.php docker compose up --build -d ``` > Alle ENV-Variablen sind dokumentiert in /docs/reference-konfiguration.md. -> `config/config.php` ist Pflicht fuer den App-Bootstrap und wird einmalig aus `config/config.php.example` erzeugt. > docker compose up startet auch den globalen Scheduler-Runner (Service scheduler) im Hintergrund. Danach erreichbar: diff --git a/docs/tutorial-03-setup-und-erster-login.md b/docs/tutorial-03-setup-und-erster-login.md index 28ffdce..3cc1124 100644 --- a/docs/tutorial-03-setup-und-erster-login.md +++ b/docs/tutorial-03-setup-und-erster-login.md @@ -17,7 +17,6 @@ Lokal starten, einloggen, Basisfunktion prüfen. ```bash cp .env.example .env -cp config/config.php.example config/config.php docker compose up --build -d ``` diff --git a/tests/Architecture/ConfigContractsTest.php b/tests/Architecture/ConfigContractsTest.php index eb6e260..5f16b54 100644 --- a/tests/Architecture/ConfigContractsTest.php +++ b/tests/Architecture/ConfigContractsTest.php @@ -14,7 +14,7 @@ final class ConfigContractsTest extends TestCase 'config/assets.php', 'config/routes.php', 'config/modules.php', - 'config/config.php.example', + 'config/config.php', ]; foreach ($required as $file) { $this->assertFileExists($this->projectRootPath() . '/' . $file, 'Missing required config file: ' . $file); @@ -23,15 +23,16 @@ final class ConfigContractsTest extends TestCase $forbidden = [ 'config/router.php', 'config/settings.php', + 'config/config.php.example', ]; foreach ($forbidden as $file) { $this->assertFileDoesNotExist($this->projectRootPath() . '/' . $file, 'Forbidden runtime config file exists: ' . $file); } } - public function testConfigExampleDoesNotDefineLegacyRouteConstants(): void + public function testConfigDoesNotDefineLegacyRouteConstants(): void { - $content = $this->readProjectFile('config/config.php.example'); + $content = $this->readProjectFile('config/config.php'); $this->assertStringNotContainsString('APP_ROUTE_DEFINITIONS', $content); $this->assertStringNotContainsString('APP_PUBLIC_PATHS', $content);