fix: Produktions-Crash durch TypeORM-synchronize beheben
Build and Push Multi-Platform Images / build-and-push (push) Successful in 44s

NODE_ENV=production deaktiviert synchronize (zerstörerischer ADD/DROP-COLUMN-
Churn auf MariaDB, der die 8126-Byte-Zeilengröße sprengte) und aktiviert
migrationsRun. Neue data-source.ts als einzige Konfigquelle (Laufzeit + CLI),
Migrations-Workflow (generate/run/revert) inkl. dotenv ergänzt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 09:27:04 +02:00
parent ed57477324
commit 41eed1871e
8 changed files with 143 additions and 72 deletions
+27 -1
View File
@@ -78,11 +78,37 @@ Use `@Public()` to bypass auth guards entirely.
### Database
- TypeORM with MySQL 8+, UTF8MB4, `synchronize: true` (schema auto-migrates)
- TypeORM with MySQL/MariaDB, UTF8MB4
- Connection config lives in `src/database/data-source.ts` (single source of truth,
shared by the NestJS runtime and the TypeORM CLI). `database.module.ts` consumes it.
- **Schema strategy depends on `NODE_ENV`:**
- Dev (`NODE_ENV` unset): `synchronize: true` — schema auto-migrates from entities.
- Production (`NODE_ENV=production`): `synchronize: false` + `migrationsRun: true`
pending migrations in `src/database/migrations/` are applied automatically on boot.
**Never run `synchronize` against the production DB** — on MariaDB it issues
destructive `ADD`/`DROP COLUMN` churn every boot (see caveat below).
- 23 entities in `src/database/entities/`
- JSON columns use transformers to normalize empty arrays/objects to `null`
- Key entities: `InboxDocument`, `Task`, `Email`, `Attachment`, `Postprocessing`, `BarcodeTemplate`, `LabelPrintJob`, `ApiKey`, `Setting`
#### Migrations workflow
```bash
npm run migration:generate -- src/database/migrations/<Name> # diff entities → DB
npm run migration:run # apply pending
npm run migration:revert # roll back last
```
The existing production schema is the implicit baseline (no baseline migration); only
future changes get migration files.
**Caveat — MariaDB reports `json` as `longtext`:** every `@Column({ type: 'json' })`
is stored as `longtext ... CHECK (json_valid(...))`, so `migration:generate` always
emits spurious no-op `CHANGE` statements (json↔longtext, nullable/default re-declares).
**Hand-trim generated migrations** down to the real change before committing. (This same
false diff is exactly why `synchronize` must stay off in production — left unchecked it
accumulates `ALGORITHM=INSTANT` drops until a table trips the 8126-byte row-size limit.)
### Document Processing Pipeline
**Preprocessing** (`preprocessing/document-pipeline.service.ts`):