Zabbix supply backend rebuild + data-driven model supplies

Rewrite the printer Zabbix integration (Bearer auth, host-by-IP, tag-based
supply lookup, ping) and replace the hardcoded toner table with a
modelsupplies table + CRUD + seed. Add mock Zabbix server, live test
harness, and the Playwright screenshot tooling.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-06-26 08:35:02 -04:00
parent 9d78b363dc
commit f1b3b65532
14 changed files with 1411 additions and 103 deletions

55
tools/shot.py Normal file
View File

@@ -0,0 +1,55 @@
"""Headless-Chromium screenshot helper for the dev UI.
Logs in once via the API, injects the token into localStorage the same way
the auth store does, then screenshots each path passed on the command line.
venv/bin/python tools/shot.py /printers/1 /reports/toner /printers/1/edit
Images land in the scratchpad dir as shot_<sanitised-path>.png.
"""
import sys
import json
import urllib.request
from playwright.sync_api import sync_playwright
UI = "http://localhost:5173"
API = "http://localhost:5001/api"
USERNAME = "270015376"
PASSWORD = "changeme"
OUTDIR = "/tmp/claude-1000/-home-camp-projects/effc3424-ed5e-4b09-b83e-d141bee23c42/scratchpad"
def login():
body = json.dumps({"username": USERNAME, "password": PASSWORD}).encode()
loginrequest = urllib.request.Request(f"{API}/auth/login", data=body,
headers={"Content-Type": "application/json"})
data = json.load(urllib.request.urlopen(loginrequest))["data"]
return data["access_token"], data["refresh_token"], data["user"]
def main(paths):
token, refresh, user = login()
seed = f"""
localStorage.setItem('token', {json.dumps(token)});
localStorage.setItem('refreshToken', {json.dumps(refresh)});
localStorage.setItem('user', {json.dumps(json.dumps(user))});
"""
with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context(viewport={"width": 1400, "height": 1000})
context.add_init_script(seed)
page = context.new_page()
for path in paths:
page.goto(f"{UI}{path}", wait_until="networkidle", timeout=30000)
page.wait_for_timeout(1200) # let supply fetch + render settle
name = "shot_" + (path.strip("/").replace("/", "_") or "home") + ".png"
out = f"{OUTDIR}/{name}"
page.screenshot(path=out, full_page=True)
print(out)
browser.close()
if __name__ == "__main__":
main(sys.argv[1:] or ["/printers/1"])