-- t-paliad-171 — SmartTimeline Slice 1. -- Add the `timeline_kind` opt-in column to paliad.project_events so a -- subset of audit rows can surface as timeline content. Existing rows -- stay NULL (audit-only) and are filtered out of the SmartTimeline -- read path; new write paths (custom milestone, counterclaim_created -- in later slices) set the column on insert. -- -- Value space (enforced in code, not via CHECK — see -- internal/services/projection_service.go): -- 'milestone' — structural event worth pinning to the timeline -- (counterclaim_filed, third_party_intervened, -- party_amendment, our_side_changed, scope_change) -- 'custom_milestone' — free-text user-added event ("Eigener Meilenstein") -- NULL — audit only (default, all existing rows) -- -- Design ref: docs/design-smart-timeline-2026-05-08.md §2.2. ALTER TABLE paliad.project_events ADD COLUMN IF NOT EXISTS timeline_kind text NULL; COMMENT ON COLUMN paliad.project_events.timeline_kind IS 'When non-NULL, this audit event also surfaces as a SmartTimeline ' 'milestone. NULL keeps the row audit-only. See ' 'internal/services/projection_service.go for the value space.'; -- Partial index — the SmartTimeline read path filters on -- (project_id, timeline_kind IS NOT NULL); making the index partial -- keeps it tiny (most rows stay audit-only) while still serving the -- common lookup. CREATE INDEX IF NOT EXISTS project_events_timeline_kind_idx ON paliad.project_events (project_id, timeline_kind) WHERE timeline_kind IS NOT NULL;