feat(import): RennmausPro-III-Analyse — Abgleich, Dedup, Feature-Gap, Ticket-Generierung

- compare_rpro3.py: RPRO3-SQLite ↔ aktueller Stand (Dedup Name+DOB+Farbe+Herkunft)
- rpro3-vergleich.md / rpro3-feature-gap.md: erzeugte Reports
- rpro3_tickets.py / rpro3_post_tickets.py: 413 Rückfrage-Tickets mit Herkunft + Links

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 22:38:24 +02:00
parent c15dd78bc7
commit 4e30dc7fe3
5 changed files with 1239 additions and 0 deletions

View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Postet die von rpro3_tickets.py erzeugten Rückfrage-Tickets in die laufende WebAPI.
Pro Ticket: POST /feedback (legt „Open" an, mit GerbilId/EntityName) + PUT /feedback/{id}
(setzt Question -> NeedsInfo, und AgentContext).
Re-runfähig: überspringt Tickets, deren EntityName bereits als Context=rpro3-import existiert.
Aufruf: python rpro3_post_tickets.py <tickets.json> [http://localhost:5179]
"""
from __future__ import annotations
import sys, json, urllib.request, urllib.error
def req(method, url, body=None):
data = json.dumps(body, ensure_ascii=False).encode("utf-8") if body is not None else None
r = urllib.request.Request(url, data=data, method=method,
headers={"Content-Type": "application/json; charset=utf-8"})
with urllib.request.urlopen(r, timeout=30) as resp:
raw = resp.read().decode("utf-8")
return json.loads(raw) if raw else None
def main():
tickets_path = sys.argv[1]
base = sys.argv[2] if len(sys.argv) > 2 else "http://localhost:5179"
tickets = json.load(open(tickets_path, encoding="utf-8"))
existing = req("GET", f"{base}/feedback") or []
seen = {f.get("entityName") for f in existing if f.get("context") == "rpro3-import"}
print(f"Vorhandene rpro3-import-Tickets: {len(seen)}")
created = skipped = failed = 0
for i, tk in enumerate(tickets, 1):
if tk["EntityName"] in seen:
skipped += 1
continue
try:
post_body = {
"message": tk["Message"],
"context": tk["Context"],
"entityName": tk["EntityName"],
"gerbilId": tk.get("GerbilId"),
}
created_dto = req("POST", f"{base}/feedback", post_body)
fid = created_dto["id"]
req("PUT", f"{base}/feedback/{fid}", {
"question": tk["Question"],
"agentContext": tk["AgentContext"],
})
created += 1
seen.add(tk["EntityName"])
if created % 50 == 0:
print(f"{created} erstellt ({i}/{len(tickets)})")
except urllib.error.HTTPError as e:
failed += 1
print(f" FEHLER bei „{tk['EntityName']}\": {e.code} {e.read().decode('utf-8','replace')[:160]}")
except Exception as e: # noqa
failed += 1
print(f" FEHLER bei „{tk['EntityName']}\": {e}")
print(f"\nFertig: {created} erstellt, {skipped} übersprungen, {failed} Fehler.")
if __name__ == "__main__":
main()