politiker

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:

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.

persistent send state
        |
        v
     Queue
        |
        v
queue consumer
        |
        v
CredentialRateLimiter
        |
        v
provider / Email

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

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.