Files
paliad/internal/db/migrations/160_user_name_compositions.down.sql
mAi 73f379d305 feat(submissions): per-user name-composition overrides, system→user precedence (t-paliad-356 Slice 3)
PRD §3. A user can now override the system-default name composition for an
artifact; rendering prefers a valid user override over the system default.
No UI yet (Slice 4) — overrides are settable via the service API + tests.

- Migration 160: users.name_compositions jsonb NOT NULL DEFAULT '{}' — a
  { artifact_id: Composition } map.
- NameCompositionSpec (internal/services/name_composition_spec.go): Validate
  (write: known artifact + segments reference the artifact's catalog vars)
  and SanitizeForRead (read: drop unknown artifacts, drop segments with
  unknown vars, clamp version) — mirrors DashboardLayoutSpec. Plus
  nomen.Composition.SanitizeForRead and lowercase JSON tags on the nomen
  types so the stored shape is stable.
- Resolution: resolveComposition(artifact, overrides) returns the user
  override when present + valid, else the system default. The firm slot
  (PRD §3.1) is reserved for Slice 5 — system is the fallback below user
  here. Wired into BOTH artifacts: the draft-title via the create path
  (newDraftName → autoNameFor{Project,NonProject}) and the .docx filename
  via RenderSubmissionFilenameFor in the three download handlers.
  AutoSubmissionTitle / RenderSubmissionFilename stay as the nil-override
  (system-default) references the #155/354 matrices pin.
- Per-document keyword override generalised: writes now land at
  composer_meta.name_overrides.keyword (the general {var:value} shape);
  reads honour both that and the legacy composer_meta.filename_keyword
  (back-compat). The read moved to services.SubmissionFilenameKeyword
  (handlers delegate) so it is live-testable.

BACK-COMPAT FINDING: the one shipped filename_keyword row needs no data
migration — the read resolves legacy composer_meta.filename_keyword as
name_overrides.keyword. Verified by a live round-trip (seed legacy jsonb →
Get → SubmissionFilenameKeyword == the legacy value).

Verified (TEST_DATABASE_URL): (a) name_compositions Set/Get round-trip +
write-time Validate rejection of an out-of-catalog variable; (b) a user
override beats the system default for the title (through Create:
'Klageerwiderung <date>' vs default '<date> Klageerwiderung') and the
filename (through RenderSubmissionFilenameFor), with the nil-override
default unchanged; (c) legacy filename_keyword back-compat read. Plus unit
tests for nomen.SanitizeForRead, NameCompositionSpec Validate/Sanitize/
resolve, and the keyword back-compat read. go vet + go test ./... (15
pkgs) + bun build clean. No Playwright (no UI this slice).
2026-06-01 12:20:19 +02:00

3 lines
70 B
SQL

ALTER TABLE paliad.users
DROP COLUMN IF EXISTS name_compositions;