feat(kiosk): Stempel-Endpunkte für Kiosk-Sessions (fehlten bisher komplett)

Login (PIN/NFC/QR/Liste) lieferte einen session_token, aber es gab keinen
Endpunkt der ihn tatsächlich zum Stempeln nutzt (X-Kiosk-Session-Token war
nur als Konzept in kiosk_session_service dokumentiert, nirgends verdrahtet).

Neu: POST /kiosk/stamp/{in,out,break-start,break-end,status}. Gerät wird
weiterhin per Ed25519 verifiziert (verify_kiosk_request), zusätzlich validiert
_user_from_session() dass der session_token zu genau diesem Gerät gehört und
der User noch aktiv/in der richtigen Firma ist. Reuse von time_service
(stamp_in/out/break_start/break_end/get_today), source=KIOSK.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gis16MnuwkYcivLrSxK1pD
This commit is contained in:
2026-08-27 13:32:46 +02:00
co-authored by Claude Sonnet 5
parent 3650da8022
commit 2ce363c422
2 changed files with 115 additions and 0 deletions
+24
View File
@@ -37,3 +37,27 @@ class KioskUserListEntry(BaseModel):
class KioskUserListResponse(BaseModel):
users: list[KioskUserListEntry]
class KioskStampRequest(BaseModel):
"""Body für Stempel-Aktionen. session_token identifiziert den eingeloggten
Mitarbeiter (aus /auth/pin|nfc|qr|list), das Gerät ist bereits über die
Ed25519-Signatur (verify_kiosk_request) authentifiziert."""
session_token: str = Field(..., min_length=1)
note: str | None = None
class KioskStampResponse(BaseModel):
entry_id: uuid.UUID
status: str # "stamped_in" | "stamped_out" | "break_started" | "break_ended"
warnings: list[str] = []
class KioskStampStatusRequest(BaseModel):
session_token: str = Field(..., min_length=1)
class KioskStampStatusResponse(BaseModel):
stamped_in: bool
on_break: bool
start_time: str | None = None