Die Ausgangslage
Ein Schweizer Dienstleistungsunternehmen führte sein gesamtes Backoffice mit Tabellen und einem Textprogramm. Offerten entstanden, indem das Dokument vom Vormonat kopiert und die Zahlen angepasst wurden. Rechnungen wurden von Hand getippt, und der Schweizer QR-Zahlteil am unteren Rand, also genau der Teil, den die Bank tatsächlich liest, wurde aus einem separaten Online-Generator eingefügt, wobei die Referenznummer jedes Mal manuell eingetragen wurde. Eine falsche Ziffer in dieser 27-stelligen Referenz, und die Zahlung landet ohne Zuordnung.
Spesen lebten in einer zweiten Tabelle, Belege in einem Ordner, nach Datum benannt, falls überhaupt. Es gab keinen einzigen Ort, um die Fragen zu beantworten, die ein Unternehmen wirklich steuern: Wie viel ist gerade offen, was haben wir dieses Quartal ausgegeben, wie ist der Saldo pro Konto, sind wir dieses Jahr profitabel. Diese Zahlen zu erstellen bedeutete einen Nachmittag manueller Abstimmung, und die Antwort war nur so verlässlich wie die letzte Person, die die Datei angefasst hatte.
Der Auftrag war direkt: das ganze Flickwerk durch ein System ersetzen, das der Inhaber kontrolliert, das korrekte Schweizer Dokumente erzeugt und das nie Daten verliert.
Was ich gebaut habe
Ich entwarf und baute ein vollständiges ERP von Grund auf: eine Node.js-/Express-Anwendung auf Basis von SQLite, selbst gehostet auf einem gehärteten VPS. Keine Vorlage, kein SaaS-Abo, bei dem jemand anderes die Daten hält, sondern ein einziges eigenes System, zugeschnitten darauf, wie dieses Unternehmen tatsächlich arbeitet.
Dokument-Workflow mit QR-Rechnung. Der Kern ist eine Dokument-Engine, die die ganze Kette abdeckt, die ein Schweizer Dienstleister ausstellt: Offerte → Auftragsbestätigung → Rechnung → Abnahmeprotokoll. Jedes Dokument wird in einem Rich-Text-Editor zusammengestellt, Positionen und Summen werden automatisch berechnet und als sauberes A4-PDF gerendert. Rechnungen tragen einen vollständig konformen QR-Rechnungs-Zahlteil mit einer korrekt generierten, prüfziffer-validierten Referenznummer: genau das Stück, das früher kopiert und fehleranfällig war, wird jetzt vom System jedes Mal generiert. Eine Aktion per Klick macht aus einer angenommenen Offerte eine Rechnung, ohne irgendetwas neu einzugeben.
Finanzen, Cashflow und GuV. Ein Finanzmodul erfasst Spesen nach eigener Kategorie, Belege werden hochgeladen und zu jedem Eintrag gespeichert (der Dateityp wird durch Prüfung der tatsächlichen Datei-Bytes verifiziert, nicht nur anhand der Endung). Es erfasst weitere Einnahmen, hält einen Anfangssaldo pro Bankkonto und stellt ein chronologisches Cashflow-Journal mit laufendem Saldo über alle Konten zusammen. Jahresend-Berichte für Gewinn-und-Verlust und Cashflow werden per Klick nach Excel exportiert: aus dem Nachmittag der Abstimmung wurde ein Knopfdruck.
Kunden-CRM und Analytics. Ein Kundenregister speist die Autovervollständigung im Dokument-Editor, sodass das Ausstellen eines Dokuments für einen wiederkehrenden Kunden nur ein paar Tastenanschläge braucht. Das Umbenennen eines Kunden zieht sich sauber durch dessen gesamte Rechnungshistorie. Ein Analytics-Dashboard zeigt Summen, Offenes und Erhaltenes auf einen Blick, mit Filtern nach Status und Zeitraum und Detail pro Dokument: die Frage «Wo stehen wir gerade?» live beantwortet.
Sicherheit, von Anfang an eingebaut. Dieses System hält Finanzdaten, also wurde es gehärtet statt nachträglich notdürftig verriegelt: modernes Passwort-Hashing mit automatischer Aufwertung älterer Hashes beim Login, vollständiger CSRF-Schutz, ratenbegrenztes und bot-geprüftes Login, Protokollierung der Login-Versuche mit Admin-Ansicht, strenge Validierung von Datei-Uploads sowie durchgehender Schutz gegen Path-Traversal und Cross-Site-Scripting. Am Rand beschränkt eine Firewall den Zugriff nach Land, eine Application Firewall filtert den Verkehr, und ein strenger Satz an Security-Headern wird erzwungen.
Self-Hosting, Deployment und Disaster Recovery. Die Anwendung läuft unter einem Process-Manager hinter nginx mit TLS, auf Infrastruktur, die ich bereitgestellt und abgesichert habe (SSH nur per Schlüssel, fail2ban, eine enge Firewall). Jeder Push ins Repository löst eine automatisierte Pipeline aus: Sync, Installation, Neustart und ein Health-Check, der bestätigt, dass die App tatsächlich ausliefert, bevor das Deploy als erledigt gilt. Backups laufen nächtlich auf externen Speicher mit einem Jahr Aufbewahrung, ein stündlicher Datenbank-Snapshot hält den Worst-Case-Datenverlust unter einer Stunde, und eine monatliche automatische Wiederherstellungsprobe beweist, dass die Backups sich tatsächlich zurückspielen lassen, denn ein ungetestetes Backup ist nur eine Hoffnung. Uptime-Monitoring und Error-Tracking benachrichtigen den Inhaber, falls etwas kaputtgeht. Das Ganze ist zudem eine PWA, lässt sich also wie eine native App auf dem Handy installieren.
Ergebnisse
- Ein System ersetzte das Flickwerk aus Tabellen und Textprogramm: Offerten, Auftragsbestätigungen, Rechnungen, Abnahmeprotokolle, Spesen, Cashflow, Kunden und Analytics an einem Ort.
- Fehler bei QR-Rechnungs-Referenzen eliminiert: Referenzen werden generiert und prüfziffer-validiert, nicht kopiert.
- Offerte → Rechnung per Klick: kein Dokument wird je von Grund auf neu getippt.
- Live-Finanzbild: Offenes, Erhaltenes, Spesen, Saldo pro Konto und GuV seit Jahresbeginn sofort verfügbar statt nach einem Nachmittag Abstimmung.
- Jahresend-Reporting auf einen einzigen Export reduziert: GuV und Cashflow auf Abruf nach Excel.
- Worst-Case-Datenverlust unter einer Stunde, mit monatlichen Wiederherstellungsproben, die belegen, dass die Wiederherstellung wirklich funktioniert.
- Der Inhaber kontrolliert die Daten: selbst gehostet, im Eigentum, keine SaaS-Gebühren pro Platz und keine Drittpartei, die die Bücher hält.
Was den Unterschied gemacht hat
Die Entscheidung, die alles prägte, war der Bau eines einzigen eigenen Systems statt des Zusammenstückelns von Standard-Tools. Ein Rechnungs-SaaS plus eine separate Buchhaltungs-App plus ein Cloud-Speicher für Belege hätten die Funktionen abgedeckt, aber die Daten hätten in den Datenbanken dreier Firmen gelegen, die QR-Rechnung wäre weiterhin jemandes fremde Vorstellung von korrekt gewesen, und jeder Ablauf wäre den Tools angepasst worden. Ein eigenes System bedeutet, dass es dem Unternehmen angepasst werden kann statt umgekehrt.
Das Zweite war, Zuverlässigkeit als Funktion zu behandeln, nicht als nachträglichen Einfall. Für ein System, das die Bücher hält, reicht «läuft auf meinem Rechner» nicht: Entscheidend ist, dass ein schlechtes Deploy die Nutzer nicht erreichen kann, dass eine defekte Festplatte nicht ein Quartal an Datensätzen kostet, und dass die Backups nachweislich wiederherstellbar sind. Das automatisierte, gesundheitsgeprüfte Deployment, die stündlichen Snapshots und die monatliche Wiederherstellungsprobe sind der Unterschied zwischen einem Tool, dem der Inhaber sein Unternehmen anvertraut, und einem, von dem er «zur Sicherheit» eine nervöse Tabellenkopie behält.