Att utveckla ett komplett system för anmälningar och betalningar låter som något som kräver backend, drift, miljöer och en budget.
Det gjorde det inte.
Vi byggde ett komplett system för ett löplopp; med registrering, betalflöden, adminfunktioner och accesskontroll, för ungefär 50 kr per månad i drift.
Byggt med hjälp av AI, men styrt av tydliga arkitekturbeslut.
Utmaningen
Projektet gjordes i en ideell kontext, med samma krav på stabilitet och användarupplevelse som i vilken produktionsmiljö som helst.
Jag är med och arrangerar ett löplopp genom en ideell förening.
Vi behövde:
- en hemsida för att presentera loppet
- interaktiva kartor för banorna
- anmälningar och betalningar
- ett sätt för företag att köpa startplatser
- ett administratörsgränssnitt
Kort sagt: ett riktigt system. Samtidigt var förutsättningarna:
- budgeten var i princip noll
- ingen ville drifta servrar
- lösningen behövde vara stabil nog för ~1000 deltagare
Standardlösningar (som vi undvek)
I ett sådant här scenario är det lätt att hamna i en ganska tung egen lösning:
- en hostad backend
- en molndatabas
- extern autentisering
- en månadskostnad som växer över tid
Det fungerar. Men det är ofta mer system än vad som faktiskt behövs.
Den andra vägen är att inte bygga alls, utan använda ett färdigt system för anmälningar och betalningar.
Det hade varit ett rimligt val. Men det kommer med andra tradeoffs.
Kostnaden är högre, och framför allt tappar man kontroll över upplevelsen. Användaren lämnar den egna sajten, klickar sig vidare genom ett externt flöde och får en mer fragmenterad upplevelse.
För ett lopp där deltagarupplevelsen är central blir det snabbt märkbart.
Vi valde därför att bygga själva. Inte för att det är roligare, utan för att det gav oss bättre kontroll över både kostnad och helhet.
Lösningen: mindre system, tydligare ansvar
Utgångspunkten var enkel:
Vi bygger bara det vi faktiskt behöver. Och inget mer.
Arkitekturen landade i fyra delar.
1. Statisk grund
Själva hemsidan är byggd med Hugo och hostas via GitHub Pages. Det innebär att allt som inte kräver dynamik är statiskt. Snabbt, gratis och utan något att drifta.
2. Dynamik där det behövs
För de delar som kräver interaktivitet används JavaScript i webbläsaren. Startlistor laddas dynamiskt, formulär hanterar anmälningar och betalflödet kopplas in där det behövs.
Det gör att vi kan behålla enkelheten i en statisk sajt, men ändå leverera en modern användarupplevelse.
3. Serverless på kanten
För logiken såsom anmälningar, betalningar och administration, används Cloudflare Workers.
Det ger oss:
- ingen server att drifta
- ingen traditionell deployment
- låg latens
- skalning utan extra arbete
Data lagras i en SQLite-databas via Cloudflare, och samma plattform hanterar även miljövariabler och secrets. Det gör att vi kan hålla hela systemet samlat, även ur ett säkerhetsperspektiv.
4. Betalning och access
Betalflödet hanteras av Stripe och transaktionella mail skickas via ReSend. Företagsköp löses genom värdekoder, vilket gör det enkelt att erbjuda startplatser som en förmån.
Accessen är uppdelad:
- publika endpoints är öppna men med rate-limit
- adminfunktioner och API:er skyddas via Cloudflare Zero Trust
Resultatet är ett system där publika delar är tillgängliga, känsliga delar är strikt kontrollerade och inget exponeras i onödan.
Hur det hänger ihop

När allt sätts ihop blir flödet ganska rakt och enkelt.
En användare går in på den statiska sajten och fyller i en anmälan. Formuläret skickar data till en endpoint i Cloudflare Workers, där anmälan valideras och lagras i databasen.
Vid betalning initieras ett Stripe-flöde, och när det är klart uppdateras statusen i systemet. Därefter skickas en bekräftelse via ReSend.
För administratörer sker samma sak, men via skyddade endpoints bakom Zero Trust, där man kan hantera anmälningar, följa upp betalningar och administrera eventet.
Det finns inga långa kedjor av tjänster eller beroenden. Varje del har ett tydligt ansvar, och flödet mellan dem är medvetet enkelt. Det är också det som håller nere både komplexitet och kostnad.
Persondata och ansvar
Systemet hanterar personuppgifter i form av deltagarinformation, vilket innebär att GDPR behöver tas på allvar även i en liten lösning.
Vi har därför hållit datamodellen minimal och begränsat vilken information som lagras till det som behövs för att administrera loppet och publicera resultat, exempelvis namn, e-post och födelseår för klassindelning, men inte mer än så.
Resultatlistor är en central del av loppet och sparas över tid, vilket också är en del av hur deltagandet är definierat i de allmänna villkoren. E-post används för deltagarrelaterad kommunikation och, vid samtycke, för information om framtida lopp.
Vid behov finns även stöd för att anonymisera deltagare.
Det är inga avancerade lösningar, men tillräckligt för att hantera ansvar och risk på en rimlig nivå.
AI som verktyg, inte lösning
All kod i projektet är framtagen med hjälp av AI. Främst via Claude Code, men även med stöd av andra modeller.
AI har hjälpt till att:
- skriva kod snabbare
- arbeta effektivt i TypeScript
- fungera som en produktiv “pair programmer”
Men den har inte tagit några beslut.
- arkitekturen är inte genererad
- säkerhetsbeslut är inte automatiserade
- tradeoffs är inte delegerade
Det är fortfarande människan som bestämmer vad som ska byggas, vad som är tillräckligt bra och hur helheten ska hänga ihop.
AI accelererar implementation.
Men det är fortfarande vi som designar systemet, sätter gränserna och tar ansvar för konsekvenserna.
Den ersätter inte förståelse.
Resultatet
Systemet är idag i produktion och hanterar:
- anmälningar
- betalningar
- företagsköp
- administration
För ett lopp med runt 1000 deltagare är det mer än tillräckligt.
Och kostnaden?
Cirka 50 kr per månad för att drifta hela systemet. Främst för lagring av bilder via CDN.
Det säger mer om arkitekturen än om systemets funktionalitet.
Slutsats
Det är lätt att anta att fler krav kräver mer komplexa system. Ofta är det tvärtom.
Med rätt avgränsningar, rätt verktyg och tydliga beslut går det att bygga robusta lösningar utan att bygga stort.
AI gör det snabbare att skriva kod. Men det är fortfarande vi som måste förstå vad vi bygger och vilka problem vi faktiskt försöker lösa.
Det här är ett system som många hade byggt betydligt mer komplext. Och betydligt dyrare.
De mest effektiva systemen är sällan de mest avancerade.
De är de mest genomtänkta.

