Source code for exlab_wizard.lims.schemas
"""msgspec.Struct types for the LIMS read-only client. Backend Spec §7.2.
These types model the subset of LIMS data the wizard reads via Mapping B.
The LIMS itself owns project identity; ExLab-Wizard only consumes it. The
LIMSProject struct mirrors the fields documented in §7.2.3 plus a
``fetched_at`` timestamp used by the local SQLite cache for freshness
bookkeeping.
Style:
- ``kw_only=True`` on every Struct so callers always specify field names
-- the wire-format ordering of LIMS fields is not a stable contract.
- ``forbid_unknown_fields=False`` so that LIMS payload additions in
future versions do not break the read path. Unknown fields are
silently dropped by ``msgspec.json.decode``; we re-emit only the
fields we know about when writing the offline catalogue.
- ``frozen=False`` on LIMSProject because the cache layer mutates
``fetched_at`` when re-stamping rows; LIMSUser is frozen since users
are read-only.
"""
from __future__ import annotations
from dataclasses import dataclass
from msgspec import Struct
from exlab_wizard.constants import LIMSProjectStatus
__all__ = [
"HealthStatus",
"LIMSProject",
"LIMSUser",
]
[docs]
class LIMSProject(
Struct,
kw_only=True,
forbid_unknown_fields=False,
):
"""One LIMS project row. Backend Spec §7.2.3.
The ``metadata`` field is a JSONB blob the LIMS owns; ExLab-Wizard
does not mutate it. ``fetched_at`` is a UTC ISO 8601 timestamp set
when the wizard pulled the row -- the local cache uses it for
freshness bookkeeping (§7.2.4).
"""
uid: str
short_id: str
name: str
status: LIMSProjectStatus
owner: str
fetched_at: str
description: str | None = None
contact_name: str | None = None
metadata: dict = {}
[docs]
class LIMSUser(
Struct,
kw_only=True,
frozen=True,
forbid_unknown_fields=False,
):
"""One LIMS user row. Backend Spec §7.2.3.
Mirrors the upstream ``safe_user`` contract returned by
``GET /api/v1/me``. Only the fields ExLab-Wizard surfaces are
typed; everything else is dropped by msgspec.
"""
uid: str
email: str
role: str
[docs]
@dataclass(frozen=True)
class HealthStatus:
"""Result of ``LIMSClient.health_check()``. Backend Spec §7.2.3.
``ok`` is True iff the LIMS responded to ``GET /me`` with 2xx.
``latency_ms`` is the wall-clock duration in milliseconds (rounded
to the nearest int). ``reason`` is None on success and carries a
short human-readable failure summary on failure.
"""
ok: bool
latency_ms: int
reason: str | None = None