# Epic 04 — Assets Details zu ASSET-001 … ASSET-010. ASSET-010 ergänzt am 2026-09-09 aus Open-Source-Vergleich (Shelf.nu Custody-Feature), noch offen/ungeplant. --- ## ASSET-001 — AssetCategory - **Ziel:** Oberste Gliederungsebene für Ressourcentypen. - **Beschreibung:** Kategorie-Stammdaten (z.B. „Medizin", „Fahrzeuge", „Funk"). - **Benutzerwert:** Navigierbare Struktur beim Anlegen/Suchen. - **Abhängigkeiten:** FOUND-002 - **Datenmodell:** `asset_category` (id, name) - **Backend:** CRUD - **Frontend:** Verwaltung Kategorie - **Mobile:** nur Anzeige/Filter - **QR-Code/Seriennummer/Inventarnummer:** nein - **Akte:** nein direkt - **Rechte:** Administrator - **Audit:** Änderung geloggt - **Akzeptanzkriterien:** Kategorie anlegen/umbenennen/löschen (nur wenn unbenutzt). - **Tests:** CRUD-Test, Löschschutz-Test bei Verwendung. - **DoD:** mind. 3 Beispielkategorien angelegt. ## ASSET-002 — AssetType - **Ziel:** Konkreter Typ innerhalb einer Kategorie (z.B. „AED Philips FRx"). - **Beschreibung:** Typ-Stammdaten, verweist auf Kategorie + Hersteller/Modell (IDENT-005). - **Benutzerwert:** Wiederverwendbare Vorlage für alle Exemplare dieses Typs. - **Abhängigkeiten:** ASSET-001 - **Datenmodell:** `asset_type` (id, category_id, name, hersteller_id, modell) - **Backend:** CRUD - **Frontend:** Verwaltung - **Mobile:** Anzeige - **QR-Code/Seriennummer/Inventarnummer:** nein direkt - **Akte:** Stammdatenbereich referenziert den Typ - **Rechte:** Materialwart/Administrator - **Audit:** Änderung geloggt - **Akzeptanzkriterien:** Typ anlegen mit Kategorie- und Hersteller-Verknüpfung. - **Tests:** CRUD- + Verknüpfungstest. - **DoD:** mind. ein Typ je Kategorie angelegt. ## ASSET-003 — Asset/AssetInstance - **Ziel:** Das konkrete Einzelobjekt (physische Ressource) — Kernentität der Plattform. - **Beschreibung:** Instanz eines AssetType mit eigener Objekt-ID, Inventarnummer, Seriennummer. - **Benutzerwert:** „Ein Ding, ein Datensatz" — Grundlage für praktisch alle anderen Epics. - **Abhängigkeiten:** ASSET-002, IDENT-001/002/004 - **Datenmodell:** `asset` (id, asset_type_id, inventarnummer, seriennummer, status, ...) - **Backend:** CRUD - **Frontend:** Anlegen-Formular, Liste - **Mobile:** Anzeige/Anlage im Feld - **QR-Code:** wird für diese Instanz erzeugt (IDENT-006) - **Seriennummer/Inventarnummer:** hier verortet - **Akte:** 1:1 Grundlage der Akte - **Rechte:** Materialwart/Administrator schreibt, alle lesen - **Audit:** Anlage/Änderung geloggt - **Akzeptanzkriterien:** Asset anlegen mit Typ-Referenz, Inventarnummer/SN eindeutig im jeweiligen Scope. - **Tests:** CRUD-Test, Eindeutigkeits-Constraint-Test. - **DoD:** durchgängig mit IDENT-001/002/004 verzahnt getestet. ## ASSET-004 — Asset-Status-Modell - **Ziel:** Genereller Lebenszyklus-Status, den alle Ressourcentypen teilen. - **Beschreibung:** Enum z.B. AKTIV/IN_WARTUNG/AUSSER_DIENST — Erweiterungspunkt für Readiness; spezifische Module wie Fleet dürfen feiner erweitern (FLEET-004). - **Benutzerwert:** Einheitliche Sprache über alle Ressourcentypen hinweg. - **Abhängigkeiten:** ASSET-003 - **Datenmodell:** `asset.status` (enum) - **Backend:** Statuswechsel-Endpoint - **Frontend:** Status-Dropdown - **Mobile:** Anzeige/Änderung - **QR-Code/Seriennummer/Inventarnummer:** nein - **Akte:** Stammdatenbereich (Status-Badge) - **Rechte:** Materialwart/Administrator - **Audit:** Statuswechsel geloggt - **Akzeptanzkriterien:** Statuswechsel möglich, ungültige Übergänge (falls modelliert) abgelehnt. - **Tests:** Statuswechsel-Test. - **DoD:** Status fließt sichtbar in FILE-002 ein. ## ASSET-005 — Asset-Suche & Liste - **Ziel:** Ressourcen wiederfinden, ohne ihre Akte-ID einzeln zu kennen. - **Beschreibung:** Liste mit Filter (Kategorie/Typ/Status) + Volltextsuche (Name/Inventarnummer/SN). - **Benutzerwert:** Alltagswerkzeug für Materialwart/Helfer. - **Abhängigkeiten:** ASSET-003 - **Datenmodell:** keins neu - **Backend:** Such-/Filter-Query-Parameter am Listen-Endpunkt - **Frontend:** Listen-Seite mit Suchfeld/Filtern - **Mobile:** kompakte Listenansicht - **QR-Code:** nein - **Seriennummer/Inventarnummer:** Suchfelder - **Akte:** Sprungziel je Zeile - **Rechte:** wie Lese-Recht - **Audit:** nein - **Akzeptanzkriterien:** Suche nach Inventarnummer/SN/Name liefert korrekte Treffer. - **Tests:** Suchtest mit kombinierten Kriterien. - **DoD:** Performance akzeptabel bei realistischer Datenmenge (Index statt Volltabellen-Scan). ## ASSET-006 — Asset-Bewegungshistorie - **Ziel:** Generisches Standortwechsel-Protokoll für jedes Asset, nicht nur fahrzeug-/warehouse-spezifisch. - **Beschreibung:** Bewegung(asset_id, von, nach, wer, wann, warum) — Basis für WH-007/FILE-003. - **Benutzerwert:** Nachvollziehbarkeit „wo war das Ding wann". - **Abhängigkeiten:** ASSET-003, WH-001 - **Datenmodell:** `asset_bewegung` - **Backend:** Bewegung erzeugen bei Standortwechsel - **Frontend:** Verschieben-Aktion - **Mobile:** ggf. später (P2) - **QR-Code/Seriennummer/Inventarnummer:** nein - **Akte:** Standort- und Historienbereich - **Rechte:** Materialwart+ - **Audit:** eigenständiges Fach-Protokoll (nicht generisches Audit-JSON, da Von/Nach-Felder strukturiert gebraucht werden — bewusst getrennt von FOUND-006) - **Akzeptanzkriterien:** Standortwechsel erzeugt Bewegungseintrag korrekt. - **Tests:** Bewegungstest. - **DoD:** funktional deckungsgleich mit dem in MABEA bereits existierenden Lagerbewegung-Modell (dient hier als Vorbild/Referenzimplementierung). ## ASSET-007 — AssetSet - **Ziel:** Mehrere Assets als ein handhabbares Bündel (Materialset) verwalten. - **Beschreibung:** Set-Entität mit Mitgliedsliste (Assets oder Consumables in bestimmter Menge). - **Benutzerwert:** z.B. „Verbandsset" als eine Ausgabeeinheit statt Einzelteile einzeln zu handhaben. - **Abhängigkeiten:** ASSET-003 - **Datenmodell:** `asset_set`, `asset_set_mitglied` - **Backend:** CRUD Set + Mitglieder - **Frontend:** Set-Zusammenstellung - **Mobile:** Anzeige - **QR-Code:** Set kann eigene Identität/eigenen QR bekommen (IDENT-001 anwendbar) - **Seriennummer/Inventarnummer:** Set selbst kann eigene Inventarnummer haben - **Akte:** eigene Akte für das Set - **Rechte:** Materialwart+ - **Audit:** Änderung der Mitgliederliste geloggt - **Akzeptanzkriterien:** Set anlegen, Mitglieder hinzufügen/entfernen. - **Tests:** CRUD-Test. - **DoD:** mind. ein Set mit 2+ Mitgliedern funktionsfähig. **Lücke gegenüber MABEA:** Beladungsvorlage ist konzeptionell ähnlich, aber fest ans Objekt gebunden — kein eigenständiges, wiederverwendbares Set-Konzept. - **Referenz (Open-Source-Vergleich 2026-09-09):** Shelf.nu (`shelf-nu/shelf.nu`) nennt dasselbe Konzept „Kits" — Assets zu einer wiederverwendbaren Einheit bündeln (Laptop+Charger+Dock). Bestätigt den Bedarf, löst aber keine MABEA-spezifische Frage zusätzlich (Set-Aufbau bleibt wie hier beschrieben). ## ASSET-010 — Custody/Ausgabe an Person (P2, neu, vollständig ausgearbeitet 2026-09-09) - **Ziel:** Nachvollziehen, welche Person ein bestimmtes Einzelgerät aktuell persönlich in Verwahrung hat — unabhängig vom Standort-/Objekt-bezogenen ZUST-001 und von der reinen Kontroll-**Zuständigkeit** in ZUST-002. - **Abgrenzung zu ZUST-002 (geklärt 2026-09-09):** ZUST-002 sagt „Max soll den Notfallkoffer #12 kontrollieren" — das Objekt bleibt am Standort, jeder darf es trotzdem kontrollieren, reine Empfehlung ohne Zugriffssperre. ASSET-010 sagt „Max hat Funkgerät #7 heute persönlich dabei" — das Gerät wandert physisch mit der Person, bis sie es zurückgibt; danach kann es an jemand anderen ausgegeben werden. Unterschiedliche Konzepte (Kontroll-Zuständigkeit vs. physischer Besitz), echter Bedarf bestätigt — kein Duplikat. - **Ziel-Entität (geklärt 2026-09-09): `GeraetInstanz`, nicht generisches `Objekt`.** `GeraetInstanz` hängt an einer `Objektposition` und trägt die eigene Seriennummer (`backend/app/models/geraet_instanz.py`) — genau das einzelne, seriennummerpflichtige Gerät (Funkgerät, Atemschutzgerät), das eine Person persönlich mitführt. Ein ganzes `Objekt` (z.B. ein Fahrzeug oder ein Materiallager) wird nicht „mitgeführt" — dafür ist Custody nicht gedacht. - **Beschreibung:** Ausgabe-/Rücknahme-Vorgang je `GeraetInstanz` an eine `Person` (PERS-001), mit Zeitstempel, Bestätigungsmechanismus (siehe unten) und Verlauf. - **Benutzerwert:** Bei Verlust/Defekt sofort klar, wer das Gerät zuletzt hatte, ohne Rückfrage-Runde. - **Bestätigungsmechanismus bei Ausgabe (überarbeitet 2026-09-09, final 2026-09-09 — Unterschrift OPTIONAL pro Ausgabe, cross-device per QR-Scan):** - Unterschrift/Protokoll ist **keine Pflicht für jede Ausgabe**, sondern eine Entscheidung der ausgebenden Stelle im Moment der Ausgabe — Toggle „Mit Protokoll+Unterschrift" im Ausgabe-Dialog. Ohne Toggle: einfache, formlose Ausgabe wie ursprünglich geplant (nur Custody-Zeile, kein PDF, kein QR-Signier-Flow) — schnelle Übergabe für den Alltag. Mit Toggle: voller Signier-Flow inkl. PDF-Protokoll, gedacht für kritisches/hochwertiges Material oder wenn die ausgebende Stelle es für nötig hält. - **Ablauf (nur wenn „Mit Protokoll" gewählt):** Portal (Tablet/Desktop der ausgebenden Stelle) zeigt nach Auswahl von Gerät+Empfänger einen QR-Code an, der auf eine einmalig gültige, kurzlebige Signier-Seite verweist (Token-basiert, kein Login nötig — die Legitimation ist der physische Besitz des Tablets der ausgebenden Stelle + der QR-Code selbst). Empfänger scannt den QR-Code mit dem **eigenen** Handy, öffnet die Signier-Seite, unterschreibt dort per Touch-Canvas auf dem eigenen Gerät (hygienischer/praktischer als eine geteilte Tablet-Oberfläche), sendet ab. Das Portal erkennt den Abschluss (Polling auf den Ausgabe-Status) und zeigt „unterschrieben ✓" an, danach gilt die Ausgabe als abgeschlossen. - Signier-Token: einmalig verwendbar, kurze Lebensdauer (z.B. 5 Minuten), an genau einen Ausgabevorgang gebunden — verhindert Wiederverwendung/Weitergabe des Links. - Aus Signatur + Geräte-/Personendaten + Zeitstempel wird automatisch ein **Ausgabeprotokoll** (PDF) generiert und über den DOC-001-Mechanismus am Custody-Eintrag UND in der Akte des Geräts abgelegt. - Bei Rücknahme: dieselbe Wahl gilt spiegelbildlich — wurde die Ausgabe mit Protokoll gemacht, läuft die Rücknahme ebenfalls über QR-Code→eigenes Handy→Unterschrift→Rückgabeprotokoll. Wurde die Ausgabe formlos gemacht, ist auch die Rücknahme formlos (kein nachträglicher Zwang zum Protokoll). - **Sicherheitsanforderungen (Security-Review 2026-09-09, owasp-top10-expert — verbindlich für die Implementierung, kein Nice-to-have):** 1. **Token:** `secrets.token_urlsafe(32)` (256 Bit), serverseitig nur als SHA-256-Hash gespeichert (wie ein Passwort-Reset-Token) — Klartext existiert nur im QR-Code/URL, nie in Logs. Access-Logs dieser Route ohne Query-String protokollieren. 2. **Route:** Token als Pfad-Parameter (`/signieren/{token}`), nicht Query — Query-Strings landen häufiger in Logs/Referrer/Browser-History. `slowapi`-Rate-Limit pro IP UND pro Token (z.B. 10/Minute). Lookup ausschließlich über Token-Hash, niemals über fortlaufende Custody-ID (IDOR). 3. **Race Condition:** Token-Verwendung als atomares DB-Update, nicht Read-then-Write — `UPDATE ... WHERE token_hash=$1 AND status='ausstehend'`, Rowcount prüfen statt separatem Check+Write. 4. **QR-Abfoto-Risiko:** bewusst akzeptiertes Restrisiko, **kein zusätzlicher PIN-Schritt** (Entscheidung 2026-09-09 — Reibung im Feldeinsatz wiegt schwerer, Ausgabe findet ohnehin unter Aufsicht der ausgebenden Stelle statt, die den Vorgang beobachtet). 5-Minuten-Ablauf + Einmalverwendung des Tokens bleiben als Grundschutz bestehen. 5. **Transport:** HTTPS zwingend (ohnehin nur über nginx-TLS erreichbar). `VITE_API_BASE_URL` bleibt relativ (`/api/v1`) — Empfänger-Handy nutzt dieselbe Domain/dasselbe TLS-Zertifikat. Explizit auf echtem Fremdgerät testen, nicht nur localhost. 6. **Datensparsamkeit (DSGVO):** GET-Endpunkt der Signier-Seite liefert nur Minimaldaten (Gerätebezeichnung, Empfängername, Zeitfenster) — keine vollständige Custody-Historie, keine internen IDs. Bei ungültigem/ abgelaufenem/bereits verwendetem Token identische generische Fehlermeldung (kein Enumerieren des Status). Signatur/PDF nach Abschluss nicht mehr über denselben Token abrufbar — Download nur im authentifizierten Portal-Bereich. 7. **PDF-Generierung:** falls HTML-basiert (`weasyprint`) — Jinja2-Autoescape aktiv lassen, kein `|safe` auf Nutzereingaben. Signatur-Bild serverseitig validieren (Magic-Bytes/Größe/Dimensionen), bevor es ins PDF eingebettet wird — keine beliebigen Datei-URLs oder SVG mit Skript zulassen. - **Abhängigkeiten:** ASSET-003, PERS-001, DOC-001 (Ausgabeprotokoll-PDF), FOUND-002 (Signier-Token braucht eigene, kurzlebige Tabelle/Cache) - **Datenmodell:** `geraet_instanz_custody` (geraet_instanz_id → `geraet_instanz.id`, person_id, ausgegeben_am, ausgegeben_von_benutzer_id, mit_protokoll: bool (Toggle-Entscheidung der ausgebenden Stelle), ausgabeprotokoll_dokument_id nullable FK auf `dokument` (nur bei `mit_protokoll=true`), zurueckgegeben_am nullable, zurueckgenommen_von_benutzer_id nullable, rueckgabeprotokoll_dokument_id nullable) — aktuelle Inhaberschaft = Zeile mit `zurueckgegeben_am IS NULL`. `signier_token` (token, custody_id, ablauf_am, verwendet: bool) — nur relevant wenn `mit_protokoll=true`, kurzlebig, kann nach Ablauf/Verwendung gelöscht werden (kein Langzeit-Speicherbedarf). - **Backend:** Ausgabe-Endpoint verzweigt nach `mit_protokoll` — `false`: Custody- Zeile direkt als abgeschlossen anlegen (formlose Ausgabe, wie ursprünglich geplant); `true`: Custody-Zeile unsigniert anlegen + Signier-Token erzeugen, QR-Code-Inhalt zurückgeben, öffentlicher (token-authentifizierter, kein Login) Signier-Endpoint nimmt Signatur-PNG entgegen, erzeugt PDF, markiert Custody als abgeschlossen, Status-Polling-Endpoint fürs Portal. In beiden Fällen: verhindert Doppel-Ausgabe (GeraetInstanz nur an eine Person gleichzeitig, DB-Constraint: max. eine offene Zeile je `geraet_instanz_id`); bei `mit_protokoll=true` zusätzlich Token-Ablauf serverseitig erzwungen (abgelaufene Tokens/unsignierte Ausgaben nach Timeout verwerfen) - **Frontend:** Ausgabe-Dialog am Gerät — Person auswählen, Toggle „Mit Protokoll+Unterschrift"; bei aktiviertem Toggle QR-Code anzeigen → Warten-auf-Signatur-Status, sonst sofortiger Abschluss. Separate mobile Signier-Seite (eigenständige Route, kein Admin-Layout, funktioniert auf jedem Handy-Browser ohne Login) nur relevant bei aktiviertem Toggle. - **Mobile:** Ausgabe-Start per QR-Scan am Gerät selbst (wie gehabt), Signatur läuft auf dem Empfänger-Handy über die separate Signier-Seite - **QR-Code:** zwei unterschiedliche QR-Codes im Spiel — (1) Geräte-QR zum Auswählen des Geräts (bestehender Mechanismus), (2) neuer Signier-Token-QR zum Öffnen der Signier-Seite auf dem Empfänger-Handy - **Seriennummer/Inventarnummer:** nutzt bestehende `GeraetInstanz`-Identität - **Akte:** eigener Custody-Verlauf im Akte-Historienbereich (FILE-005) - **Rechte:** Ausgabe/Rücknahme: Mitarbeiter+; Korrektur: Materialverantwortlicher+ - **Audit:** jede Ausgabe/Rücknahme geloggt, inkl. Zeitpunkt der Signatur - **Akzeptanzkriterien:** Gerät kann nicht an zwei Personen gleichzeitig ausgegeben sein; formlose Ausgabe (`mit_protokoll=false`) ist sofort abgeschlossen, kein Signier-Flow ausgelöst; Ausgabe mit Protokoll ohne abgeschlossene Signatur gilt nicht als abgeschlossen (Gerät bleibt bis zur Signatur „in Ausgabe schwebend", nicht schon fest zugeordnet); abgelaufener/bereits verwendeter Signier-Token wird abgelehnt; Ausgabeprotokoll- PDF enthält Geräte-, Personen-, Zeit- und Signaturdaten; Verlauf zeigt lückenlose Kette. - **Tests:** Doppel-Ausgabe-Ablehnung, abgelaufener-Token-Ablehnungstest, bereits- verwendeter-Token-Ablehnungstest, PDF-Generierungstest, Ausgabe→Signatur→ Rücknahme→Signatur→Neuausgabe-Zyklus, Race-Condition-Test (paralleler Request auf denselben Token, nur einer darf gewinnen), Rate-Limit-Test, IDOR-Test (Token-Lookup nur über Hash, keine ID-Erratbarkeit), Signatur-Bild-Validierungs- test (ungültige/manipulierte Datei wird abgelehnt). - **DoD:** offen — Design vollständig geklärt (2026-09-09), bereit für Implementierung. **Referenz (Open-Source-Vergleich 2026-09-09):** Shelf.nu (`shelf-nu/shelf.nu`, AGPL-3.0 — nur Konzeptvorbild, keine Codeübernahme wegen Copyleft) — „Custody"-Feature, Kernaussage „know who has what at all times". ## ASSET-008 — Consumable - **Ziel:** Verbrauchsmaterial als eigenes Konzept vom Einzelgerät abgrenzen. - **Beschreibung:** Consumable-Typ mit Mengenführung statt Einzelinstanz-pro-Objekt-ID. - **Benutzerwert:** Verbandsmaterial/Medikamente etc. sinnvoll ohne künstliche Einzel-IDs je Stück verwalten. - **Abhängigkeiten:** ASSET-002 - **Datenmodell:** `consumable` (asset_type_id, ...) — im Unterschied zu Asset keine 1:1 Objekt-ID pro Stück, sondern Menge an einem Ort (Ausbau folgt in INV-003) - **Backend:** Grundmodell - **Frontend:** Unterscheidung im AssetType-Formular („ist Verbrauchsmaterial") - **Mobile:** Anzeige - **QR-Code/Seriennummer:** Consumables i.d.R. ohne SN, ggf. Charge (INV-004) - **Inventarnummer:** i.d.R. nicht je Stück, ggf. je Charge - **Akte:** vereinfachte Akte (Bestandsverlauf statt Einzelverlauf) - **Rechte:** Materialwart+ - **Audit:** Änderung geloggt - **Akzeptanzkriterien:** Consumable-Typ anlegen, unterscheidet sich klar von Asset im Datenmodell (keine Einzel-Instanzen entstehen). - **Tests:** Abgrenzungstest. - **DoD:** Grundlage für INV-003 gelegt. ## ASSET-009 — Nutzungszähler (Kilometer/Betriebsstunden generisch) - **Nachtrag (Nutzer-Fund):** ursprünglich fälschlich als FLEET-003 fahrzeug-gebunden geplant. Betriebsstunden brauchen aber auch Stromerzeuger, Pumpen und andere Geräte (explizit in der Ursprungs-Anforderung Modul 14 „Wartung": „kilometerabhängige UND betriebsstundenabhängige Wartung" — nicht auf Fahrzeuge beschränkt). Generischer Nutzungszähler gehört daher ins Assets-Epic, nicht ins Fleet-Epic. - **Ziel:** Nutzungsgrad JEDES Assets erfassen, das einen Zähler hat (Kilometer ODER Betriebsstunden ODER beides) — Basis für zähler-abhängige Wartungsintervalle (MAINT-002). - **Beschreibung:** generisches Zählerfeld je Asset (Typ: km/Betriebsstunden/keins), Erfassungsverlauf (nicht nur aktueller Wert, sondern Verlauf der Meldungen). - **Benutzerwert:** Fahrzeuge (km), aber auch Stromerzeuger/Pumpen/Kompressoren (Betriebsstunden) bekommen dieselbe Wartungslogik, ohne dass jedes Modul sein eigenes Zählerfeld neu erfindet. - **Abhängigkeiten:** ASSET-003 - **Datenmodell:** `asset.zaehler_typ` (enum: keiner/kilometer/betriebsstunden), `asset.zaehlerstand` (aktuell), optional `zaehlerstand_historie` - **Backend:** Update-Endpoint mit Plausibilitätsprüfung (nur steigend, Override nur Administrator) - **Frontend:** Eingabefeld bei Kontrolle/Rückkehr bzw. nach Nutzung - **Mobile:** Eingabe im Feld - **QR-Code/Seriennummer/Inventarnummer:** nein - **Akte:** Stammdatenbereich - **Rechte:** jeder Nutzer darf melden, Korrektur nur Administrator - **Audit:** Änderung geloggt - **Akzeptanzkriterien:** Wert kann nur steigen (Validierung gegen Rückwärtslauf, außer Admin-Override); funktioniert gleichermaßen für ein Fahrzeug (km) und ein Gerät (Betriebsstunden). - **Tests:** Validierungstest je Zählertyp, Test mit einem Nicht-Fahrzeug-Asset (z.B. Stromerzeuger). - **DoD:** mind. ein Fahrzeug UND ein Gerät (z.B. Stromerzeuger) nutzen denselben Mechanismus nachweisbar. --- **MABEA-Ist-Stand-Abgleich:** ASSET-001…004 entsprechen `Bereich`/`Kategorie`, `Objekttyp`, `Objekt`, `ObjektStatus` — vollständig vorhanden, inkl. des 5-stufigen Fahrzeug-Status als Beispiel für ASSET-004-Erweiterung. ASSET-005 (Suche/Filter) vorhanden in ObjektListPage/ObjektSection. ASSET-006 (Bewegungshistorie) vorhanden als `Lagerbewegung` (diente hier sogar als Vorbild). **ASSET-007 (AssetSet) und ASSET-008 (Consumable als eigenständiges Konzept) fehlen** — echte Lücken, wie schon in der Gap-Analyse vorher notiert. **ASSET-009 (generischer Nutzungszähler) fehlt ebenfalls:** MABEA hat Kilometerstand/Betriebsstunden nur an `fahrzeugdetails` (1:1 zu Objekt mit `ist_zugfahrzeug`), Geräte wie Stromerzeuger/Pumpen (`GeraetInstanz`) haben aktuell KEIN Betriebsstunden-Feld — echte Lücke, wenn Wartung künftig betriebsstundenabhängig geplant werden soll (MAINT-002, Wartungs-Epic in MABEA ohnehin noch komplett offen).