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:
parent
cb7f88035d
commit
c13a39317e
4 changed files with 57 additions and 13 deletions
|
|
@ -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
|
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
|
5. Sync-worker persisterer til PG via `ai_update` action
|
||||||
6. Ved feil: `clear_ai_processing` reducer rydder flagget
|
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`.
|
||||||
|
|
|
||||||
|
|
@ -127,16 +127,10 @@ async fn health(State(state): State<AppState>) -> Result<Json<HealthResponse>, S
|
||||||
.await
|
.await
|
||||||
.map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?;
|
.map_err(|_| StatusCode::SERVICE_UNAVAILABLE)?;
|
||||||
|
|
||||||
// Sjekk STDB ved å kalle clear_all med en ufarlig test
|
// STDB helsesjekk: prøv å slette en ikke-eksisterende node.
|
||||||
// (vi bruker en enkel healthcheck-reducer i fremtiden)
|
// Kallet når STDB og returnerer ok (noop), men feiler ved nettverksfeil.
|
||||||
let stdb_status = match state.stdb.create_node(
|
let stdb_status = match state.stdb.delete_node("__healthcheck_nonexistent__").await {
|
||||||
"__healthcheck__", "system", "", "", "hidden", "{}", "",
|
Ok(()) => "connected",
|
||||||
).await {
|
|
||||||
Ok(()) => {
|
|
||||||
// Rydd opp
|
|
||||||
let _ = state.stdb.delete_node("__healthcheck__").await;
|
|
||||||
"connected"
|
|
||||||
}
|
|
||||||
Err(_) => "unavailable",
|
Err(_) => "unavailable",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ pub async fn run(db: &PgPool, stdb: &StdbClient) -> Result<WarmupStats, Box<dyn
|
||||||
|
|
||||||
// 2. Last alle noder
|
// 2. Last alle noder
|
||||||
let nodes = sqlx::query_as::<_, PgNode>(
|
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, \
|
COALESCE(metadata::text, '{}') as metadata, \
|
||||||
created_at, COALESCE(created_by::text, '') as created_by \
|
created_at, COALESCE(created_by::text, '') as created_by \
|
||||||
FROM nodes ORDER BY created_at"
|
FROM nodes ORDER BY created_at"
|
||||||
|
|
|
||||||
3
tasks.md
3
tasks.md
|
|
@ -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.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.
|
- [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.
|
- [x] 2.3 SpacetimeDB-klient i maskinrommet: koble til STDB, skriv noder og edges via reducers.
|
||||||
> Påbegynt: 2026-03-17T12:35
|
|
||||||
- [ ] 2.4 Skrivestien: `POST /intentions/create_node` — valider, skriv STDB (instant), spawn async PG-skriving. Returner node_id umiddelbart.
|
- [ ] 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.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.
|
- [ ] 2.6 Docker Compose: legg maskinrommet inn i server-stacken. Intern nettverkstilgang til PG og STDB.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue