# Core Boundaries (MUST / MUST NOT) ## Schichtgrenzen 1. MUST SQL nur in `core/Repository/**` halten. 2. MUST Business-Logik in `core/Service/**` halten. 3. MUST `pages/**` auf Input, Auth/AuthZ, Orchestrierung, Response begrenzen. 4. MUST NOT Business- oder Permission-Logik in `templates/**` legen. ## Instanziierung 1. MUST in Actions/Helpern/Templates nur `app(Foo::class)` verwenden. 2. MUST NOT in `pages/**` direkt `new ...Service|Gateway|Repository` nutzen. 3. MUST NOT in `core/Service/**` (ausser `*Factory.php`) direkt `new ...Factory|Service|Gateway|Repository` nutzen. 4. MUST NOT in `pages/admin/**` `Factory::class` referenzieren oder `app(...Factory::class)->create...` nutzen. ## Input / Validation 1. MUST Input in `pages/**` ueber `requestInput()` lesen. 2. MUST NOT `$_POST`, `$_GET`, `$_FILES`, `REQUEST_METHOD` in `pages/**` verwenden. 3. MUST NOT `$_SESSION`, `$_SERVER`, `$_COOKIE`, `$_ENV` in `pages/**` direkt verwenden. 4. MUST Form-Validation ueber `FormErrors` fuehren. 5. MUST API-Validation-Fehler ueber `ApiResponse::validationFromFormErrors(...)` ausgeben. 6. MUST NOT `ApiResponse::readJsonBody(...)` in `pages/api/v1/**` verwenden. ## List-Data Endpoints 1. MUST `pages/**/data().php` als GET-only Endpunkte umsetzen (`gridRequireGetRequest()`). 2. MUST Query-Filter ueber `gridParseFilters(...)` + `filter-schema.php` normalisieren. 3. MUST NOT Query-Filter inline/parallele Alias-Parser in `data().php` neu einfuehren. ## Security / API 1. MUST AuthZ serverseitig erzwingen. 2. MUST Tenant-Scope serverseitig erzwingen. 3. MUST CSRF auf POST-Endpunkten vor Body-Verarbeitung verifizieren. 4. MUST NOT PII/Secrets unredacted in Logs oder Audit-Metadata schreiben. 5. MUST SQL nur ueber Repository mit prepared statements ausfuehren. 6. MUST extern UUID-first bleiben. 7. MUST API-Fehler konsistent halten (`error`, optional `errors`). 8. MUST OpenAPI im selben Merge aktualisieren, wenn API geaendert wird. ## Pruef-Hinweis - Harte Repo-Gates: `tests/Architecture/CoreStarterkitContractTest.php`