Migrering 0005 samler kanban-kort, kalenderhendelser, faktoider og notater til én felles messages-tabell med view-config-tabeller. Actors og topics erstattes av unified entities-tabell. - 0005_meldingsboks.sql: messages utvides med title/pinned/visibility, kanban_card_view + calendar_event_view + message_reactions opprettes, entities erstatter actors+topics, gamle tabeller droppes - seed_dev.sql: oppdatert til meldingsboks-modell + 5 test-entiteter med graf-relasjoner - API-ruter: kanban/kalender/notater bruker messages + view-config - Dokumentasjon: meldingsboks feature-spec, oppdatert arkitektur, kunnskapsgraf, jobbkø, konseptdokumenter og proposals Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
258 lines
8.5 KiB
PL/PgSQL
258 lines
8.5 KiB
PL/PgSQL
-- Meldingsboks: Universell diskusjonsprimitiv
|
|
-- Erstatter separate tabeller for kanban-kort, kalenderhendelser, faktoider og notater.
|
|
-- Alle disse blir meldingsbokser (messages) med view-config-tabeller.
|
|
-- Se docs/features/meldingsboks.md for full spec.
|
|
--
|
|
-- Avhenger av: 0001, 0002, 0003, 0004
|
|
|
|
BEGIN;
|
|
|
|
-- ============================================================
|
|
-- 1. ALTER messages-tabellen
|
|
-- ============================================================
|
|
|
|
-- channel_id nullable (notater, standalone-bokser trenger ikke channel)
|
|
ALTER TABLE messages ALTER COLUMN channel_id DROP NOT NULL;
|
|
|
|
-- Nye kolonner
|
|
ALTER TABLE messages ADD COLUMN title TEXT;
|
|
ALTER TABLE messages ADD COLUMN pinned BOOLEAN NOT NULL DEFAULT false;
|
|
ALTER TABLE messages ADD COLUMN visibility TEXT NOT NULL DEFAULT 'workspace';
|
|
ALTER TABLE messages ADD COLUMN updated_at TIMESTAMPTZ NOT NULL DEFAULT now();
|
|
|
|
-- Indeks for reply_to (tråd-oppslag)
|
|
CREATE INDEX IF NOT EXISTS idx_messages_reply ON messages(reply_to) WHERE reply_to IS NOT NULL;
|
|
|
|
-- updated_at trigger
|
|
CREATE TRIGGER trg_messages_updated_at BEFORE UPDATE ON messages
|
|
FOR EACH ROW EXECUTE FUNCTION set_updated_at();
|
|
|
|
-- ============================================================
|
|
-- 2. View-config-tabeller
|
|
-- ============================================================
|
|
|
|
-- Kanban: view-metadata for meldingsbokser som vises som kort
|
|
CREATE TABLE kanban_card_view (
|
|
message_id UUID PRIMARY KEY REFERENCES messages(id) ON DELETE CASCADE,
|
|
column_id UUID NOT NULL REFERENCES kanban_columns(id) ON DELETE CASCADE,
|
|
position REAL NOT NULL DEFAULT 0,
|
|
color TEXT,
|
|
assignee_id TEXT REFERENCES users(authentik_id) ON DELETE SET NULL
|
|
);
|
|
|
|
CREATE INDEX idx_kanban_card_view_column ON kanban_card_view(column_id, position);
|
|
|
|
-- Kalender: view-metadata for meldingsbokser som vises som hendelser
|
|
CREATE TABLE calendar_event_view (
|
|
message_id UUID PRIMARY KEY REFERENCES messages(id) ON DELETE CASCADE,
|
|
calendar_id UUID NOT NULL REFERENCES calendars(id) ON DELETE CASCADE,
|
|
starts_at TIMESTAMPTZ NOT NULL,
|
|
ends_at TIMESTAMPTZ,
|
|
all_day BOOLEAN NOT NULL DEFAULT false,
|
|
color TEXT
|
|
);
|
|
|
|
CREATE INDEX idx_calendar_event_view_calendar ON calendar_event_view(calendar_id, starts_at);
|
|
|
|
-- ============================================================
|
|
-- 3. Migrer kanban_cards → messages + kanban_card_view
|
|
-- ============================================================
|
|
|
|
-- Oppdater node_type til 'melding'
|
|
UPDATE nodes SET node_type = 'melding'
|
|
WHERE id IN (SELECT id FROM kanban_cards);
|
|
|
|
-- Opprett meldingsbokser fra kanban-kort
|
|
INSERT INTO messages (id, channel_id, author_id, message_type, title, body, created_at, updated_at)
|
|
SELECT
|
|
kc.id,
|
|
NULL,
|
|
kc.created_by,
|
|
'text',
|
|
kc.title,
|
|
COALESCE(kc.description, ''),
|
|
kc.created_at,
|
|
kc.updated_at
|
|
FROM kanban_cards kc;
|
|
|
|
-- Opprett kanban view-config
|
|
INSERT INTO kanban_card_view (message_id, column_id, position, assignee_id)
|
|
SELECT
|
|
kc.id,
|
|
kc.column_id,
|
|
kc.position,
|
|
kc.assignee_id
|
|
FROM kanban_cards kc;
|
|
|
|
-- ============================================================
|
|
-- 4. Migrer calendar_events → messages + calendar_event_view
|
|
-- ============================================================
|
|
|
|
UPDATE nodes SET node_type = 'melding'
|
|
WHERE id IN (SELECT id FROM calendar_events);
|
|
|
|
INSERT INTO messages (id, channel_id, author_id, message_type, title, body, created_at, updated_at)
|
|
SELECT
|
|
ce.id,
|
|
NULL,
|
|
ce.created_by,
|
|
'text',
|
|
ce.title,
|
|
COALESCE(ce.description, ''),
|
|
ce.created_at,
|
|
ce.created_at
|
|
FROM calendar_events ce;
|
|
|
|
INSERT INTO calendar_event_view (message_id, calendar_id, starts_at, ends_at, all_day, color)
|
|
SELECT
|
|
ce.id,
|
|
ce.calendar_id,
|
|
ce.starts_at,
|
|
ce.ends_at,
|
|
ce.all_day,
|
|
ce.color
|
|
FROM calendar_events ce;
|
|
|
|
-- ============================================================
|
|
-- 5. Reaksjoner (erstatter message_votes og factoid_votes)
|
|
-- ============================================================
|
|
|
|
CREATE TABLE message_reactions (
|
|
message_id UUID NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
|
|
user_id TEXT NOT NULL REFERENCES users(authentik_id) ON DELETE CASCADE,
|
|
reaction TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (message_id, user_id, reaction)
|
|
);
|
|
|
|
-- Migrer eksisterende message_votes til reactions
|
|
INSERT INTO message_reactions (message_id, user_id, reaction, created_at)
|
|
SELECT
|
|
mv.message_id,
|
|
mv.user_id,
|
|
CASE WHEN mv.vote = 1 THEN 'upvote' ELSE 'downvote' END,
|
|
mv.created_at
|
|
FROM message_votes mv;
|
|
|
|
-- ============================================================
|
|
-- 6. Migrer factoids → messages
|
|
-- ============================================================
|
|
|
|
UPDATE nodes SET node_type = 'melding'
|
|
WHERE id IN (SELECT id FROM factoids);
|
|
|
|
INSERT INTO messages (id, channel_id, author_id, message_type, body, created_at, updated_at)
|
|
SELECT
|
|
f.id,
|
|
NULL,
|
|
f.created_by,
|
|
'factoid',
|
|
f.body,
|
|
f.created_at,
|
|
f.created_at
|
|
FROM factoids f;
|
|
|
|
-- Flytt factoid_votes til reactions
|
|
INSERT INTO message_reactions (message_id, user_id, reaction, created_at)
|
|
SELECT
|
|
fv.factoid_id,
|
|
fv.user_id,
|
|
CASE WHEN fv.vote = 1 THEN 'upvote' ELSE 'downvote' END,
|
|
fv.created_at
|
|
FROM factoid_votes fv
|
|
ON CONFLICT (message_id, user_id, reaction) DO NOTHING;
|
|
|
|
-- ============================================================
|
|
-- 7. Migrer notes → messages
|
|
-- ============================================================
|
|
|
|
UPDATE nodes SET node_type = 'melding'
|
|
WHERE id IN (SELECT id FROM notes);
|
|
|
|
INSERT INTO messages (id, channel_id, author_id, message_type, title, body, created_at, updated_at)
|
|
SELECT
|
|
n.id,
|
|
NULL,
|
|
n.created_by,
|
|
'text',
|
|
n.title,
|
|
COALESCE(n.content, ''),
|
|
n.created_at,
|
|
n.updated_at
|
|
FROM notes n;
|
|
|
|
-- ============================================================
|
|
-- 8. Drop gamle tabeller
|
|
-- ============================================================
|
|
|
|
-- Triggers først
|
|
DROP TRIGGER IF EXISTS trg_kanban_cards_updated_at ON kanban_cards;
|
|
DROP TRIGGER IF EXISTS trg_calendar_events_updated_at ON calendar_events;
|
|
DROP TRIGGER IF EXISTS trg_notes_updated_at ON notes;
|
|
|
|
-- Tabeller (rekkefølge: FK-avhengigheter)
|
|
DROP TABLE factoid_votes;
|
|
DROP TABLE factoids;
|
|
DROP TABLE message_votes;
|
|
DROP TABLE kanban_cards;
|
|
DROP TABLE calendar_events;
|
|
DROP TABLE notes;
|
|
|
|
-- ============================================================
|
|
-- RLS: Ikke nødvendig på messages/view-config-tabeller.
|
|
-- Workspace-isolasjon arves via FK til nodes (samme mønster
|
|
-- som episodes, segments, entities).
|
|
-- ============================================================
|
|
|
|
COMMIT;
|
|
|
|
-- ============================================================
|
|
-- 9. Entities (erstatter actors + topics)
|
|
-- ============================================================
|
|
-- Alt som kan nevnes med # er en entitet: personer, organisasjoner,
|
|
-- steder, temaer, konsepter. Én tabell, én autocomplete.
|
|
--
|
|
-- ALTER TYPE ADD VALUE kan ikke kjøres i en transaksjon (PG < 16),
|
|
-- derfor utenfor BEGIN/COMMIT-blokken.
|
|
|
|
ALTER TYPE node_type ADD VALUE IF NOT EXISTS 'entitet';
|
|
|
|
BEGIN;
|
|
|
|
CREATE TABLE entities (
|
|
id UUID PRIMARY KEY REFERENCES nodes(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
type TEXT NOT NULL, -- 'person', 'organisasjon', 'sted', 'tema', 'konsept'
|
|
aliases TEXT[] DEFAULT '{}', -- Forkortelser, kallenavn: {'JGS', 'Støre'}
|
|
avatar_url TEXT
|
|
);
|
|
|
|
CREATE INDEX idx_entities_name ON entities(name);
|
|
CREATE INDEX idx_entities_aliases ON entities USING GIN(aliases);
|
|
|
|
-- Migrer actors → entities
|
|
INSERT INTO entities (id, name, type)
|
|
SELECT id, name, COALESCE(type, 'person')
|
|
FROM actors;
|
|
|
|
UPDATE nodes SET node_type = 'entitet'
|
|
WHERE id IN (SELECT id FROM actors);
|
|
|
|
-- Migrer topics → entities
|
|
INSERT INTO entities (id, name, type)
|
|
SELECT id, name, 'tema'
|
|
FROM topics;
|
|
|
|
UPDATE nodes SET node_type = 'entitet'
|
|
WHERE id IN (SELECT id FROM topics);
|
|
|
|
DROP TABLE actors;
|
|
DROP TABLE topics;
|
|
|
|
-- ============================================================
|
|
-- RLS: Ikke nødvendig på messages/view-config/entities.
|
|
-- Workspace-isolasjon arves via FK til nodes (samme mønster
|
|
-- som episodes, segments).
|
|
-- ============================================================
|
|
|
|
COMMIT;
|