"""Welchen Rang eine Fundstelle hat — damit die Antwort sie einordnen kann. Der Quellenblock nennt bisher das Dokument („Rahmenvertrag nach § 129 Absatz 2 SGB V"), und das reicht, um § 16 des Vertrages von § 16 SGB V zu unterscheiden. Es reicht nicht, um zu entscheiden, welche der beiden die Frage **trägt**. Die Metadaten helfen dabei nicht: `container_type` steht bei rv129, amabrv *und* amrl auf „vertrag" — die Richtlinie ist über denselben Ingest-Pfad gelaufen wie die Vertragswerke. Wer den Rang daraus liest, hält die Arzneimittel-Richtlinie für einen Vertrag. Deshalb eine kuratierte Zuordnung über die Korpus-Id, wie bei den übrigen Registern dieses Projekts. **Warum der Rang in den Kontext gehört.** Die Auswertung zeigte Antworten, die eine Anlage oder eine Ausführungsregelung als „Maßgebliche Norm" führten, obwohl die tragende Vorschrift im selben Kontext stand. Das ist kein Zitierfehler, sondern eine falsche Herleitung: Anlage VII Teil A sagt, welche Darreichungsformen austauschbar sind, aber *dass* ausgetauscht werden darf, ordnet § 129 Abs. 1 SGB V an und konkretisiert § 40 AM-RL. Wer nur die Anlage nennt, nennt das Ergebnis ohne seinen Grund. **Der Rang ist eine Angabe, keine Rangfolge.** Dieses Modul sagt, was eine Quelle *ist* — Gesetz, Richtlinie, Vertrag, Anlage. Es sagt nicht, welche Vorschrift vorgeht; das hängt am Fall und bleibt beim Modell und beim Ankerregister. Eine automatische Regel „Gesetz schlägt Vertrag" wäre hier falsch: der Rahmenvertrag konkretisiert § 129 SGB V bindend, und für die Frage, welches Fertigarzneimittel abzugeben ist, ist er die genauere Vorschrift. """ from __future__ import annotations from typing import Any, Dict # Korpus-Id -> Rang, mit der Norm, auf der das Regelwerk beruht. Die Klammer # ist der eigentliche Nutzen: sie nennt dem Modell die Ermächtigungsgrundlage, # die es sonst erraten müsste. RANG_JE_KORPUS: Dict[str, str] = { "sgb5": "Gesetz", "rv129": "Vertrag nach § 129 Abs. 2 SGB V", "amabrv": "Vertrag nach § 300 Abs. 3 SGB V", "amrl": "Richtlinie nach § 92 Abs. 1 Satz 2 Nr. 6 SGB V", } # Fällt die Korpus-Id aus (Einzelkorpus-Betrieb, alte Trefferdicts), trägt die # doc_id dieselbe Auskunft — sie wird vom Ingest aus dem Dokument gebildet. _RANG_JE_DOC_PREFIX = ( ("SGB_V", "Gesetz"), ("RV_129", "Vertrag nach § 129 Abs. 2 SGB V"), ("AMAbrV", "Vertrag nach § 300 Abs. 3 SGB V"), ("AM_RL", "Richtlinie nach § 92 Abs. 1 Satz 2 Nr. 6 SGB V"), ) def _wert(hit: Dict[str, Any], *keys: str) -> str: metadata = hit.get("metadata") or {} for key in keys: value = hit.get(key) or metadata.get(key) if value: return str(value) return "" def rang(hit: Dict[str, Any]) -> str: """Der Rang einer Fundstelle, als eine Zeile für den Quellenblock. Anlagen werden gesondert ausgewiesen, weil sie im Index Container ihres eigenen Regelwerks sind: § 10 gibt es im Rahmenvertrag und in dessen Anlage 11. Eine Fundstelle aus der Anlage als „Vertrag" auszuweisen, verwischt genau den Unterschied, den die Zeile sichtbar machen soll. """ korpus = _wert(hit, "corpus_id") grundrang = RANG_JE_KORPUS.get(korpus, "") if not grundrang: doc_id = _wert(hit, "doc_id") for prefix, wert in _RANG_JE_DOC_PREFIX: if doc_id.startswith(prefix): grundrang = wert break container = _wert(hit, "container", "container_id") if container.strip().lower().startswith("anlage"): return f"Anlage zum Regelwerk ({container})" if not grundrang else ( f"Anlage zu: {grundrang} ({container})" ) return grundrang