feat: Nutzerverwaltung + CMDB + Wissensdatenbank (Grundgeruest)
This commit is contained in:
parent
b802d252ba
commit
8c089d4f67
175
db.py
175
db.py
|
|
@ -135,6 +135,36 @@ def email_exists(email):
|
|||
return cur.fetchone() is not None
|
||||
|
||||
|
||||
def list_users(tenant_id):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
cur.execute(
|
||||
"SELECT id, email, role, active, auth_source, created_at, last_login_at "
|
||||
"FROM users WHERE tenant_id=%s ORDER BY email", (tenant_id,))
|
||||
return cur.fetchall()
|
||||
|
||||
|
||||
def get_user(tenant_id, user_id):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
cur.execute(
|
||||
"SELECT id, email, role, active, auth_source, created_at, last_login_at "
|
||||
"FROM users WHERE tenant_id=%s AND id=%s", (tenant_id, user_id))
|
||||
return cur.fetchone()
|
||||
|
||||
|
||||
def set_user_role(tenant_id, user_id, role):
|
||||
with get_conn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("UPDATE users SET role=%s WHERE tenant_id=%s AND id=%s", (role, tenant_id, user_id))
|
||||
|
||||
|
||||
def set_user_active(tenant_id, user_id, active):
|
||||
with get_conn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("UPDATE users SET active=%s WHERE tenant_id=%s AND id=%s", (active, tenant_id, user_id))
|
||||
|
||||
|
||||
# ── Audit-Log ───────────────────────────────────────────────────────────────────
|
||||
def log_audit(tenant_id, user_id, aktion, entity_typ=None, entity_id=None, details=None, ip=None):
|
||||
with get_conn() as conn:
|
||||
|
|
@ -321,3 +351,148 @@ def run_retention_cleanup():
|
|||
finally:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("SELECT pg_advisory_unlock(%s)", (_RETENTION_LOCK_KEY,))
|
||||
|
||||
|
||||
|
||||
# ── CMDB (Configuration Management Database) ─────────────────────────────────
|
||||
def create_ci(tenant_id, name, ci_typ, status, beschreibung, attribute):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
cur.execute(
|
||||
"""INSERT INTO configuration_items
|
||||
(tenant_id, name, ci_typ, status, beschreibung, attribute)
|
||||
VALUES (%s,%s,%s,%s,%s,%s) RETURNING id""",
|
||||
(tenant_id, name, ci_typ, status, beschreibung, json.dumps(attribute or {})),
|
||||
)
|
||||
return cur.fetchone()["id"]
|
||||
|
||||
|
||||
def list_cis(tenant_id, ci_typ=None):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
if ci_typ:
|
||||
cur.execute(
|
||||
"SELECT * FROM configuration_items WHERE tenant_id=%s AND ci_typ=%s ORDER BY name",
|
||||
(tenant_id, ci_typ))
|
||||
else:
|
||||
cur.execute(
|
||||
"SELECT * FROM configuration_items WHERE tenant_id=%s ORDER BY ci_typ, name",
|
||||
(tenant_id,))
|
||||
return cur.fetchall()
|
||||
|
||||
|
||||
def get_ci(tenant_id, ci_id):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
cur.execute(
|
||||
"SELECT * FROM configuration_items WHERE tenant_id=%s AND id=%s",
|
||||
(tenant_id, ci_id))
|
||||
ci = cur.fetchone()
|
||||
if not ci:
|
||||
return None
|
||||
ci = dict(ci)
|
||||
cur.execute(
|
||||
"""SELECT r.*, c.name AS to_name FROM ci_relationships r
|
||||
JOIN configuration_items c ON c.id = r.to_ci_id
|
||||
WHERE r.tenant_id=%s AND r.from_ci_id=%s ORDER BY r.id""",
|
||||
(tenant_id, ci_id))
|
||||
ci["rel_out"] = cur.fetchall()
|
||||
cur.execute(
|
||||
"""SELECT r.*, c.name AS from_name FROM ci_relationships r
|
||||
JOIN configuration_items c ON c.id = r.from_ci_id
|
||||
WHERE r.tenant_id=%s AND r.to_ci_id=%s ORDER BY r.id""",
|
||||
(tenant_id, ci_id))
|
||||
ci["rel_in"] = cur.fetchall()
|
||||
return ci
|
||||
|
||||
|
||||
def update_ci(tenant_id, ci_id, name, ci_typ, status, beschreibung, attribute):
|
||||
with get_conn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""UPDATE configuration_items SET name=%s, ci_typ=%s, status=%s,
|
||||
beschreibung=%s, attribute=%s, updated_at=now()
|
||||
WHERE tenant_id=%s AND id=%s""",
|
||||
(name, ci_typ, status, beschreibung, json.dumps(attribute or {}), tenant_id, ci_id),
|
||||
)
|
||||
|
||||
|
||||
def delete_ci(tenant_id, ci_id):
|
||||
with get_conn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("DELETE FROM configuration_items WHERE tenant_id=%s AND id=%s", (tenant_id, ci_id))
|
||||
|
||||
|
||||
def create_ci_relationship(tenant_id, from_ci_id, to_ci_id, beziehungs_typ):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
cur.execute(
|
||||
"""INSERT INTO ci_relationships (tenant_id, from_ci_id, to_ci_id, beziehungs_typ)
|
||||
VALUES (%s,%s,%s,%s) RETURNING id""",
|
||||
(tenant_id, from_ci_id, to_ci_id, beziehungs_typ),
|
||||
)
|
||||
return cur.fetchone()["id"]
|
||||
|
||||
|
||||
def delete_ci_relationship(tenant_id, rel_id):
|
||||
with get_conn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("DELETE FROM ci_relationships WHERE tenant_id=%s AND id=%s", (tenant_id, rel_id))
|
||||
|
||||
|
||||
# ── Wissensdatenbank ──────────────────────────────────────────────────────────
|
||||
def create_kb_article(tenant_id, titel, kategorie, inhalt, tags, autor_user_id):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
cur.execute(
|
||||
"""INSERT INTO kb_articles (tenant_id, titel, kategorie, inhalt, tags, autor_user_id)
|
||||
VALUES (%s,%s,%s,%s,%s,%s) RETURNING id""",
|
||||
(tenant_id, titel, kategorie, inhalt, tags, autor_user_id),
|
||||
)
|
||||
return cur.fetchone()["id"]
|
||||
|
||||
|
||||
def list_kb_articles(tenant_id, kategorie=None, q=None):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
sql = """SELECT k.*, u.email AS autor_email FROM kb_articles k
|
||||
LEFT JOIN users u ON u.id = k.autor_user_id
|
||||
WHERE k.tenant_id=%s"""
|
||||
params = [tenant_id]
|
||||
if kategorie:
|
||||
sql += " AND k.kategorie=%s"
|
||||
params.append(kategorie)
|
||||
if q:
|
||||
sql += " AND (k.titel ILIKE %s OR k.inhalt ILIKE %s OR k.tags ILIKE %s)"
|
||||
like = "%%%s%%" % q
|
||||
params += [like, like, like]
|
||||
sql += " ORDER BY k.updated_at DESC"
|
||||
cur.execute(sql, params)
|
||||
return cur.fetchall()
|
||||
|
||||
|
||||
def get_kb_article(tenant_id, article_id):
|
||||
with get_conn() as conn:
|
||||
with _dict_cursor(conn) as cur:
|
||||
cur.execute(
|
||||
"""SELECT k.*, u.email AS autor_email FROM kb_articles k
|
||||
LEFT JOIN users u ON u.id = k.autor_user_id
|
||||
WHERE k.tenant_id=%s AND k.id=%s""",
|
||||
(tenant_id, article_id))
|
||||
return cur.fetchone()
|
||||
|
||||
|
||||
def update_kb_article(tenant_id, article_id, titel, kategorie, inhalt, tags):
|
||||
with get_conn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""UPDATE kb_articles SET titel=%s, kategorie=%s, inhalt=%s, tags=%s, updated_at=now()
|
||||
WHERE tenant_id=%s AND id=%s""",
|
||||
(titel, kategorie, inhalt, tags, tenant_id, article_id),
|
||||
)
|
||||
|
||||
|
||||
def delete_kb_article(tenant_id, article_id):
|
||||
with get_conn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("DELETE FROM kb_articles WHERE tenant_id=%s AND id=%s", (tenant_id, article_id))
|
||||
|
|
|
|||
Loading…
Reference in New Issue