ProofedMesh/services/admin-api
CTO Agent 65514559dc
Some checks failed
validate / Rego (opa fmt + opa test) (push) Successful in 12s
validate / JSON Schema (ajv) (push) Has been cancelled
services: add admin-api Go service (per-diem rates CRUD, in-memory + Postgres stub store, HTML templates, 13/13 go tests pass, go vet clean)
2026-10-25 17:28:14 +00:00
..
cmd/admin-api services: add admin-api Go service (per-diem rates CRUD, in-memory + Postgres stub store, HTML templates, 13/13 go tests pass, go vet clean) 2026-10-25 17:28:14 +00:00
internal services: add admin-api Go service (per-diem rates CRUD, in-memory + Postgres stub store, HTML templates, 13/13 go tests pass, go vet clean) 2026-10-25 17:28:14 +00:00
web/templates services: add admin-api Go service (per-diem rates CRUD, in-memory + Postgres stub store, HTML templates, 13/13 go tests pass, go vet clean) 2026-10-25 17:28:14 +00:00
admin-api services: add admin-api Go service (per-diem rates CRUD, in-memory + Postgres stub store, HTML templates, 13/13 go tests pass, go vet clean) 2026-10-25 17:28:14 +00:00
go.mod services: add admin-api Go service (per-diem rates CRUD, in-memory + Postgres stub store, HTML templates, 13/13 go tests pass, go vet clean) 2026-10-25 17:28:14 +00:00
README.md services: add admin-api Go service (per-diem rates CRUD, in-memory + Postgres stub store, HTML templates, 13/13 go tests pass, go vet clean) 2026-10-25 17:28:14 +00:00

admin-api

Admin-only HTTP service for ProofedMesh. Currently covers one concern: Verwaltung der Per-Diem-Pauschalen (per_diem_rates), die vom agent-per-diem-calculator deterministisch angewandt werden (siehe docs/architecture/v1.1.md §6.2 und ADR-0003).

Status: Skelett. Datenbankanbindung (pgx) und Signing-Service-Call sind Stubs mit expliziten Fehlern; HTTP-Handler, HTML-Templates, Modell-Typen und Store-Interface sind vollständig und getestet. Prod-Deployment folgt nach Phase-1-Trust-Core.

Scope

  • Admin-Oberfläche /admin/per-diem-rates — Liste + Neuanlage + „Retire" (valid_to setzen) über HTML + HTMX-ähnlichen simple-POST-Flow.
  • JSON-API hinter denselben Pfaden für Automatisierung (Accept: application/json).
  • Jede Create/Retire-Operation erzeugt eine Rate Change Attestation über den Signing Service — predicateType https://basicstack.de/attestations/rate_change/v1. Rückgabe-Hash wird in per_diem_rates.rate_change_attestation_ref sowie in per_diem_rate_changes persistiert.
  • Keine Delete-Operation. Historie ist unveränderlich (Schema-Trigger erzwingt das).

Auth

  • OIDC via Pocket ID (Authorization-Code-Flow, Session-Cookie).
  • Autorisierung: Gruppenmitgliedschaft proofedmesh-admin wird aus dem ID-Token gelesen und ist Pflicht für alle Endpunkte außer Login.
  • Hintergrund-Dienste rufen die API nicht — Admin-API ist Human-only. Deshalb kein client_credentials-Pfad.

HTTP-Endpunkte (geplant)

Methode Pfad Beschreibung
GET /admin/per-diem-rates/ Liste aller Rates (gefiltert nach Country, aktiv/retired)
GET /admin/per-diem-rates/{rate_id} Detailansicht einer Rate
POST /admin/per-diem-rates/ Neue Rate anlegen (JSON oder Form)
POST /admin/per-diem-rates/{rate_id}/retire valid_to setzen (Rate ablaufen lassen)

Content-Negotiation per Accept-Header: text/html → Templates, application/json → JSON.

Layout

services/admin-api/
├── README.md                       — diese Datei
├── go.mod
├── cmd/admin-api/main.go           — HTTP-Entry (bind + router + graceful shutdown)
├── internal/
│   ├── model/rate.go               — Rate struct, validation
│   ├── store/
│   │   ├── store.go                — RateStore interface
│   │   ├── memory.go               — in-memory impl (für Tests + Dev)
│   │   ├── memory_test.go
│   │   └── postgres.go             — pgx impl, derzeit Stub
│   ├── httpapi/
│   │   ├── rates.go                — Handler
│   │   └── rates_test.go           — Handler-Tests gegen in-memory store
│   └── attest/
│       └── ratechange.go           — Signing-Service-Client, derzeit Stub
└── web/
    └── templates/per_diem_rates.html

Lokal bauen (sobald Code vollständig)

cd services/admin-api
go test ./...
# Dev-Modus mit in-memory store, kein Postgres:
go run ./cmd/admin-api -store=memory -listen=:8080
# Prod-Modus (sobald postgres.go fertig):
go run ./cmd/admin-api -store=postgres \
  -db="postgres://trust:…@trust-postgres:5432/trust?sslmode=verify-full"

Rate Change Attestation (Entwurf)

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    { "name": "per_diem_rate/PDR-42", "digest": { "sha256": "<content hash>" } }
  ],
  "predicateType": "https://basicstack.de/attestations/rate_change/v1",
  "predicate": {
    "change_kind": "create",
    "rate_id": "PDR-42",
    "country": "DE",
    "city": null,
    "currency": "EUR",
    "full_day": "28.00",
    "partial_day_min8h": "14.00",
    "arrival_day": "14.00",
    "departure_day": "14.00",
    "valid_from": "2026-01-01",
    "valid_to": null,
    "source_regulation": "BMF-Schreiben …",
    "performed_by": {
      "iss": "https://auth.basicstack.de",
      "sub": "user-admin-42",
      "session_id": "SES-admin-…"
    },
    "performed_at": "2026-10-25T18:30:00Z"
  }
}

Signiert vom Signing Service, Attestations-Hash wandert zurück in die Tabellen per_diem_rates.rate_change_attestation_ref und per_diem_rate_changes.rate_change_attestation_ref.