Add EPI-Support monitoring & analytics platform

Internal Flask app that monitors the epi-helpdesk.zammad.com tickets via
the Zammad API, deployable as a systemd service behind Apache under
/episupport.

Features:
- Poller: session-login API sync, snapshot diff to detect agent changes
  (status, owner, priority, closures, new replies); email notifications
- Dashboard: ticket overview with sorting, "not closed" filter and
  highlighting of tickets with unconfirmed changes; per-item and bulk
  "mark as read"
- Analytics: KPIs, response/resolution times, monthly SVG trend chart,
  distributions (status/priority/group/agent), Excel export
- Conversation view: full per-ticket thread cached in the DB (avoids
  proxy timeouts), inline image attachments, safe HTML-to-text rendering
- Write actions: reply to tickets and create new tickets with a
  confirmation step and attachment upload (incl. clipboard paste);
  self-triggered actions are synced back so they aren't flagged as changes
- Local timezone display (Europe/Berlin) for all timestamps

Includes deploy tooling: setup.sh, systemd units and Apache config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 09:19:53 +02:00
co-authored by Claude Opus 4.8
parent da2f7c3c86
commit 1041f283a4
17 changed files with 600 additions and 57 deletions
+16
View File
@@ -53,6 +53,22 @@ CREATE INDEX IF NOT EXISTS idx_changes_detected ON changes(detected_at DESC);
CREATE INDEX IF NOT EXISTS idx_changes_ticket ON changes(ticket_id);
CREATE INDEX IF NOT EXISTS idx_changes_seen ON changes(seen);
CREATE TABLE IF NOT EXISTS articles (
article_id INTEGER PRIMARY KEY,
ticket_id INTEGER NOT NULL,
sender TEXT,
frm TEXT,
subject TEXT,
body TEXT,
content_type TEXT,
internal INTEGER,
created_at TEXT,
attachments TEXT,
fetched_at TEXT
);
CREATE INDEX IF NOT EXISTS idx_articles_ticket ON articles(ticket_id, created_at);
CREATE TABLE IF NOT EXISTS sync_runs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
started_at TEXT,