# Proposal: Chat/forum-dualitet + lest/ulest ## Konsept En kommunikasjonsnode kan vises som chat (kronologisk) eller forum (trådet). Samme data, to visninger. Brukeren bytter fritt mellom dem. Lest/ulest er én status per bruker per samtale — transitiv mellom alle visninger. ## Problemstilling Chatter er gode for rask diskusjon, dårlige for å finne igjen beslutninger. Forum er bra for struktur, dårlige for spontanitet. I praksis trenger en redaksjon begge — og de snakker om de samme tingene. To separate systemer betyr duplisering og informasjonstap. ## Datamodell Meldinger er noder med `belongs_to`-edge til kommunikasjonsnoden. Forum-egenskaper er metadata på meldingsnoden: ```json { "node_kind": "content", "metadata": { "forum_thread": "Episodetema S02E05", "reply_to": "melding-uuid-her", "forum_category": "Planlegging" } } ``` - `forum_thread`: tildeles når meldingen opprettes i forum-visning, eller når noen i chat-visningen "tråder" en melding - `reply_to`: svar på en spesifikk melding (trådstruktur) - `forum_category`: valgfri gruppering i forumet Meldinger uten `forum_thread` vises i forumet under "Generelt" eller "Utrådede". ## To visninger, én datakilde ### Chat-visning ``` ┌─ Redaksjonen (chat) ──────────────┐ │ │ │ Vegard 10:03 │ │ Vi bør ta klimatilpasning │ │ │ │ Trond 10:15 │ │ Fant en god kilde om flom │ │ │ │ Arne 10:22 │ │ Enig, passer med forrige ep │ │ │ │ Vegard 10:30 │ │ Teknisk: mic-nivåene var lave │ │ │ │ [skriv melding...] │ │ [Bytt til 📋] │ └────────────────────────────────────┘ ``` - Alle meldinger kronologisk - Ingen gruppering — strøm - Forum-metadata (tråd, kategori) er usynlig som default - Valgfritt: vis tråd-markør som subtil tag på meldinger som tilhører en tråd ### Forum-visning ``` ┌─ Redaksjonen (forum) ─────────────┐ │ │ │ Planlegging │ │ 📌 Episodetema S02E05 (3) ● │ │ Vegard: Vi bør ta klima... │ │ └ Trond: Fant en god kild... │ │ └ Arne: Enig, passer med... │ │ │ │ Teknisk │ │ Mic-nivåer (1) │ │ Vegard: mic-nivåene var... │ │ │ │ [ny tråd...] │ │ [Bytt til 💬] │ └────────────────────────────────────┘ ``` - Gruppert etter `forum_category`, deretter `forum_thread` - Trådstruktur via `reply_to` - Uleste tråder markert med ● (se lest/ulest under) - Innleggsteller per tråd ### Bytte mellom visninger En knapp i panelet: "Bytt til 📋" / "Bytt til 💬" Byttet er øyeblikkelig — ingen data lastes på nytt, bare renderingen endres. Samme WebSocket-abonnement, samme noder. Kan også være to separate paneler i arbeidsflaten som viser samme kommunikasjonsnode — ett som chat, ett som forum. ## Tråding fra chat I chat-visningen kan brukeren tråde en melding: 1. Høyreklikk / lang-trykk på en melding 2. "Opprett tråd" → sett `forum_thread` på meldingen 3. Fremtidige svar i tråden får samme `forum_thread` 4. I chatten vises de fortsatt kronologisk 5. I forumet vises de som en tråd ## Skrive fra forum Når du skriver i forumet: 1. Velg tråd (eksisterende eller ny) 2. Skriv innlegg 3. Noden opprettes med `forum_thread` og evt `reply_to` 4. Dukker opp i chatten kronologisk (med subtil trådmarkør) ## Lest/ulest ### Modell Én verdi per bruker per kommunikasjonsnode: `last_seen` timestamp. ``` Vegard --[member_of { role: "owner", last_seen: "2026-03-19T08:30:00Z" }]--> Redaksjonen ``` Alle meldinger med `created_at > last_seen` er **uleste**. ### Oppdatering - **Chat:** `last_seen` oppdateres når brukeren scroller til bunnen av chatten (eller ser nyeste melding) - **Forum:** `last_seen` oppdateres når brukeren åpner en tråd med uleste meldinger - **Mine ting:** viser ulest-badge basert på `last_seen` Begge visninger skriver til samme `last_seen`. Lest i chat = lest i forum. Ingen doble varsler. ### Ulest-indikatorer **Chat:** - Uleste meldinger under en separator-linje: "3 nye meldinger" - Bold / blå prikk på samtalen i Mine ting - Badge-teller i kontekst-velger **Forum:** - Uleste tråder markert med ● (prikk) - Ulest-teller per tråd: "(3)" der noen er uleste - Bold tråd-tittel for uleste tråder - Ulest-teller per kategori **Mine ting:** - Badge-teller per samtale - Kan gruppere uleste øverst ### Transitiv Lest/ulest er knyttet til **noden** (meldingen), ikke visningen. Har du sett noden — uansett gjennom chat, forum, søk, eller Mine ting — er den lest. ### Effektivitet Ikke én edge per melding per bruker. Bare ett timestamp i edge-metadata. Sjekken er enkel: ```sql SELECT count(*) FROM nodes n JOIN edges e ON e.target_id = $communication_id AND e.source_id = n.id AND e.edge_type = 'belongs_to' WHERE n.created_at > $last_seen ``` ## Forum-egenskaper ### Kategorier Valgfri gruppering. Lagres i kommunikasjonsnodens metadata: ```json { "forum_categories": ["Planlegging", "Teknisk", "Generelt"] } ``` Eier/admin kan opprette og rekkefølge-sortere kategorier. Meldinger uten kategori havner i "Generelt". ### Pinning Meldinger kan pinnes til toppen av en tråd eller kategori: ```json { "pinned": true } ``` Synlig som 📌 i forum-visningen. Usynlig i chat (eller subtil markør). ### Lukking Tråder kan lukkes (ingen nye svar): ```json { "forum_thread_closed": true } ``` Synlig i forum. I chat kan du fortsatt se meldingene men ikke svare i tråden. ## Implementering ### Fase 1: Grunnleggende dualitet - Legg til `forum_thread`, `reply_to`, `forum_category` i meldings-metadata (ingen skjemaendring, bare metadata) - Ny ForumTrait-komponent som viser kommunikasjonsnode som forum - "Bytt visning"-knapp i ChatTrait og ForumTrait - Registrer `forum` i TRAIT_PANEL_INFO ### Fase 2: Tråding fra chat - Høyreklikk-meny på meldinger i chat: "Opprett tråd" - Chat viser subtil trådmarkør på trådede meldinger ### Fase 3: Lest/ulest - `last_seen` i member_of edge-metadata - Oppdateres ved scroll (chat) og åpning (forum) - Ulest-indikatorer i chat, forum og Mine ting ### Fase 4: Forum-egenskaper - Kategorier, pinning, lukking - Kategori-admin i innstillinger ## Hva som eksisterer allerede - Kommunikasjonsnoder med meldinger (✓) - ChatTrait med WebSocket-abonnement (✓) - member_of-edges med metadata (✓) - BlockShell-paneler og trait-system (✓) - Drag-and-drop (✓) Hovedsakelig ny ForumTrait-komponent + metadata-konvensjoner. Ingen ny infrastruktur.