// EKSEMPLER

Eksempler på projekter og proof-of-concepts.

Besøg min Codeberg-side for offentligt tilgængelige repositories.

Alle disse småprojekter/POC'er er hostet på en gammel Lenovo-kasse hjemme hos mig sammen med en masse private whitelisted ting. Foran den står en Ubuntu VPS, som kun fungerer som en fast IP-adresse og reverse proxy via Caddy til Lenovo-kassen gennem en sikker WireGuard-protokol.

Beskrivelse

RAGGo er en selvhostet applikation, der indekserer dine dokumenter og billeder og giver dig mulighed for at chatte med dem ved hjælp af naturligt sprog. Alt kører på en Linux-server i din egen IT-infrastruktur. Dine data forlader aldrig din server, sendes aldrig gennem en tredjeparts cloud-udbyder og forbliver fuldstændig under din kontrol. Der er ingen uventede månedlige API-regninger eller skjulte licensomkostninger. Når RAGGo er installeret, kører systemet uden yderligere omkostninger.

RAGGo understøtter følgende dokumentformater:
pdf, docx, odt, xlsx, pptx, html, htm, epub, txt og md

RAGGo understøtter følgende billedformater:
png, jpg, jpeg, webp og gif

Strukturerede dokumenter (såsom PDF, DOCX, ODT, XLSX, PPTX, HTML, HTM og EPUB) analyseres semantisk, mens sidetal, overskrifter, tabeller og lister bevares som metadata, der opretholder konteksten. Almindelige tekstfiler og Markdown-filer opdeles i semantisk meningsfulde tekststykker i stedet for at blive delt midt i en sætning. Billeder behandles ved hjælp af AI-genererede billedbeskrivelser, som beskriver deres indhold, og indekseres derefter sammen med de øvrige dokumenter, så visuelt indhold også bliver søgbart ved hjælp af naturligt sprog.

Bygget på åbne teknologier som Go, PostgreSQL med pgvector og Ollama er installationen enkel og let at reproducere og revidere. En webgrænseflade giver adgang til chat og dokumenthåndtering. For virksomheder og organisationer, der administrerer store dokumentsamlinger, skaber dette en søgbar vidensbase, som er nem at vedligeholde med forudsigelige omkostninger og uden afhængighed af eksterne AI-udbydere.

Vejledning

Log ind – For at bruge RAGGo skal du logge ind via linket nedenfor.
Brugernavn: raggo
Adgangskode: oKfE!DHecTgJM9zPjjgfqL#mt59#n5G4C3gsjF4f

Tilføj dokumenter – Klik på +-knappen under inputfeltet. Vælg en understøttet fil (PDF, DOCX, ODT, XLSX, PPTX, HTML, EPUB, TXT eller Markdown). Filen analyseres og indekseres automatisk og bliver søgbar i løbet af få sekunder. Du får en bekræftelse med filnavnet og antallet af oprettede tekststykker.

Tilføj billeder – Klik på billedikonet ved siden af +-knappen. Vælg en billedfil (PNG, JPG, JPEG, WEBP eller GIF), og skriv en kort beskrivelse af billedet. Beskrivelsen gør billedet søgbart. Hvis en vision-model er konfigureret, kan du klikke på Auto-caption for automatisk at generere en beskrivelse.

Stil spørgsmål – Skriv dit spørgsmål i inputfeltet, og tryk på Enter (brug Shift+Enter for linjeskift). RAGGo finder de mest relevante tekstuddrag fra de indekserede dokumenter og billeder og genererer et svar baseret på dette materiale. Hvert svar angiver kildefilen og, hvor det er relevant, sidetallet for strukturerede dokumenter.

Vis indekserede filer – Klik på Documents i navigationsmenuen for at se en opdateret tabel over alt indhold i din samling: filnavne, filtyper, antal tekststykker, tidspunkt for import og registrerede strukturelle elementer som tabeller og lister. Listen opdateres automatisk.

Skift tema – Klik på den runde knap nederst til højre for at skifte mellem lyst og mørkt (Tokyo Night) tema.

Teknologi
Go – med tredjepartsbibliotekerne tsawler/tabula, openai/openai-go og fsnotify/fsnotify
Postgres 18 + pgvector – PostgreSQL-backend med pgvector som vector store
Taskfile – bruges til build-, deployment- og orkestreringskommandoer
Ollama – inferensserver
▸ AI-komponenter – samtalemodel som primært chatinterface; embedding-model, der konverterer tekststykker til vektorer til lighedssøgning; multimodal model, der tager billeder som input og producerer tekst som output; query rewriter, der omskriver tidligere brugerforespørgsler til en optimeret søgeforespørgsel
▸ AI-modeller – gemma4, nomic-embed-text
▸ CSS
▸ HTML
▸ JavaScript

Kildekode
Privat
Brugernavn
raggo
Adgangskode
oKfE!DHecTgJM9zPjjgfqL#mt59#n5G4C3gsjF4f
Link
RAGGo
Beskrivelse

Webapp til tidsregistrering og fakturagenerering til PDF. Jeg bruger selv denne app i mit daglige arbejde som konsulent. Jeg byggede den, fordi der ikke er nogen app, der gør præcis dette på det færøske marked. Derudover er jeg også for nærig til at betale en virksomhed et månedligt gebyr for dette. Denne prototype kører kun i browseren uden nogen backend, så alle data bliver slettet hvert 10. minut.

Ellers er der i den version, jeg bruger, tilknyttet et backend-API til en VPS, som reverse proxy'er kald gennem Caddy til min hjemmeserver, hvor en SQLite-database tager imod alle CRUD-operationer. Denne version er selvfølgelig IP-whitelistet, så du kan ikke bruge den ;-)

Vejledning

1. Indtast information om din virksomhed på [SETTINGS]-siden (der er default values, hvis du ikke gider det her)

2. På [TIMER]-siden opretter du Company, som er den virksomhed, du skal arbejde for. Indtast navn, adresse, e-mail, telefonnummer og standard timepris. Alt dette bliver brugt til at regne den endelige pris ud og som information til fakturagenerering.

3. Opret derefter en Assignment, som er en større klump arbejde. Det kan for eksempel være Udvikle backend til den nye hjemmeside hos example.com. Et Company kan have flere Assignments. Her kan du også give en længere beskrivelse af opgaven og en særlig pris for netop denne Assignment. Hvis der ikke bliver angivet nogen pris, er det standardprisen hos den virksomhed, der lige er oprettet.

4. Opret derefter en Task. Dette er en underklump af arbejde under en Assignment. En Assignment kan eje mange Tasks. Så vi opretter en Task, der hedder Udvikle GET customer endpoint eller noget.

5. Herfra kan du så vælge at knytte tid til en Task, enten ved at starte Timer eller ved at indtaste en Manual entry.

6. Nu er opgaven færdig, og du skal sende faktura til Company. Tryk på Generate invoice (PDF). På denne side ser du timer, beløb og pris. Skriv en kort beskrivelse af denne Assignment i Comment. Her kan du også knytte fakturalinjer på, som ikke er timer, men en eller anden enhed. Så du kan f.eks. sætte en router på til 500 kr. stykket eller noget. Nå, men når du er klar, tryk på Generate PDF, og tada, en smuk faktura, klar til at sende til Company. Pyha, det var meget, men prøv det?

Teknologi
Go - webserveren, backendkode, templating language osv.
HTMX - brugt til at lave CRUD-operationer
GNU Make - brugt til at automatisere bygning af binary og deployment til remote server via ssh med én kommando.
▸ CSS
▸ HTML
▸ JavaScript
▸ SQLite
Kildekode
Privat
Link
zeitkort
Beskrivelse

Jeg har længe haft lyst til at lave et projekt, der streamer hændelser fra en database til en event-consumer. Altså ved hjælp af det, man kalder CDC (Change Data Capture), hvor ændringer hentes fra databasens transaktionslog eller replication-mekanisme og sendes videre til en consumer.

CDC/log-based replication bygger på, at databasen allerede registrerer ændringer for at kunne håndtere recovery og replication. I PostgreSQL er det f.eks. WAL og logical replication/logical decoding, i MariaDB/MySQL er det binlog, og i SQL Server findes CDC som en indbygget funktion. Disse mekanismer kan fange INSERT, UPDATE og DELETE i tabeller, og derfor er det en effektiv måde at streame ændringer fra en database på, uden at applikationen selv skal sende ekstra events.

Jeg mener, at Debezium er en af de stærkeste løsninger, når det handler om at streame data mellem en database og en consumer, såsom Apache Kafka eller NATS. Debezium kan læse ændringer fra databasen og sende dem videre som events med metadata. Det er skrevet i Java og er let at deploye som en container på en Linux-server.

Jeg har ofte rodet med Apache Kafka, og ofte står jeg tilbage uden resultat og med hovedpine efter en lang dag med trial and error. Derfor valgte jeg denne gang at bruge NATS i stedet. NATS er skrevet i Go og er en binary, ikke som det Kafka-Java-monster, der har tusind bevægelige dele.

Nå, men kort fortalt: dette er et inventory management-system. Inde på siden kan man lave CUD-operationer, som resulterer i SQL DML mod PostgreSQL-databasen. CDC fanger ændringerne fra loggen, Debezium sender ændringen sammen med metadata til NATS, og derfra kunne flere systemer subscribe til real-time data fra databasen.

Fordelen ved dette er, at det operative system bliver decoupled fra downstream-brugen af live-data. Inventory-systemet skal bare gøre sit normale arbejde mod databasen, mens andre systemer kan bruge ændringerne uden at være direkte bundet til selve applikationen. Det kunne for eksempel være et BI-dashboard, som viser live-data fra inventory, eller andre systemer og medarbejdere, som skal kunne træffe beslutninger ud fra live operative data.

I dette tilfælde bliver data flowet blot vist tilbage på skærmbilledet.

Vejledning

I demoen ser du inventory-systemet til venstre og CDC-trace til højre. Vælg en vare og lav en ændring, f.eks. sell, restock, rename/move eller delete. Når ændringen er udført, kan du til højre se, hvordan den bevæger sig gennem flowet: PostgreSQL -> Debezium -> NATS JetStream -> browser. Nederst vises selve eventet som raw JSON og audit trail, så du kan se både tilstanden før og efter ændringen.

Teknologi
Go - webserver, API-endpoints, NATS-consumer og SSE event stream.
PostgreSQL - inventory-database med logical replication slået til.
Debezium Server - fanger ændringer fra PostgreSQL og publisher dem som events.
NATS JetStream - event streaming-lag mellem Debezium og Go-backend.
Taskfile - brugt til build, deployment og orchestration-kommandoer.
Podman - kører development- og production-infrastruktur som containers (NATS, PostgreSQL, Debezium).
▸ Server-Sent Events - streamer CDC-events live fra Go-backend til browseren.
▸ HTML
▸ CSS
▸ JavaScript
Kildekode
Codeberg
Link
inventory-fló
Beskrivelse

Web API til at hente data fra backend, skrevet i Go. Dette er et tænkt eksempel på registrering af vold i hjemmet til et API-endpoint, både som registreringsværktøj og til senere analyse.

Bliver deployed som kun én binary uden dependencies eller runtime environment. Hele frontend'en er embedded i binary. Projektet bruger kun Go standard library, ingen ekstern dependency.

Vejledning

Se den tekniske vejledning på linket nedenfor.

Teknologi
Go - 100% Golang std lib: html/template, net/http, flag, crypto
Taskfile - procesautomatisering, builds og deployment
Reflex - hurtig genopbygning og start af binary ved ændring af filer i repoet
Rsync - til at sync'e til produktion
▸ CSS
▸ HTML
▸ JavaScript
Kildekode
Codeberg repos
Link
go-api
Beskrivelse

Webapp udviklet for Landsverk. Brugt til jobmatch og lignende.

Gratis hosting og deployment til GitHub Pages med Hugo/Go som static site generator, der er integreret med en CI/CD pipeline. Et PR ind på main opdaterer hele siden.

Vejledning
Find ud af, hvilken profil du er, ved at klikke dig gennem Starvskumpass.
Teknologi
Go - Hugo bruger Go html/template som templating language
Hugo - Static Site Generator skrevet i Go
▸ JavaScript - quizlogik
▸ CSS
▸ HTML
Kildekode
Github repos
Link
Starvskumpass-link
Beskrivelse

Et simpelt POC af en chatfunktion skrevet i Rust. Rust fascinerer, så jeg ville prøve at bygge og deploye et Rust-projekt.

Vi har back office, hvor en supporter venter på beskeder, mens han spiser chips.

Så skriver to brugere ind i chatten, og supporteren kan chatte med begge brugere på én gang.

Fremadrettet har jeg tænkt mig at knytte back office til en backend, hvor en supporter kan knytte metadata til chats, så man i fremtiden kan lave kvantitative analyser. Hvis man også gemmer samtalerne, kan man lave sentimentanalyser eller kvalitative analyser.

Men jeg har børn og et hus og et arbejde, jeg skal tage mig af, så...

Vejledning

Dette POC sletter al data/chats hvert 3. minut og har rate limiting på req/resp, så min hjemmeserver ikke bliver smadret.

Gå ind på linket nedenfor. Vælg først supporteren, gå tilbage til forsiden i en ny fane, og vælg derefter bruger.

Giv brugeren et eller andet navn, og chatten starter. Skriv noget, og supporteren ser, at en samtale begynder. Nu kan du chatte med dig selv.

Men hvad hvis du vil chatte endnu mere med dig selv? Opret en ny bruger, og nu har supporteren to chats åbne.

Teknologi
    Axum - web framework i Rust. Tager sig af routing og middleware og alt det der. Nogenlunde det samme som Gin i Golang og FastAPI i Python
    Tokio - det man altid bruger, når man skal have async await i Rust
    Serde - serialisering/deserialisering fra JSON til Rust structs
    GNU Make - brugt til at automatisere bygning af binary og deployment til remote server via ssh med én kommando.
    ▸ CSS
    ▸ HTML
    ▸ JavaScript
Kildekode
Privat
Link
rs-chat
Beskrivelse

Denne hjemmeside er hostet på en Lenovo-kasse hjemme hos mig.

Vejledning
N/A
Teknologi
Go - 100% Golang std lib, bortset fra en rimelig standard dot-env-læser, joho/godotenv
Taskfile - procesautomatisering, builds og deployment
Reflex - hurtig genopbygning og start af binary ved ændring af filer i repoet
Rsync - til at sync'e til produktion
▸ CSS
▸ HTML
▸ JavaScript
Kildekode
Privat
Link
fló.fo