Arkitektur og stack
Monorepo med Turborepo + pnpm
Section titled “Monorepo med Turborepo + pnpm”Monorepo gir felles TypeScript-typer, delt konfigurasjon og effektiv bygging. Turborepo cacher builds og kjører tasks parallelt. pnpm er raskere og mer diskeffektiv enn npm/yarn.
packages/types/ — Delte typer som importeres av både API og Webpackages/db/ — Drizzle-skjema, migrations, tilkoblingpackages/auth/ — Auth.js-konfigurasjon, passord-hashing, middlewareapps/api/ — Express.js: routes, services, AI-integrasjonapps/web/ — React: pages, components, hooksBackend: Express.js v5
Section titled “Backend: Express.js v5”Enkel og veldokumentert. Gir full kontroll over routing, middleware og API-design uten magi.
Lag-ansvar (strict separation):
- Routes — Input-validering med Zod + HTTP-respons. Ingen forretningslogikk.
- Services — All domenelogikk. Typede feil. Ingen HTTP-avhengighet.
- DB — Drizzle-spørringer. Kalles kun fra services.
- AI — Kontekstbygging, prompts, API-kall.
Database: PostgreSQL 16 + Drizzle ORM + pgvector
Section titled “Database: PostgreSQL 16 + Drizzle ORM + pgvector”PostgreSQL er valgt framfor grafdatabase (Neo4j) fordi relasjonene i dette systemet ikke krever graftraversal. Drizzle ORM gir typesikre spørringer og full SQL-kontroll.
pgvector gjør semantisk søk mulig uten ekstern vector store (Pinecone, Weaviate).
Embeddings lagres som vector(1536) kolonner direkte i PostgreSQL.
Autentisering: Auth.js v5
Section titled “Autentisering: Auth.js v5”Self-hosted med Credentials-provider (e-post/passord). Ingen ekstern avhengighet.
- Passord-hashing: PBKDF2-SHA256, 100 000 iterasjoner, Node.js crypto (ikke bcrypt)
- Sesjon: JWT i httpOnly-cookie
- Middleware:
requireAuthogrequireAdminpå Express-routes
Fillagring: MinIO
Section titled “Fillagring: MinIO”S3-kompatibel objektlagring i Docker. Kan erstattes av AWS S3 eller Cloudflare R2 uten kodeendringer — identisk API. Håndterer bilder, PDF-er og dokumenter.
AI-arkitektur
Section titled “AI-arkitektur”Kontekstbygging (strukturert)
Section titled “Kontekstbygging (strukturert)”Når brukeren stiller et spørsmål, bygges en strukturert kontekstblokk:
Eiendom: Hellebakken 9, enebolig, byggeår 1975Valgt rom: Stue (34 m², 1. etasje)Designretning interiør: nordisk, naturlig, varmBrukerprofil: balanced budsjett, hybrid arbeidsstrategiSemantisk søk (pgvector)
Section titled “Semantisk søk (pgvector)”Brukerens spørsmål embeddes (text-embedding-3-small) og søkes mot:
- Rom-beskrivelser
- Issue-tekster
- Observation-tekster
- DesignDirection-tekster
- Manualinnhold (chunked)
De mest relevante entitetene inkluderes i konteksten (cosine similarity).
Document Ingestion Engine
Section titled “Document Ingestion Engine”PDF-onboarding i 8 steg:
Upload → Queue → Parse → Extract → Structure → Store → Review → PersistKritisk prinsipp: AI foreslår → bruker godkjenner → system lagrer.
// Forenklet extraction-promptconst systemPrompt = `Du er ekspert på norske takstrapporter.Ekstraher strukturerte data og returner JSON.For hvert faktum: verdi, sidenummer, tekstutdrag, confidence (0.0-1.0).`Kostnad per takstrapport: ~$0.25 (60 sider ≈ 80 000 tokens ved Sonnet 4.6-priser).
Deployment: MVP og fremtid
Section titled “Deployment: MVP og fremtid”MVP — lokal Docker Compose
Section titled “MVP — lokal Docker Compose”services: postgres: PostgreSQL 16 + pgvector + pgcrypto minio: S3-kompatibel fillagring api: Express.js (multi-stage Dockerfile) web: React + Nginx (statisk bygg)Ekstern tilgang via Cloudflare Tunnel — ingen åpne porter i hjemmeruteren.
Fremtidig skymigrering
Section titled “Fremtidig skymigrering”Arkitekturen er container-basert og kan flyttes til Fly.io, Railway, Render, AWS eller GCP uten kodeendringer — kun miljøvariabler og CI/CD.
Se råteksten fra tech-architecture.md for den fullstendige begrunnelsen.