feat(geschichte): bound title and JOURNEY intro at all three layers

Title: requireTitle() turns the VARCHAR(255) DB bound into a friendly 400
(GESCHICHTE_TITLE_TOO_LONG). JOURNEY intro: MAX_INTRO_LENGTH = 4000 in
bodyForType() plus a V75 CHECK as atomic backstop (defensive clamp first,
STORY bodies exempt) — GESCHICHTE_INTRO_TOO_LONG. Both codes wired through
ErrorCode.java, errors.ts, getErrorMessage and de/en/es. DB-layer boundary
pins added: exactly-2000 note insert (V74 CHECK) and 4000/4001 intro
inserts against real Postgres. Docs: error-code lists, db puml diagrams.

The matching maxlength attributes land with the component commits.

Review round 3: Markus (b), Nora (1), Sara (DB 2000 boundary).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-11 08:28:08 +02:00
parent 98805f596a
commit b9bed19610
14 changed files with 244 additions and 5 deletions

View File

@@ -357,7 +357,7 @@ package "Supporting" {
id : UUID <<PK>>
--
title : VARCHAR(255) NOT NULL
body : TEXT
body : TEXT CHECK (JOURNEY: length <= 4000)
status : VARCHAR(32) NOT NULL
type : VARCHAR(32) NOT NULL
author_id : UUID <<FK>>

View File

@@ -132,5 +132,6 @@ geschichten_persons }o--|| persons : person_id
journey_items }o--|| geschichten : geschichte_id (ON DELETE CASCADE)
journey_items }o--o| documents : document_id (ON DELETE SET NULL)
note right of journey_items : partial UNIQUE (geschichte_id, document_id)\nWHERE document_id IS NOT NULL (V74)
note right of geschichten : CHECK length(body) <= 4000\nfor type = JOURNEY (V75)
@enduml