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
417 lines
21 KiB
Markdown
417 lines
21 KiB
Markdown
# 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.
|