# Synops — Claude Code Prosjektguide ## Prosjektoversikt Synops er en plattform for redaksjonelt arbeid og podcast-produksjon. Self-hosted på Hetzner VPS med full datakontroll. Synops er plattformen. Sidelinja (podcastredaksjonen) er en tenant — en organisasjon som bruker Synops. Denne distinksjonen er bevisst: plattformkode og infrastruktur er skilt fra tenant-data og -innhold. ## Arbeidsflyt - **Standard arbeidsmodus:** Start i planleggingsmodus. Lag en grundig plan, få godkjenning, deretter implementer. Jobbene er ment å kunne kjøre lenge autonomt uten input underveis. - **Testmiljø:** `./dev.sh` er den kanoniske måten å starte utviklingsmiljøet. Når nye steg eller oppsett-quirks oppdages, oppdater alltid `dev.sh`. Før Vegard tester i browser: kjør `./dev.sh`, verifiser med `cargo check`/`svelte-check`/`curl`, og meld tilbake at det er klart. - **Browser-testing:** Claude har ikke tilgang til browser. Visuell testing gjøres av Vegard. Claude verifiserer backend (kompilering, API, DB-state). - **Utvikling mot server.** Ingen lokale databaser eller tjenester. Frontend utvikles lokalt mot server-API. Rust bygges lokalt, deployes til server for integrasjonstest. - **Commit og push:** Bruk egen vurdering. Trygt og reverserbart. - **Deploy til produksjon:** Krever alltid eksplisitt godkjenning fra Vegard. - **Diskusjon:** Forklar og diskuter før arkitekturendringer. For implementering innenfor eksisterende spec — bare kjør. ## Dokumentasjonstre CLAUDE.md er eneste startdokument. Alt annet ligger under `docs/`: - `docs/arkitektur.md` — Overordnet arkitektur, lagmodell, teknologivalg - `docs/retninger/` — Arkitektoniske teser og vedtatte retninger: - `README.md` — Oversikt og status - `status_quo.md` — Hva v1 var: ambisiøse primitiver, tradisjonell overflate - `rom_ikke_forum.md` — Opplevelse-først, to-lags-modell, administrativ opplevelse - `universell_input.md` — Tre primitiver (input, mottak, kommunikasjon), noder+edges - `maskinrommet.md` — Rust-orkestrator: fang, prosesser, lever - `bruker_ikke_workspace.md` — Brukeren er sentrum, samlings-noder med RLS-siloer - `datalaget.md` — PG(+AGE) som graf og arkiv, SpacetimeDB som sanntidslag - `docs/primitiver/` — Spesifikasjoner for kjerneprimitivene: - (kommer: input, mottak, kommunikasjonsnode, node, edge) - `docs/concepts/` — Brukeropplevelser/produktområder: - `studioet.md`, `møterommet.md`, `redaksjonen.md`, `podcastfabrikken.md`, `kunnskapsgrafen.md`, `valgomaten.md`, `den_asynkrone_gjesten.md` - `docs/features/` — Tekniske byggeklosser: - Se individuelle filer for chat, kanban, kalender, meldingsboks, kunnskapsgraf, whiteboard, live transkripsjon, m.fl. - `docs/proposals/` — Idébank med 32+ uimplementerte forslag (se README.md) - `docs/setup/` — Oppsett og drift: - `produksjon.md` — Steg-for-steg oppsett av Hetzner VPS fra scratch - `lokal.md` — Lokalt utviklingsmiljø (WSL2, mot server) - `migration_safety.md` — Sjekkliste for PostgreSQL-migrasjoner (RLS-verifisering) - `docs/infra/` — Infrastruktur og drift: - `ai_gateway.md` — LiteLLM som sentralisert AI-ruter (BYOK + fallback) - `api_grensesnitt.md` — Kommunikasjonskart: SvelteKit er web-API, Rust er worker - `jobbkø.md` — PostgreSQL-basert køsystem for bakgrunnsjobber - `synkronisering.md` — PostgreSQL ↔ SpacetimeDB dataflyt og eierskapsmodell - `docs/erfaringer/` — Lærdommer fra v1 (adapter-mønster, Svelte 5, SpacetimeDB, Authentik) - `reference/` — Kode fra v1 med gjenbruksverdi (Editor.svelte) - `ops/` — Repeterbare vedlikeholdsjobber (ryddejobb, doc-audit, drift-sjekk) ## Aktører - **Vegard** — serveradmin, utvikler, bruker. SSH: `vegard@157.180.81.26` - **Claude** — AI-agent, utvikler. SSH: `claude@157.180.81.26` - Begge har sudo + docker-tilgang. Tjenestebruker `sidelinja` eier filer/Docker. ## Stack - **Orkestrator/Backend:** Rust (maskinrommet) - **Frontend:** SvelteKit (TypeScript, PWA) - **Sanntid:** SpacetimeDB - **Database/Graf:** PostgreSQL (+Apache AGE ved behov) - **Binærlagring:** CAS (content-addressable store) - **AI:** LiteLLM (AI Gateway), faster-whisper (STT), ElevenLabs (TTS) - **Infra:** Docker Compose, Caddy, Authentik (SSO) ## Produksjonsserver - **IP:** 157.180.81.26 - **SSH:** `ssh vegard@157.180.81.26` / `ssh claude@157.180.81.26` - **Root-login:** Deaktivert - **SSH-nøkkel (lokal WSL2):** `/home/vegard/.ssh/id_ed25519` - **Server-filer:** `/srv/synops/` (docker-compose.yml, .env, config/, data/) - **Domener:** - `sidelinja.org` — Tenant-app (Sidelinja podcastredaksjonen) - `auth.sidelinja.org` — Authentik SSO - `git.sidelinja.org` — Forgejo (SSH port 222) - `vegard.info` — Separat nettsted - `synops.no` — Plattformdomene (reservert, ikke i bruk ennå) ## Git - **Forgejo-org:** `sidelinja` - **Repos:** - `synops` — plattformkode og arkitektur - `sidelinja` — podcastinnhold: `ssh://git@git.sidelinja.org:222/sidelinja/sidelinja.git` - **Git-identitet:** vegard / vnotnes@pm.me - **Forgejo-bruker:** vegard (admin) - **CLI:** Bruk `tea`, ikke `gh` (vi bruker Forgejo, ikke GitHub) ## Viktige regler - Aldri eksponere databaseporter mot internett - All AI-trafikk via maskinrommet, aldri direkte til leverandør-APIer - Tunge jobber (Whisper, LLM, TTS) blokkerer aldri brukerforespørsler - Sjekk alltid relevant doc i `docs/` før implementering - Dokumenter lærdommer i `docs/erfaringer/` ## Lagmodell ``` GUI (SvelteKit) │ skriv │ les (sanntid, direkte WebSocket) ▼ ▼ Maskinrommet (Rust) SpacetimeDB ──→ GUI │ ▼ Tjenester: PG+AGE, SpacetimeDB, CAS, Whisper, LiteLLM, LiveKit ... ``` ## Kjerneprinsipper 1. **Alt er noder og edges.** Ingen separate tabeller for chat, kanban, kalender, notater. Visninger er spørringer mot grafen. 2. **Tre primitiver:** Input (fanger), Mottak (presenterer), Kommunikasjon (samler folk). Alt annet er visninger og edges. 3. **Maskinrommet orkestrerer alt.** Fang, prosesser, lever. Edge-drevet ressursallokering. Tjenester under er utbyttbare. 4. **Brukeren er sentrum.** Ingen workspace-velger. Du ser dine edges. Samlings-noder gir felles kontekst med RLS-siloer under. 5. **Privat er default.** Input uten mottaker-edge er privat. Security by design, ikke konfigurasjon. 6. **PG er arkivet, SpacetimeDB er nåtid.** Ingen eierskapskonflikt. To lag, to roller.