- Server: ORM-Modelle Kontaktadresse (kontaktadressen) und CallLog (call_logs) mit FK projekt_id - Server: Geschäftslogik kontaktadresse.py und call_log.py (get/create/update/delete) - Server: DB-Migration V01_03 (kontaktadressen + call_logs Tabellen) - Server: REST-Endpunkte /xhr/kontaktadresse/* und /xhr/calllog/* mit Autorisierung - Server: CLI init-db legt Muster-Kontaktadressen (1-3/Projekt) und Muster-Gesprächsnotizen (2-5/Projekt) an - Client: kontaktadresse.ts auf REST umgestellt, snake_case, In-Memory entfernt - Client: call_log.ts auf REST umgestellt, snake_case, In-Memory entfernt, Submit-Handler implementiert - Client: projekt.ts In-Memory vollständig entfernt (keine weiteren Verbraucher) - Client: Route-Params projektId → projekt_id korrigiert (3 Stellen in projekt.ts) - Client: addCallLog in projekt.ts Route-Params auf snake_case angepasst - AGENTS.md: Erinnerung client-build-Skill nach .ts-Änderungen hinzugefügt Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
256 lines
8.6 KiB
Python
256 lines
8.6 KiB
Python
"""
|
|
REST-Endpunkte für die CRM-Domain.
|
|
|
|
Die Endpunkte orientieren sich 1:1 an den clientseitig definierten Pfaden
|
|
(siehe Client/models/*.ts). Pro Entität gibt es einen zusammenhängenden Block
|
|
mit den Aktionen list/get/create/update/delete.
|
|
|
|
Die Autorisierung erfolgt über den Decorator authorisation_required; AppAdmin
|
|
und SysAdmin sind darin implizit immer erlaubt. Die Rollen Mitarbeiter und
|
|
KundenManager werden aus crm.model importiert.
|
|
|
|
:author: Mistral Vibe <vibe@mistral.ai>
|
|
:date: 2026-09-02
|
|
:version: 1.0
|
|
"""
|
|
from flask import current_app as app
|
|
from flask import jsonify, request
|
|
|
|
from auth.decorators import authorisation_required
|
|
from crm.model import KUNDEN_MANAGER, MITARBEITER
|
|
from crm.model import kunde as kunden
|
|
from crm.model import kontakt as kontakte
|
|
from crm.model import projekt as projekte
|
|
from crm.model import kontaktadresse as kontaktadressen
|
|
from crm.model import call_log as call_logs
|
|
|
|
print("crm-routes")
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Kunde #
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
@app.get("/xhr/kunde/list")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def kunde_list():
|
|
"""Liefert alle Kunden als Liste."""
|
|
result = [k.to_dict() for k in kunden.get_kunden()]
|
|
return jsonify(result), 200
|
|
|
|
|
|
@app.get("/xhr/kunde/get")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def kunde_get():
|
|
"""Liefert einen einzelnen Kunden anhand seiner ID (Query-Param id)."""
|
|
kunde = kunden.get_kunde(int(request.args.get("id")))
|
|
return jsonify(kunde.to_dict()), 200
|
|
|
|
|
|
@app.post("/xhr/kunde/create")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kunde_create():
|
|
"""Legt einen neuen Kunden an. ID wird serverseitig vergeben."""
|
|
kunde = kunden.create_kunde(request.json)
|
|
return jsonify(kunde.to_dict()), 200
|
|
|
|
|
|
@app.put("/xhr/kunde/update")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kunde_update():
|
|
"""Aktualisiert einen bestehenden Kunden."""
|
|
kunde = kunden.update_kunde(request.json)
|
|
return jsonify(kunde.to_dict()), 200
|
|
|
|
|
|
@app.delete("/xhr/kunde/delete")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kunde_delete():
|
|
"""Löscht einen Kunden anhand seiner ID (Query-Param id)."""
|
|
kunden.delete_kunde(int(request.args.get("id")))
|
|
return jsonify({}), 200
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Kontakt #
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
@app.get("/xhr/kontakt/list")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def kontakt_list():
|
|
"""Liefert alle Kontakte als Liste."""
|
|
result = [k.to_dict() for k in kontakte.get_kontakte()]
|
|
return jsonify(result), 200
|
|
|
|
|
|
@app.get("/xhr/kontakt/get")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def kontakt_get():
|
|
"""Liefert einen einzelnen Kontakt anhand seiner ID (Query-Param id)."""
|
|
kontakt = kontakte.get_kontakt(int(request.args.get("id")))
|
|
return jsonify(kontakt.to_dict()), 200
|
|
|
|
|
|
@app.post("/xhr/kontakt/create")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kontakt_create():
|
|
"""Legt einen neuen Kontakt an. ID wird serverseitig vergeben."""
|
|
kontakt = kontakte.create_kontakt(request.json)
|
|
return jsonify(kontakt.to_dict()), 200
|
|
|
|
|
|
@app.put("/xhr/kontakt/update")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kontakt_update():
|
|
"""Aktualisiert einen bestehenden Kontakt."""
|
|
kontakt = kontakte.update_kontakt(request.json)
|
|
return jsonify(kontakt.to_dict()), 200
|
|
|
|
|
|
@app.delete("/xhr/kontakt/delete")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kontakt_delete():
|
|
"""Löscht einen Kontakt anhand seiner ID (Query-Param id)."""
|
|
kontakte.delete_kontakt(int(request.args.get("id")))
|
|
return jsonify({}), 200
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Projekt #
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
@app.get("/xhr/projekt/list")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def projekt_list():
|
|
"""Liefert alle Projekte als Liste."""
|
|
result = [p.to_dict() for p in projekte.get_projekte()]
|
|
return jsonify(result), 200
|
|
|
|
|
|
@app.get("/xhr/projekt/get")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def projekt_get():
|
|
"""Liefert ein einzelnes Projekt anhand seiner ID (Query-Param id)."""
|
|
projekt = projekte.get_projekt(int(request.args.get("id")))
|
|
return jsonify(projekt.to_dict()), 200
|
|
|
|
|
|
@app.post("/xhr/projekt/create")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def projekt_create():
|
|
"""Legt ein neues Projekt an. ID wird serverseitig vergeben."""
|
|
projekt = projekte.create_projekt(request.json)
|
|
return jsonify(projekt.to_dict()), 200
|
|
|
|
|
|
@app.put("/xhr/projekt/update")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def projekt_update():
|
|
"""Aktualisiert ein bestehendes Projekt."""
|
|
projekt = projekte.update_projekt(request.json)
|
|
return jsonify(projekt.to_dict()), 200
|
|
|
|
|
|
@app.delete("/xhr/projekt/delete")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def projekt_delete():
|
|
"""Löscht ein Projekt anhand seiner ID (Query-Param id)."""
|
|
projekte.delete_projekt(int(request.args.get("id")))
|
|
return jsonify({}), 200
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# Kontaktadresse #
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
@app.get("/xhr/kontaktadresse/list")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def kontaktadresse_list():
|
|
"""Liefert alle Kontaktadressen als Liste."""
|
|
result = [k.to_dict() for k in kontaktadressen.get_kontaktadressen()]
|
|
return jsonify(result), 200
|
|
|
|
|
|
@app.get("/xhr/kontaktadresse/get")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def kontaktadresse_get():
|
|
"""Liefert eine einzelne Kontaktadresse anhand ihrer ID (Query-Param id)."""
|
|
kontaktadresse = kontaktadressen.get_kontaktadresse(int(request.args.get("id")))
|
|
return jsonify(kontaktadresse.to_dict()), 200
|
|
|
|
|
|
@app.post("/xhr/kontaktadresse/create")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kontaktadresse_create():
|
|
"""Legt eine neue Kontaktadresse an. ID wird serverseitig vergeben."""
|
|
kontaktadresse = kontaktadressen.create_kontaktadresse(request.json)
|
|
return jsonify(kontaktadresse.to_dict()), 200
|
|
|
|
|
|
@app.put("/xhr/kontaktadresse/update")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kontaktadresse_update():
|
|
"""Aktualisiert eine bestehende Kontaktadresse."""
|
|
kontaktadresse = kontaktadressen.update_kontaktadresse(request.json)
|
|
return jsonify(kontaktadresse.to_dict()), 200
|
|
|
|
|
|
@app.delete("/xhr/kontaktadresse/delete")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def kontaktadresse_delete():
|
|
"""Löscht eine Kontaktadresse anhand ihrer ID (Query-Param id)."""
|
|
kontaktadressen.delete_kontaktadresse(int(request.args.get("id")))
|
|
return jsonify({}), 200
|
|
|
|
|
|
# --------------------------------------------------------------------------- #
|
|
# CallLog (Gesprächsnotiz) #
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
|
|
@app.get("/xhr/calllog/list")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def calllog_list():
|
|
"""Liefert alle Gesprächsnotizen als Liste."""
|
|
result = [l.to_dict() for l in call_logs.get_call_logs()]
|
|
return jsonify(result), 200
|
|
|
|
|
|
@app.get("/xhr/calllog/get")
|
|
@authorisation_required([MITARBEITER, KUNDEN_MANAGER])
|
|
def calllog_get():
|
|
"""Liefert eine einzelne Gesprächsnotiz anhand ihrer ID (Query-Param id)."""
|
|
call_log = call_logs.get_call_log(int(request.args.get("id")))
|
|
return jsonify(call_log.to_dict()), 200
|
|
|
|
|
|
@app.post("/xhr/calllog/create")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def calllog_create():
|
|
"""Legt eine neue Gesprächsnotiz an. ID wird serverseitig vergeben."""
|
|
call_log = call_logs.create_call_log(request.json)
|
|
return jsonify(call_log.to_dict()), 200
|
|
|
|
|
|
@app.put("/xhr/calllog/update")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def calllog_update():
|
|
"""Aktualisiert eine bestehende Gesprächsnotiz."""
|
|
call_log = call_logs.update_call_log(request.json)
|
|
return jsonify(call_log.to_dict()), 200
|
|
|
|
|
|
@app.delete("/xhr/calllog/delete")
|
|
@authorisation_required([KUNDEN_MANAGER])
|
|
def calllog_delete():
|
|
"""Löscht eine Gesprächsnotiz anhand ihrer ID (Query-Param id)."""
|
|
call_logs.delete_call_log(int(request.args.get("id")))
|
|
return jsonify({}), 200
|
|
|
|
|
|
print("########## crm.routes importiert")
|