ops: Lokale Datenbank gegen fremde Testläufe absichern — DB_* nicht mehr als Container-Umgebung, Agenten-Regel, Testdatenbank-Pflicht im Baukasten
Am 07.10.2026 hat das RefreshDatabase eines frischen Demo-Projekts (Test der Vorlagen aus dev/git-deploy-monitoring) die lokale Datenbank `pressekonto` auf global-mysql vollständig geleert (Binärlog binlog.000009, Pos. 566161486). Ursache: docker-compose.yml setzte DB_* als Container-Umgebungsvariablen, die in Laravel Vorrang vor jeder .env haben; die phpunit.xml des Demo-Projekts erzwang kein SQLite. Die eigene Suite war nicht beteiligt (force="true" und Guard in tests/TestCase.php greifen; Gegenprobe mit MySQL-Variablen grün). - docker-compose.yml: DB_* entfernt (Werte identisch in .env), wirksam nach Neuerstellen des Containers. - Baukasten: „Testdatenbank absichern" (phpunit.xml mit force, Guard, Gegenprobe) als Pflicht vor RefreshDatabase. - .ai/rules/general.md und CLAUDE.md: fremde/frische Laravel-Projekte nur mit SQLite :memory: testen; migrate hier erst nach migrate:status. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
32e1349517
commit
fd8dd74d5f
6 changed files with 81 additions and 9 deletions
|
|
@ -150,6 +150,50 @@ glitchtip“), `ErrorSignalsTest.php`, `BrowserErrorReportingTest.php`,
|
|||
Die Tests setzen `RefreshDatabase` voraus (in `tests/Pest.php` aktivieren) und
|
||||
eine `User`-Factory.
|
||||
|
||||
### Testdatenbank absichern (vor `RefreshDatabase`!)
|
||||
|
||||
`RefreshDatabase` führt `migrate:fresh` aus und **löscht alle Tabellen** der
|
||||
Datenbank, auf die die Tests zeigen. In einer frischen Laravel-Installation
|
||||
sind die SQLite-Zeilen in `phpunit.xml` auskommentiert, und ohne `force="true"`
|
||||
haben vorhandene Umgebungsvariablen (Docker-/Container-`environment`, CI) Vorrang
|
||||
vor `phpunit.xml` und `.env`. So hat am 07.10.2026 das Testen dieser Vorlagen
|
||||
in einem Demo-Projekt die lokale Datenbank eines anderen Projekts geleert, das
|
||||
im selben Container lief.
|
||||
|
||||
`phpunit.xml`, im `<php>`-Block:
|
||||
|
||||
```xml
|
||||
<env name="DB_CONNECTION" value="sqlite" force="true"/>
|
||||
<env name="DB_DATABASE" value=":memory:" force="true"/>
|
||||
<env name="DB_URL" value="" force="true"/>
|
||||
<server name="DB_CONNECTION" value="sqlite" force="true"/>
|
||||
<server name="DB_DATABASE" value=":memory:" force="true"/>
|
||||
<server name="DB_URL" value="" force="true"/>
|
||||
```
|
||||
|
||||
Guard in `tests/TestCase.php` — `setUpTraits()` läuft vor jedem
|
||||
Datenbank-Trait und bricht ab, bevor etwas geleert wird (auch bei einem
|
||||
gecachten `bootstrap/cache/config.php`):
|
||||
|
||||
```php
|
||||
protected function setUpTraits(): array
|
||||
{
|
||||
$default = (string) \Illuminate\Support\Facades\DB::getDefaultConnection();
|
||||
$connection = (array) config('database.connections.'.$default, []);
|
||||
|
||||
if (! empty($connection['url'])
|
||||
|| ($connection['driver'] ?? null) !== 'sqlite'
|
||||
|| ($connection['database'] ?? null) !== ':memory:') {
|
||||
throw new \RuntimeException("Tests laufen nicht gegen SQLite :memory: ({$default}) — abgebrochen, bevor RefreshDatabase etwas leert.");
|
||||
}
|
||||
|
||||
return parent::setUpTraits();
|
||||
}
|
||||
```
|
||||
|
||||
Wer Vorlagen in einem Wegwerf-Projekt ausprobiert, startet die Tests
|
||||
zusätzlich explizit mit `DB_CONNECTION=sqlite DB_DATABASE=:memory: php artisan test`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Regeln für den Code
|
||||
|
|
|
|||
|
|
@ -32,7 +32,13 @@ Platzhalter: `meineapp` (Projektname), `meineapp.de` (Live-Domain),
|
|||
- [ ] `AppServiceProvider::boot()`: `Queue::failing` → `OperationalAlert`, `AboutCommand::add`
|
||||
- [ ] Vite-Eingang `resources/js/error-reporting.js`; `<x-monitoring.browser-errors build="build" area="…" />` in jedem Layout-`<head>`
|
||||
- [ ] Basic Auth / `trustHosts`: `/health` ausgenommen bzw. erreichbar
|
||||
- [ ] `phpunit.xml`: Sentry-DSNs leer (`force="true"`); `tests/Pest.php` mit `RefreshDatabase`
|
||||
- [ ] **Vor** `RefreshDatabase`: Testdatenbank absichern (02 §5, „Testdatenbank absichern“):
|
||||
`phpunit.xml` mit SQLite `:memory:` **und `force="true"`** (`DB_CONNECTION`, `DB_DATABASE`, `DB_URL` leer;
|
||||
je als `<env>` und `<server>`), dazu der Guard in `tests/TestCase.php`. Eine frische Laravel-Installation
|
||||
hat diese Zeilen nur auskommentiert — ohne `force` gewinnen vorhandene Umgebungsvariablen.
|
||||
- [ ] Gegenprobe: `DB_CONNECTION=mysql DB_DATABASE=gibtsnicht php artisan test` muss trotzdem grün laufen
|
||||
(bzw. der Guard laut abbrechen) — nie eine echte Datenbank leeren
|
||||
- [ ] `phpunit.xml`: Sentry-DSNs leer (`force="true"`); danach `tests/Pest.php` mit `RefreshDatabase`
|
||||
- [ ] `.env.example` um `vorlagen/env-beispiel.env` ergänzt
|
||||
- [ ] Tests grün: `php artisan test --compact tests/Feature/Monitoring tests/Unit/Monitoring` (30 Tests)
|
||||
- [ ] Datenschutzerklärung: Fehlerprotokollierung (Kategorien, Frist, Rechtsgrundlage)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue