INTERN — nicht an den Kunden. Enthält die Bewertung des eigenen Angebots und Befunde zu personenbezogenen Daten.

Interne Prüfung · nicht an den Kunden

Was im Angebot noch offen ist

Durchsicht der Rohfassung v2 vor dem Termin bei Nemeth: die markierten Leerstellen, die Widersprüche zwischen den Abschnitten, die fehlenden Angebotsbestandteile und die offenen Zulieferungen — dazu der Stand des Codes, gemessen an den Abnahmekriterien aus Anhang A.

Dokument
nemeth_angebot_rohfassung_v2.md
Stand
28.08.2026
Geprüft
03.09.2026
Fixpreis
21.000 EUR exkl.

Der Termin ist heute. Die Unterschrift am 03.09.2026 trägt den gesamten Zeitplan. Versandfertig ist das Dokument nicht: sechs Leerstellen stehen im Text, und die AGB, auf die Punkt 10 verweist, gibt es nicht. Der Code ist dagegen weiter, als das Angebot behauptet — siehe Abschnitt G und H.

Befunde A · B · I · J · K

A Leerstellen im Text

Die sechs mit >> offen: markierten Stellen. Jede davon steht im sichtbaren Text und muss vor dem Versand verschwinden — entweder gefüllt oder gestrichen.

A1Blocker
Kopftabelle · Angebot Nr.

Die Angebotsnummer fehlt

Es gibt noch keinen Nummernkreis. Ein Angebot ohne Nummer ist später weder referenzierbar noch der Rechnung zuordenbar.

Vorschlag: Nummernkreis einmalig festlegen (etwa 2026-001), er gilt dann für alle DigiNative-Angebote, nicht nur für dieses.

A2Blocker
Kopftabelle · Ansprechpartner

„Roland“ ohne Nachnamen

Im Anbieterblock steht nur der Vorname. Fällt beim ersten Lesen auf und wirkt in einem 21.000-EUR-Angebot unfertig.

Vorschlag: Nachname eintragen, dazu je Ansprechpartner Telefon und E-Mail.

A3Blocker
Umfangsdefinition Baustein 3

Welche Vertragsarten in Phase 1 kommen, ist nicht entschieden

Der Satz lautet derzeit sinngemäß: enthalten sind die Hausvorlage sowie offen aus B.1 und offen aus B.4. Das ist die kalkulationsrelevanteste Lücke des ganzen Dokuments — Annahme 1 und das Abnahmekriterium für Baustein 3 hängen daran. Ohne Auswahl bedeutet „die übergebenen Vorlagen“ 41 Dokumente in sieben Klassen.

Vorschlag (korrigiert am 03.09.): Der Import hat gezeigt, dass die vermeintliche Hausvorlage keine ist — siehe V1. Tragfähig sind stattdessen die vier zuletzt erstellten Mietverträge aus B.2 (sie gliedern sich mit Abstand am besten), Richtwert und angemessener HMZ aus B.1 sowie die Verlängerungsvereinbarung aus B.4.

A4Klärung
Punkt 3 · Nicht im Leistungsumfang

Der Ausschluss der Nachträge widerspricht dem eigenen Anhang

Punkt 3 schließt Nachträge und Änderungen bestehender Verträge aus, versehen mit >> offen: bestätigen. Anhang B.4 zählt zwölf solcher Dokumente, die Verlängerungsvereinbarung allein in fünf Fassungen. Fünf Fassungen entstehen nicht bei einem seltenen Vorgang — der Ausschluss trifft damit möglicherweise den häufigsten Anwendungsfall der Kanzlei.

Vorschlag: Die Verlängerungsvereinbarung als eigene Vertragsart in den Umfang nehmen und den Ausschluss auf die übrigen Nachtragsarten verengen. Das ist zugleich Frage 6 für den Termin.

A5Beobachten
Punkt 9 · Ausblick

Betriebsmodell nach der Abnahme unentschieden

Monatliche Pauschale oder Abrechnung nach Aufwand — die Frage steht offen im Text. Für dieses Angebot ist sie nicht entscheidend, der Betrieb ist ausdrücklich nicht Teil davon.

Vorschlag: Die Frage aus dem Angebotstext entfernen und den Satz auf „Für den Betrieb nach der Abnahme machen wir ein getrenntes Angebot“ kürzen. Intern entscheiden, bevor die Frage im Termin von selbst kommt.

A6Blocker
Punkt 10 · Rahmenbedingungen

Die AGB, auf die verwiesen wird, existieren nicht

„Es gelten die AGB von DigiNative“ verweist auf ein Dokument, das erst aufgesetzt werden muss — inklusive Gerichtsstand, Haftung und Nutzungsrechten am Code. Ein Verweis auf nicht vorhandene Bedingungen ist im Streitfall wertlos.

Vorschlag: Bis morgen nicht zu schaffen. Entweder die drei Punkte Gerichtsstand, Haftungsbegrenzung und Nutzungsrechte direkt in Punkt 10 schreiben, oder die AGB als Beilage nachreichen und im Angebot so benennen.

B Widersprüche und Fehler im Dokument

Stellen, an denen zwei Abschnitte einander widersprechen oder eine Angabe nicht stimmt. Nicht im Text markiert — bei der Durchsicht gefunden.

B1Blocker
Anhang A, Baustein 2, Kriterium 4 ↔ Frage 2

Die Erkennungsquote ist zweimal geregelt, einmal offen

Der Anhang legt 50 Rechnungen und 80 Prozent als Abnahmekriterium fest, die Fragenliste stellt Stichprobengröße und Prozentsatz noch zur Klärung. Steht beides so im versandten Angebot, ist das Kriterium bestreitbar — genau der Punkt, an dem die Abnahme später hängen kann.

Vorschlag: Die Zahl im Anhang ist die bessere Fassung, weil sie prüfbar ist. Frage 2 streichen und den Wert im Termin bestätigen lassen.

B2Blocker
Anhang A, Baustein 3, Kriterium 1

Das Abnahmekriterium verspricht mehr als der Umfang

Es lautet „für jede der übergebenen Vertragsarten“. Übergeben wurden 41 Dokumente, geliefert wird eine Auswahl. Nach dem Wortlaut wäre die Abnahme erst mit allen Vorlagen erfüllt — der teuerste Satz im Anhang.

Vorschlag: Umformulieren auf „für jede der in der Umfangsdefinition eingerichteten Vertragsarten“. Hängt an A3.

B3Klärung
Punkt 3 · Einleitungssatz

„Die ersten fünf“ sind vier

Der gemeinsame Conthaus-Grund gilt für Datenabgleich, Dublettenprüfung, 4-Augen-Prinzip und Kontenrahmen — vier Punkte. Der fünfte in der Liste ist Freshdesk und hat mit Conthaus nichts zu tun.

Vorschlag: „für die ersten vier“ schreiben.

B4Klärung
Anhang B · Gruppenzählung

Die Dokumentenzahlen gehen nicht auf

B.2 ist mit (7) überschrieben und listet acht Zeilen, B.5 mit (5) und listet vier Einträge. Die Überschriften summieren sich auf 40, die Einleitung nennt 41 Dokumente. Der Anhang ist die Grundlage der Umfangsabgrenzung — dort darf nicht gezählt werden müssen.

Erledigt am 03.09.: Der Import hat nachgezählt. 41 Dateien mit Vertragsendung, davon 2 im alten .doc-Format unlesbar. Die Vermutung aus Anhang B ist bewiesen: die drei richt-mz-PDFs sind bytegleich (identische Prüfsumme), die Dublettenprüfung hat sie selbst erkannt. Aus acht standardisierten Verträgen werden damit tatsächlich sechs. Die Gruppenzahlen in Anhang B lassen sich jetzt belegen statt schätzen.

B5Klärung
Punkt 5 · Mitwirkungstabelle, Zeilen 1–2

Spalten vertauscht

Bei Vertragsmustern und Kontoplan steht „erledigt“ in der Spalte Wann und „21.08.2026“ in der Spalte Status. In allen übrigen Zeilen ist es umgekehrt.

Vorschlag: Tauschen — Wann: 21.08.2026, Status: erledigt.

B6Klärung
Punkt 6 / Punkt 8 · Vor-Ort-Termine

Drei Anlässe vor Ort, Reisekosten für zwei

Kalkuliert sind 12 Stunden Arbeiten vor Ort „auf zwei Termine“ plus 8 Stunden Einschulung, die laut Zeitplan ebenfalls vor Ort stattfindet — das ist ein dritter Anlass. Die Reisekostenklausel deckt aber ausdrücklich nur „die beiden im Zeitplan vorgesehenen Vor-Ort-Termine“. Dazu kommt der Termin am 03.09. selbst, der vor dem Auftrag liegt.

Vorschlag: Entweder die Einschulung als einen der Vor-Ort-Termine benennen und auf drei Anlässe umstellen, oder die Reisekostenklausel auf „alle im Zeitplan vorgesehenen Termine“ verallgemeinern. Linz–Wien viermal ist sonst eine unbezahlte Position.

C Was ganz fehlt

Bestandteile, die im Dokument nicht vorkommen und in einem versandfertigen Angebot stehen müssen.

FehltWarum es gebraucht wirdDringlichkeit
Vollständige AnbieterdatenIm Kopf steht nur „DigiNative, Linz“. Es fehlen Rechtsform, Anschrift, UID-Nummer und Firmenbuchnummer. Ohne UID kann Nemeth die spätere Rechnung nicht sauber verbuchen — bei einem Buchhaltungsprojekt ein unglücklicher erster Eindruck.vor Versand
Annahme- und UnterschriftsblockDer Zeitplan setzt die Unterschrift am 03.09. voraus, das Dokument bietet aber keine Stelle zum Unterschreiben. Ort, Datum, zwei Unterschriftsfelder.vor Versand
AuftragsverarbeitungsvertragPunkt 10 nennt nur den Verarbeitungsort. Verarbeitet werden Mieter- und Eigentümerdaten im Auftrag — ein AV-Vertrag nach Art. 28 DSGVO ist dafür Pflicht und gehört als Beilage angekündigt.vor Versand
Zeitfenster für TestrückmeldungenAnnahme 7 verlangt Rückmeldungen „innerhalb des vereinbarten Zeitfensters“, vereinbart ist aber keines. Eine Annahme, die keine Zahl nennt, trägt im Streitfall nicht.03.09.
Termin für die CSV-AbstimmungAnnahme 6 und das Abnahmekriterium B2.7 setzen ein abgestimmtes CSV-Format voraus. In der Mitwirkungstabelle kommt diese Abstimmung nicht vor — weder Termin noch Verantwortlicher.03.09.
Definition von „Liefertermin“Die Annahmen 3, 4 und 8 beziehen sich auf den Liefertermin. Der Zeitplan kennt den Begriff nicht, er nennt nur Schritte mit Datum.Wording

D Offene Zulieferungen von Nemeth

Acht der elf Positionen in der Mitwirkungstabelle sind offen. Drei davon sind erst zum 10.09. fällig, die Entwicklung beginnt aber am 07.09. — die ersten drei Entwicklungstage laufen damit ohne Liegenschaftsliste, ohne vollständigen Kontenplan und ohne Musterrechnungen.

BeitragFälligWas daran hängt
Klärung der Kontonummernstruktur03.09.
morgen
Führende Ziffer vor der fünfstelligen Kontonummer, vermutlich der Abrechnungskreis. Ohne Bestätigung ist die Buchungszeile nicht sicher erzeugbar.
Vollständige Liegenschaftsliste10.09.
nach Start
Zuordnung Rechnung → Liegenschaft, Abnahmekriterium B2.5.
Vollständiger Kontenplan samt Erläuterung der Gegenkonten10.09.
nach Start
Der übergebene Plan ist als „in aller Regel“ gekennzeichnet und an drei Stellen unvollständig. Grundlage der Vorkontierung.
Zweites Buchungsjournal einer WEG10.09.
nach Start
Beide übergebenen Journale betreffen ENK05. Ohne ein zweites fehlt der Fall mit mehreren Abrechnungskreisen.
Mindestens 50 Musterrechnungen10.09.
nach Start
Grundlage der Erkennung und zugleich Prüfmenge des 80-Prozent-Kriteriums. Die Hälfte der Abnahmestichprobe muss ungesehen bleiben — die 50 sind also nicht dieselben 50.
Benannte Testpersonen mit Zeitfenster21.09.Testphase 21.09.–02.10. Ohne benannte Personen verschiebt sich die Fehlerbehebung.
Server, Domain, eingerichtete Subdomain12.10.Übergabe auf das Livesystem nach der Abnahme. Beschaffung ist ausdrücklich nicht Teil des Angebots.
Befüllung des Dashboards mit Objekt- und ZuordnungsdatenlaufendSolange die Zuordnung Objekt → Sachbearbeiterin fehlt, bleibt die Auslastungsauswertung abgeschaltet.

E Fragen für den Termin am 03.09.

Die neun Fragen aus dem Dokument, sortiert danach, was sie kosten, wenn sie unbeantwortet bleiben.

FrageWenn offen bleibt
Auswahl der Vertragsarten für Phase 1. Welche der 41 Vorlagen werden eingerichtet, und wie wird mit den zwölf Nachträgen umgegangen?Baustein 3 bleibt unkalkulierbar. Siehe A3 und A4.
Kontonummern. Ist die führende Ziffer der Abrechnungskreis?Die Buchungszeile kann nicht verlässlich erzeugt werden.
Aufbau und Verwendung der Gegenkonten. Wer erklärt es, bis wann liegt die vollständige Liste vor?Die Vorkontierung baut auf Vermutungen auf.
Zweites Buchungsjournal. Beide Dateien enthalten Enkplatz.Der WEG-Fall mit mehreren Abrechnungskreisen bleibt ungetestet.
Liegenschaftsliste. Conthaus-Export oder händisch erfasst?Zuordnung und Abnahmekriterium B2.5 hängen daran.
Erkennungsquote. Welche Stichprobengröße, welcher Prozentsatz?Im Anhang bereits mit 50 / 80 % beantwortet — siehe B1, hier nur bestätigen lassen.
Zuordnung Objekt zu Sachbearbeiterin. Gibt es die Liste, wer pflegt sie?Die Auslastungsauswertung bleibt abgeschaltet. Kein Terminrisiko.
Testpersonen und Zeitfenster ab 21.09. fixieren.Die Testphase startet ohne benannte Personen.
Server für den Livebetrieb. Wer stellt ihn, bis wann, wer richtet ihn ein?Betrifft erst die Übergabe nach dem 19.10.

F Nachgerechnet und in Ordnung

Was geprüft wurde und stimmt — damit im Termin klar ist, worüber nicht mehr diskutiert werden muss.

210 Stunden150 + 40 + 8 + 12 — die Summe der Positionen stimmt.
30.450 EUR210 × 145 EUR, korrekt gerechnet.
21.000 EURNach Abzug von 9.450 EUR. Das sind exakt 31,03 %, ausgewiesen als 31 % — gerundet zugunsten des Kunden, um 10,50 EUR.
50 / 30 / 2010.500 + 6.300 + 4.200 = 21.000 EUR. Geht auf.
150 h in zwei WochenZwei Entwickler × 10 Arbeitstage = 160 Stunden Kapazität. Plausibel, aber nur 6 % Puffer.
GültigkeitZwei Wochen ab 28.08. deckt den Termin am 03.09. ab.

G Stand des Codes

Gemessen, nicht geschätzt: Typprüfung und Testlauf am 03.09.2026 (der Durchgang durch die laufende App steht in Abschnitt K) auf dem Branch mandantentrennung-und-zusagen. Die Tabelle stellt jedes Abnahmekriterium aus Anhang A dem gegenüber, was im Code tatsächlich steht.

613Tests, alle grün
46Testdateien
32Migrationen, von null durchgelaufen
0Typfehler (tsc --noEmit)
~16.800Zeilen TypeScript in 66 Modulen
140+API-Routen
KriteriumWas gefordert istStandWo im Code
B1.1Beleg erscheint unter „Zu prüfen“ und verschwindet nach der Prüfungstehtdashboard-buchhaltung.ts, board.html
B1.2Ticket mit Objekt, Frist und Zustandstehttickets.ts — inkl. überfällig, dringend, unzugeordnet je Objekt
B1.3Von der Objektansicht zu Belegen und Tickets in zwei KlicksteilweiseObjektübersicht existiert im Ticketmodul, die Belegliste gruppiert nach Liegenschaft — eine gemeinsame Objektseite gibt es nicht. Das ist die Einstiegsseite aus Baustein 1.
B1.4Jede Statusänderung mit Benutzer und Zeitpunkt sichtbarstehtaudit.ts, platform_audit_log ohne Update/Delete, Route /moves/:id/audit
B1.5Rollenabhängige Aktionenstehtaccess.ts serverseitig erzwungen, eigene Enforcement-Tests
B2.1Dokument als Rechnung erkannt, Felder ausgelesenstehtKaskade: E-Rechnung (exakt geparst) → PDF-Textebene → OCR → lokales Modell als letzte Instanz
B2.2Buchungszeile mit Konto, Gegenkonto, Steuercode, Kostenstelle, Textstehtprecontra.ts + estate_posting_rule; seit gestern zusätzlich die Kostenart-Regeln
B2.3Soll und Haben ausgeglichen, Kontrollsumme sichtbarstehtmoves.ts, zusätzlich als Datenbank-Constraint
B2.480 % von 50 Rechnungen ohne Korrektur richtig vorkontiertnicht messbarDie Messung baut sich selbst (labels.ts, /api/extraction/quality), aber sie misst gegen erfundene Muster. Es fehlen Echtbelege — genau die Zulieferung aus Abschnitt D.
B2.5Zuordnung zur richtigen Liegenschaftstehtingest.ts, Matching gegen die hinterlegte Liste
B2.6Dublette gekennzeichnet, keine Weiterverarbeitung ohne Bestätigungstehtprecontra.ts — Kreditor + Rg-Nr. + Betrag, setzt needs_review
B2.7CSV mit den abgestimmten Spalten in der abgestimmten ReihenfolgewartetTechnisch fertig und konfigurierbar (Spaltenwahl, Trennzeichen, Encoding). Was fehlt, ist die Abstimmung selbst — das echte Conthaus-Layout ist unbekannt.
B2.8Exportierter Beleg erscheint nicht erneut im Stapelstehtconthaus.ts über estate_conthaus_transfer
B3.1Entwurf je Vertragsart, Klauseln in der richtigen Reihenfolgestehtcontracts.ts — deterministisches Regelwerk, kein Sprachmodell
B3.2Schalter wirken nachweisbarstehtcontracts.ts, eigene Tests
B3.3Fehlen Pflichtfelder, wird kein Entwurf erzeugtanders gelöstDer Entwurf entsteht trotzdem und markiert die Lücken farbig (gap_count). Das ist im Alltag vermutlich besser — aber es ist nicht das, was das Kriterium beschreibt. Eines von beiden muss weichen.
B3.4Klauseln stimmen wörtlich mit den Vorlagen übereinwartetDer Weg steht: Word- und PDF-Vorlagen werden gelesen und zu Baustein-Vorschlägen, ein Mensch übernimmt. Befüllt ist die Bibliothek noch nicht.
B3.5Entwurf als bearbeitbares Dokument speichern, in Word weiterbearbeitenfehltEs gibt eine Bildschirmansicht und einen Drucken-Knopf, keine .docx-Ausgabe. Word wird gelesen, nicht geschrieben. Das einzige Kriterium ohne Code dahinter.
B3.6Mitarbeiter legt einen Baustein selbst an und verwendet ihnnur als AdminDer Weg existiert, aber Anlegen ist auf die Rolle Admin beschränkt — Sachbearbeitung und Freigabe dürfen nur lesen. Beim Import am 03.09. ist das aufgefallen: eine Sachbearbeiterin hätte ihn nicht ausführen dürfen. Das Kriterium sagt „von einem Ihrer Mitarbeiter“; entweder die Rechte öffnen oder das Kriterium auf die Rolle einschränken.

H Wo das Angebot untertreibt

Fünf Punkte stehen in Abschnitt 3 unter „Nicht im Leistungsumfang“, obwohl der Code sie schon kann. Das ist keine Kleinigkeit: bei zweien ist die im Angebot genannte Begründung sachlich falsch, und das fällt im Termin auf, sobald jemand die Software sieht.

Im Angebot ausgeschlossenWas tatsächlich im Code steht
4-Augen-Prinzip als technisch erzwungener Schritt — „setzt den Schreibzugriff auf Conthaus voraus und kommt mit diesem“Ist gebaut und erzwungen, ganz ohne Conthaus: Prüfer und Freigeber müssen verschiedene Personen sein, abgesichert im Buchungsdienst und als Datenbank-Constraint, dazu betragsabhängige Freigabeketten. Der Export nimmt ohnehin nur gebuchte Belege — die Kontrolle liegt also bereits davor. Die Begründung im Angebot hält nicht.
Anbindung von Freshdesk — „die Ticketansicht ist in dieser Phase eine Vorschau“Ist gebaut: echte API-Anbindung, die Tickets liest und spiegelt, mit Zuordnung zur Liegenschaft und Konfigurationsseite. Bewusst nur lesend. Was fehlt, sind die Zugangsdaten des Kunden — nicht der Code.
Kontenrahmen und Kostenstellen je Objekt — „in dieser Phase eine einheitliche Kontenliste“Die Kontierungsregeln kennen die Liegenschaft bereits als Kriterium, der Kontenrahmen ist je Haus pflegbar samt Import mit Vorschau. Die objektweise Logik ist da; unbekannt ist nur, wie Conthaus sie benennt.
Datenabgleich mit Conthaus in beide RichtungenExport und Import sind gebaut, letzterer klassifiziert eingelesene Stapel nach neu und Dublette. Der Ausschluss bleibt trotzdem richtig: beide arbeiten gegen ein selbst gewähltes Format, weil das echte nicht bekannt ist. Hier stimmt die Begründung.
Kennzeichnung fehlender Zuständigkeiten — „setzt die Zuordnung Objekt zu Sachbearbeiterin voraus“Unzugeordnete Vorgänge werden je Objekt gezählt und ausgewiesen, samt Zuordnungsquote. Stärker noch: die Zuordnung existiert als Tabelle und schützt bereits Daten — eine Sachbearbeiterin kann auf einem fremden Objekt nichts anlegen (im Durchgang belegt, Befund R3). Was fehlt, sind allein Nemeths Daten.

Das ist zuerst eine kaufmännische Frage, keine technische: Das Angebot verkauft 150 Stunden Entwicklung für Bausteine, die in weiten Teilen stehen. Beides ist vertretbar — ein Fixpreis für ein fertiges Produkt oder ein Stundensatz für Neuentwicklung —, aber die Begründungen in Abschnitt 3 sollten nicht behaupten, etwas sei technisch unmöglich, was heute läuft.

I Befunde im Code

Aus der Durchsicht der noch nicht eingecheckten Arbeit (Kostenart-Regeln, Paket A) und der Kriterien oben.

K1behoben
src/kostenarten.ts · waehleRegel

Eine Textregel „Gas“ trifft jede Wiener Adresse

Der Textvergleich prüft auf Teilzeichenketten, ohne Wortgrenze. Nachgestellt mit der echten Funktion: die Regel Gas greift auf „Mollardgasse“ und auf „Liftgasse“ — und im zweiten Fall gewinnt sie sogar gegen die Regel Lift. Der Belegtext, gegen den verglichen wird, enthält den ganzen Beleg samt Anschrift, und in Wien steht in fast jeder Adresse eine Gasse.

Verschärfend: ein Regeltreffer setzt kein needs_review. Ein aus dem Beleg gelesener Wert löst eine Prüfung aus, ein falscher Regeltreffer läuft ungeprüft durch — über die Kostenart in das Aufwandskonto und weiter in den Conthaus-Export.

Behoben am 03.09. Zwei Regeln statt einer, beide in kostenarten.ts:

Ein Bestandteil trifft nur noch am Wortanfang. „Aufzug“ findet weiterhin „Aufzugswartung“ — Deutsch setzt zusammen, und genau dafür ist ein Textbestandteil da —, aber „Mollardgasse“ trägt „gas“ nur hinten und trifft nicht mehr.

Das allein reichte nicht: in „Lange Gasse“ steht „Gasse“ als eigenes Wort und fängt mit „Gas“ an. Deshalb zählen alleinstehende Straßenwörter (Gasse, Straße, Allee, Promenade, Zeile) nicht mehr als Belegtext — ein Wort, das für sich nur eine Straßenart benennt, sagt nie etwas über die Art der Ausgabe. Zusammensetzungen bleiben unberührt, „Straßenreinigung“ ist eine Leistung und keine Adresse.

Vier neue Tests halten es fest, in der laufenden App nachgeprüft: „Objekt Lange Gasse 14“, „Mollardgasse 2“, „Untere Zeile 8“ und „Passage Nord“ treffen nicht mehr; „Gasrechnung“, „Gasleitung“ und „Lieferung Gas“ treffen weiter. 617 Tests grün.

K2Klärung
Baustein 3 · Abnahmekriterium B3.5

Der Vertragsentwurf lässt sich nicht in Word öffnen

Word-Vorlagen werden gelesen, aber nichts wird als .docx geschrieben. Der Entwurf ist eine Bildschirmansicht mit Drucken-Knopf. Das Abnahmekriterium verlangt ausdrücklich ein bearbeitbares Dokument — und für eine Kanzlei, die jeden Vertrag noch anfasst, ist das kein Nebenpunkt.

Vorschlag: Der einzige Punkt aus Anhang A, für den noch gar nichts existiert. Einplanen, nicht im Termin zusagen, ohne ihn geschätzt zu haben.

K3Klärung
Baustein 1 · Abnahmekriterium B1.3

Die Objektansicht als Einstiegsseite fehlt noch

Vorhanden sind eine Objektübersicht im Ticketmodul und eine Gruppierung nach Liegenschaft in der Belegliste. Was das Angebot beschreibt, ist eine Seite pro Liegenschaft, von der aus Vorgänge und Tickets erreichbar sind. Die Bestandteile sind da, die Klammer fehlt.

Vorschlag: Überschaubar, weil beide Datenquellen samt Berechtigungsfilter schon stehen. Sollte vor der Abnahme kommen, sonst hängt B1.3 an einer Auslegung.

K4behoben
src/kostenarten.ts · resolveCategory

Jeder Beleg zahlt für eine Zahl, die er nicht braucht

Der Belegweg lädt die Regelliste über dieselbe Funktion wie die Pflegeseite — mitsamt der Unterabfrage, die je Regel zählt, wie viele Kontierungsregeln ihre Kostenart bedienen. Für die Auflösung ist diese Zahl bedeutungslos. Bei 30.000 bis 40.000 Belegen im Jahr ist das kein Ausfall, aber Arbeit ohne Zweck.

Behoben am 03.09. Der Belegweg lädt die Regeln jetzt über einen eigenen, schlanken Lader ohne den Zähl-Join; die Liste der Pflegeseite behält ihn. Die Probe auf der Pflegeseite benutzt bewusst denselben schlanken Lader wie der Belegweg — eine Probe, die auf einer anderen Zeilenmenge rechnet als die Entscheidung, zeigt etwas anderes an, als sie tut.

Zum Gesamteindruck: Die Prüfungen liefen sauber durch — 613 Tests, keine Typfehler, die Migrationskette von null. Die Entscheidungen sind im Code begründet, nicht nur ausgeführt, und die Trennung von Extraktion, Kategorisierung und Kontierung trägt. Der Befund K1 ist eine Wortgrenze, kein Konstruktionsfehler.

J Der Vorlagen-Import vom 03.09.

Alle 41 Vertragsdateien wurden über denselben Dienst eingelesen, den auch die Oberfläche benutzt — mit Rechteprüfung, Audit und Dublettenerkennung. Erzeugt wurden Vorschläge; in die Baustein-Bibliothek wandert nichts ohne die Übernahme durch einen Menschen. Genau so ist der Weg gebaut, und dabei bleibt es.

39Dateien eingelesen, keine Fehler
2im alten .doc-Format unlesbar
256Baustein-Vorschläge
908erkannte Ausfüllstellen
29Vorlagen sauber gegliedert
10blieben ein einziger Block
V1Blocker
2019 AKTUELL MUSTER GBV NEMETH.dotx · Anhang B.2

Die „Hausvorlage“ ist ein Briefkopf, kein Mietvertrag

Anhang B führt die Datei als „wahrscheinlich die Hausvorlage“, und ich hatte sie gestern als Kern von Baustein 3 vorgeschlagen. Der Import liest daraus 399 Zeichen: Firmenkopf, Anschriftenfeld, „Wien, am“, „Betreff“, „Sehr geehrte Damen und Herren“, Grußformel. Das ist die Briefvorlage der Kanzlei.

Vorschlag: In Anhang B von B.2 nach B.6 (keine Verträge) verschieben und aus der Umfangsdefinition streichen. Die eigentliche Hausschrift steht in den vier zuletzt erstellten Mietverträgen — die gliedern sich mit 18 bis 19 Bausteinen am saubersten von allen und sind der bessere Ausgangspunkt.

V2Blocker
11 von 39 Dateien · Punkt 10 / Anhang B

Die Muster sind keine Muster — sie enthalten echte Mieterdaten

Neun Dateien tragen Geburtsdaten oder Bankverbindungen, dazu kommen ein namentlich genannter Mieter samt Anschrift in einer Datei mit „MUSTER“ im Namen und ein Personenname im Dateinamen der Schlüsselgenehmigung. Die IBANs sind echte Konten, keine Platzhalter.

Damit liegen personenbezogene Daten von Mietern in einem Ordner, der als Vorlagensammlung übergeben wurde — und nach dem Import in unserer Datenbank. Der Auftragsverarbeitungsvertrag, der das tragen müsste, fehlt bis heute (Abschnitt C).

Vorschlag: Zwei Dinge, beide heute ansprechbar. Erstens: Nemeth bitten, die Muster ohne echte Daten zu übergeben, oder ausdrücklich zu bestätigen, dass wir sie bereinigen dürfen. Zweitens: der AV-Vertrag ist damit kein Formalpunkt mehr, sondern überfällig. Der Löschweg für einzelne Importe ist im System vorhanden — die betroffenen Sätze lassen sich restlos entfernen.

V3Klärung
10 Dateien · Gliederung

Zehn Vorlagen bleiben ein einziger Block

Vier davon sind zu Recht ungeteilt — Vollmacht, Schlüsselgenehmigung und ähnliche Einseiter haben keine Paragraphen. Die anderen sechs sind echte Verträge, deren Gliederung nicht erkannt wurde, darunter die Werkstätten-Vereinbarung mit 7.000 Zeichen am Stück und das Kellerabteil-Muster.

Die Ursache ist nachgeprüft und steht als Vermutung schon im Code: diese Vorlagen nummerieren über Word-Listen. Die Nummer steht dann nicht im Text, sondern in der Formatierung — die Überschrift „Mietobjekt“ kommt ohne Ziffer an, während „2. Mietzweck“ im selben Dokument von Hand getippt ist und erkannt wird. Das System sagt das von sich aus: jede dieser Dateien trägt die Warnung „von Hand zu teilen“.

Vorschlag: Kein Fehler, sondern Nacharbeit — entweder von Hand teilen oder die Word-Listennummern beim Lesen auflösen. Letzteres ist überschaubar und würde sechs Vorlagen ohne Handarbeit brauchbar machen. Für die Schätzung von Baustein 3 ist das die relevante Zahl: 29 Vorlagen kommen fertig gegliedert an, 6 kosten Handarbeit.

V4Beobachten
Dublettenprüfung · Anhang B.1

Die Dublettenprüfung hat sich selbst bewiesen

Die drei richt-mz-PDFs sind bytegleich — das System hat sie beim Import ohne Zutun als dieselbe Datei erkannt und benannt, ebenso fünf Dateien, die aus einem früheren Versuch schon in der Datenbank lagen. Aus den acht standardisierten Mietverträgen in Anhang B.1 werden damit belegbar sechs.

Vorschlag: Die Vermutung in Anhang B durch die Tatsache ersetzen. Nebenbei ein vorführbarer Beweis für Abnahmekriterium B2.6, an derselben Mechanik.

K Durchgang durch die laufende App

Am 03.09. gegen die laufende Instanz auf localhost:3001 mit der Entwicklungsdatenbank — echte HTTP-Aufrufe als echte Benutzer, keine Testfixtures. Der Unterschied zu Abschnitt G: dort steht, was im Code steht, hier steht, was die App tatsächlich tut. Zuletzt als ein Durchgang am Stück aus definiertem Ausgangszustand: 40 Prüfungen, 38 wie erwartet. Die zwei Abweichungen sind der bestätigte Befund K1 und ein falscher Feldname in meinem Prüfskript — die geprüfte Sache selbst stimmte.

40Prüfungen im Durchgang am Stück
38wie erwartet
1bestätigter Befund (K1)
3neue Befunde aus den Läufen
GeprüftWas dabei herauskam
Anmeldung
falsches Passwort, Zugriff ohne Sitzung, Abmelden
401 ohne Auskunft darüber, welcher Teil falsch war. Ohne Token kein Zugriff. Nach dem Abmelden ist die Sitzung sofort ungültig.
Zweiter Faktor
eingerichtet, falsch bestätigt, wiederverwendet
Einrichtung liefert zehn Wiederherstellungscodes, einmalig. Falscher Code: „Code stimmt nicht“. Derselbe Code im selben 30-Sekunden-Fenster wird abgelehnt — der Wiedereinspielschutz greift; erst im nächsten Fenster kommt die Anmeldung durch. Das hat mein eigener Testlauf zuerst für einen Fehler gehalten.
Rollen (B1.5)
Sachbearbeitung an drei verbotenen Stellen
Jedes Mal 403, und die Meldung nennt Modell und Rolle: „Kein create-Recht auf estate_category_rule für Rollen [Sachbearbeitung]“. Lesen bleibt erlaubt.
Beleg einlesen (B2.1, B2.5)
Rechnung Wien Energie, 1.244,50 netto
Netto, Steuersatz, Rechnungsdatum und Nummer gelesen, Kreditor „Wien Energie GmbH“ und Objekt MHS zugeordnet, Gesamtsicherheit 95 %. Kostenart „Strom“ kam aus Regel 2, begründet mit dem Kreditor — nicht aus dem Belegtext.
Buchung (B2.2, B2.3)Drei Buchungszeilen, Soll 1.493,40 gegen Haben 1.493,40, Aufwandskonto 7540, Steuer getrennt.
Dublette (B2.6)
dieselbe Rechnung ein zweites Mal
„Mögliche Dublette zu Beleg #16“, Prüfhaken gesetzt — der Beleg läuft nicht ohne Bestätigung weiter.
Vier-Augen
Erfasser will selbst freigeben
403 „Erfasser darf nicht freigeben“. Die Freigabe gelingt erst der zweiten Person mit der Rolle Freigabe und bestätigter Zwei-Faktor-Sitzung. Danach gebucht.
Conthaus-Export (B2.7, B2.8)Vorschau: 1 Beleg, 3 Zeilen, ausgeglichen. Export #2 erzeugt, CSV abgerufen:
belegnr;rg_nr;konto;soll;haben;text;steuercode;kostenstelle
ERE-2026-000001;PRUEF-361573;7540;1244,50;0,00;Strom Wien Energie GmbH 2026-08-12;;MHS
Der zweite Exportversuch wird abgelehnt: der Beleg ist erledigt.
Verlauf (B1.4)Fünf Einträge mit Benutzer und Zeitstempel: erfasst (berger) → geprüft (berger) → freigegeben (i.nemeth) → gebucht (i.nemeth, Vermerk „4-Augen“) → exportiert (d.neulinger). Genau die Kette, die das Kriterium verlangt.
Vertragsentwurf (B3.1, B3.3)12 Bausteine, 4.157 Zeichen, Werte eingesetzt (Liegenschaft, Mieter, 68,50 m², 3 Zimmer, Beginn 01.10.2026, Kündigungsfrist 3 Monate). Sechs fehlende Angaben stehen im Text als [[ fehlt: top ]].
Schalter (B3.2)
zweiter Vertrag mit Wertsicherung, Parkplatz, Haustieren, Untervermietung
14 statt 12 Bausteine. Hinzu: wertsicherung, parkplatz, haustiere_erlaubt, untervermietung_erlaubt. Weg: haustiere_untersagt, untervermietung_untersagt. Die Schalter tauschen die Klausel, sie hängen sie nicht nur an.
Zuständigkeit je Liegenschaft
Buchung auf ein fremdes Objekt
403 „Anlegen nur für eigene Liegenschaften erlaubt“. berger ist für die Mariahilfer Straße zuständig, nicht für die Lange Gasse — und die Plattform setzt das satzweise durch, nicht nur in der Ansicht. Erst durch diesen Fehlschlag meines eigenen Testlaufs aufgefallen (Befund R3).
RobustheitUnbekannte Route 404 ohne Innenansicht. Beleg ohne Inhalt: 400 mit dem Satz, was fehlt. Content-Security-Policy gesetzt. Regel ohne Kriterium: 400 mit der Begründung, warum eine solche Regel schadet.
R1Blocker
ir_model_access · account_move · Kriterium B1.5

Die Rolle „Buchhaltung“ darf keinen Beleg anfassen

Der Versuch, als Buchhalterin einen Beleg einzulesen, endet mit: „Kein create-Recht auf account_move für Rollen [Buchhaltung]“. In der Rechtetabelle hat die Rolle auf Belege gar keine Rechte — nicht einmal lesen. Anlegen und Ändern darf die Sachbearbeitung, freigeben die Rolle Freigabe.

Die Buchhaltung darf dafür Konten, Journale, Steuersätze, Kontierungs- und Kostenartregeln pflegen und nach Conthaus exportieren. Sie richtet also das Regelwerk ein und exportiert das Ergebnis, sieht aber den einzelnen Beleg nicht. Für eine Anwendung, deren erster Baustein „Rollen und Berechtigungen für Buchhaltung und Sachbearbeitung“ verspricht, ist das mindestens erklärungsbedürftig.

Vorschlag: Vor der Abnahme klären, was die Buchhaltung bei Nemeth am Beleg tun können soll — das ist eine fachliche Frage an Lisbeth Steidl, keine technische. Die Rechtetabelle ist Daten, keine Programmierung; die Antwort ist eine Migration, kein Umbau. Ohne die Klärung ist Kriterium B1.5 nicht abnehmbar, weil niemand sagen kann, was „die für seine Rolle vorgesehenen Aktionen“ für die Buchhaltung sind.

R2Klärung
contract_clause_rule · Baustein-Bibliothek

Ein übernommener Baustein ohne Bedingung gilt für jeden Vertrag

Kein Vertragsentwurf ließ sich erzeugen. Der Grund: stellplatz_kaution — eine Klausel, die beim Vorlagen-Import aus „Entwurf Stellplatz.docx“ übernommen wurde. Sie trägt keine Bedingung, und ohne Bedingung gilt ein Baustein immer. Eine Stellplatz-Kaution wäre damit in jedem Wohnungsmietvertrag gelandet.

Aufgehalten hat das die Freigabesperre: die Klausel war unfreigegeben, und das System hat den Entwurf mit Namen und Grund verweigert statt sie stillschweigend einzubauen. Die Kontrolle hat also funktioniert — der Fehler wäre nur mit einer voreiligen Freigabe durchgekommen. Beim Freigeben greift zusätzlich die Funktionstrennung: „Wer den Baustein verfasst hat, kann ihn nicht selbst freigeben.“

Teilweise erledigt: Der konkrete Baustein hat seine Bedingung bekommen (R4). Offen bleibt der Ablauf: Vorschlag: Beim Übernehmen eines Bausteins die Bedingung abfragen, statt sie leer zu lassen — „gilt immer“ sollte eine bewusste Wahl sein. Wichtig für die Kalkulation: Bedingungen kann Nemeth aus 13 vorhandenen Merkmalen (Vertragsart, befristet, möbliert, Parkplatz, MRG-Bereich …) selbst zusammenstellen. Ein neues Merkmal ist Entwicklungsaufwand. Genau diese Grenze gehört in die Umfangsdefinition.

R3Beobachten
estate_property_res_users_rel · Punkt 3 des Angebots

Die Zuordnung Objekt zu Sachbearbeiterin gibt es — und sie schützt bereits Daten

Mein zweiter Durchgang buchte versehentlich auf ein fremdes Objekt und lief in eine Sperre: „Anlegen nur für eigene Liegenschaften erlaubt“. Die Zuordnung steht in einer eigenen Tabelle, ist in der Demo befüllt und wird satzweise durchgesetzt — wer für die Mariahilfer Straße zuständig ist, kann für die Lange Gasse nichts anlegen.

Das Angebot sagt in Punkt 3 das Gegenteil: die Auswertung setze voraus, „dass im System hinterlegt ist, welches Objekt von welcher Person betreut wird. Diese Zuordnung liegt uns nicht vor.“ Nicht vorliegen tun Nemeths Daten. Der Mechanismus ist gebaut und trägt bereits die Zugriffskontrolle.

Vorschlag: Die Formulierung in Punkt 3 und Baustein 1 geraderücken — „die Ansicht ist angelegt“ untertreibt deutlich. Und im Termin die Frage anders stellen: nicht „gibt es diese Liste?“, sondern „in welcher Form liefern Sie sie, damit wir sie einspielen?“

R4behoben
contract_clause · Folge des Durchgangs

Die Stellplatz-Kaution steht jetzt in jedem Wohnungsvertrag

Um Baustein 3 überhaupt prüfen zu können, habe ich die drei offenen Bausteine freigeben lassen — darunter stellplatz_kaution aus R2, der keine Bedingung trägt. Genau das Vorhergesagte ist eingetreten: beide im Test erzeugten Wohnungsmietverträge enthalten seither eine Stellplatz-Kaution, zwischen Kaution und Erhaltung.

Damit ist der Befund nicht mehr Theorie, sondern im Datenbestand sichtbar — in der Entwicklungsdatenbank, nicht beim Kunden.

Behoben am 03.09. Der Baustein hat eine zweite Fassung mit der Bedingung parkplatz ist_wahr bekommen — über den vorgesehenen Weg, ohne Programmierung und ohne SQL: Bedingungen sind Teil des Bausteins und werden beim Speichern mitgegeben. Die alte Fassung ist damit abgelöst, die neue wurde von einer zweiten Person freigegeben (die Funktionstrennung gilt auch hier).

Gegenprobe in der App: ein Wohnungsvertrag ohne Stellplatz enthält 10 Bausteine ohne die Stellplatz-Kaution, derselbe Vertrag mit einem Stellplatz enthält sie — zusammen mit der Parkplatz-Klausel.

Was ich nicht geprüft habe: die Oberfläche im Browser — geprüft ist die Schnittstelle darunter. Ebenso nicht: der Postfach-Abruf (braucht den Microsoft-365-Zugang), Freshdesk (braucht die Zugangsdaten des Kunden), OCR an echten Scans, das Verhalten unter Last. Was der Durchgang in der Entwicklungsdatenbank hinterlassen hat: ein gebuchter und exportierter Testbeleg, vier Testverträge, drei nachträglich freigegebene Bausteine (die Bibliothek war vorher blockiert), eine Testregel — angelegt und wieder gelöscht — und ein zweiter Faktor für i.nemeth, eingerichtet und wieder entfernt.