AgentSkillsCN

event-sourcing

事件溯源架构指南。在处理事件、状态投影,或业务规则时使用此功能。

SKILL.md
--- frontmatter
name: event-sourcing
description: Guide til Event Sourcing arkitekturen. Bruk ved arbeid med events, state-projeksjoner, eller forretningsregler.
allowed-tools: Read, Grep, Glob

Event Sourcing & Datamodell

Oversikt

Systemet bruker Event Sourcing Light - alle endringer lagres som immutable events som kan prosesseres uavhengig på tre parallelle spor.

Kjerneprinsipp

code
Events (immutable) → Projeksjon → SakState (computed view)
  • Events lagres i Supabase event store
  • SakState beregnes fra event-loggen ved hver request
  • Ingen direkte state-mutasjon - kun nye events

Event-Typer

Grunnlag (TE sender, BH responderer)

EventAktørBeskrivelse
grunnlag_opprettetTEOppretter varsel om endring
grunnlag_oppdatertTEOppdaterer eksisterende varsel
grunnlag_trukketTETrekker tilbake varselet
respons_grunnlagBHBH responderer (godkjent/avslått/delvis)
respons_grunnlag_oppdatertBHBH endrer standpunkt ("snuoperasjon")

Vederlag (TE sender krav, BH responderer)

EventAktørBeskrivelse
vederlag_krav_sendtTESender vederlagskrav
vederlag_krav_oppdatertTEOppdaterer krav
vederlag_krav_trukketTETrekker krav
respons_vederlagBHBH responderer på vederlag
respons_vederlag_oppdatertBHBH endrer standpunkt

Frist (TE sender krav, BH responderer)

EventAktørBeskrivelse
frist_krav_sendtTESender fristkrav (nøytralt/spesifisert)
frist_krav_oppdatertTEOppdaterer krav
frist_krav_spesifisertTESpesifiserer dager for nøytralt varsel
frist_krav_trukketTETrekker krav
respons_fristBHBH responderer på frist
respons_frist_oppdatertBHBH endrer standpunkt

Forsering (§33.8)

EventAktørBeskrivelse
forsering_varselTEVarsler om forsering
forsering_responsBHBH aksepterer/avslår forsering
forsering_stoppetTEStopper pågående forsering
forsering_kostnader_oppdatertTEOppdaterer påløpte kostnader
forsering_koe_lagt_tilTELegger til KOE i forseringssak
forsering_koe_fjernetTEFjerner KOE fra forseringssak

Endringsordre (§31.3)

EventAktørBeskrivelse
eo_opprettetBHOppretter EO-sak
eo_koe_lagt_tilBHLegger KOE til i EO
eo_koe_fjernetBHFjerner KOE fra EO
eo_utstedtBHUtsteder EO formelt
eo_akseptertTETE aksepterer EO
eo_bestridtTETE bestrider EO
eo_revidertBHBH reviderer EO

System-Events

EventAktørBeskrivelse
sak_opprettetSystemOppretter ny sak i systemet

Spor-Status

Hvert spor har en status som endres basert på events:

code
IKKE_RELEVANT → UTKAST → SENDT → UNDER_BEHANDLING → GODKJENT/AVSLÅTT/DELVIS_GODKJENT
                                       ↓                    ↓
                                UNDER_FORHANDLING      TRUKKET
                                       ↓
                                    LAAST

Statuser:

  • UNDER_FORHANDLING - BH har avslått/delvis godkjent, forhandling pågår
  • LAAST - Grunnlag låst etter godkjenning

Data-Strukturer

SakEvent (Base)

python
class SakEvent:
    event_id: str           # Unik ID
    sak_id: str             # Hvilken sak
    event_type: EventType   # Type hendelse
    tidsstempel: datetime   # Når (UTC)
    aktor: str              # Hvem
    aktor_rolle: "TE" | "BH"
    kommentar: Optional[str]
    refererer_til_event_id: Optional[str]  # For responser

SakState (Projeksjon)

python
class SakState:
    sak_id: str
    sakstittel: str
    sakstype: SaksType                           # standard/forsering/endringsordre
    grunnlag: GrunnlagTilstand
    vederlag: VederlagTilstand
    frist: FristTilstand
    relaterte_saker: List[SakRelasjon]
    forsering_data: Optional[ForseringData]      # Kun for sakstype=forsering
    endringsordre_data: Optional[EndringsordreData]  # Kun for sakstype=endringsordre
    opprettet: Optional[datetime]
    siste_aktivitet: Optional[datetime]

Frontend/Backend Synkronisering

KRITISK: Typer må matche mellom frontend og backend!

FrontendBackendFormål
src/types/timeline.tsbackend/models/events.pyEvent-typer
src/types/timeline.tsbackend/models/sak_state.pyState-modell
src/constants/categories.tsbackend/constants/grunnlag_categories.pyKategorier

Bruk python scripts/check_drift.py for å verifisere synkronisering.

API Flyt

Sende event

code
POST /api/events
{
  "sak_id": "SAK-001",
  "event_type": "grunnlag_opprettet",
  "aktor": "Ola Nordmann",
  "aktor_rolle": "TE",
  "data": { ... }
}

Hente state

code
GET /api/cases/{sak_id}/state
→ Returns: SakState (projisert fra alle events)

Regler og Validering

Rekkefølge-regler

  • Kan ikke sende respons_grunnlag før grunnlag_opprettet finnes
  • Kan ikke sende vederlag_krav_sendt på trukket grunnlag
  • BH kan bare respondere på events fra TE og vice versa

Forretningsregler

Se backend/services/business_rules.py for komplett liste.

Vanlige oppgaver

Legge til ny event-type

  1. Legg til i EventType enum i backend/models/events.py
  2. Opprett data-klasse hvis nødvendig
  3. Legg til i AnyEvent union type
  4. Oppdater src/types/timeline.ts (frontend)
  5. Oppdater state-projeksjon i timeline_service.py
  6. Kjør python scripts/check_drift.py for å verifisere

Endre state-modell

  1. Oppdater Pydantic-modell i backend/models/sak_state.py
  2. Oppdater TypeScript interface i src/types/timeline.ts
  3. Oppdater projeksjon i backend/services/timeline_service.py
  4. Kjør python scripts/state_drift.py for å verifisere