feat: Herkunfts-ID + OE-Join für Admin-Geräteliste
resolve_katalog_overrides() liefert jetzt zusätzlich quelle_id (konkrete oe_id/gruppe_id, die eine Auftragskatalog-Einstellung geliefert hat) statt nur den Herkunfts-Typ - Grundlage für anklickbare Herkunfts-Links im Kundenplattform-Auftragskatalog. fetch_auftragskatalog_listing() gibt quelle_id mit aus, fetch_auftragskatalog_state() (Agent-Pfad) ignoriert sie weiterhin. fetch_all_devices() (Admin-Geräteliste) bekommt denselben OE-Join wie fetch_devices_for_organization() letzte Session - Grundlage für OE-Spalte in der Admin-Geräteliste. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
a0df9f3ef9
commit
e5b7081955
55
app.py
55
app.py
@ -637,10 +637,14 @@ def resolve_katalog_overrides(device_id: str) -> dict:
|
||||
"""
|
||||
Ermittelt für ein Gerät die OE-/Gruppen-Zwischenschicht des
|
||||
Auftragskatalogs (siehe Konfigurationsgruppen-Plan): pro Merkmal-ID ein
|
||||
(aktiv, quelle)-Tupel, falls die OE-Kette oder eine Gruppe eine explizite
|
||||
Meinung dazu hat - fehlt der Merkmal-Key im Ergebnis, hat weder OE-Kette
|
||||
noch eine Gruppe eine Meinung, der Aufrufer fällt dann auf den
|
||||
Workspace-Default zurück.
|
||||
(aktiv, quelle, quelle_id)-Tupel, falls die OE-Kette oder eine Gruppe eine
|
||||
explizite Meinung dazu hat - fehlt der Merkmal-Key im Ergebnis, hat weder
|
||||
OE-Kette noch eine Gruppe eine Meinung, der Aufrufer fällt dann auf den
|
||||
Workspace-Default zurück. quelle_id ist die konkrete oe_id/gruppe_id, die
|
||||
das Ergebnis geliefert hat (fürs Kundenportal, Sprung von der
|
||||
Herkunfts-Anzeige zur verantwortlichen OE/Gruppe) - bei mehreren
|
||||
zustimmenden Gruppen wird eine davon genannt, kein Anspruch auf
|
||||
vollständige Attribution aller Beitragenden.
|
||||
|
||||
Reihenfolge: innerhalb der OE-Kette gewinnt die spezifischste OE
|
||||
(klassische Vererbung, von der eigenen OE aus nach oben zur Wurzel
|
||||
@ -692,30 +696,36 @@ def resolve_katalog_overrides(device_id: str) -> dict:
|
||||
|
||||
for oe_id_in_chain in oe_chain:
|
||||
for merkmal_id, aktiv in rows_by_oe.get(oe_id_in_chain, {}).items():
|
||||
oe_aktiv_by_merkmal.setdefault(merkmal_id, aktiv)
|
||||
oe_aktiv_by_merkmal.setdefault(merkmal_id, (aktiv, oe_id_in_chain))
|
||||
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT gm.merkmal_id, gm.aktiv
|
||||
SELECT gm.merkmal_id, gm.gruppe_id, gm.aktiv
|
||||
FROM device_gruppen dg
|
||||
JOIN gruppen_merkmale gm ON gm.gruppe_id = dg.gruppe_id
|
||||
WHERE dg.device_id = %s
|
||||
""",
|
||||
(device_id,),
|
||||
)
|
||||
gruppen_aktiv_by_merkmal = {}
|
||||
for merkmal_id, aktiv in cur.fetchall():
|
||||
gruppen_aktiv_by_merkmal.setdefault(merkmal_id, []).append(aktiv)
|
||||
gruppen_stimmen_by_merkmal = {}
|
||||
for merkmal_id, gruppe_id, aktiv in cur.fetchall():
|
||||
gruppen_stimmen_by_merkmal.setdefault(merkmal_id, []).append((gruppe_id, aktiv))
|
||||
|
||||
ergebnis = {}
|
||||
for merkmal_id in set(oe_aktiv_by_merkmal) | set(gruppen_aktiv_by_merkmal):
|
||||
oe_aktiv = oe_aktiv_by_merkmal.get(merkmal_id)
|
||||
gruppen_stimmen = gruppen_aktiv_by_merkmal.get(merkmal_id, [])
|
||||
for merkmal_id in set(oe_aktiv_by_merkmal) | set(gruppen_stimmen_by_merkmal):
|
||||
oe_aktiv, oe_id_gewinner = oe_aktiv_by_merkmal.get(merkmal_id, (None, None))
|
||||
gruppen_stimmen = gruppen_stimmen_by_merkmal.get(merkmal_id, [])
|
||||
aktive_gruppen = [gruppe_id for gruppe_id, aktiv in gruppen_stimmen if aktiv]
|
||||
inaktive_gruppen = [gruppe_id for gruppe_id, aktiv in gruppen_stimmen if not aktiv]
|
||||
|
||||
if oe_aktiv is True or True in gruppen_stimmen:
|
||||
ergebnis[merkmal_id] = (True, "oe" if oe_aktiv is True else "gruppe")
|
||||
if oe_aktiv is True or aktive_gruppen:
|
||||
quelle = "oe" if oe_aktiv is True else "gruppe"
|
||||
quelle_id = oe_id_gewinner if oe_aktiv is True else aktive_gruppen[0]
|
||||
ergebnis[merkmal_id] = (True, quelle, quelle_id)
|
||||
else:
|
||||
ergebnis[merkmal_id] = (False, "oe" if oe_aktiv is False else "gruppe")
|
||||
quelle = "oe" if oe_aktiv is False else "gruppe"
|
||||
quelle_id = oe_id_gewinner if oe_aktiv is False else inaktive_gruppen[0]
|
||||
ergebnis[merkmal_id] = (False, quelle, quelle_id)
|
||||
|
||||
return ergebnis
|
||||
|
||||
@ -774,7 +784,7 @@ def fetch_auftragskatalog_state(device_id: str):
|
||||
if device_override is not None:
|
||||
aktiv = device_override
|
||||
elif merkmal_id in overrides:
|
||||
aktiv, _quelle = overrides[merkmal_id]
|
||||
aktiv, _quelle, _quelle_id = overrides[merkmal_id]
|
||||
else:
|
||||
aktiv = workspace_default
|
||||
|
||||
@ -842,11 +852,11 @@ def fetch_auftragskatalog_listing(device_id: str):
|
||||
device_override, workspace_default, optionen,
|
||||
) in rows:
|
||||
if device_override is not None:
|
||||
aktiv, quelle = device_override, "geraet"
|
||||
aktiv, quelle, quelle_id = device_override, "geraet", None
|
||||
elif merkmal_id in overrides:
|
||||
aktiv, quelle = overrides[merkmal_id]
|
||||
aktiv, quelle, quelle_id = overrides[merkmal_id]
|
||||
else:
|
||||
aktiv, quelle = workspace_default, "workspace"
|
||||
aktiv, quelle, quelle_id = workspace_default, "workspace", None
|
||||
|
||||
ergebnis.append({
|
||||
"merkmal": key,
|
||||
@ -858,6 +868,7 @@ def fetch_auftragskatalog_listing(device_id: str):
|
||||
),
|
||||
"state": "present" if aktiv else "absent",
|
||||
"quelle": quelle,
|
||||
"quelle_id": str(quelle_id) if quelle_id is not None else None,
|
||||
"optionen": optionen,
|
||||
})
|
||||
|
||||
@ -1381,9 +1392,10 @@ def fetch_all_devices():
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT d.id, d.hostname, d.device_fingerprint, d.agent_last_checkin,
|
||||
d.organization_id, o.name, d.deprovisioned_at
|
||||
d.organization_id, o.name, d.deprovisioned_at, d.oe_id, oe.name
|
||||
FROM devices d
|
||||
JOIN organizations o ON o.id = d.organization_id
|
||||
LEFT JOIN organisationseinheiten oe ON oe.id = d.oe_id
|
||||
WHERE d.archived_at IS NULL
|
||||
ORDER BY o.name, d.hostname NULLS LAST, d.created_at
|
||||
"""
|
||||
@ -1401,10 +1413,13 @@ def fetch_all_devices():
|
||||
"deprovisioned_at": (
|
||||
deprovisioned_at.isoformat() if deprovisioned_at is not None else None
|
||||
),
|
||||
"oe_id": str(oe_id) if oe_id is not None else None,
|
||||
"oe_name": oe_name,
|
||||
}
|
||||
for (
|
||||
device_id, hostname, fingerprint, last_checkin,
|
||||
organization_id, organization_name, deprovisioned_at,
|
||||
oe_id, oe_name,
|
||||
) in cur.fetchall()
|
||||
]
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user