Fullfør oppgave 2.3: STDB-klient, warmup og docs

- Fiks NULL-håndtering i warmup (COALESCE for title/content/created_by)
- Renere health check (delete nonexistent node i stedet for create+delete)
- Dokumenter HTTP API-format og warmup-flyt i erfaringer
- Lagre STDB-token i server .env
- Republiser STDB-modul etter containerrestart

Verifisert: warmup laster 2 noder + 1 edge, /health viser stdb=connected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-17 12:49:50 +01:00
parent cb7f88035d
commit c13a39317e
4 changed files with 57 additions and 13 deletions

View file

@ -185,3 +185,53 @@ Worker som gjør AI-behandling av meldinger:
4. Kaller `ai_update_message` reducer → SpacetimeDB oppdaterer body/metadata/edited_at atomisk, lagrer revisjon, legger outbox-entry
5. Sync-worker persisterer til PG via `ai_update` action
6. Ved feil: `clear_ai_processing` reducer rydder flagget
## 11. HTTP API for å kalle reducere fra Rust (maskinrommet)
SpacetimeDB eksponerer et HTTP JSON API for å kalle reducere server-side.
Maskinrommet bruker `reqwest` (allerede en avhengighet) — ingen STDB SDK nødvendig.
### Endepunkt
```
POST /v1/database/{database_name}/call/{reducer_name}
Authorization: Bearer {stdb_token}
Content-Type: application/json
{
"param1": "verdi1",
"param2": "verdi2"
}
```
### Viktige detaljer
- **Navngitte parametre:** Body er et JSON-objekt med nøkler som matcher
reducer-parameternavn, IKKE en `{"args": [...]}` array.
- **Token:** Opprettes via `POST /v1/identity``{"identity": "...", "token": "..."}`.
Token er en JWT signert med serverens ES256-nøkkel. Ny server = ny nøkkel = nye tokens.
- **Suksess:** HTTP 200 med tom body.
- **Reducer-feil:** HTTP 200 med `Err(String)` — feilmeldingen er i body.
- **Valideringsfeil:** HTTP 400 med beskrivende feilmelding.
- **Auth-feil:** HTTP 401/403.
### Token-håndtering ved containerrestart
Hvis SpacetimeDB-containeren gjenskapes (data slettet), må:
1. Ny identitet opprettes via `POST /v1/identity`
2. Modulen republiseres med `spacetime publish`
3. STDB-tokenet i `.env` oppdateres
Maskinrommet kan automatisk opprette en ny identitet ved oppstart hvis
`SPACETIMEDB_TOKEN` ikke er satt, men denne identiteten vil ikke ha
tilgang til en eksisterende database. Bruk derfor alltid et stabilt token.
### Warmup via HTTP API
Maskinrommet gjør warmup (PG → STDB) ved oppstart:
1. `clear_all` — tøm STDB (unngå duplikater ved restart)
2. Last alle noder fra PG, kall `create_node` for hver
3. Last alle edges fra PG, kall `create_edge` for hver
NULLable PG-kolonner (title, content, created_by) må håndteres med
`COALESCE` i SQL-spørringen — STDB-modulen bruker `String`, ikke `Option`.

View file

@ -127,16 +127,10 @@ async fn health(State(state): State<AppState>) -> Result<Json<HealthResponse>, S
.await
.map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?;
// Sjekk STDB ved å kalle clear_all med en ufarlig test
// (vi bruker en enkel healthcheck-reducer i fremtiden)
let stdb_status = match state.stdb.create_node(
"__healthcheck__", "system", "", "", "hidden", "{}", "",
).await {
Ok(()) => {
// Rydd opp
let _ = state.stdb.delete_node("__healthcheck__").await;
"connected"
}
// STDB helsesjekk: prøv å slette en ikke-eksisterende node.
// Kallet når STDB og returnerer ok (noop), men feiler ved nettverksfeil.
let stdb_status = match state.stdb.delete_node("__healthcheck_nonexistent__").await {
Ok(()) => "connected",
Err(_) => "unavailable",
};

View file

@ -19,7 +19,8 @@ pub async fn run(db: &PgPool, stdb: &StdbClient) -> Result<WarmupStats, Box<dyn
// 2. Last alle noder
let nodes = sqlx::query_as::<_, PgNode>(
"SELECT id, node_kind::text, title, content, visibility::text, \
"SELECT id, node_kind::text, COALESCE(title, '') as title, \
COALESCE(content, '') as content, visibility::text, \
COALESCE(metadata::text, '{}') as metadata, \
created_at, COALESCE(created_by::text, '') as created_by \
FROM nodes ORDER BY created_at"

View file

@ -53,8 +53,7 @@ Uavhengige faser kan fortsatt plukkes.
- [x] 2.1 Rust-prosjekt: opprett `maskinrommet/` med axum, tokio, sqlx (PG), serde. Dockerfile. Kompilerer og starter. Ref: `docs/retninger/maskinrommet.md`.
- [x] 2.2 Auth-middleware: valider Authentik JWT-tokens, slå opp `auth_identities` → node_id. Returner 401 for ugyldige tokens.
- [~] 2.3 SpacetimeDB-klient i maskinrommet: koble til STDB, skriv noder og edges via reducers.
> Påbegynt: 2026-03-17T12:35
- [x] 2.3 SpacetimeDB-klient i maskinrommet: koble til STDB, skriv noder og edges via reducers.
- [ ] 2.4 Skrivestien: `POST /intentions/create_node` — valider, skriv STDB (instant), spawn async PG-skriving. Returner node_id umiddelbart.
- [ ] 2.5 Flere intensjoner: `create_edge`, `update_node`, `delete_node`. Validering av tilgang (created_by eller owner/admin-edge).
- [ ] 2.6 Docker Compose: legg maskinrommet inn i server-stacken. Intern nettverkstilgang til PG og STDB.