Files
qr-tabellen/CLAUDE.md
2026-07-05 11:00:40 +02:00

3.7 KiB

QR-Tabellen (table.lehrstun.de)

Status

Phase: MVP fertig — lokal verifiziert, Deployment auf Hetzner in Arbeit Stand: 2026-07-05

Zweck

Kleines selbst gehostetes Tool für den Schuleinsatz: CSV-Tabellen (Stationenlernen, Materiallisten, Linksammlungen) werden hochgeladen und als hübsche statische HTML-Seite veröffentlicht; Link-Spalten bekommen automatisch lokal erzeugte QR-Codes (kein externer API-Call, DSGVO). Dateneingabe bleibt bewusst in Excel/LibreOffice — Austausch ausschließlich über CSV.

Quickstart

cd D:\Claude-Projekte\qr-tabellen
venv\Scripts\python -m flask --app app.main run   # Admin: http://localhost:5000/admin/
venv\Scripts\python tests\test_engine.py           # Engine-Selbsttest

Architektur

  • Python 3.13 + Flask + segno — einzige Abhängigkeiten (Jinja2 kommt mit Flask)
  • Kein JS-Framework, keine DB — Ablage im Dateisystem
app/
  engine.py    — Kern: CSV parsen/validieren, QR-SVGs (segno), HTML rendern (framework-frei)
  storage.py   — Dateiablage: Schemas, CSV-Versionen, Veröffentlichung
  main.py      — Flask-Admin: Schema-Designer, Dropzone, Linkliste, Versionen
  templates/   — table.html (öffentliche Seite) + admin/*
  static/      — table.css (Design-Tokens, wird in Seiten eingebettet) + admin.css
data/tables/<slug>/schema.json + versions/<zeitstempel>.csv   (gitignored)
public/<slug>/index.html                                       (gitignored)
tests/test_engine.py — Selbsttest ohne pytest

Datenfluss

  1. Schema online anlegen (Spalten: text, text_long, number, date, url, rating_5)
  2. CSV-Vorlage herunterladen (Semikolon + UTF-8-BOM → Excel-tauglich)
  3. Befüllte CSV in die Dropzone → Zuordnung per Dateiname, sonst Header-Signatur
  4. Validierung (URLs, Bewertung 1-5, Zahlen); bei Fehlern wird nichts gespeichert
  5. Version abgelegt + in sich geschlossene HTML-Seite nach public/<slug>/ gerendert

Produktion (Ziel)

  • Öffentliche Seiten: Nginx liefert public/ statisch aus (App-Ausfall egal)
  • Admin-Panel: Flask via gunicorn + systemd, hinter Nginx Basic Auth unter /admin
  • Env: QT_BASE_URL=https://table.lehrstun.de, QT_DATA_DIR, QT_PUBLIC_DIR

Design

Tokens in table.css (:root-Variablen: Farben, Fonts, QR-Größe, Breite). Systemfont-Stack mit Source Serif 4 / Fira Sans als Wunschfonts — bei Bedarf lokal hosten (kein Google-CDN, Schulkontext). Print-Media-Query vorhanden.

Entscheidungen

Datum Entscheidung Begründung
2026-07-05 Python/Flask + segno statt Node Passt zum Hetzner-Deploy-Muster; csv ist Stdlib, segno erzeugt SVG-QR ohne weitere Deps
2026-07-05 Nur CSV im MVP, kein XLSX Excel/LO speichern CSV; spart exceljs/openpyxl komplett
2026-07-05 Öffentliche Seiten statisch, App nur fürs Admin Schüler-Traffic trifft nie den Python-Prozess; robust bei App-Ausfall
2026-07-05 QR-Codes als Inline-SVG in der Seite Eine Datei pro Tabelle, keine Bild-Assets, skaliert per CSS
2026-07-05 Versions-Erkennung: Dateiname → Header-Signatur → manuell Kein Ratespiel; Vorlage heißt schon <slug>.csv
2026-07-05 Kein Login in der App; Basic Auth via Nginx Single-Admin, unveröffentlichte Slugs reichen für Schüler
2026-07-05 CSV-Vorlage mit Semikolon + UTF-8-BOM Deutsches Excel öffnet sie direkt korrekt
2026-07-05 Fehlerhafte CSVs werden komplett abgelehnt Klare Fehlermeldung statt halb veröffentlichter Tabelle

Blocker

  • Keine

Nächste Schritte

  • Deployment: DNS table.lehrstun.de, Gitea-Repo, gunicorn + systemd, Nginx (statisch + /admin Basic Auth), TLS
  • Design-Feintuning (Tokens in table.css), ggf. Fonts lokal hosten
  • Später: XLSX-Direkt-Upload, QR-Label-Styling, XLSX-Re-Export mit QR-Bildern