ligbox-ops-platform/app/desk_tickets.py
Ligbox Spec Hub 3a2c64834b Initial import: ligbox-ops-platform + specs + LAPTOP + obsidian merge (CT130)
Source: VM122 /opt + obsidian-infra + LAPTOP
Hub: CT130 spec-hub 10.10.10.130
2026-06-19 17:26:41 +00:00

105 lines
2.8 KiB
Python

"""Desk-internal tickets (registration, infra ops)."""
from __future__ import annotations
import json
import sqlite3
from datetime import datetime, timezone
DESK_SOURCE = "desk-registration"
OPS_TENANT_ID = 1
def _now() -> str:
return datetime.now(timezone.utc).isoformat()
def create_ticket(
conn: sqlite3.Connection,
*,
subject: str,
event: str,
email: str,
data: dict,
assigned_to: str | None = None,
) -> int:
payload = {
"event": event,
"source": DESK_SOURCE,
"domain": email,
"data": data,
}
cur = conn.execute(
"""
INSERT INTO tickets (tenant_id, subject, status, payload, created_at, assigned_to, assigned_at)
VALUES (?, ?, 'open', ?, ?, ?, ?)
""",
(
OPS_TENANT_ID,
subject,
json.dumps(payload),
_now(),
assigned_to,
_now() if assigned_to else None,
),
)
conn.commit()
return int(cur.lastrowid)
def ticket_registration_pending(conn: sqlite3.Connection, request_id: int, email: str, display_name: str | None) -> int:
name = display_name or email
return create_ticket(
conn,
subject=f"[cadastro pendente] {email}{name}",
event="desk.registration.pending",
email=email,
data={
"request_id": request_id,
"display_name": display_name,
"status": "pending",
"message": "Novo pedido de acesso ao Ligbox Ops Desk. Aprovar em Mensagens.",
},
assigned_to="root",
)
def ticket_registration_approved(
conn: sqlite3.Connection,
request_id: int,
email: str,
role: str,
activation_url: str,
display_name: str | None,
) -> int:
name = display_name or email
return create_ticket(
conn,
subject=f"[ativar conta] {email}{name}",
event="desk.registration.approved",
email=email,
data={
"request_id": request_id,
"role": role,
"status": "approved",
"activation_url": activation_url,
"message": "Conta aprovada. Complete 2 de 3 fatores (e-mail, telefone ou app 2FA) no link abaixo.",
},
assigned_to=email,
)
def ticket_postfix_ready(conn: sqlite3.Connection, pending_activations: list[dict]) -> int:
return create_ticket(
conn,
subject="[infra] Postfix VM122 ativo — e-mails Desk operacionais",
event="desk.infra.postfix",
email="ligbox-ops@itecnologys.com",
data={
"status": "completed",
"relayhost": "10.10.10.112",
"pending_activations": pending_activations,
"message": "Postfix instalado na VM122 (relay interno VM112). E-mails de cadastro/OTP ativos.",
},
assigned_to="root",
)