feat: Kontakt-/Stammdaten je Organisation (organizations)
Neue Spalten kontakt_name, adresse, telefon, kontakt_email, notizen -
bewusst nur einfache Kontaktdaten, keine Richtlinien-/Sicherheitsfelder
(Network Profile/Secret Reference bleiben laut ADR-0001 weiterhin
unspezifiziert, eigenständiges Thema). Bestehender PATCH-Endpoint
(/api/v1/organizations/{id}) wird nur breiter, keine neue Route.
fetch_organizations() (Liste, fuer den Admin-Bereich) und
fetch_organization() (Einzelabruf, fuer Self-Service) beide erweitert,
damit intern und im Kundenportal dieselben Daten sichtbar sind.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e5b7081955
commit
34e5254984
67
app.py
67
app.py
@ -90,6 +90,11 @@ class CreateOrganizationRequest(BaseModel):
|
|||||||
|
|
||||||
class UpdateOrganizationRequest(BaseModel):
|
class UpdateOrganizationRequest(BaseModel):
|
||||||
name: str
|
name: str
|
||||||
|
kontakt_name: str | None = None
|
||||||
|
adresse: str | None = None
|
||||||
|
telefon: str | None = None
|
||||||
|
kontakt_email: str | None = None
|
||||||
|
notizen: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class CreateMerkmalRequest(BaseModel):
|
class CreateMerkmalRequest(BaseModel):
|
||||||
@ -1604,22 +1609,42 @@ def archive_device(device_id: str) -> bool:
|
|||||||
)
|
)
|
||||||
return cur.fetchone() is not None
|
return cur.fetchone() is not None
|
||||||
|
|
||||||
|
ORGANIZATION_KONTAKTFELDER = ("kontakt_name", "adresse", "telefon", "kontakt_email", "notizen")
|
||||||
|
|
||||||
def fetch_organizations():
|
def fetch_organizations():
|
||||||
with get_database_connection() as conn:
|
with get_database_connection() as conn:
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"SELECT id, name, created_at FROM organizations ORDER BY name"
|
"""
|
||||||
|
SELECT id, name, created_at, kontakt_name, adresse, telefon, kontakt_email, notizen
|
||||||
|
FROM organizations ORDER BY name
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
return [
|
return [
|
||||||
{"id": str(org_id), "name": name, "created_at": created_at.isoformat()}
|
{
|
||||||
for org_id, name, created_at in cur.fetchall()
|
"id": str(org_id),
|
||||||
|
"name": name,
|
||||||
|
"created_at": created_at.isoformat(),
|
||||||
|
"kontakt_name": kontakt_name,
|
||||||
|
"adresse": adresse,
|
||||||
|
"telefon": telefon,
|
||||||
|
"kontakt_email": kontakt_email,
|
||||||
|
"notizen": notizen,
|
||||||
|
}
|
||||||
|
for (
|
||||||
|
org_id, name, created_at,
|
||||||
|
kontakt_name, adresse, telefon, kontakt_email, notizen,
|
||||||
|
) in cur.fetchall()
|
||||||
]
|
]
|
||||||
|
|
||||||
def fetch_organization(organization_id: str):
|
def fetch_organization(organization_id: str):
|
||||||
with get_database_connection() as conn:
|
with get_database_connection() as conn:
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"SELECT id, name, created_at FROM organizations WHERE id = %s",
|
"""
|
||||||
|
SELECT id, name, created_at, kontakt_name, adresse, telefon, kontakt_email, notizen
|
||||||
|
FROM organizations WHERE id = %s
|
||||||
|
""",
|
||||||
(organization_id,),
|
(organization_id,),
|
||||||
)
|
)
|
||||||
row = cur.fetchone()
|
row = cur.fetchone()
|
||||||
@ -1627,7 +1652,16 @@ def fetch_organization(organization_id: str):
|
|||||||
if row is None:
|
if row is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return {"id": str(row[0]), "name": row[1], "created_at": row[2].isoformat()}
|
return {
|
||||||
|
"id": str(row[0]),
|
||||||
|
"name": row[1],
|
||||||
|
"created_at": row[2].isoformat(),
|
||||||
|
"kontakt_name": row[3],
|
||||||
|
"adresse": row[4],
|
||||||
|
"telefon": row[5],
|
||||||
|
"kontakt_email": row[6],
|
||||||
|
"notizen": row[7],
|
||||||
|
}
|
||||||
|
|
||||||
def create_organization(name: str):
|
def create_organization(name: str):
|
||||||
organization_id = uuid4()
|
organization_id = uuid4()
|
||||||
@ -1652,12 +1686,26 @@ def create_organization(name: str):
|
|||||||
|
|
||||||
return {"id": str(organization_id), "name": name}
|
return {"id": str(organization_id), "name": name}
|
||||||
|
|
||||||
def update_organization(organization_id: str, name: str):
|
def update_organization(organization_id: str, name: str, kontaktfelder: dict):
|
||||||
with get_database_connection() as conn:
|
with get_database_connection() as conn:
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
cur.execute(
|
cur.execute(
|
||||||
"UPDATE organizations SET name = %s WHERE id = %s RETURNING id, name",
|
"""
|
||||||
(name, organization_id),
|
UPDATE organizations
|
||||||
|
SET name = %s, kontakt_name = %s, adresse = %s, telefon = %s,
|
||||||
|
kontakt_email = %s, notizen = %s
|
||||||
|
WHERE id = %s
|
||||||
|
RETURNING id, name
|
||||||
|
""",
|
||||||
|
(
|
||||||
|
name,
|
||||||
|
kontaktfelder.get("kontakt_name"),
|
||||||
|
kontaktfelder.get("adresse"),
|
||||||
|
kontaktfelder.get("telefon"),
|
||||||
|
kontaktfelder.get("kontakt_email"),
|
||||||
|
kontaktfelder.get("notizen"),
|
||||||
|
organization_id,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
row = cur.fetchone()
|
row = cur.fetchone()
|
||||||
|
|
||||||
@ -2691,7 +2739,8 @@ def update_organization_endpoint(
|
|||||||
"message": "Fehlendes oder ungültiges Service-Token.",
|
"message": "Fehlendes oder ungültiges Service-Token.",
|
||||||
}
|
}
|
||||||
|
|
||||||
organization = update_organization(organization_id, payload.name)
|
kontaktfelder = {feld: getattr(payload, feld) for feld in ORGANIZATION_KONTAKTFELDER}
|
||||||
|
organization = update_organization(organization_id, payload.name, kontaktfelder)
|
||||||
|
|
||||||
if organization is None:
|
if organization is None:
|
||||||
return {
|
return {
|
||||||
|
|||||||
16
migrations/0020_organization_kontaktdaten.sql
Normal file
16
migrations/0020_organization_kontaktdaten.sql
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- Kontakt-/Stammdaten je Organisation (Ansprechpartner, Adresse, Telefon,
|
||||||
|
-- Kontakt-E-Mail, Notizen) - bislang hatte organizations ausser dem Namen
|
||||||
|
-- keine Felder. Bewusst nur einfache Stammdaten, keine Richtlinien-/
|
||||||
|
-- Sicherheitsfelder (Network Profile/Secret Reference bleiben laut
|
||||||
|
-- ADR-0001/09-data-model-v1.md weiterhin unspezifiziert, eigenstaendiges
|
||||||
|
-- Thema). Alle Spalten nullable - kein Pflichtfeld, bestehende und neue
|
||||||
|
-- Organisationen starten leer.
|
||||||
|
ALTER TABLE organizations ADD COLUMN kontakt_name TEXT;
|
||||||
|
ALTER TABLE organizations ADD COLUMN adresse TEXT;
|
||||||
|
ALTER TABLE organizations ADD COLUMN telefon TEXT;
|
||||||
|
ALTER TABLE organizations ADD COLUMN kontakt_email TEXT;
|
||||||
|
ALTER TABLE organizations ADD COLUMN notizen TEXT;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
Loading…
x
Reference in New Issue
Block a user