# Beweiskette: von Anfang bis Ende prüfbar Seine Vorgabe vom 06.09.2026, wörtlich: > „ich will für den prüfer sichtbar machen: ich wollte das so. die software dokumentiert das, > und damit wird es nachvollziehbar, weil es einen checkmark nun gibt in der sqlite" > — „das soll alles von anfang bis ende prüfbar sein" > — „damit denke ich überfüllen wir sogar das gobd, sogar mehr, weil es nun eine beweiskette > darstellt" **Grundgedanke:** GoBD verlangt Nachvollziehbarkeit und Unveränderbarkeit — aber **keinen dokumentierten Freigabe-Entscheid**. Den gibt es jetzt zusätzlich. Damit die Kette trägt, muss jedes Glied für sich prüfbar sein und keines allein tragen. --- ## Schritt 1 — Freigabe vor dem Beleg ✅ ERLEDIGT (Commit 95a9063) - Rückfrage vor dem Schreiben, Text nennt § 14 UStG, § 14 Abs. 4 Nr. 4 UStG, § 147 Abs. 3 AO, § 146 Abs. 4 AO; Angebot bekommt einen eigenen Text (ausdrücklich **keine** Rechnung). - Storno/Korrektur und Berichtigung behalten ihre eigene Rückfrage — nicht verdoppelt. - Spalte `freigabe` (ISO-Zeitstempel) in `nummern` im gemeinsamen Nummernbuch, mit ALTER-TABLE-Migration. **Alte Zeilen bleiben leer** — dort wurde nie gefragt. - `pruef_freigabe.py` prüft beide Richtungen. Alle 16 Prüfstände grün. --- ## Schritt 2 — Freigabe zusätzlich in die PDF-Metadaten ⬜ OFFEN **Warum das nötig ist:** `gemeinsam.py` sagt über die SQLite selbst: *„Die Datei ist ein REGISTER, keine zweite Buchhaltung: die Wahrheit bleiben die Rechnungs-PDFs. Geht das Buch verloren, fehlt keine Rechnung — es muss nur neu gefüllt werden."* Ein solcher Neuaufbau kennt die Freigabe-Zeitstempel **nicht**. Damit hinge die Beweiskette an der schwächsten Datei. **Zu tun:** `freigabe` in `pdf_renderer._kenndaten()` aufnehmen (die maschinenlesbaren Kenndaten im `/Subject`, die das Steuerjournal ohnehin liest). Dann steht der Zeitstempel an zwei Stellen und übersteht den Verlust des Registers. **Prüfstand:** `pruef_freigabe.py` erweitern — nach dem Ja muss `bestand.kenndaten_lesen(pdf)` den Zeitstempel liefern, und er muss mit dem in der SQLite übereinstimmen. --- ## Schritt 3 — Steuerprüfungs-Ausdruck im Beherbergungssteuer-Tool ⬜ OFFEN Sein Wortlaut: *„wir müssen im kassenbuch, was das beherbergungstool ist, einen button in die einstellungen machen: steuerprüfungs-ausdruck. damit bekommt der prüfer einen ausdruck aus der db und kann damit das in der tabelle prüfen auf richtigkeit, oder halt wenn der typ das als papierversion hat."* **Zu tun:** Knopf in den Einstellungen, der aus der Datenbank ein PDF erzeugt, das ein Prüfer gegen die Belege halten kann. **Vor dem Bauen zu klären:** - Welcher Zeitraum? (Jahr, Monat, frei wählbar) - Welche Spalten? Mindestens: Nummer, Datum, Art, Beträge, Vorgang/Storno-Bezug, **Freigabe** - Wie wird gezeigt, dass nichts fehlt? Lückenlosigkeit der Nummern ist der Kern jeder Prüfung — Lücken müssen **sichtbar** sein, nicht stillschweigend übersprungen. - Summen je Zeitraum, damit der Prüfer gegenrechnen kann. - Kennzeichnung als Auswertung, **nicht** als Beleg (sonst dasselbe Problem wie beim Amt-Blatt). ⚠️ **Nicht verwechseln:** Der bestehende „Bericht fürs Amt" ist die **Steueranmeldung** nach kommunaler Satzung. Der Prüfungs-Ausdruck ist etwas anderes: eine Auswertung für die Betriebsprüfung. Beide bleiben nebeneinander bestehen. --- ## Schritt 4 — Updater als Starter ⬜ OFFEN Sein Bild (06.09.2026): *„der updater schaut beim starten erst: ist auf dem git link eine neue version mit exe? wenn ja, erst laden, ersetzen und dann starten."* Dazu: *„einmal prüfen auf vollständigkeit."* **Warum das der richtige Aufbau ist:** Der Updater ist das, was der Nutzer startet. Er läuft **bevor** das Programm läuft — damit gibt es das übliche Problem gar nicht, dass eine laufende EXE sich nicht selbst ersetzen kann. **Ablauf:** 1. Beim Start die Release-Angaben vom Repository holen. 2. Ist die dortige Version neuer als die installierte → Datei in einen **Zwischenordner** laden. 3. **Vollständigkeit prüfen** — Größe und Prüfsumme gegen die Angabe des Releases. Erst wenn beides stimmt, wird ersetzt. Ein halb geladener Download darf die Installation nie erreichen. 4. Alte Fassung als **Rückfallebene** behalten; scheitert der Start, zurücktauschen. 5. Programm starten. **⚠️ Zwei Voraussetzungen fehlen noch:** - **Es gibt keine Versionsnummer im Programm.** Ohne die kann kein Updater vergleichen. Muss zuerst eingeführt werden — an einer Stelle, aus der auch die EXE-Metadaten und der Info-Dialog lesen. - **Sind die Repositories öffentlich?** Wenn nicht, braucht der Updater einen Zugangstoken — und ein Token, das in einer verteilten EXE steckt, ist kein Geheimnis mehr. Dann müssten die Releases öffentlich sein oder über eine andere Stelle ausgeliefert werden. **Und Andreas' Ansage zu den Releases:** *„die alten als experimental taggen, nicht als stabil — weil die sind nicht stabil."* --- ## Schritt 5 — Pcore-Design im Steuerrechnungstool ⬜ OFFEN Sein Wunsch: *„aber bitte mit unserm theme style."* **Befund:** Das Steuerrechnungstool hat **kein `theme.py`**. Es benutzt nackte ttk-Widgets mit Segoe UI. Das Rechnungstool hat das ganze Pcore/Ravokk-Design — Farben, Roboto, Glass-Buttons, eigene Meldungsfenster (`MeldungMixin`), hell und dunkel. **Zu tun:** `theme.py` herüberziehen und die Oberfläche darauf umstellen. Das ist ein eigener Bau, kein Nebenbei — Menüs, Tabellen, Dialoge, Statusleiste. Vorher planen. --- ## ⚠️ Gefundener Altfehler — `pruef_wache` (Steuerrechnungstool) ⬜ OFFEN **Nicht von den Arbeiten am 06.09.2026 verursacht** — bei der Ausgangsmessung vor dem Umbau bereits rot, nur mit anderem Text. `pruef_wache.py` erwartet nach einem Push des Rechnungstools in der Statuszeile den Hinweis **„Rechnungstool meldet"**. Tatsächlich steht dort das Ergebnis des anschließenden Einlesens (`0 neu, 0 aktualisiert, 1 unverändert`; bei der Ausgangsmessung: `Nummernbuch: 1 Nummern eingetragen`). Das Einlesen **überschreibt die Meldung**, bevor der Nutzer sie lesen kann. **Zu klären:** Ist das ein Fehler im Programm (die Meldung soll stehen bleiben, das Ergebnis danebengehören) oder eine veraltete Erwartung im Prüfstand? Nicht nebenbei entscheiden — die Statuszeile ist das Einzige, was dem Nutzer sagt, dass die andere Anwendung etwas gemeldet hat. Folgefehler derselben Stelle: „dann kommt keine Meldung dazu". --- ## Reihenfolge Schritt 2 zuerst — er schließt eine Lücke in dem, was gerade gebaut wurde, und ist klein. Schritt 3 danach, mit eigenem Plan, weil dort Entscheidungen offen sind.