rechnungstool/AUFGABE_ONLINE_API_MYSQL.md
TheMockTv 73042b771c Logo in der Statuszeile, Bau an einer Stelle, Startprobe fuer die EXE
Logo
  Das Programmlogo steht jetzt klein neben "powered by ravokk" - dort sitzt
  die Kennung des Werkzeugs, nicht die des Kunden. Eine eigene Kopfzeile hat
  dieses Programm nicht; oben sind die Reiter.

bauen.py
  Der Weg von der Quelle zur Setup-Datei war eine Folge von Befehlen, die
  jemand von Hand eintippen musste. Wer einen Schritt vergisst, liefert eine
  Setup-Datei mit einer alten EXE aus - und sieht es ihr nicht an. Genau das
  ist heute passiert. Jetzt ist es ein Befehl, die Nummer kommt aus
  version.py, und am Ende stehen die SHA256-Summen fuer den Release-Text.

pruef_start_exe.py
  Prueft, was kein anderer Pruefstand prueft: ob die GEBAUTE EXE ein
  sichtbares Fenster zeigt. Alle uebrigen fahren das Programm aus der Quelle,
  dort trat der Fehler nie auf. "Der Prozess laeuft" beweist dabei nichts -
  er lief ja, waehrend nichts zu sehen war.

Aufgeraeumt
  "Rechnung Campinghof.exe" ist weg; gebaute Dateien gehoeren ins Release,
  nicht ins Repo. Die .spec-Dateien dagegen schon: ohne sie kann niemand die
  EXE nachbauen, die der Updater ausliefert.

Fassung 1.7.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
2026-09-06 20:34:59 +02:00

417 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Online-Betrieb: API, MySQL, Tablet, Rechnungsversand
Seine Idee vom 06.09.2026, wörtlich:
> „die software ist aktuell nur lokal, und da reicht sqlite. wenn wir die online funktion einbauen,
> dann muss man einen api key eintragen, und die api verteilt das auf die mysql — dann ist das
> extern auf dem server und du kannst von überall über domain und apikey auch unterwegs per tablet
> beim kunden die rechnung schreiben, live oder vorab-rechnung, und der smtp-server schickt sie
> direkt dem kunden auf die hinterlegte e-mail. fertig. alles automatisch."
**Status: Idee. Nichts davon ist gebaut.** Der Schnitt ist richtig gedacht — lokal SQLite, zentral
MySQL, die API als einzige Tür dazwischen.
---
## 1. ⭐ Die Rechnungsnummer darf nur vom Server kommen
Heute stimmen sich zwei lokale Programme über eine gemeinsame SQLite ab. Zentral wird das
**einfacher**: eine Transaktion in MySQL vergibt die Nummer, fertig.
**Aber:** Auf dem Tablet beim Kunden ohne Empfang darf keine Nummer entstehen.
> **Regel: Offline entsteht ein ENTWURF, keine Rechnung.** Die Nummer wird vergeben, sobald der
> Server erreichbar ist.
Sonst gibt es irgendwann zwei Belege mit derselben Nummer — genau der Fehler, wegen dem das
Amt-Blatt herausgeflogen ist (§ 14 Abs. 4 Nr. 4 UStG).
Daraus folgt für die Oberfläche: Ein Entwurf muss **sichtbar** ein Entwurf sein, ohne Nummer, und
darf nicht ausgedruckt oder verschickt werden können.
## ⭐⭐ Das Offline-Problem — und seine Lösung: NUMMERNKONTINGENTE
Sein Einwand (06.09.2026):
> „das ding, was wir haben, ist das offline-problem. wenn das internet schwach oder weg ist, bringt
> das online nichts — also musst du auf dem client eine kopie per sqlite haben. wie willst es sonst
> machen?"
**Er hat recht, und das ersetzt die zu strenge Regel „offline nur Entwürfe" aus Punkt 1.**
### Was zwischengespeichert werden kann — und was nicht
| | offline möglich? |
|---|---|
| Kundenstamm, Preise, Einstellungen, alte Rechnungen zum Nachschlagen | **ja** — lokale SQLite, lesend, mit sichtbarem Alter |
| **Vergabe der Rechnungsnummer** | **nein** — zwei Geräte nähmen beide „die nächste" |
### Die Lösung: der Server gibt Blöcke im Voraus aus
So machen es Kassensysteme. Tablet A bekommt **2026-101 bis 2026-150**, Tablet B **2026-151 bis
2026-200**. Offline vergibt jedes Gerät aus **seinem eigenen** Block — eine Kollision ist
**unmöglich**, weil kein anderes Gerät diese Nummern besitzt. Bei Netz meldet es den Verbrauch und
holt einen neuen Block.
→ **Damit sind beim Kunden echte Rechnungen möglich, nicht nur Entwürfe.**
### Zwei Bedingungen, die dazugehören
1. **Lücken werden normal — und müssen erklärbar sein.** Kommt Tablet A nur bis 2026-137 und holt
dann einen neuen Block, fehlen 138–150. Das ist zulässig: § 14 UStG verlangt eine **einmalig
vergebene** fortlaufende Nummer, ausdrücklich auch in mehreren Kreisen (z. B. je Filiale).
**Aber das System muss zeigen können, welcher Block wem gehörte und welche Nummern daraus nie
verbraucht wurden.** Sonst sieht ein Prüfer eine Lücke und fragt nach der Rechnung.
→ Gehört in den **Steuerprüfungs-Ausdruck** (siehe `AUFGABE_BEWEISKETTE_PRUEFBAR.md`, Schritt 3).
2. **Der Block ist endlich.** Ist er verbraucht und kein Netz da, ist Schluss — dann wieder
Entwürfe. **Lieber ein Gerät, das sagt „ich kann gerade nicht", als eines, das sich Nummern
ausdenkt.**
### ⭐⭐ Woher die Blockgröße kommt: aus der Disposition (Andreas, 06.09.2026)
> „die disponentin hat jedem handwerker ja kunden zugeteilt — daraus kann ein block generiert
> werden. die software sagt: handwerker hans werner hat 10 kunden, also bekommt er block A mit 10
> nummern, der hans werner heißt. dann ist es erklärbar, weil hans die kunden im log hatte. wenn er
> mehr kunden hatte, bekommt er von anfang an 10 puffernummern als schutz. und wenn die nicht
> gebraucht werden, bekommt er sie für den nächsten tag wieder. wenn sie voll sind, überspringt er
> in den nächsten block. der server hält selber immer reserve."
**Der starke Punkt daran ist die Erklärbarkeit.** Ein Prüfer sieht reservierte Nummernbereiche und
fragt, warum ausgerechnet diese. Hier gibt es eine Antwort **aus dem Betrieb heraus**: Die
Disposition hat Hans an dem Tag zehn Kunden zugeteilt, also zehn Nummern plus Puffer. **Die
Zuteilung ist der Beleg für die Reservierung** — besser als jede technische Begründung.
### ⚠️ Zwei Korrekturen daran
**1. Der Block darf NICHT am Kalendertag hängen.**
*„Heute hast du 100 bis 110"* klingt logisch, ist aber gefährlich: Hat Hans zwei Tage keinen
Empfang, wäre er am zweiten Tag arbeitsunfähig, obwohl er noch Nummern hätte.
> **Der Block gehört ihm, bis er ihn zurückmeldet. Kein Ablaufdatum.** Die Disposition gibt morgens
> neue *dazu*, nimmt aber nichts weg, was er noch hat.
Am Bild der Disposition ändert das nichts — nur verhungert das Tablet nicht, wenn das Netz drei
Tage weg ist.
**2. Eine Nummer ist erst verbraucht, wenn ein BELEG entsteht.**
Nicht bei der Zuteilung, und **nicht durch einen Entwurf**. Nur so stimmt, dass unbenutzte Nummern
am nächsten Tag wieder gelten — sonst würden Nummern wiederverwendet, die schon auf einem
Bildschirm standen.
**Der Rest passt unverändert:** Puffer von Anfang an · Überspringen in den nächsten Block, wenn
voll · **Server hält eigene Reserve** für das, was die Disposition nicht wusste (Notfall,
Zusatzauftrag, Kunde ruft an).
### ⭐ Beim Synchronisieren: Verbrauch melden, nicht blind neu ausgeben
Sein Einwand (06.09.2026):
> „wenn das tablet lte wieder hat, kann er das syncen und bekommt einen neuen block — oder sagt
> einfach: eh, ich habe aber in dem block erst 10 % genutzt"
**Richtig, und das vermeidet Lücken statt sie nur zu erklären.** Das Gerät meldet seinen Stand:
*„2026-101 bis 110 verbraucht, 111 bis 150 gehören mir noch."* Der Server entscheidet:
| Lage | Antwort |
|---|---|
| noch viel übrig | **nichts tun** — kein neuer Block, keine verbrannten Nummern |
| fast leer, folgende Nummern frei | **den vorhandenen Block VERLÄNGERN** (101–150 → 101–180) → **keine Lücke** |
| fast leer, folgende Nummern gehören schon jemandem | neuer Block weiter hinten → Lücke, aber eine, die der Server **benennen** kann |
**Verlängern schlägt Neuausgabe.** Das ist der Unterschied zwischen einem System, das Lücken erzeugt
und sie hinterher erklären muss, und einem, das erst gar keine macht.
### Warum das nicht optional ist
> „kannst ja nicht kunden fragen nach wlan"
Beim Kunden im Keller, im Neubau ohne Anschluss, auf dem Hof: kein WLAN, oft auch kein
Mobilfunknetz. Nach dem Passwort fragen macht kein Handwerker.
**Zwei praktische Regeln daraus:**
1. **Der Block muss großzügig sein** — nicht zehn Nummern, sondern so viele, dass eine Woche Arbeit
hineinpasst. Nummern kosten nichts, ein abgerissener Vorgang beim Kunden schon.
2. **Das Gerät warnt, BEVOR es eng wird.** *„Noch 5 Nummern im Vorrat, bitte einmal ins Netz"* —
solange man noch in der Werkstatt steht. Eine Warnung, die erst beim Kunden kommt, ist wertlos.
Nachgefüllt wird **automatisch**, sobald irgendwo Netz da ist. Der Benutzer soll darüber nicht
nachdenken müssen.
## 2. ⚠️ Beim Datenschutz kippt die Lage vollständig
Heute lautet die Aussage im Programm: *Es verlässt nichts den Rechner.* Das ist der ganze
Datenschutztext. Sobald Gästedaten auf einem Server liegen, gilt die DSGVO in voller Breite:
- verschlüsselte Übertragung (TLS), keine Ausnahme
- **Zugriffstrennung je Betrieb** — ein API-Schlüssel ist ein Passwort, keine Zugriffskontrolle
- Löschkonzept und Aufbewahrungsfristen (§ 147 AO) müssen zusammenpassen
- **Wenn er das für ANDERE Betriebe hostet, ist er deren Auftragsverarbeiter** und braucht einen
Vertrag nach Art. 28 DSGVO. Das ist keine Formalie, sondern Voraussetzung dafür, dass die
Betriebe das Programm überhaupt einsetzen dürfen.
Der Datenschutztext im Programm muss dann neu geschrieben werden — der heutige wäre schlicht falsch.
## 3. ⭐⭐ E-Rechnung (ZUGFeRD) — jetzt entscheiden, nicht später
In Deutschland läuft die Pflicht zur elektronischen Rechnung im B2B an. Wer ein System baut, das
Rechnungen **per Mail verschickt**, sollte die PDF gleich mit **eingebettetem strukturiertem XML**
erzeugen (ZUGFeRD / PDF/A-3).
Der Unterschied zwischen „von Anfang an mitgedacht" und „später nachrüsten" ist hier ein halber
Neubau: PDF/A-3 stellt andere Anforderungen an Schriften und Farbprofile als das heutige PDF, und
das XML muss aus denselben Daten kommen wie das Blatt — nicht daneben gepflegt werden.
Stand schon auf der allerersten Aufgabenliste des Rechnungstools.
## 4. Versand
- **SMTP genügt zum Senden.** POP3/IMAP braucht man nur, um **Unzustellbarkeitsmeldungen** zu lesen
— und die *muss* man lesen. Sonst meldet das Programm „verschickt", und die Rechnung liegt
nirgends.
- **Eine per Mail verschickte Rechnung ist eine Rechnung** (§ 14 UStG). Für die GoBD muss das
Dokument **genau so archiviert werden, wie es verschickt wurde** — samt Versandnachweis.
- Zustellung ist nicht garantiert. Der Versandstatus gehört sichtbar in die Oberfläche, nicht nur
ins Log.
## ⭐ Das Produktbild (Andreas, 06.09.2026) — lokal ist der Normalfall
> „solange er den apikey mit domain nicht hat, kann er auch nur sqlite nutzen — reicht auch, wenn
> einer es als single programm für sich nutzt. will einer das online nutzen, dann trägt er beides
> ein, das programm synct einmal auf die mysql, fertig."
**Damit ist der Aufbau entschieden: local-first, Online ist eine Zusatzfunktion, die man
einschaltet.** Wer nichts einträgt, merkt vom Server nichts. Kein Konto, keine Pflicht, keine
Abhängigkeit.
### Die eine Regel, die den Umzug sicher macht
**„Synct einmal" ist eine EINMALIGE ÜBERNAHME, keine ständige Synchronisierung in beide
Richtungen.** Danach gehört die Nummernvergabe dem Server; die lokale SQLite ist nur noch
Zwischenspeicher für Entwürfe (siehe Punkt 1).
Zwei Richtungen dauerhaft offen zu halten hieße: zwei Stellen vergeben Nummern. Genau der Fehler,
wegen dem das Amt-Blatt herausflog.
### Und daraus folgt eine Entscheidung VOR der ersten Übernahme
Zwei Installationen, die beide 2026-001 bis 2026-050 vergeben haben, lassen sich **nicht** in eine
Datenbank übernehmen — dort lägen Nummern doppelt. Gehen je mehrere Betriebe auf denselben Server,
muss die **Trennung der Nummernkreise vorher** feststehen (eigene Datenbank je Betrieb, oder
Präfix je Betrieb). Nachträglich geht es nicht: die Belege sind dann schon beim Kunden.
### Was der Umzug NICHT gefährdet
**Die Wahrheit bleiben die Rechnungs-PDFs** — so steht es schon heute im Nummernbuch-Code: *„Die
Datei ist ein REGISTER, keine zweite Buchhaltung."* Geht bei der Übernahme etwas schief, fehlt
keine Rechnung; es muss nur neu eingelesen werden.
## ⭐⭐ Die Umschaltung ist eine Tür, die nur in eine Richtung aufgeht
Sein Modell (06.09.2026):
> „ein einmal sync, danach ist es only online. die sql ist dann deaktiviert für immer — außer er
> trägt den key und die domain aus, dann hat er aber einen alten datenstand."
> „das muss er mit einem popup — mit dem speichern-button, den es dafür gibt — am ende noch mal als
> ja/nein-frage kommen, ob ihm das bewusst ist, dass er sozusagen bei 0 anfängt."
### Harte Anforderung
**Beim SPEICHERN** von API-Schlüssel und Domain (nicht beim Eintippen) kommt eine Ja/Nein-Frage.
Beim Tippen weiß niemand, ob es ernst gemeint ist — beim Speichern schon.
Entwurf des Textes:
> **Auf Online-Betrieb umstellen?**
>
> Die vorhandenen Daten werden einmalig auf den Server übernommen. Danach läuft alles über den
> Server: Rechnungsnummern werden dort vergeben, und die lokale Datenbank wird **nicht mehr
> fortgeführt**.
>
> Entfernen Sie später Schlüssel und Domain, arbeitet das Programm wieder lokal weiter — dann aber
> mit dem Stand von **[Datum von heute]**. Alles, was zwischenzeitlich online entstanden ist, fehlt
> dort.
>
> Diese Umstellung lässt sich nicht rückgängig machen.
>
> Jetzt umstellen?
Dasselbe Muster wie beim Erprobungshinweis und bei der Freigabe vor dem Beleg: Der Nutzer wird
**vorher** aufgeklärt, und die Entscheidung wird mit Datum vermerkt.
### Die lokale Datenbank wird STILLGELEGT, nicht gelöscht
Sie ist der Stand von damals und muss lesbar bleiben — schon wegen § 147 AO.
### ⭐ Und der Punkt, der daran hängt: die PDFs müssen erreichbar bleiben
Heute gilt in beiden Programmen: **Die Wahrheit sind die Rechnungs-PDFs, die Datenbank ist nur ein
Register.** Wird künftig auf dem Server erzeugt, muss der Betrieb **jederzeit an alle seine Belege
herankommen — als Dateien**, nicht nur als Ansicht im Browser.
Der Grund ist **§ 147 AO: zehn Jahre Aufbewahrungspflicht.** Ein System, das den Betrieb von seinen
eigenen Belegen trennen kann — Server fällt aus, Vertrag endet, man zerstreitet sich — bringt den
BETRIEB in Schwierigkeiten.
→ **Empfehlung: automatische lokale Kopie jeder Rechnung, auch im Online-Betrieb.** Dann bleibt der
Satz „die Wahrheit sind die PDFs" wahr, und der Betrieb hat seine Unterlagen auch dann, wenn nichts
mehr läuft. Das ist zugleich ein Verkaufsargument.
## 📄 Paperless als Archiv (Andreas, 06.09.2026) — löst die Aufbewahrungsfrage
> „ich dachte später an ein paperless — da muss eh alles rein"
**Das ist die bessere Antwort auf § 147 AO als eine Exportfunktion.** Läuft jede Rechnung
automatisch in ein Dokumentensystem, liegt das Archiv **außerhalb** des Programms und überlebt
sowohl einen abgeschalteten Server als auch das Programm selbst.
**Anbindung ist klein:** Paperless-ngx nimmt Dokumente über eine REST-Schnittstelle **oder über
einen überwachten Ordner** entgegen — Datei hineinlegen, fertig. Für das Rechnungstool eine
zusätzliche Zeile beim Speichern, kein Umbau.
**⭐ Und die Verschlagwortung ist schon gebaut:** Rechnungsnummer, Datum, Beträge, Art und Vorgang
stehen bereits als maschinenlesbare Kenndaten im `/Subject` jeder PDF (das Steuerjournal liest sie
von dort). Daraus kann das Archiv seine Schlagworte ziehen — ohne Abtippen, ohne Texterkennung.
⚠️ **Ehrlicher Vorbehalt:** Ein Dokumentensystem macht **nicht automatisch GoBD-konform**. Es
erfüllt den Kern (Belege bleiben unverändert und vollständig), aber dazu gehört eine
**Verfahrensdokumentation** — wie Belege entstehen, wohin sie laufen, wer was darf. Die schreibt
kein Programm. Ein großer Teil davon steht allerdings schon in den Aufgabendateien und
Commit-Texten dieser Projekte.
## 🔑 Die API ist der Schlüssel zu allem (Andreas, 06.09.2026)
> „das tool schickt es an die api, die api verteilt das alles. die api ist der schlüssel zu allem —
> wie beim gta fivem server"
**Das ist seine eigene Serverregel, angewandt:** *Der Wille kommt vom Client, gerechnet wird auf dem
Server.* (Vgl. PcoreLife: nichts im Client, was Serversachen übernimmt.)
| | Client (Tool/Tablet) | Server (API) |
|---|---|---|
| Was | „Rechnung für diese Leistungen an diesen Kunden" | Nummer vergeben, Beträge und Steuer rechnen, PDF erzeugen |
| Danach | zeigt an, was zurückkommt | verteilt: MySQL · Paperless · Mailversand |
### ⭐ Folge 1: `berechnung.py` zieht auf den Server
Heute steht dort ausdrücklich *„die einzige Stelle, an der gerechnet wird"*. Zentral gehört sie auf
den Server.
**Das löst nebenbei die offene Frage aus `AUFGABE_KUNDENSTAMM_UND_WEB.md`:** die zwei Steuerwelten
(deutsche Bruttopreise 7/19 % gegen polnische Nettopreise mit Reverse Charge). Weiß der Server,
welcher Betrieb anfragt, weiß er auch, wie zu rechnen ist. **Der Client muss davon nichts wissen —
und die Frage „beide Welten in einem Programm oder zwei Fassungen" erledigt sich.**
### ⭐ Die Aufgabenteilung im Einzelnen (Andreas, 06.09.2026)
> „das tool schickt nur die metadaten, der server rendert die pdf und das tool bekommt den link.
> oder halt die vorschau muss es selber machen — das auf dem server ist dumm. und paperless macht
> den rest: archivieren und senden an die mitgegebene e-mail, und speichert das unter der
> kundennummer."
| Wer | Was |
|---|---|
| **Tool** | schickt die Metadaten · zeichnet die **Vorschau lokal** · bekommt den Link zum fertigen PDF |
| **Server (API)** | vergibt die Nummer · rechnet · rendert das endgültige PDF · **verschickt per SMTP** · verteilt |
| **Paperless** | archiviert · verschlagwortet (Kundennummer als Korrespondent/Schlagwort) |
**Vorschau lokal ist richtig:** ein Netzweg pro Tastendruck wäre sofort träge.
### ⚠️ Die Regel, die dazugehört: EIN Zeichner, zwei Ausführungsorte
Zeichnet das Tool die Vorschau und der Server das endgültige Blatt, gibt es **zwei Zeichner — und
zwei Zeichner driften auseinander**. Genau davor schützt sich der heutige Code bereits:
`berechnung.py` wird von Oberfläche UND PDF benutzt, *„damit Bildschirm und Ausdruck garantiert
identisch sind"*.
Eine Vorschau, die nicht dem entspricht, was hinausgeht, ist **schlimmer als keine** — sie erzeugt
Vertrauen, das nicht gerechtfertigt ist. (Und die Vorschau war seine ausdrückliche Begründung für
das Ganze: *„sonst haben die den storno-aufwand"*.)
→ **`pdf_renderer.py` und `berechnung.py` bleiben EINE gemeinsame Bibliothek**, die an zwei Orten
ausgeführt wird. Kein zweiter Code.
### ⚠️ Korrektur: Paperless archiviert, es VERSCHICKT NICHT
Paperless-ngx nimmt Dokumente entgegen, erkennt Text, verschlagwortet und lagert ein. **Rechnungen
an Kunden mailen kann es nicht.** Der Versand per SMTP gehört auf den Server / in die API.
Die Ablage unter der Kundennummer geht dagegen sauber — Paperless kennt Korrespondenten und
Schlagworte, die Kundennummer passt in beides.
### ⛔ Verworfen: PDF auf dem Client zeichnen und hochladen
Andreas hatte es erwogen (*„ob das schlau ist, weiß ich nicht"*). **Nein**, aus einem Grund:
Zeichnet der Client den endgültigen Beleg, entscheidet der Client, was darauf steht — und der
Server archiviert blind, was ankommt. Er könnte nicht mehr garantieren, dass zur Nummer, die er
vergeben hat, auch das Blatt gehört, das er ablegt. Eine ältere oder veränderte Fassung des Tools
erzeugte Dokumente, die niemand prüft.
**Der Beleg entsteht dort, wo auch die Nummer entsteht.** Dazu käme: jede künftige Oberfläche
(Tablet, Browser) müsste den ganzen Renderer mitschleppen.
Die **Vorschau** bleibt lokal — sie ist kein Beleg: ohne Nummer, mit Wasserzeichen, wie heute.
### ⭐ Kundenstamm offline: ein ZWISCHENSPEICHER, kein Sync
Seine Frage: *„wenn ein kunde eine kundennummer bekommt, wie willst die wiederfinden? musst die api
auch abfragen dafür — heißt, ohne internet wird da eh nichts. sonst musst wieder alles lokal und
online speichern, um das schnell zu halten, und dann nur eine art rsync raufpacken."*
**Der Instinkt stimmt — nur ist es kein Sync, sondern ein Spiegel.** Der Unterschied ist keine
Wortklauberei:
| | bedeutet | Folge |
|---|---|---|
| **Sync** | beide Seiten dürfen ändern | braucht Konfliktauflösung — wer gewinnt bei doppelter Änderung? |
| **Spiegel** | nur der Server besitzt die Daten, der Client hält eine Lesekopie | **keine Konflikte**, nur ein Stand, der mal älter ist |
**Und die Datenmenge passt:** Kunden sind wenige und ändern sich selten — anders als Rechnungen.
Den ganzen Kundenstamm lokal zu halten kostet nichts und macht die Suche sofort schnell, auch ohne
Netz.
**Sein Wort dafür: „eine Art Zwischenspeicher"** — und das ist ehrlicher als „Spiegel", weil es
schon sagt, dass er veralten darf.
**Zwei Dinge braucht er, sonst wird er selbst zur Fehlerquelle:**
1. **Er muss sein Alter zeigen.** Klein in der Oberfläche: *„Kundendaten vom 06.09.2026, 15:40"*.
Sonst sucht jemand einen Kunden, findet ihn nicht, legt ihn neu an — dabei war er nur seit
gestern nicht heruntergeladen. **Ein Zwischenspeicher, dem man sein Alter nicht ansieht, wird
irgendwann für die Wahrheit gehalten.**
2. **Er darf nie Quelle für etwas sein, das geschrieben wird.** Lesen und Suchen: ja. Eine Nummer
daraus vergeben: nie. Aufgefrischt wird beim Start (wenn Netz da ist) und auf Knopfdruck.
**Dieselbe Regel wie bei den Rechnungsnummern:** Ein offline angelegter Kunde bekommt seine Nummer
**erst vom Server** — bis dahin ist er ein Entwurf. Sonst vergeben zwei Tablets dieselbe
Kundennummer.
### Folge 2: der Client wird schlank
Das Tablet beim Kunden braucht kein PDF-Werkzeug, keine Steuerlogik, keinen Nummernkreis. Ein Weg
hinein, mehrere hinaus.
### Der Preis
**Ohne Server geht nichts außer Entwürfen** (siehe Punkt 1). Bei FiveM ist das dasselbe — nur hängt
hier ein Beleg dran, den jemand zehn Jahre aufbewahren muss.
### Sicherheit, weil „Schlüssel zu allem" wörtlich zutrifft
Wenn ein Schlüssel alles öffnet, muss er: **je Installation** vergeben sein (nicht einer für alle),
**widerrufbar**, **nur über TLS** unterwegs, und die API muss **Missbrauch begrenzen**
(Rate-Limit). Sonst ist ein einziger abhandengekommener Schlüssel der Zugang zu allen Gästedaten.
## 5. Offene Entscheidungen
- Wer betreibt den Server, und für wen? (nur Bartl, oder mehrere Betriebe)
- Ein Mandant je Datenbank oder ein gemeinsames Schema mit Mandantenspalte?
- Was passiert mit dem lokalen Betrieb — bleibt SQLite als Offline-Fassung, oder wird alles zentral?
- Wie kommt der Bestand in die MySQL, ohne dass Nummern doppelt vergeben werden?
---
**Nichts davon beginnen, bevor die Punkte 1 bis 3 entschieden sind** — sie bestimmen den Aufbau,
nicht die Ausstattung.