Arkitektur¶
Översikt¶
Browser
|
v
access-index.ts
|
v
index.ts
| | | | |
| | | | +--> Email
| | | +------------> R2 attachments
| | +---------------------> KV sessions
| +------------------------------> D1 application state
|
+--> Queue send jobs
|
+--> retries
+--> dead-letter queue
|
v
CredentialRateLimiter DO
|
v
mail delivery
Request boundary¶
app/src/access-index.ts är extern entrypoint. Requestpolicyn ska appliceras server-side innan applikationslogik eller assets svarar.
Känsliga API-svar ska fortsatt behandlas som icke-cachebar privat data.
Auth och session¶
Sessioner ligger i KV, medan konton och övrig canonical applikationsstate ligger i D1. Det är en viktig gräns: sessioncache och persistent datamodell har olika konsistens- och livscykelkrav.
Authändringar måste verifiera:
- login/logout och sessionslivscykel,
- lösenords-/TOTP-flöden där de berörs,
- OAuth identity linking där det berörs,
- access till privata API-routes.
D1¶
D1 är canonical datalager för applikationen. Queue, KV och Durable Objects ska inte skapa konkurrerande canonical kopior av samma affärsstate.
Offentligt mottagarregister¶
public_contacts är den gemensamma modellen för offentliga mottagare. Politiska nivåer, media och akademi delar grundfält för namn, e-post, område/kategori och verifieringsstatus. Akademiposter kompletteras med organisation, enhet, titel, akademiskt fält och officiell käll-URL.
public_contact_assignments lagrar de politiska kommun-/regionrelationer som behövs för sakområdesfiltrering. Relationerna ska inte användas för att modellera akademiska ämnen.
Den kanoniska sökvägen är /api/public-contacts/search. /api/politicians/search finns kvar som kompatibilitetsalias och ska inte användas av ny klientkod.
Akademiska e-postadresser får endast tas från officiellt publicerade yrkeskällor. Adresser ska inte konstrueras från namn eller adressmönster.
Bilagor¶
R2 lagrar bilagor. D1 kan bära metadata/referenser medan objektbytes ligger i R2.
Utskicksflöde¶
Ett utskick skapas som persistent applikationsstate och köas för asynkron bearbetning. Brevets originaltext hålls separat från valbara inledningar. Vid leverans använder personalizeLetter ordningen personlig hälsning → snapshot av valda inledningar → brevtext; samma personaliseringspunkt hanterar även {GREETING} och äldre Hej [förnamn]!-utkast.
Queue retries och DLQ representerar transport-/bearbetningsstate. Persistent D1-state behövs för att avgöra applikationens faktiska status.
Rate limiting¶
CredentialRateLimiter använder Durable Object för serialiserad koordinering per credential/mailkonto. Den designen skyddar mot samtidiga Worker-invocations som annars skulle kunna överskrida avsedd leveranstakt.
Cron¶
Cron-triggern kör varje minut och används för att fortsätta väntande arbete enligt applikationens körmodell. Cron ska inte introducera en separat state machine vid sidan av D1/queue.
Trust boundaries¶
- Internet → accesslager
- session/token → authkontroll
- app → D1/KV/R2
- app → Queue
- queue consumer → rate limiter → mail/provider
- adminfunktioner → explicit authorization
Failure model¶
Vid leveransproblem ska både persistent send state och queue/DLQ-state undersökas. Att bara återköra en queue-operation utan att förstå persistent state kan ge dubblerad eller felaktig behandling.