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
|
Ermittelt für ein Gerät die OE-/Gruppen-Zwischenschicht des
|
||||||
Auftragskatalogs (siehe Konfigurationsgruppen-Plan): pro Merkmal-ID ein
|
Auftragskatalogs (siehe Konfigurationsgruppen-Plan): pro Merkmal-ID ein
|
||||||
(aktiv, quelle)-Tupel, falls die OE-Kette oder eine Gruppe eine explizite
|
(aktiv, quelle, quelle_id)-Tupel, falls die OE-Kette oder eine Gruppe eine
|
||||||
Meinung dazu hat - fehlt der Merkmal-Key im Ergebnis, hat weder OE-Kette
|
explizite Meinung dazu hat - fehlt der Merkmal-Key im Ergebnis, hat weder
|
||||||
noch eine Gruppe eine Meinung, der Aufrufer fällt dann auf den
|
OE-Kette noch eine Gruppe eine Meinung, der Aufrufer fällt dann auf den
|
||||||
Workspace-Default zurück.
|
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
|
Reihenfolge: innerhalb der OE-Kette gewinnt die spezifischste OE
|
||||||
(klassische Vererbung, von der eigenen OE aus nach oben zur Wurzel
|
(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 oe_id_in_chain in oe_chain:
|
||||||
for merkmal_id, aktiv in rows_by_oe.get(oe_id_in_chain, {}).items():
|
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(
|
cur.execute(
|
||||||
"""
|
"""
|
||||||
SELECT gm.merkmal_id, gm.aktiv
|
SELECT gm.merkmal_id, gm.gruppe_id, gm.aktiv
|
||||||
FROM device_gruppen dg
|
FROM device_gruppen dg
|
||||||
JOIN gruppen_merkmale gm ON gm.gruppe_id = dg.gruppe_id
|
JOIN gruppen_merkmale gm ON gm.gruppe_id = dg.gruppe_id
|
||||||
WHERE dg.device_id = %s
|
WHERE dg.device_id = %s
|
||||||
""",
|
""",
|
||||||
(device_id,),
|
(device_id,),
|
||||||
)
|
)
|
||||||
gruppen_aktiv_by_merkmal = {}
|
gruppen_stimmen_by_merkmal = {}
|
||||||
for merkmal_id, aktiv in cur.fetchall():
|
for merkmal_id, gruppe_id, aktiv in cur.fetchall():
|
||||||
gruppen_aktiv_by_merkmal.setdefault(merkmal_id, []).append(aktiv)
|
gruppen_stimmen_by_merkmal.setdefault(merkmal_id, []).append((gruppe_id, aktiv))
|
||||||
|
|
||||||
ergebnis = {}
|
ergebnis = {}
|
||||||
for merkmal_id in set(oe_aktiv_by_merkmal) | set(gruppen_aktiv_by_merkmal):
|
for merkmal_id in set(oe_aktiv_by_merkmal) | set(gruppen_stimmen_by_merkmal):
|
||||||
oe_aktiv = oe_aktiv_by_merkmal.get(merkmal_id)
|
oe_aktiv, oe_id_gewinner = oe_aktiv_by_merkmal.get(merkmal_id, (None, None))
|
||||||
gruppen_stimmen = gruppen_aktiv_by_merkmal.get(merkmal_id, [])
|
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:
|
if oe_aktiv is True or aktive_gruppen:
|
||||||
ergebnis[merkmal_id] = (True, "oe" if oe_aktiv is True else "gruppe")
|
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:
|
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
|
return ergebnis
|
||||||
|
|
||||||
@ -774,7 +784,7 @@ def fetch_auftragskatalog_state(device_id: str):
|
|||||||
if device_override is not None:
|
if device_override is not None:
|
||||||
aktiv = device_override
|
aktiv = device_override
|
||||||
elif merkmal_id in overrides:
|
elif merkmal_id in overrides:
|
||||||
aktiv, _quelle = overrides[merkmal_id]
|
aktiv, _quelle, _quelle_id = overrides[merkmal_id]
|
||||||
else:
|
else:
|
||||||
aktiv = workspace_default
|
aktiv = workspace_default
|
||||||
|
|
||||||
@ -842,11 +852,11 @@ def fetch_auftragskatalog_listing(device_id: str):
|
|||||||
device_override, workspace_default, optionen,
|
device_override, workspace_default, optionen,
|
||||||
) in rows:
|
) in rows:
|
||||||
if device_override is not None:
|
if device_override is not None:
|
||||||
aktiv, quelle = device_override, "geraet"
|
aktiv, quelle, quelle_id = device_override, "geraet", None
|
||||||
elif merkmal_id in overrides:
|
elif merkmal_id in overrides:
|
||||||
aktiv, quelle = overrides[merkmal_id]
|
aktiv, quelle, quelle_id = overrides[merkmal_id]
|
||||||
else:
|
else:
|
||||||
aktiv, quelle = workspace_default, "workspace"
|
aktiv, quelle, quelle_id = workspace_default, "workspace", None
|
||||||
|
|
||||||
ergebnis.append({
|
ergebnis.append({
|
||||||
"merkmal": key,
|
"merkmal": key,
|
||||||
@ -858,6 +868,7 @@ def fetch_auftragskatalog_listing(device_id: str):
|
|||||||
),
|
),
|
||||||
"state": "present" if aktiv else "absent",
|
"state": "present" if aktiv else "absent",
|
||||||
"quelle": quelle,
|
"quelle": quelle,
|
||||||
|
"quelle_id": str(quelle_id) if quelle_id is not None else None,
|
||||||
"optionen": optionen,
|
"optionen": optionen,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -1381,9 +1392,10 @@ def fetch_all_devices():
|
|||||||
cur.execute(
|
cur.execute(
|
||||||
"""
|
"""
|
||||||
SELECT d.id, d.hostname, d.device_fingerprint, d.agent_last_checkin,
|
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
|
FROM devices d
|
||||||
JOIN organizations o ON o.id = d.organization_id
|
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
|
WHERE d.archived_at IS NULL
|
||||||
ORDER BY o.name, d.hostname NULLS LAST, d.created_at
|
ORDER BY o.name, d.hostname NULLS LAST, d.created_at
|
||||||
"""
|
"""
|
||||||
@ -1401,10 +1413,13 @@ def fetch_all_devices():
|
|||||||
"deprovisioned_at": (
|
"deprovisioned_at": (
|
||||||
deprovisioned_at.isoformat() if deprovisioned_at is not None else None
|
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 (
|
for (
|
||||||
device_id, hostname, fingerprint, last_checkin,
|
device_id, hostname, fingerprint, last_checkin,
|
||||||
organization_id, organization_name, deprovisioned_at,
|
organization_id, organization_name, deprovisioned_at,
|
||||||
|
oe_id, oe_name,
|
||||||
) in cur.fetchall()
|
) in cur.fetchall()
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user