diff --git a/internal/db/migrations/075_project_events_timeline_kind.down.sql b/internal/db/migrations/075_project_events_timeline_kind.down.sql new file mode 100644 index 0000000..eb93921 --- /dev/null +++ b/internal/db/migrations/075_project_events_timeline_kind.down.sql @@ -0,0 +1,6 @@ +-- t-paliad-171 down — drop the SmartTimeline opt-in column. + +DROP INDEX IF EXISTS paliad.project_events_timeline_kind_idx; + +ALTER TABLE paliad.project_events + DROP COLUMN IF EXISTS timeline_kind; diff --git a/internal/db/migrations/075_project_events_timeline_kind.up.sql b/internal/db/migrations/075_project_events_timeline_kind.up.sql new file mode 100644 index 0000000..4cfd5eb --- /dev/null +++ b/internal/db/migrations/075_project_events_timeline_kind.up.sql @@ -0,0 +1,32 @@ +-- 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;