{"openapi":"3.1.0","info":{"title":"casa.ai API","version":"0.1.0","description":"CLI-first API (ADR-10) — dieselben Tool-Funktionen wie UI/CLI. Auth per Bearer-Session-Token (Better Auth)."},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Better-Auth-Session-Token (`Authorization: Bearer <token>`)."}},"schemas":{"ApiErrorBody":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthenticated","forbidden","not_found","invalid_request","conflict","unavailable","internal"]},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"]},"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","unhealthy"]},"checks":{"type":"array","items":{"type":"object","properties":{"service":{"type":"string"},"status":{"type":"string","enum":["healthy","unhealthy"]}},"required":["service","status"]}}},"required":["status","checks"]},"VersionResponse":{"type":"object","properties":{"buildId":{"type":"string"}},"required":["buildId"]},"MeResponse":{"type":"object","properties":{"tenantId":{"type":"string","format":"uuid"},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"}},"required":["id","email"]},"authenticatedAt":{"type":"number"},"stepUp":{"type":"object","properties":{"allowed":{"type":"boolean"},"reason":{"type":"string"},"reAuthUrl":{"type":"string"}},"required":["allowed"]}},"required":["tenantId","user","stepUp"]},"BelegUploadResponse":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"outcome":{"type":"string","enum":["received","duplicate","quarantined"]},"quarantineReason":{"type":["string","null"],"enum":["malware","unsupported-type","oversize","scan-unavailable",null],"description":"grober Quarantäne-Grund (nur bei outcome=quarantined gesetzt, sonst null). scan-unavailable = Sicherheitsprüfung war nicht verfügbar (Beleg ungeprüft, NICHT beanstandet — unterscheidbar von malware)."},"dispatchEnqueued":{"type":"boolean","description":"Ob der Dispatch-Job (Router-Naht #350) eingereiht werden konnte. Der Ingest ist bei false trotzdem committet (Beleg sichtbar in „Empfangen\"); ein Enqueue-Ausfall ist damit SICHTBAR und wird nicht als Erfolg maskiert (PR #525, Finding 2)."}},"required":["documentId","outcome","quarantineReason","dispatchEnqueued"]},"Objekt":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyNo":{"type":"string"},"name":{"type":"string"},"adresse":{"type":["string","null"],"description":"Kurzanschrift zur BESCHRIFTUNG des Objekts („Schloßallee 21, München\", #2483) — abgeleitet aus dem ÄLTESTEN AKTIVEN Gebäude, ohne PLZ. null ⇒ kein aktives Gebäude oder keine brauchbare Anschrift hinterlegt. Reine Anzeige und NICHT pflegbar; die pflegbare Anschrift ist `Gebaeude.address`."},"verwaltungsart":{"type":"string","enum":["miet","weg","pro"],"description":"Verwaltungsart des Objekts (geschlossenes Vokabular): miet = Mietverwaltung, weg = Verwaltung der Eigentümergemeinschaft, pro = WEG mit Mietverwaltung (PRO)."},"verwaltungsverhaeltnis":{"type":"string","enum":["eigen","fremd"],"description":"Verwaltungsverhältnis des Objekts (geschlossenes Vokabular, orthogonal zur Verwaltungsart): eigen = Eigenverwaltung/Eigenbestand (der Verwalter verwaltet eigenes Eigentum), fremd = Fremdverwaltung (fremdes Eigentum im Auftrag; Regelfall/Default)."},"bundesland":{"type":["string","null"],"enum":["bb","be","bw","by","hb","he","hh","mv","ni","nw","rp","sh","sl","sn","st","th",null],"description":"Bundesland des Objekts (#947); null ⇒ nicht erfasst."},"bankentscheid":{"type":["string","null"],"enum":["verbunden","ohne_bankanbindung",null],"description":"Der Bankentscheid am Objekt (#3297): `verbunden` = an eine Bankverbindung angebunden, `ohne_bankanbindung` = bewusst ohne. null ⇒ NICHT ENTSCHIEDEN — der Zustand jedes vor #3297 entstandenen Objekts. Er wird über die eigene Fachhandlung `set_property_bank_decision` gesetzt und geändert, NICHT über `update_property`."},"anteilNachkommastellen":{"type":["integer","null"],"minimum":0,"maximum":6,"description":"Nachkommastellen der Anteile (#2066); null ⇒ nicht erfasst."},"grundkostenAchsen":{"type":["object","null"],"properties":{"heizung":{"type":"object","properties":{"anteilProzent":{"type":"integer","minimum":0,"maximum":100,"description":"Grundkostenanteil in GANZEN Prozent (0-100), § 7 HeizkostenV."},"bezugsflaecheAttributKey":{"type":"string","description":"unit_attributes-Schluessel der Bezugsflaeche dieser Achse (z. B. wohnflaeche_qm bzw. wohnflaeche_warmwasser_qm)."}},"required":["anteilProzent","bezugsflaecheAttributKey"],"description":"Eine Grundkosten-Achse: Prozentsatz + Bezugsflaeche. BEWUSST inline (kein eigener Komponentenname), damit die Komponentenliste stabil bleibt."},"warmwasser":{"type":"object","properties":{"anteilProzent":{"type":"integer","minimum":0,"maximum":100,"description":"Grundkostenanteil in GANZEN Prozent (0-100), § 7 HeizkostenV."},"bezugsflaecheAttributKey":{"type":"string","description":"unit_attributes-Schluessel der Bezugsflaeche dieser Achse (z. B. wohnflaeche_qm bzw. wohnflaeche_warmwasser_qm)."}},"required":["anteilProzent","bezugsflaecheAttributKey"],"description":"Eine Grundkosten-Achse: Prozentsatz + Bezugsflaeche. BEWUSST inline (kein eigener Komponentenname), damit die Komponentenliste stabil bleibt."}},"required":["heizung","warmwasser"],"description":"Die vier Grundkosten-Achsen (#2304); null ⇒ das Objekt rechnet keinen § 7-Split (reine Verbrauchsverteilung)."},"billingPeriod":{"type":["string","null"]},"istSollVersteuerung":{"type":["string","null"]},"ustSettings":{"type":"object","additionalProperties":{}},"accountingCircleId":{"type":["string","null"],"format":"uuid"},"accountingCircleName":{"type":["string","null"]},"managementStartDate":{"type":["string","null"],"format":"date","description":"Verwaltungsbeginn — ERSTER betreuter Tag (inklusiv); null ⇒ nicht erfasst / offener Beginn."},"managementEndDate":{"type":["string","null"],"format":"date","description":"Verwaltungsende — LETZTER betreuter Tag (inklusiv); null ⇒ das Mandat läuft weiter."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"gesetzt ⇒ archiviert (K5: kein DELETE)"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyNo","name","adresse","verwaltungsart","verwaltungsverhaeltnis","bundesland","bankentscheid","anteilNachkommastellen","grundkostenAchsen","billingPeriod","istSollVersteuerung","ustSettings","accountingCircleId","accountingCircleName","managementStartDate","managementEndDate","archivedAt","createdAt"]},"ObjektListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","aktiv","archiviert"],"description":"der wirksame 3-Wege-Filter"},"objekte":{"type":"array","items":{"$ref":"#/components/schemas/Objekt"}}},"required":["status","objekte"]},"ObjektCreateRequest":{"type":"object","properties":{"propertyNo":{"type":"string","description":"Objektnummer — fachliche Ordnungsnummer, KEINE erzwungene Eindeutigkeit (kein Unique-Index; s. #416). Die Identität eines Objekts ist `id`."},"verwaltungsart":{"type":"string","enum":["miet","weg","pro"],"description":"Verwaltungsart des Objekts (geschlossenes Vokabular): miet = Mietverwaltung, weg = Verwaltung der Eigentümergemeinschaft, pro = WEG mit Mietverwaltung (PRO)."},"verwaltungsverhaeltnis":{"type":"string","enum":["eigen","fremd"],"description":"Eigen-/Fremdverwaltung; ohne Angabe gilt der Default fremd (#590)."},"bundesland":{"type":["string","null"],"enum":["bb","be","bw","by","hb","he","hh","mv","ni","nw","rp","sh","sl","sn","st","th",null],"description":"Bundesland des Objekts (#947); ohne Angabe/null nicht erfasst."},"anteilNachkommastellen":{"type":["integer","null"],"minimum":0,"maximum":6,"description":"Nachkommastellen der Anteile (#2066); ohne Angabe/null nicht erfasst."},"grundkostenAchsen":{"type":["object","null"],"properties":{"heizung":{"type":"object","properties":{"anteilProzent":{"type":"integer","minimum":0,"maximum":100,"description":"Grundkostenanteil in GANZEN Prozent (0-100), § 7 HeizkostenV."},"bezugsflaecheAttributKey":{"type":"string","description":"unit_attributes-Schluessel der Bezugsflaeche dieser Achse (z. B. wohnflaeche_qm bzw. wohnflaeche_warmwasser_qm)."}},"required":["anteilProzent","bezugsflaecheAttributKey"],"description":"Eine Grundkosten-Achse: Prozentsatz + Bezugsflaeche. BEWUSST inline (kein eigener Komponentenname), damit die Komponentenliste stabil bleibt."},"warmwasser":{"type":"object","properties":{"anteilProzent":{"type":"integer","minimum":0,"maximum":100,"description":"Grundkostenanteil in GANZEN Prozent (0-100), § 7 HeizkostenV."},"bezugsflaecheAttributKey":{"type":"string","description":"unit_attributes-Schluessel der Bezugsflaeche dieser Achse (z. B. wohnflaeche_qm bzw. wohnflaeche_warmwasser_qm)."}},"required":["anteilProzent","bezugsflaecheAttributKey"],"description":"Eine Grundkosten-Achse: Prozentsatz + Bezugsflaeche. BEWUSST inline (kein eigener Komponentenname), damit die Komponentenliste stabil bleibt."}},"required":["heizung","warmwasser"],"description":"Die vier Grundkosten-Achsen (#2304); ohne Angabe/null rechnet das Objekt keinen § 7-Split."},"name":{"type":"string","description":"Anzeigename; ohne Angabe gilt die Objektnummer"},"billingPeriod":{"type":["string","null"]},"istSollVersteuerung":{"type":["string","null"]},"ustSettings":{"type":"object","additionalProperties":{}},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["propertyNo","verwaltungsart"]},"ObjektUpdateRequest":{"type":"object","properties":{"propertyNo":{"type":"string"},"verwaltungsart":{"type":"string","enum":["miet","weg","pro"],"description":"Verwaltungsart des Objekts (geschlossenes Vokabular): miet = Mietverwaltung, weg = Verwaltung der Eigentümergemeinschaft, pro = WEG mit Mietverwaltung (PRO)."},"verwaltungsverhaeltnis":{"type":"string","enum":["eigen","fremd"],"description":"Verwaltungsverhältnis des Objekts (geschlossenes Vokabular, orthogonal zur Verwaltungsart): eigen = Eigenverwaltung/Eigenbestand (der Verwalter verwaltet eigenes Eigentum), fremd = Fremdverwaltung (fremdes Eigentum im Auftrag; Regelfall/Default)."},"bundesland":{"type":["string","null"],"enum":["bb","be","bw","by","hb","he","hh","mv","ni","nw","rp","sh","sl","sn","st","th",null],"description":"Bundesland des Objekts (#947); null setzt zurück auf nicht erfasst."},"anteilNachkommastellen":{"type":["integer","null"],"minimum":0,"maximum":6,"description":"Nachkommastellen der Anteile (#2066); null setzt zurück auf nicht erfasst."},"grundkostenAchsen":{"type":["object","null"],"properties":{"heizung":{"type":"object","properties":{"anteilProzent":{"type":"integer","minimum":0,"maximum":100,"description":"Grundkostenanteil in GANZEN Prozent (0-100), § 7 HeizkostenV."},"bezugsflaecheAttributKey":{"type":"string","description":"unit_attributes-Schluessel der Bezugsflaeche dieser Achse (z. B. wohnflaeche_qm bzw. wohnflaeche_warmwasser_qm)."}},"required":["anteilProzent","bezugsflaecheAttributKey"],"description":"Eine Grundkosten-Achse: Prozentsatz + Bezugsflaeche. BEWUSST inline (kein eigener Komponentenname), damit die Komponentenliste stabil bleibt."},"warmwasser":{"type":"object","properties":{"anteilProzent":{"type":"integer","minimum":0,"maximum":100,"description":"Grundkostenanteil in GANZEN Prozent (0-100), § 7 HeizkostenV."},"bezugsflaecheAttributKey":{"type":"string","description":"unit_attributes-Schluessel der Bezugsflaeche dieser Achse (z. B. wohnflaeche_qm bzw. wohnflaeche_warmwasser_qm)."}},"required":["anteilProzent","bezugsflaecheAttributKey"],"description":"Eine Grundkosten-Achse: Prozentsatz + Bezugsflaeche. BEWUSST inline (kein eigener Komponentenname), damit die Komponentenliste stabil bleibt."}},"required":["heizung","warmwasser"],"description":"Die vier Grundkosten-Achsen (#2304) — immer GEMEINSAM; null setzt alle vier zurueck auf kein § 7-Split."},"name":{"type":"string"},"billingPeriod":{"type":["string","null"]},"istSollVersteuerung":{"type":["string","null"]},"ustSettings":{"type":"object","additionalProperties":{}}},"description":"Partieller Patch — mindestens ein Feld muss gesetzt sein."},"ObjektArchiveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":"string","format":"date-time"},"accountingCircleId":{"type":["string","null"],"format":"uuid"},"alreadyArchived":{"type":"boolean","description":"true ⇒ das Objekt war bereits archiviert (expliziter No-op)."},"hinweise":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","enum":["verwaltungsende_fehlt"],"description":"maschinenlesbarer Hinweis-Code (geschlossenes Vokabular)."},"message":{"type":"string","description":"deutscher Anzeigetext; die Wahrheit ist code."}},"required":["code","message"]},"description":"Hinweise zum erfolgreichen Archivieren; leeres Array ⇒ kein Befund. Ein `verwaltungsende_fehlt` meldet fehlendes Verwaltungsende."}},"required":["id","archivedAt","accountingCircleId","alreadyArchived","hinweise"]},"ObjektReactivateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reactivatedAt":{"type":"string","format":"date-time"},"accountingCircleId":{"type":["string","null"],"format":"uuid"},"alreadyActive":{"type":"boolean","description":"true ⇒ das Objekt war bereits aktiv (expliziter No-op, kein Write)."},"reactivatedBuildings":{"type":"integer","description":"Anzahl der von DIESER Kaskade zurückgeholten Gebäude."},"reactivatedUnits":{"type":"integer","description":"Anzahl der von DIESER Kaskade zurückgeholten Einheiten."}},"required":["id","reactivatedAt","accountingCircleId","alreadyActive","reactivatedBuildings","reactivatedUnits"]},"ObjektCheckBefund":{"type":"object","properties":{"code":{"type":"string","description":"Maschinenlesbarer Befund-Code. Struktur: objekt_ohne_gebaeude | objekt_ohne_einheiten | gebaeude_ohne_einheiten. Fläche (§20 NMV): flaeche_fehlt | flaeche_unplausibel | flaeche_mehrdeutig. Miteigentumsanteil: mea_fehlt | mea_summe_abweichung | mea_nenner_uneinheitlich | mea_unplausibel. Die Flächenpflicht ist fail-closed (DENYLIST): pflichtig ist jede Einheiten-Art, die nicht nachweislich befreit ist (Stellplatz/Garage/„sonstige\") — unit_kind ist offenes Vokabular ohne CHECK."},"ampel":{"type":"string","enum":["gruen","gelb","rot"],"description":"Ampel dieses Befunds (zentrale Definition, GG6/BP #13)."},"scope":{"type":"string","enum":["objekt","gebaeude","einheit"],"description":"Bezugsebene des Befunds."},"refId":{"type":["string","null"],"format":"uuid","description":"ID der betroffenen Einheit/des Gebäudes; null bei Objekt-Ebene."},"message":{"type":"string","description":"Deutsche Klartext-Meldung (Anzeige; die Wahrheit ist code)."}},"required":["code","ampel","scope","refId","message"]},"ObjektCheckGebaeudeFlaeche":{"type":"object","properties":{"buildingId":{"type":"string","format":"uuid"},"summeQm":{"type":["string","null"],"description":"Summe der lesbaren Einheiten-Flächen als m²-Dezimalstring; null ⇒ keine."},"einheiten":{"type":"integer","description":"Anzahl aktiver Einheiten des Gebäudes am Stichtag."}},"required":["buildingId","summeQm","einheiten"]},"ObjektCheckResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"asOf":{"type":"string","format":"date","description":"Wirksamer Stichtag, gegen den die Attribut-Scheiben gemessen wurden."},"ampel":{"type":"string","enum":["gruen","gelb","rot"],"description":"Objekt-Ampel = riskanteste Einzel-Ampel aller Befunde; ohne Befund gruen."},"einheitenGesamt":{"type":"integer","description":"Anzahl aktiver Einheiten des Objekts am Stichtag."},"gesamtflaecheQm":{"type":["string","null"],"description":"Summe der lesbaren Einheiten-Flächen des Objekts als m²-Dezimalstring; null ⇒ keine."},"flaecheJeGebaeude":{"type":"array","items":{"$ref":"#/components/schemas/ObjektCheckGebaeudeFlaeche"}},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/ObjektCheckBefund"}}},"required":["propertyId","asOf","ampel","einheitenGesamt","gesamtflaecheQm","flaecheJeGebaeude","befunde"]},"Konto":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":["string","null"],"format":"uuid","description":"Objektbindung des Kontos; null ausschließlich beim mandantenweiten Kreditorkonto (#1487)"},"accountNo":{"type":"string","description":"Kontonummer — je Objekt eindeutig (DB-UNIQUE, keine bloße Konvention)"},"name":{"type":"string"},"costCategoryId":{"type":["string","null"],"format":"uuid"},"costCategoryKey":{"type":["string","null"],"description":"Schlüssel der Betriebskosten-Kategorie (cost_categories.key)"},"costCategoryName":{"type":["string","null"]},"ustRate":{"type":["string","null"],"description":"USt-Satz als exakter Dezimalstring (numeric), z. B. \"19.00\" — nie als Gleitkommazahl"},"isUmlagefaehig":{"type":["boolean","null"]},"datevAccountNo":{"type":["string","null"],"description":"DATEV-Zielkonto des Kontos (SKR03/SKR04-Export-Mapping, #2990) — 4–8 Ziffern ohne führende Null; null = nicht zugeordnet (das Konto fällt dann aus dem DATEV-Export)"},"allocationKeyId":{"type":["string","null"],"format":"uuid","description":"zugeordneter Umlageschlüssel (allocation_keys.id); null ⇒ keiner. Bei umlagefähigem Konto ⇒ Readiness-Fund schluessel_fehlt."},"lockedAfterFirstBooking":{"type":"boolean","description":"true ⇒ nach Erstbuchung fix: nur name bleibt änderbar. HEUTE setzt noch kein Produktionspfad dieses Flag."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"gesetzt ⇒ archiviert (K5: kein DELETE)"},"createdAt":{"type":"string","format":"date-time"},"kontoart":{"type":["string","null"],"enum":["ausgabe","einnahme",null],"description":"Kontoart des Sachkontos (#5551): ausgabe | einnahme; null an Geld- und Personenkonten und im noch nicht klassifizierten Bestand (DB-CHECK: nur am Sachkonto)"}},"required":["id","propertyId","accountNo","name","costCategoryId","costCategoryKey","costCategoryName","ustRate","isUmlagefaehig","datevAccountNo","allocationKeyId","lockedAfterFirstBooking","archivedAt","createdAt","kontoart"]},"KontoListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","aktiv","archiviert"],"description":"der wirksame 3-Wege-Filter"},"propertyId":{"type":["string","null"],"format":"uuid","description":"die wirksame Objekt-Eingrenzung (null = alle Objekte des Tenants)"},"konten":{"type":"array","items":{"$ref":"#/components/schemas/Konto"}}},"required":["status","konten"]},"KontoCreateRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"accountNo":{"type":"string"},"name":{"type":"string"},"costCategoryKey":{"type":["string","null"],"description":"unbekannter Schlüssel ⇒ 400 (fail-loud, nie stilles NULL)"},"ustRate":{"type":["string","null"],"description":"Dezimalstring wie \"19.00\""},"isUmlagefaehig":{"type":"boolean"},"datevAccountNo":{"type":["string","null"],"description":"DATEV-Zielkonto (#2990) — 4–8 Ziffern ohne führende Null; null = nicht zugeordnet"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["propertyId","accountNo","name"]},"KontoUpdateRequest":{"type":"object","properties":{"accountNo":{"type":"string"},"name":{"type":"string"},"costCategoryKey":{"type":["string","null"]},"ustRate":{"type":["string","null"]},"isUmlagefaehig":{"type":"boolean"},"datevAccountNo":{"type":["string","null"],"description":"DATEV-Zielkonto (#2990); null hebt die Zuordnung auf. NICHT buchungsrelevant — auch nach der Erstbuchung änderbar."}},"description":"Partieller Patch — mindestens ein Feld muss gesetzt sein. Nach Erstbuchung sind nur `name` und `datevAccountNo` änderbar."},"KontoUmlageschluesselRequest":{"type":"object","properties":{"allocationKeyId":{"type":["string","null"],"format":"uuid","description":"Ziel-Umlageschlüssel; null hebt die Zuordnung auf."}},"required":["allocationKeyId"],"description":"Setzt/hebt die Konto→Umlageschlüssel-Zuordnung. Der Schlüssel muss demselben Objekt wie das Konto gehören (fremdes Objekt/Tenant ⇒ Fehler, kein stiller No-op)."},"KontoArchiveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":"string","format":"date-time"},"alreadyArchived":{"type":"boolean","description":"true ⇒ das Konto war bereits archiviert (expliziter No-op)."}},"required":["id","archivedAt","alreadyArchived"]},"Kontenrahmen":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"version":{"type":"string","description":"Inhaltsversion — geht in den Idempotency Key des Einspielens ein"},"description":{"type":"string"},"accountCount":{"type":"integer"}},"required":["id","name","version","description","accountCount"]},"KontenrahmenListResponse":{"type":"object","properties":{"kontenrahmen":{"type":"array","items":{"$ref":"#/components/schemas/Kontenrahmen"}}},"required":["kontenrahmen"]},"KontenrahmenApplyRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid","description":"das Objekt, dessen Kontenplan bestückt wird"}},"required":["propertyId"]},"KontenrahmenApplyResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"kontenrahmenId":{"type":"string"},"kontenrahmenVersion":{"type":"string"},"created":{"type":"array","items":{"type":"object","properties":{"accountNo":{"type":"string"},"name":{"type":"string"}},"required":["accountNo","name"]},"description":"die NEU angelegten Konten (Vorlagen-Reihenfolge)"},"skipped":{"type":"array","items":{"type":"object","properties":{"accountNo":{"type":"string"},"name":{"type":"string"}},"required":["accountNo","name"]},"description":"Konten, die es am Objekt schon gab — unangetastet (DO NOTHING)"},"unresolvedCostCategoryKeys":{"type":"array","items":{"type":"string"},"description":"Kategorie-Schlüssel der Vorlage, die es im Tenant nicht gibt (sichtbar gemeldet)"}},"required":["propertyId","kontenrahmenId","kontenrahmenVersion","created","skipped","unresolvedCostCategoryKeys"]},"Bank":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"propertyNo":{"type":["string","null"],"description":"Objektnummer des Elternobjekts (Anzeige, LEFT JOIN)"},"iban":{"type":"string","description":"IBAN in kanonischer Form (ohne Leerraum, Großbuchstaben), prüfziffernvalidiert"},"kind":{"type":"string","enum":["bank","kasse","ruecklage","kautionskonto"],"description":"Kontoart; `kautionskonto` = getrennte Anlage der Mietkaution (§ 551 Abs. 3 BGB, #5178)"},"glaeubigerId":{"type":["string","null"],"description":"SEPA-Gläubiger-Identifikationsnummer (Lastschrift)"},"glAccountId":{"type":["string","null"],"format":"uuid","description":"zugeordnetes Bank-Sachkonto (gl_accounts.id, #1859); null ⇒ nicht gepflegt, der Bankabgleich leitet dann über das Objekt ab"},"archivedAt":{"type":["string","null"],"format":"date-time","description":"gesetzt ⇒ archiviert (K5: kein DELETE)"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","propertyNo","iban","kind","glaeubigerId","glAccountId","archivedAt","createdAt"]},"BankListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","aktiv","archiviert"],"description":"der wirksame 3-Wege-Filter"},"propertyId":{"type":["string","null"],"format":"uuid","description":"die wirksame Objekt-Eingrenzung (null = alle Objekte des Tenants)"},"bankverbindungen":{"type":"array","items":{"$ref":"#/components/schemas/Bank"}}},"required":["status","bankverbindungen"]},"BankCreateRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"iban":{"type":"string","description":"IBAN — wird normalisiert und prüfziffernvalidiert; ungültig ⇒ 400"},"kind":{"type":"string","enum":["bank","kasse","ruecklage","kautionskonto"]},"glaeubigerId":{"type":["string","null"],"description":"SEPA-Gläubiger-ID; weglassen ⇒ keine"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["propertyId","iban","kind"]},"BankUpdateRequest":{"type":"object","properties":{"iban":{"type":"string","description":"wird normalisiert und prüfziffernvalidiert"},"kind":{"type":"string","enum":["bank","kasse","ruecklage","kautionskonto"]},"glaeubigerId":{"type":["string","null"],"description":"null setzt die Gläubiger-ID zurück"},"glAccountId":{"type":"string","format":"uuid","description":"Bank-Sachkonto dieser Bankverbindung (#1859) — muss ein aktives Konto mit kontotyp=bank DESSELBEN Objekts sein. Nicht nullable: gesetzt oder nicht angefasst."}},"description":"Partieller Patch — mindestens ein Feld muss gesetzt sein. `propertyId` ist nicht patchbar."},"BankArchiveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":"string","format":"date-time"},"alreadyArchived":{"type":"boolean","description":"true ⇒ die Bankverbindung war bereits archiviert (expliziter No-op)."}},"required":["id","archivedAt","alreadyArchived"]},"BankUmsatzImportResponse":{"type":"object","properties":{"importBatchId":{"type":"string","format":"uuid","description":"Kennung DIESES Import-Laufs (append-only; jeder Aufruf erzeugt eine neue)."},"bankAccountId":{"type":"string","format":"uuid"},"format":{"type":"string","enum":["camt.053","camt.052","mt940"],"description":"Das aus der DATEI ERKANNTE Format — nicht das per ?format= deklarierte (das wählt nur den Parser)."},"total":{"type":"integer","description":"Quell-Posten der Datei (gebuchte + beim Parsen verworfene)."},"imported":{"type":"integer","description":"in DIESEM Aufruf frisch persistierte Zeilen."},"deduplicated":{"type":"integer","description":"bereits vorhandene Zeilen (vom Unique-Index verschluckt) — ein Wiederhol-Import ist gefahrlos."},"discarded":{"type":"integer","description":"nicht gebuchte (Status ≠ BOOK) und nicht dedup-fähige Posten."},"excluded":{"type":"integer","description":"Posten, die wegen Konto-Ausschluss (#998) NICHT importiert wurden."},"exclusion":{"type":["object","null"],"properties":{"excludedAt":{"type":"string","format":"date-time"},"reason":{"type":"string"}},"required":["excludedAt","reason"],"description":"Ausschluss-Zustand der Bankverbindung (wann/warum), sonst null."}},"required":["importBatchId","bankAccountId","format","total","imported","deduplicated","discarded","excluded","exclusion"]},"PersonContact":{"type":"object","properties":{"email":{"type":"string","maxLength":320,"format":"email","description":"E-Mail — einziges formatgeprüftes Feld (Anker der Portal-Identität)"},"telefon":{"type":"string","minLength":1,"maxLength":100,"description":"Telefon privat/allgemein — der im Bestand vorhandene Schlüssel"},"mobil":{"type":"string","minLength":1,"maxLength":100,"description":"Mobilnummer"},"telefonGeschaeftlich":{"type":"string","minLength":1,"maxLength":100,"description":"Telefon geschäftlich"},"adresse":{"type":"object","properties":{"strasse":{"type":"string","minLength":1,"maxLength":200},"hausnummer":{"type":"string","minLength":1,"maxLength":50},"plz":{"type":"string","minLength":1,"maxLength":20},"ort":{"type":"string","minLength":1,"maxLength":200},"land":{"type":"string","minLength":1,"maxLength":100,"description":"Land — freier Text oder ISO-Code, KEIN geschlossenes Vokabular"}},"additionalProperties":true,"description":"Postanschrift"},"anrede":{"type":"string","enum":["herr","frau","divers","familie","firma"],"description":"Anrede — geschlossenes Vokabular (`ANREDEN`, `@casaai/domain`)"},"titel":{"type":"string","minLength":1,"maxLength":100,"description":"Titel, z. B. „Dr.“ — freier Text"},"briefanrede":{"type":"string","minLength":1,"maxLength":200,"description":"Briefanrede, z. B. „Sehr geehrter Herr Dr. Kellner,“ — Vorschlag `briefanredeVorschlag` (`@casaai/domain`), überschreibbar"},"kommunikation":{"type":"object","properties":{"bevorzugterKanal":{"type":"string","enum":["email","brief"],"description":"Bevorzugter Kanal — `email` | `brief` (`KANAELE`, `@casaai/domain`)"}},"additionalProperties":true,"description":"Kommunikationspräferenzen"}},"additionalProperties":true,"description":"Kontaktangaben (personenbezogen — nie in Logs/URLs). Benannte Felder sind typisiert; UNBEKANNTE Zusatzschlüssel bleiben erhalten (kein Datenverlust beim Round-Trip)."},"Person":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"personType":{"type":"string","description":"natuerlich | juristisch (Doc 20 §5) — nicht schema-seitig geschlossen"},"name":{"type":"string","description":"Anzeigename — KEINE erzwungene Eindeutigkeit. Die Identität einer Person ist `id`."},"contact":{"$ref":"#/components/schemas/PersonContact"},"archivedAt":{"type":["string","null"],"format":"date-time","description":"gesetzt ⇒ archiviert (K5: kein DELETE)"},"createdAt":{"type":"string","format":"date-time"},"kreditorKategorie":{"type":["string","null"],"enum":["handwerker","dienstleister","behoerde","versicherung","amt",null],"description":"Kategorie eines Kreditors — geschlossenes Vokabular (`KREDITOR_KATEGORIEN`, `@casaai/domain`); `null` ⇒ keine"},"archiveReason":{"type":["string","null"],"description":"Grund der Archivierung (Freitext, personenbezogen); nur gesetzt, wenn `archivedAt` gesetzt ist"}},"required":["id","personType","name","contact","archivedAt","createdAt","kreditorKategorie","archiveReason"]},"PersonListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","aktiv","archiviert"],"description":"der wirksame 3-Wege-Filter"},"personen":{"type":"array","items":{"$ref":"#/components/schemas/Person"}}},"required":["status","personen"]},"PersonCreateRequest":{"type":"object","properties":{"personType":{"type":"string"},"name":{"type":"string"},"contact":{"$ref":"#/components/schemas/PersonContact"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["personType","name"]},"PersonUpdateRequest":{"type":"object","properties":{"personType":{"type":"string"},"name":{"type":"string"},"contact":{"$ref":"#/components/schemas/PersonContact"}},"description":"Partieller Patch — mindestens ein Feld muss gesetzt sein. `contact` ersetzt das GANZE Kontakt-Objekt (kein Merge): wer nur ein Feld ändert, schickt die übrigen Schlüssel mit, sonst gehen sie verloren."},"PersonArchiveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":"string","format":"date-time"},"alreadyArchived":{"type":"boolean","description":"true ⇒ die Person war bereits archiviert (expliziter No-op). Rollen werden NICHT mitbeendet."}},"required":["id","archivedAt","alreadyArchived"]},"Rolle":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"personName":{"type":"string"},"role":{"type":"string","description":"mieter | eigentuemer | dienstleister | beirat … — nicht schema-seitig geschlossen"},"targetKind":{"type":["string","null"],"enum":["objekt","einheit","vertrag","mehrdeutig",null],"description":"abgeleitet; `mehrdeutig` = mehrere Ziel-Spalten gesetzt (Datendefekt, sichtbar gemacht)"},"targetId":{"type":["string","null"],"format":"uuid","description":"null bei `mehrdeutig` und ohne Ziel"},"validFrom":{"type":["string","null"],"format":"date","description":"inklusiv; null ⇒ unbegrenzt in die Vergangenheit"},"validTo":{"type":["string","null"],"format":"date","description":"EXKLUSIV; null ⇒ laufend"},"validRange":{"type":"string","description":"das rohe Postgres-daterange-Literal, z. B. `[2026-01-01,)`"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","personId","personName","role","targetKind","targetId","validFrom","validTo","validRange","createdAt"]},"RolleListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","aktiv","beendet"],"description":"der wirksame 3-Wege-GÜLTIGKEITS-Filter. ACHTUNG: aktiv ∪ beendet ≠ alle (zukünftige Rollen nur unter `alle`)."},"asOf":{"type":"string","format":"date","description":"der wirksame Stichtag, gegen den aktiv/beendet gemessen wurde"},"rollen":{"type":"array","items":{"$ref":"#/components/schemas/Rolle"}}},"required":["status","asOf","rollen"]},"RolleAssignRequest":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"role":{"type":"string"},"propertyId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"validFrom":{"type":"string","format":"date","description":"inklusiv (YYYY-MM-DD); ohne Angabe unbegrenzt"},"validTo":{"type":"string","format":"date","description":"EXKLUSIV (YYYY-MM-DD); ohne Angabe laufend"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["personId","role"],"description":"Genau EIN Ziel angeben: propertyId (Objekt) ODER unitId (Einheit). Beides oder keines ⇒ 400."},"RolleEndRequest":{"type":"object","properties":{"endDate":{"type":"string","format":"date","description":"Tag, ab dem die Rolle NICHT mehr gilt (exklusive obere Grenze)"}},"required":["endDate"]},"RolleEndResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endDate":{"type":"string","format":"date"},"validRange":{"type":"string"},"alreadyEnded":{"type":"boolean","description":"true ⇒ die Rolle war bereits beendet; `endDate` trägt dann das URSPRÜNGLICHE Ende."}},"required":["id","endDate","validRange","alreadyEnded"]},"Gebaeude":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid","description":"das Objekt; nach der Anlage unveränderlich"},"propertyNo":{"type":["string","null"],"description":"Objektnummer des Elternobjekts (LEFT JOIN)"},"address":{"type":"object","additionalProperties":{},"description":"freies Adress-JSON — KEIN erzwungenes Adressmodell"},"archivedAt":{"type":["string","null"],"format":"date-time","description":"gesetzt ⇒ archiviert (K5: kein DELETE)"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","propertyNo","address","archivedAt","createdAt"]},"GebaeudeListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","aktiv","archiviert"],"description":"der wirksame 3-Wege-Filter"},"gebaeude":{"type":"array","items":{"$ref":"#/components/schemas/Gebaeude"}}},"required":["status","gebaeude"]},"GebaeudeCreateRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid","description":"Das Objekt, an dem das Gebäude hängt. MUSS aktiv sein (sonst 400)."},"address":{"type":"object","additionalProperties":{},"description":"freies Adress-JSON; ohne Angabe {}"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["propertyId"]},"GebaeudeUpdateRequest":{"type":"object","properties":{"address":{"type":"object","additionalProperties":{}}},"description":"Partieller Patch. `propertyId` ist BEWUSST nicht patchbar (Umstrukturierung mit eigenem Pfad)."},"GebaeudeArchiveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":"string","format":"date-time"},"alreadyArchived":{"type":"boolean","description":"true ⇒ das Gebäude war bereits archiviert (expliziter No-op)."}},"required":["id","archivedAt","alreadyArchived"]},"GebaeudeReactivateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reactivatedAt":{"type":"string","format":"date-time"},"alreadyActive":{"type":"boolean"},"reactivatedUnits":{"type":"integer"}},"required":["id","reactivatedAt","alreadyActive","reactivatedUnits"]},"Einheit":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"buildingId":{"type":"string","format":"uuid","description":"das Gebäude; nach der Anlage unveränderlich"},"propertyId":{"type":["string","null"],"format":"uuid","description":"das Objekt über das Gebäude (LEFT JOIN)"},"propertyNo":{"type":["string","null"],"description":"Objektnummer (LEFT JOIN)"},"unitNo":{"type":"string","description":"Einheitennummer (Freitext) — eindeutig je Objekt unter den aktiven Einheiten (#5534); eine archivierte Nummer ist wieder frei. Identität ist `id`."},"unitKind":{"type":"string","description":"wohnung | gewerbe | stellplatz | sonstige — OFFENES Vokabular (kein CHECK)"},"bezeichnung":{"type":["string","null"],"description":"Bezeichnung der Einheit (#5534, ≤ 200 Zeichen); `null` ⇒ Bestandseinheit ohne Bezeichnung."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"gesetzt ⇒ archiviert (K5: kein DELETE)"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","buildingId","propertyId","propertyNo","unitNo","unitKind","bezeichnung","archivedAt","createdAt"]},"EinheitListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","aktiv","archiviert"],"description":"der wirksame 3-Wege-Filter (wirkt NUR auf units.archived_at)"},"einheiten":{"type":"array","items":{"$ref":"#/components/schemas/Einheit"}}},"required":["status","einheiten"]},"EinheitCreateRequest":{"type":"object","properties":{"buildingId":{"type":"string","format":"uuid","description":"Das Gebäude, an dem die Einheit hängt. MUSS aktiv sein (sonst 400)."},"unitNo":{"type":"string","description":"Einheitennummer (Freitext) — eindeutig je Objekt unter den aktiven Einheiten (#5534); vergeben ⇒ 409 „Diese Einheitennummer ist bereits vergeben.\""},"unitKind":{"type":"string","description":"wohnung | gewerbe | stellplatz | sonstige (offenes Vokabular)"},"bezeichnung":{"type":"string","minLength":1,"maxLength":200,"description":"Bezeichnung der Einheit — PFLICHT (#5534), 1…200 Zeichen."},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["buildingId","unitNo","unitKind","bezeichnung"]},"EinheitUpdateRequest":{"type":"object","properties":{"unitNo":{"type":"string","description":"Neue Einheitennummer — eindeutig je Objekt (#5534), sonst 409."},"unitKind":{"type":"string"},"bezeichnung":{"type":"string","minLength":1,"maxLength":200,"description":"Neue Bezeichnung (#5534), 1…200 Zeichen."}},"description":"Partieller Patch. `buildingId` ist BEWUSST nicht patchbar (potenzieller Rechnungskreis-Wechsel)."},"EinheitArchiveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":"string","format":"date-time"},"alreadyArchived":{"type":"boolean","description":"true ⇒ die Einheit war bereits archiviert (expliziter No-op)."}},"required":["id","archivedAt","alreadyArchived"]},"EinheitReactivateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"reactivatedAt":{"type":"string","format":"date-time"},"alreadyActive":{"type":"boolean"}},"required":["id","reactivatedAt","alreadyActive"]},"EinheitAttribut":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"attributeKey":{"type":"string","description":"Attribut-Schlüssel (OFFENES Vokabular): flaeche | personenzahl | mea | festbetrag | …"},"attributeValue":{"type":"object","additionalProperties":{},"description":"Strukturierter JSON-Wert der Scheibe (z. B. Fläche als Dezimal-String)."},"validFrom":{"type":["string","null"],"format":"date","description":"Beginn INKLUSIV; null ⇒ unbegrenzt in die Vergangenheit."},"validTo":{"type":["string","null"],"format":"date","description":"Ende EXKLUSIV; null ⇒ laufend."},"validRange":{"type":"string","description":"Rohes daterange-Literal, z. B. [2026-01-01,)."},"active":{"type":"boolean","description":"Ist die Scheibe am Stichtag (asOf) wirksam (valid_range @> asOf)?"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","unitId","attributeKey","attributeValue","validFrom","validTo","validRange","active","createdAt"]},"EinheitAttributListResponse":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"asOf":{"type":"string","format":"date","description":"der wirksame Stichtag, gegen den `active` je Scheibe gemessen wurde"},"attribute":{"type":"array","items":{"$ref":"#/components/schemas/EinheitAttribut"}}},"required":["unitId","asOf","attribute"]},"EinheitAttributSetRequest":{"type":"object","properties":{"attributeKey":{"type":"string","description":"flaeche | personenzahl | mea | festbetrag | … (offenes Vokabular)"},"attributeValue":{"type":"object","additionalProperties":{},"description":"strukturierter JSON-Wert (leeres Objekt zulässig)"},"validFrom":{"type":"string","format":"date","description":"Beginn der Gültigkeit (INKLUSIV) — das „ab\" der Änderung"},"validTo":{"type":"string","format":"date","description":"optionales Ende (EXKLUSIV); ohne Angabe laufend"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["attributeKey","attributeValue","validFrom"],"description":"Setzt/ändert eine Attribut-Zeitscheibe „ab validFrom\" (SCD-2); Überschneidungen ⇒ 400."},"EinheitAttributSetResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"attributeKey":{"type":"string"},"attributeValue":{"type":"object","additionalProperties":{}},"validFrom":{"type":"string","format":"date"},"validTo":{"type":["string","null"],"format":"date"},"validRange":{"type":"string"},"supersededPriorSlice":{"type":"boolean","description":"true ⇒ eine zuvor offene Scheibe wurde an validFrom abgeschlossen (SCD-2)."}},"required":["id","unitId","attributeKey","attributeValue","validFrom","validTo","validRange","supersededPriorSlice"]},"EinheitBelegungScheibe":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"zustand":{"type":"string","enum":["selbstgenutzt","vermietet","leerstand"],"description":"selbstgenutzt | vermietet | leerstand (geschlossen)."},"personenzahl":{"type":["integer","null"],"description":"Kopfzahl der Scheibe; null = NICHT ERFASST (Befund personenzahl_fehlt)."},"drittnutzerPersonId":{"type":["string","null"],"format":"uuid","description":"Der „Mieter des Eigentümers\" als persons.id — reiner Kontakt, kein Vertrag, kein Debitor."},"validFrom":{"type":["string","null"],"format":"date","description":"Beginn INKLUSIV; null ⇒ unbegrenzt in die Vergangenheit."},"validTo":{"type":["string","null"],"format":"date","description":"Ende EXKLUSIV; null ⇒ laufend."},"validRange":{"type":"string","description":"Rohes daterange-Literal, z. B. [2026-01-01,)."},"active":{"type":"boolean","description":"Ist die Scheibe am Stichtag wirksam (valid_range @> stichtag)?"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","unitId","zustand","personenzahl","drittnutzerPersonId","validFrom","validTo","validRange","active","createdAt"]},"EinheitBelegungPartei":{"type":"object","properties":{"art":{"type":"string","enum":["mietpartei","eigentuemer","drittnutzer","leerstand"]},"personId":{"type":["string","null"],"format":"uuid","description":"null ausschliesslich bei art=leerstand — dort gibt es keine Person, wohl aber eine Identität."},"name":{"type":"string","description":"Anzeigename; bei art=leerstand die stabile Platzhalter-Identität (nie leer)."},"contractId":{"type":["string","null"],"format":"uuid","description":"Der casa-Mietvertrag; null ausserhalb von art=mietpartei."}},"required":["art","personId","name","contractId"]},"EinheitBelegungBefund":{"type":"object","properties":{"code":{"type":"string","enum":["belegung_fehlt","personenzahl_fehlt","zustand_widerspricht_vertragslage","drittnutzer_fehlt"]},"ampel":{"type":"string","enum":["gruen","gelb","rot"]},"hinweis":{"type":"string"}},"required":["code","ampel","hinweis"]},"EinheitBelegungResponse":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"der wirksame Stichtag, gegen den aufgelöst wurde"},"verwaltungsart":{"type":["string","null"],"enum":["miet","weg","pro",null],"description":"Verwaltungsart des Objekts; null, wenn die Kette Einheit→Gebäude→Objekt reisst."},"quelle":{"type":"string","enum":["abgeleitet","gepflegt"],"description":"abgeleitet = aus der Vertragslage (casa führt den Mietvertrag) · gepflegt = aus der erfassten Zeitscheibe (fremdverwaltete WEG-Einheit)."},"zustand":{"type":"string","enum":["selbstgenutzt","vermietet","leerstand","unbekannt"],"description":"selbstgenutzt | vermietet | leerstand | unbekannt. \"unbekannt\" ist NICHT speicherbar — es heisst „auf der gepflegten Achse ist am Stichtag nichts erfasst\" und ausdrücklich nicht „hier wohnt niemand\"."},"personenzahl":{"type":["integer","null"],"description":"Kopfzahl am Stichtag; null = nicht erfasst."},"parteien":{"type":"array","items":{"$ref":"#/components/schemas/EinheitBelegungPartei"},"description":"Mehrere sind der Normalfall (Miteigentum, zwei Mietparteien); bei Leerstand genau eine."},"zeitscheibe":{"allOf":[{"$ref":"#/components/schemas/EinheitBelegungScheibe"},{"type":["object","null"],"description":"Die gepflegte Zeitscheibe am Stichtag, falls es eine gibt."}]},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/EinheitBelegungBefund"}},"ampel":{"type":"string","enum":["gruen","gelb","rot"],"description":"Die riskanteste Einzel-Ampel aller Befunde; ohne Befund gruen."}},"required":["unitId","stichtag","verwaltungsart","quelle","zustand","personenzahl","parteien","zeitscheibe","befunde","ampel"]},"EinheitBelegungHistorieResponse":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"der Stichtag, gegen den `active` je Scheibe gemessen wurde"},"scheiben":{"type":"array","items":{"$ref":"#/components/schemas/EinheitBelegungScheibe"}}},"required":["unitId","stichtag","scheiben"]},"WechselzeitraumBefund":{"type":"object","properties":{"ungeprueftKennung":{"type":"string","description":"Zeilen-Id der Basiszeile, deren Beginn unbekannt ist (nur bei beginn-unbekannt)."},"konfliktKennung":{"type":"string","description":"Zeilen-Id der überlappten bestehenden Zeile (nur bei ueberlappt)."},"lueckeVon":{"type":"string","format":"date","description":"Erster freier Tag der Lücke zum nächsten bestehenden Zeitraum (inklusive)."},"lueckeBis":{"type":"string","format":"date","description":"Letzter freier Tag der Lücke (inklusive)."}}},"WechselzeitraumResponse":{"type":"object","properties":{"code":{"type":"string","enum":["ok","ueberlappt","zeitraum-verdreht","beginn-unbekannt","kein-personenkonto"]},"befund":{"$ref":"#/components/schemas/WechselzeitraumBefund"},"art":{"type":"string","enum":["bewohner","eigentuemer"]},"basisBeginn":{"type":["string","null"],"format":"date","description":"Beginn der Basis (Eigentums- bzw. Vertrags-/Belegungsbeginn), inklusive; null = unbekannt."},"anzahlZeilen":{"type":"integer","description":"Anzahl der gelesenen Bestandszeilen der Einheit."}},"required":["code","befund","art","basisBeginn","anzahlZeilen"]},"EinheitBelegungSetRequest":{"type":"object","properties":{"zustand":{"type":"string","enum":["selbstgenutzt","vermietet","leerstand"]},"personenzahl":{"type":["integer","null"],"minimum":0,"description":"Kopfzahl; weggelassen/null = nicht erfasst. Bei zustand=leerstand ist 0 NICHT wählbar (BGH VIII ZR 159/05)."},"drittnutzerPersonId":{"type":["string","null"],"format":"uuid","description":"Nur bei zustand=vermietet zulässig; die Person muss existieren und aktiv sein."},"validFrom":{"type":"string","format":"date","description":"Beginn der Gültigkeit (INKLUSIV) — das „ab\" der Änderung"},"validTo":{"type":"string","format":"date","description":"optionales Ende (EXKLUSIV); ohne Angabe laufend"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["zustand","validFrom"],"description":"Setzt/ändert die GEPFLEGTE Belegungs-Zeitscheibe „ab validFrom\" (SCD-2); Überschneidungen ⇒ 400."},"EinheitBelegungSetResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"zustand":{"type":"string","enum":["selbstgenutzt","vermietet","leerstand"]},"personenzahl":{"type":["integer","null"]},"drittnutzerPersonId":{"type":["string","null"],"format":"uuid"},"validFrom":{"type":"string","format":"date"},"validTo":{"type":["string","null"],"format":"date"},"validRange":{"type":"string"},"supersededPriorSlice":{"type":"boolean","description":"true ⇒ eine zuvor offene Scheibe wurde an validFrom abgeschlossen (SCD-2)."}},"required":["id","unitId","zustand","personenzahl","drittnutzerPersonId","validFrom","validTo","validRange","supersededPriorSlice"]},"EinheitEinnahmeartSetRequest":{"type":"object","properties":{"einnahmeart":{"type":["string","null"],"enum":["wohnung","andere_raeume","angehoerige","nicht_steuerpflichtig",null],"description":"wohnung | andere_raeume | angehoerige | nicht_steuerpflichtig; null = Einnahmeart entfernen. PFLICHT im Körper — kein Default, keine Ableitung aus der Einheitenart."},"geschoss":{"type":["string","null"],"minLength":1,"maxLength":50,"description":"Geschoss als Freitext (getrimmt 1…50 Zeichen); weggelassen = unverändert, null = entfernen."}},"required":["einnahmeart"],"description":"Setzt die Einnahmeart (und optional das Geschoss) einer Einheit für die Gliederung der Mieteinnahmen."},"EinheitEinnahmeartResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"einnahmeart":{"type":["string","null"],"enum":["wohnung","andere_raeume","angehoerige","nicht_steuerpflichtig",null]},"geschoss":{"type":["string","null"]}},"required":["id","einnahmeart","geschoss"]},"SevVerguetungsregel":{"type":"object","properties":{"art":{"type":"string","enum":["prozent","festbetrag","keine"],"description":"prozent | festbetrag | keine (geschlossen). \"keine\" heisst NICHT VEREINBART — wer 0 € vereinbart hat, wählt festbetrag mit 0."},"prozentSkaliert":{"type":["string","null"],"description":"Prozentsatz in SEV_PROZENT_SKALA als ZIFFERN-STRING (1 % = \"10000\"); null ausserhalb von art=prozent."},"betragCents":{"type":["string","null"],"description":"Monats-Festbetrag in ganzen Cents als ZIFFERN-STRING; null ausserhalb von art=festbetrag."}},"required":["art","prozentSkaliert","betragCents"],"description":"Art + GENAU EINE Angabe dazu. Der Leerstand hat seine eigene Regel: dort gibt es keine Miete, auf die ein Prozentsatz anwendbar wäre."},"SevVerguetungsregelInput":{"type":"object","properties":{"art":{"type":"string","enum":["prozent","festbetrag","keine"]},"prozentSkaliert":{"type":["string","null"],"description":"Pflicht bei art=prozent, sonst verboten. Ziffern-String in SEV_PROZENT_SKALA."},"betragCents":{"type":["string","null"],"description":"Pflicht bei art=festbetrag, sonst verboten. Ziffern-String in ganzen Cents."}},"required":["art"],"description":"Vergütungsregel; genau eine Angabe je Art (die Kopplung prüft der Tool-Layer und der DB-CHECK)."},"SevMandat":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"Die auftraggebende Eigentümerperson (persons.id)."},"validFrom":{"type":["string","null"],"format":"date","description":"Beginn INKLUSIV; null ⇒ unbegrenzt in die Vergangenheit."},"validTo":{"type":["string","null"],"format":"date","description":"Ende EXKLUSIV; null ⇒ laufend. „Zum 30.06. beendet\" steht hier als 2025-07-01."},"validRange":{"type":"string","description":"Rohes daterange-Literal, z. B. [2025-01-01,)."},"active":{"type":"boolean","description":"Ist das Mandat am Stichtag wirksam (valid_range @> stichtag)?"},"mitMietinkasso":{"type":"boolean","description":"UMFANG: zieht der Verwalter auch die Miete ein? false ⇒ Betreuung/Vermietung ja, Mieteinzug nein (dann ist mietgutschriftBasis zwingend \"keine\")."},"mietgutschriftBasis":{"type":"string","enum":["ist","soll","festbetrag","keine"],"description":"ist = vereinnahmte Miete · soll = geschuldete Miete · festbetrag = Garantiemiete/Pauschale · keine = keine Mietgutschrift (Umfang ohne Mietinkasso)."},"mietgutschriftFestbetragCents":{"type":["string","null"]},"verguetungVermietet":{"$ref":"#/components/schemas/SevVerguetungsregel"},"verguetungLeerstand":{"$ref":"#/components/schemas/SevVerguetungsregel"},"hausgeldQuelle":{"type":"string","enum":["weg_soll","festbetrag","keine"],"description":"weg_soll = aus der Hausgeld-Sollstellung dieser Einheit · festbetrag = vereinbarter Betrag (nötig, wenn casa die WEG-Seite nicht führt) · keine = der Eigentümer zahlt selbst."},"hausgeldFestbetragCents":{"type":["string","null"]},"sonderruecklageRegel":{"type":"string","enum":["prozent_mietgutschrift","festbetrag","keine"]},"sonderruecklageProzentSkaliert":{"type":["string","null"]},"sonderruecklageBetragCents":{"type":["string","null"]},"auszahlungRhythmus":{"type":"string","enum":["monatlich","quartalsweise","halbjaehrlich","jaehrlich","auf_abruf"]},"sockelbetragCents":{"type":"string","description":"Untergrenze, die auf dem Eigentümer-Konto stehen bleibt statt ausgezahlt zu werden, in ganzen Cents als Ziffern-String. \"0\" = kein Sockel (eine getroffene Entscheidung)."},"currency":{"type":"string","enum":["EUR"],"description":"Währung ALLER Beträge dieses Mandats — geschlossen auf EUR (Geldkern)."},"eigentuemerBankkontoId":{"type":["string","null"],"format":"uuid","description":"Privatkonto des Eigentümers als person_bank_accounts.id — bewusst eine REFERENZ und keine IBAN: dort hängt das Vier-Augen-Gate der Bankverbindung. null = keins hinterlegt."},"garantieArt":{"type":"string","enum":["keine","garantiemiete","mindestmiete"],"description":"Mietgarantie: keine (auch jedes Mandat von vor der Garantie), garantiemiete (Gutschrift = Garantiebetrag) oder mindestmiete (Gutschrift = max(erzielte Miete, Mindestbetrag))."},"garantieBetragCents":{"type":["string","null"],"description":"Garantie- bzw. Mindestbetrag JE MONAT als Ziffern-String in ganzen Cents; null bei garantieArt keine."},"garantieBasis":{"type":["string","null"],"enum":["kalt","warm",null],"description":"kalt oder warm — welche erzielte Miete dem Betrag gegenübersteht; null bei garantieArt keine."},"garantiegeberPersonId":{"type":["string","null"],"format":"uuid","description":"Der Garantiegeber (persons.id); null bei garantieArt keine."}},"required":["id","unitId","personId","validFrom","validTo","validRange","active","mitMietinkasso","mietgutschriftBasis","mietgutschriftFestbetragCents","verguetungVermietet","verguetungLeerstand","hausgeldQuelle","hausgeldFestbetragCents","sonderruecklageRegel","sonderruecklageProzentSkaliert","sonderruecklageBetragCents","auszahlungRhythmus","sockelbetragCents","currency","eigentuemerBankkontoId","garantieArt","garantieBetragCents","garantieBasis","garantiegeberPersonId"]},"SevMandatResponse":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"der wirksame Stichtag, gegen den aufgelöst wurde"},"mandat":{"allOf":[{"$ref":"#/components/schemas/SevMandat"},{"type":["object","null"],"description":"Das am Stichtag wirksame Mandat, sonst null. null heisst „am Stichtag keine Sondereigentumsverwaltung\" und NICHT „Einheit unbekannt\" (die Route antwortet dafür mit 404)."}]}},"required":["unitId","stichtag","mandat"]},"SevMandatHistorieResponse":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"der Stichtag, gegen den `active` je Mandat gemessen wurde"},"mandate":{"type":"array","items":{"$ref":"#/components/schemas/SevMandat"},"description":"Alle Zeitabschnitte, nach Beginn geordnet. Aufeinanderfolgende Abschnitte sind der Weg „mit Mietinkasso → ohne\"."}},"required":["unitId","stichtag","mandate"]},"SevMandatAnlegenRequest":{"type":"object","properties":{"personId":{"type":"string","format":"uuid","description":"Die auftraggebende Eigentümerperson. Sie muss im GESAMTEN Mandatszeitraum Eigentümerin der Einheit sein (unit_ownerships)."},"validFrom":{"type":"string","format":"date","description":"Beginn der Gültigkeit (INKLUSIV) — das „ab\" der Vereinbarung."},"validTo":{"type":"string","format":"date","description":"optionales Ende (EXKLUSIV); ohne Angabe laufend"},"mitMietinkasso":{"type":"boolean","description":"UMFANG — Pflicht, kein Default. Nachträglich NICHT änderbar: der Wechsel ist ein NEUER Zeitabschnitt (beenden + neu anlegen)."},"mietgutschriftBasis":{"type":"string","enum":["ist","soll","festbetrag","keine"]},"mietgutschriftFestbetragCents":{"type":["string","null"]},"verguetungVermietet":{"$ref":"#/components/schemas/SevVerguetungsregelInput"},"verguetungLeerstand":{"$ref":"#/components/schemas/SevVerguetungsregelInput"},"hausgeldQuelle":{"type":"string","enum":["weg_soll","festbetrag","keine"]},"hausgeldFestbetragCents":{"type":["string","null"]},"sonderruecklageRegel":{"type":"string","enum":["prozent_mietgutschrift","festbetrag","keine"]},"sonderruecklageProzentSkaliert":{"type":["string","null"]},"sonderruecklageBetragCents":{"type":["string","null"]},"sonderruecklageHoechstbetragCents":{"type":["string","null"],"description":"Höchststand der Sonderrücklage in ganzen Cents (Ziffern-String): steht ihr Saldo darauf, wird nichts mehr zugeführt. Ohne Angabe/null = ohne Höchststand. Nur bei sonderruecklageRegel ≠ keine."},"auszahlungRhythmus":{"type":"string","enum":["monatlich","quartalsweise","halbjaehrlich","jaehrlich","auf_abruf"]},"sockelbetragCents":{"type":"string","description":"Ziffern-String in ganzen Cents; \"0\" = kein Sockel."},"eigentuemerBankkontoId":{"type":["string","null"],"format":"uuid","description":"Pflicht, sobald es eine Mietgutschrift gibt (mietgutschriftBasis ≠ keine); muss DER auftraggebenden Person gehören."},"currency":{"type":"string","enum":["EUR"],"description":"Ohne Angabe EUR; andere Währungen kennt der Geldkern nicht."},"hausgeldUnterdeckung":{"type":"string","enum":["einziehen","nicht_zahlen","aus_sonderruecklage"],"description":"Regel bei Unterdeckung des Hausgelds: einziehen, nicht_zahlen (Vorgabe) oder aus_sonderruecklage."},"hausgeldSonderumlage":{"type":"string","enum":["ohne_sonderumlage","mit_sonderumlage"],"description":"Sonderumlagen aus der Miete nur bei mit_sonderumlage; Vorgabe ohne_sonderumlage (Known Issue 258695)."},"garantieArt":{"type":"string","enum":["keine","garantiemiete","mindestmiete"],"description":"Mietgarantie: keine (Vorgabe), garantiemiete (Gutschrift = Garantiebetrag) oder mindestmiete (Gutschrift = max(erzielte Miete, Mindestbetrag)). Nur mit Mietinkasso und mietgutschriftBasis ist."},"garantieBetragCents":{"type":["string","null"],"description":"Garantie- bzw. Mindestbetrag JE MONAT als Ziffern-String in ganzen Cents (> 0); nur bei garantieArt ≠ keine."},"garantieBasis":{"type":["string","null"],"enum":["kalt","warm",null],"description":"kalt oder warm — welche erzielte Miete dem Betrag gegenübersteht; nur bei garantieArt ≠ keine."},"garantiegeberPersonId":{"type":["string","null"],"format":"uuid","description":"Der Garantiegeber (eine Person DIESES Mandanten, nicht der Eigentümer); nur bei garantieArt ≠ keine. Unbekannt oder fremder Mandant ⇒ 404."},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["personId","validFrom","mitMietinkasso","mietgutschriftBasis","verguetungVermietet","verguetungLeerstand","hausgeldQuelle","sonderruecklageRegel","auszahlungRhythmus","sockelbetragCents"],"description":"Legt die Sondereigentumsverwaltung als Zeitabschnitt an. Nur in einem Objekt der Verwaltungsart \"pro\" möglich; Überschneidungen mit einem bestehenden Mandat DERSELBEN Wohnung ⇒ 400."},"SevMandatAnlegenResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"validFrom":{"type":"string","format":"date"},"validTo":{"type":["string","null"],"format":"date"},"validRange":{"type":"string"},"mitMietinkasso":{"type":"boolean"}},"required":["id","unitId","personId","validFrom","validTo","validRange","mitMietinkasso"],"description":"Identität und Zeitabschnitt der angelegten Vereinbarung. Die vollständigen Vertragswerte liest GET /api/einheit/{id}/sev-mandat."},"SevMandatBeendenRequest":{"type":"object","properties":{"endeExklusiv":{"type":"string","format":"date","description":"Der erste Tag OHNE Sondereigentumsverwaltung (EXKLUSIVE obere Grenze). „Zum 30.06. beendet\" ⇒ 2025-07-01."}},"required":["endeExklusiv"],"description":"Beendet den Zeitabschnitt durch KÜRZUNG (nicht durch Löschen — eine abgerechnete Periode bleibt erklärbar). Beenden kürzt nur: ein Ende nach einem bestehenden Ende ⇒ 400, ein Ende am Beginntag ⇒ 400."},"SevMandatBeendenResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"validFrom":{"type":["string","null"],"format":"date"},"validTo":{"type":"string","format":"date","description":"das gesetzte Ende (EXKLUSIV)"},"validRange":{"type":"string"},"beendet":{"type":"boolean","description":"false ⇒ das Mandat endete bereits GENAU an diesem Tag; es wurde nichts geändert (No-op-Erfolg statt Fehler)."}},"required":["id","unitId","personId","validFrom","validTo","validRange","beendet"]},"SevAnfangsbestandRequest":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"Übernahmestichtag YYYY-MM-DD — wird das Buchungsdatum der Anfangsbestands-Buchung. Ein Tag in der Zukunft ⇒ 400."},"betragCents":{"type":"string","description":"Der übernommene Saldo aus Sicht des EIGENTÜMERS in ganzen Cents als vorzeichenbehafteter Ziffern-String (nie eine JSON-number): positiv = Guthaben des Eigentümers, negativ = der Eigentümer schuldet. \"0\" ⇒ 400."},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["stichtag","betragCents"],"description":"Übernimmt den Saldo des Eigentümer-Verrechnungskontos aus dem Altbestand — GENAU EINE Buchung im Geldkreis Sondereigentum je Mandat. Ein zweiter aktiver Anfangsbestand ⇒ 409; Korrektur über Storno und neue Erfassung."},"SevAnfangsbestandResponse":{"type":"object","properties":{"entryId":{"type":"string","format":"uuid","description":"der geschriebene Buchungssatz (journal_entries.id)"},"mandatId":{"type":"string","format":"uuid"},"glAccountId":{"type":"string","format":"uuid","description":"das Verrechnungskonto (gl_accounts.id)"},"art":{"type":"string","enum":["anfangsbestand"],"description":"die SEV-Buchungsart des Satzes"},"buchungsdatum":{"type":"string","format":"date"},"betragCents":{"type":"string","description":"der Bestand aus Sicht des Eigentümers, vorzeichenbehafteter Cent-String"},"currency":{"type":"string","enum":["EUR"]}},"required":["entryId","mandatId","glAccountId","art","buchungsdatum","betragCents","currency"]},"SevVerrechnungskontoSaldoResponse":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"glAccountId":{"type":"string","format":"uuid","description":"das Verrechnungskonto (gl_accounts.id)"},"stichtag":{"type":"string","format":"date","description":"der Stichtag (INKLUSIV), zu dem summiert wurde"},"saldoCents":{"type":"string","description":"Saldo aus Sicht des Eigentümers als vorzeichenbehafteter Cent-String (\"0\" ohne Buchungen): positiv = Guthaben des Eigentümers."},"currency":{"type":"string","enum":["EUR"]}},"required":["mandatId","glAccountId","stichtag","saldoCents","currency"]},"SevSonderruecklageSaldoResponse":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"der Stichtag (INKLUSIV), zu dem summiert wurde"},"saldoCents":{"type":"string","description":"Bestand der Sonderrücklage des Eigentümers als Cent-String (\"0\" ohne Bewegungen), nie negativ. Geld des Eigentümers, aber NICHT Teil des Saldos des Verrechnungskontos und nicht der Rücklage der Gemeinschaft."},"hoechstbetragCents":{"type":["string","null"],"description":"vereinbarter Höchststand als Cent-String; null = ohne Höchststand (nicht 0 — 0 hiesse „nie zuführen\")."},"currency":{"type":"string","enum":["EUR"]}},"required":["mandatId","stichtag","saldoCents","hoechstbetragCents","currency"]},"SevVerguetungVorschlagResponse":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"der Monat im Format JJJJ-MM","example":"2025-06"},"fall":{"type":"string","enum":["vermietet","leerstand"],"description":"vermietet = die Einheit ist am Monatsletzten belegt; sonst gilt die Leerstandsregel"},"art":{"type":"string","enum":["prozent","festbetrag","keine"],"description":"die Art der angewandten Regel (prozent | festbetrag | keine)"},"bemessung":{"type":"string","enum":["ist","soll"],"description":"ist = Mietgutschrift des Monats, soll = Soll-Miete der Einheit im Monat"},"basisMieteCents":{"type":"string","description":"die verwendete Bemessungsgrundlage in ganzen Cents (Ziffern-String)"},"nettoCents":{"type":"string","description":"Vergütung netto in ganzen Cents (nach Mindest-/Höchstbetrag)"},"ustSatzProzent":{"type":"string","description":"USt-Satz in ganzen Prozent (\"0\" = ohne USt)"},"umsatzsteuerCents":{"type":"string","description":"die getrennt ausgewiesene Umsatzsteuer in ganzen Cents"},"bruttoCents":{"type":"string","description":"die Belastung des Verrechnungskontos in ganzen Cents (netto + USt)"},"mindestbetragGegriffen":{"type":"boolean"},"hoechstbetragGegriffen":{"type":"boolean"},"bereitsGebucht":{"type":["object","null"],"properties":{"entryId":{"type":"string","format":"uuid"},"bruttoCents":{"type":"string"}},"required":["entryId","bruttoCents"],"description":"der für den Monat bereits gebuchte, nicht stornierte Vergütungssatz — oder null"},"vorschlagHash":{"type":"string","description":"sha256-Hex über genau diesen Inhalt; POST bestätigt ihn"},"currency":{"type":"string","enum":["EUR"]}},"required":["mandatId","monat","fall","art","bemessung","basisMieteCents","nettoCents","ustSatzProzent","umsatzsteuerCents","bruttoCents","mindestbetragGegriffen","hoechstbetragGegriffen","bereitsGebucht","vorschlagHash","currency"]},"SevVerguetungBuchenRequest":{"type":"object","properties":{"monat":{"type":"string","description":"der Monat im Format JJJJ-MM","example":"2025-06"},"vorschlagHash":{"type":"string","description":"der `vorschlagHash` des GESEHENEN Vorschlags (GET); weicht die frische Rechnung ab ⇒ 409, nichts gebucht"}},"required":["monat","vorschlagHash"],"description":"Bucht die Verwaltervergütung eines Monats: Belastung des Verrechnungskontos (Art Verwaltervergütung), Ertrag beim Verwalter, USt getrennt. Genau einmal je Mandat und Monat."},"SevVerguetungBuchungResponse":{"type":"object","properties":{"ergebnis":{"type":"string","enum":["gebucht","unveraendert","keine_verguetung"],"description":"gebucht = neuer Satz; unveraendert = derselbe Satz war schon gebucht; keine_verguetung = Netto 0, nichts gebucht"},"mandatId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"der Monat im Format JJJJ-MM","example":"2025-06"},"entryId":{"type":["string","null"],"format":"uuid","description":"der Vergütungssatz (journal_entries.id); null bei keine_verguetung"},"glAccountId":{"type":"string","format":"uuid","description":"das belastete Verrechnungskonto (gl_accounts.id)"},"ertragGlAccountId":{"type":["string","null"],"format":"uuid","description":"das Ertragskonto des Verwalters; null bei keine_verguetung"},"nettoCents":{"type":"string"},"ustSatzProzent":{"type":"string"},"umsatzsteuerCents":{"type":"string"},"bruttoCents":{"type":"string"},"buchungsdatum":{"type":["string","null"],"format":"date","description":"der Monatsletzte; null bei keine_verguetung"},"currency":{"type":"string","enum":["EUR"]}},"required":["ergebnis","mandatId","monat","entryId","glAccountId","ertragGlAccountId","nettoCents","ustSatzProzent","umsatzsteuerCents","bruttoCents","buchungsdatum","currency"]},"SevAuszahlungVorschlagResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"der Auszahlungsmonat im Format JJJJ-MM","example":"2024-03"},"stichtag":{"type":"string","format":"date","description":"der Monatsletzte"},"vorschlagHash":{"type":"string","description":"sha256-Hex über genau diesen Inhalt; POST bestätigt ihn"},"auszahlungen":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"saldoCents":{"type":"string","description":"Saldo des Verrechnungskontos zum Stichtag in ganzen Cents"},"sockelCents":{"type":"string","description":"der vereinbarte Sockelbetrag in ganzen Cents"},"betragCents":{"type":"string","description":"der Auszahlungsbetrag (Saldo − Sockel, > 0) in ganzen Cents"},"verbleibtCents":{"type":"string","description":"was nach der Auszahlung auf dem Verrechnungskonto stehen bleibt (= Sockel)"},"empfaengerIban":{"type":"string","description":"die IBAN des Privatkontos des Eigentümers aus dem Mandat — der Empfänger des Zahlungsauftrags"}},"required":["mandatId","unitId","saldoCents","sockelCents","betragCents","verbleibtCents","empfaengerIban"]}},"uebersprungen":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"grund":{"type":"string","enum":["rhythmus","offene_posten","kein_ueberschuss","bereits_ausgezahlt","ohne_auszahlungskonto"],"description":"rhythmus = der Monat entspricht nicht dem vereinbarten Rhythmus (auch auf_abruf); offene_posten = vor dem Stichtag ist noch ein Posten offen; kein_ueberschuss = der Saldo übersteigt den Sockel nicht; bereits_ausgezahlt = für Mandat und Periode ist schon ausgezahlt; ohne_auszahlungskonto = das Mandat nennt kein Privatkonto des Eigentümers"},"meldung":{"type":"string","description":"lesbare Meldung für den Bediener; nennt bei offene_posten jeden sperrenden Posten mit Betrag"},"offenePosten":{"type":"array","items":{"type":"object","properties":{"referenz":{"type":"string","description":"die Kennung des Postens (z. B. die Hausgeld-Sollstellung)"},"bezeichnung":{"type":"string","description":"z. B. „Hausgeld März 2024\""},"faelligAm":{"type":"string","format":"date"},"offenCents":{"type":"string","description":"der offene Betrag in ganzen Cents"}},"required":["referenz","bezeichnung","faelligAm","offenCents"]},"description":"bei offene_posten die sperrenden Posten, ältester zuerst; sonst leer"}},"required":["mandatId","grund","meldung","offenePosten"]}}},"required":["propertyId","monat","stichtag","vorschlagHash","auszahlungen","uebersprungen"]},"SevHausgeldPosten":{"type":"object","properties":{"sollstellungId":{"type":["string","null"],"format":"uuid","description":"die Hausgeld-Sollstellung (hausgeld_sollstellungen.id); null bei Hausgeld-Quelle festbetrag"},"monat":{"type":"string","description":"JJJJ-MM"},"art":{"type":"string","enum":["hausgeld","sonderumlage"],"description":"hausgeld oder sonderumlage"},"offenCents":{"type":"string","description":"der offene Betrag in ganzen Cents (Ziffern-String)"},"grund":{"type":"string","enum":["sonderumlage_nicht_vereinbart"],"description":"nur an einem AUSGESCHLOSSENEN Posten: Sonderumlage ohne Vereinbarung mit_sonderumlage"}},"required":["sollstellungId","monat","art","offenCents"]},"SevHausgeldBefund":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"hausgeldCents":{"type":"string","description":"Summe der zu zahlenden Posten in ganzen Cents"},"guthabenCents":{"type":"string","description":"Saldo des Verrechnungskontos in ganzen Cents (darf negativ sein)"},"fehlbetragCents":{"type":"string","description":"Hausgeld − max(Guthaben, 0) in ganzen Cents"},"regel":{"type":"string","enum":["einziehen","nicht_zahlen","aus_sonderruecklage"],"description":"Regel bei Unterdeckung: einziehen (Forderung an den Eigentümer), nicht_zahlen (OP bleibt offen) oder aus_sonderruecklage"},"entnahmeSonderruecklageCents":{"type":"string","description":"aus der Sonderrücklage entnommen (nur aus_sonderruecklage), sonst \"0\""},"restFehlbetragCents":{"type":"string","description":"was beim Eigentümer offen bleibt"}},"required":["mandatId","unitId","hausgeldCents","guthabenCents","fehlbetragCents","regel","entnahmeSonderruecklageCents","restFehlbetragCents"]},"SevHausgeldUebersprungen":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"grund":{"type":"string","enum":["kein_mietinkasso","hausgeld_selbstzahler","verguetung_ausstehend"],"description":"kein_mietinkasso · hausgeld_selbstzahler (Hausgeld-Quelle keine) · verguetung_ausstehend (erst die Vergütung des Monats buchen)"}},"required":["mandatId","unitId","grund"]},"SevHausgeldZeile":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"quelle":{"type":"string","enum":["weg_soll","festbetrag"]},"zahlungsweg":{"type":"string","enum":["op_ausgleich","kreditor"],"description":"op_ausgleich = Ausgleich der Hausgeld-Sollstellung · kreditor = Ausgabe an die fremd verwaltete WEG"},"posten":{"type":"array","items":{"$ref":"#/components/schemas/SevHausgeldPosten"},"description":"die zu zahlenden Posten"},"ausgeschlossen":{"type":"array","items":{"$ref":"#/components/schemas/SevHausgeldPosten"},"description":"offen, aber nicht zu zahlen (Sonderumlage ohne Vereinbarung) — mit grund"},"fall":{"type":"string","enum":["nichts_offen","gedeckt","unterdeckung"]},"hausgeldCents":{"type":"string"},"guthabenCents":{"type":"string"},"belastungCents":{"type":"string","description":"was dem Verrechnungskonto belastet würde"},"regel":{"type":"string","enum":["einziehen","nicht_zahlen","aus_sonderruecklage"],"description":"Regel bei Unterdeckung: einziehen (Forderung an den Eigentümer), nicht_zahlen (OP bleibt offen) oder aus_sonderruecklage"},"befund":{"allOf":[{"$ref":"#/components/schemas/SevHausgeldBefund"},{"type":["object","null"]}]}},"required":["mandatId","unitId","quelle","zahlungsweg","posten","ausgeschlossen","fall","hausgeldCents","guthabenCents","belastungCents","regel","befund"]},"SevHausgeldVorschlagResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"der Monat im Format JJJJ-MM","example":"2025-06"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/SevHausgeldZeile"},"description":"je betrachtetem, nicht übersprungenem Mandat eine Zeile, nach Einheit sortiert"},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/SevHausgeldBefund"},"description":"jede Unterdeckung (Einheit, Betrag, Regel)"},"uebersprungen":{"type":"array","items":{"$ref":"#/components/schemas/SevHausgeldUebersprungen"}},"vorschlagHash":{"type":"string","description":"sha256-Hex über genau diesen Inhalt; POST bestätigt ihn"},"currency":{"type":"string","enum":["EUR"]}},"required":["propertyId","monat","zeilen","befunde","uebersprungen","vorschlagHash","currency"]},"SevAuszahlungStellenRequest":{"type":"object","properties":{"monat":{"type":"string","description":"der Auszahlungsmonat im Format JJJJ-MM","example":"2024-03"},"vorschlagHash":{"type":"string","description":"der `vorschlagHash` des GESEHENEN Vorschlags (GET); weicht die frische Rechnung ab ⇒ 409, nichts geschrieben"},"objektBankkontoId":{"type":"string","format":"uuid","description":"das abgehende Bankkonto des Objekts (bank_accounts.id)"},"requestedExecutionDate":{"type":"string","format":"date","description":"Ausführungstag der Zahlungsaufträge — explizit, nie implizit „heute\""}},"required":["monat","vorschlagHash","objektBankkontoId","requestedExecutionDate"],"description":"Stellt die Auszahlungen des Monats: je Mandat der Entnahme-Satz auf dem Verrechnungskonto und EIN Zahlungsauftrag awaiting-approval an das Privatkonto des Eigentümers. Idempotent je Mandat und Monat. Betrag und Empfänger kommen nie aus der Eingabe."},"SevAuszahlungStellenResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"der Auszahlungsmonat im Format JJJJ-MM","example":"2024-03"},"auszahlungen":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"betragCents":{"type":"string","description":"der ausgezahlte Betrag in ganzen Cents"},"verbleibtCents":{"type":"string","description":"was auf dem Verrechnungskonto stehen bleibt (= Sockel)"},"entryId":{"type":"string","format":"uuid","description":"der Entnahme-Satz auf dem Verrechnungskonto (journal_entries.id)"},"paymentOrderId":{"type":"string","format":"uuid","description":"der Zahlungsauftrag (awaiting-approval) — Freigabe über die bestehende Zahlungsfreigabe"},"paymentOrderContentHash":{"type":"string","description":"Inhalts-Hash des Zahlungsauftrags; die Freigabe bestätigt ihn"}},"required":["mandatId","betragCents","verbleibtCents","entryId","paymentOrderId","paymentOrderContentHash"]}},"uebersprungen":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"grund":{"type":"string","enum":["rhythmus","offene_posten","kein_ueberschuss","bereits_ausgezahlt","ohne_auszahlungskonto"],"description":"rhythmus = der Monat entspricht nicht dem vereinbarten Rhythmus (auch auf_abruf); offene_posten = vor dem Stichtag ist noch ein Posten offen; kein_ueberschuss = der Saldo übersteigt den Sockel nicht; bereits_ausgezahlt = für Mandat und Periode ist schon ausgezahlt; ohne_auszahlungskonto = das Mandat nennt kein Privatkonto des Eigentümers"},"meldung":{"type":"string","description":"lesbare Meldung für den Bediener; nennt bei offene_posten jeden sperrenden Posten mit Betrag"},"offenePosten":{"type":"array","items":{"type":"object","properties":{"referenz":{"type":"string","description":"die Kennung des Postens (z. B. die Hausgeld-Sollstellung)"},"bezeichnung":{"type":"string","description":"z. B. „Hausgeld März 2024\""},"faelligAm":{"type":"string","format":"date"},"offenCents":{"type":"string","description":"der offene Betrag in ganzen Cents"}},"required":["referenz","bezeichnung","faelligAm","offenCents"]},"description":"bei offene_posten die sperrenden Posten, ältester zuerst; sonst leer"}},"required":["mandatId","grund","meldung","offenePosten"]}}},"required":["propertyId","monat","auszahlungen","uebersprungen"]},"SevSchlussauszahlungVorschlagResponse":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"der bisherige Eigentümer (Person des Mandats), der das Geld bekommt"},"endeExklusiv":{"type":"string","format":"date","description":"Ende des Mandats (exklusiv)"},"stichtag":{"type":"string","format":"date","description":"der letzte Tag des Mandats — Stichtag der offenen Posten"},"saldoCents":{"type":"string","description":"Saldo des Verrechnungskontos über alle Buchungen in ganzen Cents"},"sockelCents":{"type":"string","description":"der vereinbarte Sockelbetrag — nur ausgewiesen, er wird beim Mandatsende NICHT einbehalten"},"betragCents":{"type":"string","description":"was hinausgeht: der ganze Saldo, oder \"0\" wenn gesperrt"},"auszahlbar":{"type":"boolean"},"grund":{"type":["string","null"],"enum":["offene_posten","kein_ueberschuss",null],"description":"offene_posten = ein Hausgeld-Posten aus dem Mandatszeitraum ist offen; kein_ueberschuss = der Saldo ist ≤ 0; null = auszahlbar"},"offenePosten":{"type":"array","items":{"type":"object","properties":{"referenz":{"type":"string","description":"die Kennung des Postens (z. B. die Hausgeld-Sollstellung)"},"bezeichnung":{"type":"string","description":"z. B. „Hausgeld 03/2024\""},"faelligAm":{"type":"string","format":"date"},"offenCents":{"type":"string","description":"der offene Betrag in ganzen Cents"}},"required":["referenz","bezeichnung","faelligAm","offenCents"]},"description":"bei offene_posten die sperrenden Posten, ältester zuerst; sonst leer"},"empfaengerIban":{"type":"string","description":"die IBAN des Privatkontos des bisherigen Eigentümers aus dem Mandat — der Empfänger des Zahlungsauftrags"},"vorschlagHash":{"type":"string","description":"sha256-Hex über genau diesen Inhalt; POST bestätigt ihn"}},"required":["mandatId","unitId","personId","endeExklusiv","stichtag","saldoCents","sockelCents","betragCents","auszahlbar","grund","offenePosten","empfaengerIban","vorschlagHash"]},"SevSchlussauszahlungStellenRequest":{"type":"object","properties":{"vorschlagHash":{"type":"string","description":"der `vorschlagHash` des GESEHENEN Vorschlags (GET); weicht die frische Rechnung ab ⇒ 409, nichts geschrieben"},"objektBankkontoId":{"type":"string","format":"uuid","description":"das abgehende Bankkonto des Objekts (bank_accounts.id)"},"requestedExecutionDate":{"type":"string","format":"date","description":"Ausführungstag des Zahlungsauftrags — explizit, nie implizit „heute\""}},"required":["vorschlagHash","objektBankkontoId","requestedExecutionDate"],"description":"Stellt die Schlussauszahlung nach dem Mandatsende: der Entnahme-Satz über den GANZEN Saldo (ohne Sockel) und EIN Zahlungsauftrag awaiting-approval an das Privatkonto des bisherigen Eigentümers. Betrag und Empfänger kommen nie aus der Eingabe."},"SevSchlussauszahlungStellenResponse":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"betragCents":{"type":"string","description":"der ausgezahlte Betrag (der ganze Saldo) in ganzen Cents"},"entryId":{"type":"string","format":"uuid","description":"der Entnahme-Satz auf dem Verrechnungskonto (journal_entries.id)"},"paymentOrderId":{"type":"string","format":"uuid","description":"der Zahlungsauftrag (awaiting-approval) — Freigabe über die bestehende Zahlungsfreigabe"},"paymentOrderContentHash":{"type":"string","description":"Inhalts-Hash des Zahlungsauftrags; die Freigabe bestätigt ihn"}},"required":["mandatId","betragCents","entryId","paymentOrderId","paymentOrderContentHash"]},"SevErtragsumbuchungListResponse":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"umbuchungen":{"type":"array","items":{"type":"object","properties":{"umbuchungId":{"type":"string","format":"uuid"},"entryId":{"type":"string","format":"uuid","description":"der Satz DIESES Mandats (journal_entries.id)"},"art":{"type":"string","enum":["ertragsumbuchung_abgang","ertragsumbuchung_zugang"]},"richtung":{"type":"string","enum":["abgang","zugang"],"description":"abgang = dieses Mandat gibt ab (alter Eigentümer), zugang = es empfängt (neuer Eigentümer)"},"gegenMandatId":{"type":"string","format":"uuid","description":"das jeweils andere Mandat"},"zeitraum":{"type":"object","properties":{"von":{"type":"string","format":"date","description":"erster Tag des Zeitraums (inklusiv)"},"bisExklusiv":{"type":"string","format":"date","description":"erster Tag nach dem Zeitraum (exklusiv)"}},"required":["von","bisExklusiv"]},"betragCents":{"type":"string","description":"der Betrag in ganzen Cents, immer positiv"},"saldoWirkungCents":{"type":"string","description":"Wirkung auf den Saldo DIESES Mandats in ganzen Cents (Abgang negativ, Zugang positiv)"},"buchungsdatum":{"type":"string","format":"date"},"beleg":{"type":"object","properties":{"bezeichnung":{"type":"string","description":"was die Umbuchung belegt, z. B. „Kaufvertrag UR-Nr. 123/2025, Übergang 15.07.2025\" (1–200 Zeichen)"},"datum":{"type":"string","format":"date","description":"Datum des Belegs"}},"required":["bezeichnung","datum"]}},"required":["umbuchungId","entryId","art","richtung","gegenMandatId","zeitraum","betragCents","saldoWirkungCents","buchungsdatum","beleg"]}}},"required":["mandatId","umbuchungen"]},"SevErtragsumbuchungBuchenRequest":{"type":"object","properties":{"nachMandatId":{"type":"string","format":"uuid","description":"das EMPFANGENDE Mandat (neuer Eigentümer derselben Wohnung); das abgebende steht im Pfad"},"zeitraum":{"type":"object","properties":{"von":{"type":"string","format":"date","description":"erster Tag des Zeitraums (inklusiv)"},"bisExklusiv":{"type":"string","format":"date","description":"erster Tag nach dem Zeitraum (exklusiv)"}},"required":["von","bisExklusiv"]},"betragCents":{"type":"string","description":"Betrag in ganzen Cents als Ganzzahl-String > 0 — höchstens die im Zeitraum gutgeschriebene, noch nicht umgebuchte Miete"},"beleg":{"type":"object","properties":{"bezeichnung":{"type":"string","description":"was die Umbuchung belegt, z. B. „Kaufvertrag UR-Nr. 123/2025, Übergang 15.07.2025\" (1–200 Zeichen)"},"datum":{"type":"string","format":"date","description":"Datum des Belegs"}},"required":["bezeichnung","datum"]}},"required":["nachMandatId","zeitraum","betragCents","beleg"],"description":"Bucht Mieterträge eines Zeitraums vom Mandat im Pfad (alter Eigentümer) auf das Mandat `nachMandatId` (neuer Eigentümer) um — als eigene Buchungsart mit Beleg, beide Seiten in EINER Transaktion."},"SevErtragsumbuchungBuchenResponse":{"type":"object","properties":{"umbuchungId":{"type":"string","format":"uuid"},"vonMandatId":{"type":"string","format":"uuid"},"nachMandatId":{"type":"string","format":"uuid"},"abgangEntryId":{"type":"string","format":"uuid","description":"der Satz ertragsumbuchung_abgang auf dem Verrechnungskonto des abgebenden Mandats"},"zugangEntryId":{"type":"string","format":"uuid","description":"der Satz ertragsumbuchung_zugang auf dem Verrechnungskonto des empfangenden Mandats"},"betragCents":{"type":"string","description":"der umgebuchte Betrag in ganzen Cents"},"zeitraum":{"type":"object","properties":{"von":{"type":"string","format":"date","description":"erster Tag des Zeitraums (inklusiv)"},"bisExklusiv":{"type":"string","format":"date","description":"erster Tag nach dem Zeitraum (exklusiv)"}},"required":["von","bisExklusiv"]},"beleg":{"type":"object","properties":{"bezeichnung":{"type":"string","description":"was die Umbuchung belegt, z. B. „Kaufvertrag UR-Nr. 123/2025, Übergang 15.07.2025\" (1–200 Zeichen)"},"datum":{"type":"string","format":"date","description":"Datum des Belegs"}},"required":["bezeichnung","datum"]}},"required":["umbuchungId","vonMandatId","nachMandatId","abgangEntryId","zugangEntryId","betragCents","zeitraum","beleg"]},"SevEigentuemerwechselBefundeResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"der geprüfte Monat im Format JJJJ-MM","example":"2025-07"},"befunde":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"mandatsPersonId":{"type":"string","format":"uuid","description":"die Person des Mandats (der bisherige Eigentümer)"},"ohneEigentumAb":{"type":"string","format":"date","description":"der erste Tag im Monat, an dem das Mandat wirkt und seine Person nicht Eigentümerin ist"},"eigentuemerPersonIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"die Eigentümer der Einheit an diesem Tag, aufsteigend; leer, wenn niemand eingetragen ist"}},"required":["mandatId","unitId","mandatsPersonId","ohneEigentumAb","eigentuemerPersonIds"]}}},"required":["propertyId","monat","befunde"]},"SevMonatslaufVerguetungBestaetigung":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"der `vorschlagHash` des GESEHENEN Vergütungsvorschlags (`GET /api/sev-mandat/{id}/verguetung`); weicht er ab ⇒ 409, keine Vergütung gebucht"}},"required":["mandatId","vorschlagHash"],"additionalProperties":false,"description":"eine bestätigte Vergütung: das Mandat und der Hash des gesehenen Vergütungsvorschlags"},"SevHausgeldZahlenRequest":{"type":"object","properties":{"monat":{"type":"string","description":"der Monat im Format JJJJ-MM","example":"2025-06"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Runde 2: der `vorschlagHash` des GESEHENEN Hausgeld-Vorschlags (GET bzw. `hausgeldVorschlag` aus Runde 1); weicht die frische Rechnung ab ⇒ 409, nichts bezahlt"},"verguetungen":{"type":"array","items":{"$ref":"#/components/schemas/SevMonatslaufVerguetungBestaetigung"},"x-unique-by":["mandatId"],"description":"Runde 1: die gesehenen Vergütungsvorschläge, höchstens ein Eintrag je Mandat — eindeutig ist das Feld `mandatId` (`x-unique-by`), nicht das ganze Objekt: zwei Einträge mit derselben mandatId (auch mit verschiedenen Hashes) ⇒ 400; alle Hashes werden vor der ersten Buchung geprüft"}},"required":["monat"],"additionalProperties":false,"anyOf":[{"required":["vorschlagHash"]},{"required":["verguetungen"],"properties":{"verguetungen":{"type":"array","minItems":1}}}],"description":"Der Monatslauf eines Objekts nach der Mietgutschrift in zwei Runden über diese eine Route: Runde 1 bestätigt die Vergütungen (`verguetungen`) und liefert den Hausgeld-Vorschlag NACH der Vergütung; Runde 2 bestätigt dessen Hash (`vorschlagHash`), zahlt das Hausgeld (Belastung des Verrechnungskontos, Art hausgeld_an_weg; Ausgleich der Hausgeld-Sollstellung bzw. Ausgabe an den Kreditor) und führt danach der Sonderrücklage zu. Mindestens eines der beiden Felder ist Pflicht (sonst 400)."},"SevHausgeldZahlung":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"zahlungsweg":{"type":"string","enum":["op_ausgleich","kreditor"]},"belastungCents":{"type":"string"},"entryId":{"type":"string","format":"uuid","description":"der Belastungssatz (journal_entries.id, Art hausgeld_an_weg)"},"entnahmeEntryId":{"type":["string","null"],"format":"uuid","description":"der Entnahme-Satz aus der Sonderrücklage — oder null"},"ausgeglichen":{"type":"array","items":{"type":"string","format":"uuid"},"description":"die ausgeglichenen Sollstellungen (bei kreditor leer)"}},"required":["mandatId","unitId","zahlungsweg","belastungCents","entryId","entnahmeEntryId","ausgeglichen"]},"SevMonatslaufSonderruecklage":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["gebucht","keine_zufuehrung","replay"],"description":"gebucht = dieser Lauf hat zugeführt; keine_zufuehrung = die Regel ergibt nichts; replay = der Monat lief bereits"},"grund":{"type":"string","enum":["zugefuehrt","keine_regel","hoechststand_erreicht","betrag_null"]},"zugefuehrtCents":{"type":"string","description":"der zugeführte Betrag in Cent als Ganzzahl-String (\"0\" ohne Zuführung)"}},"required":["mandatId","status","grund","zugefuehrtCents"]},"SevMonatslaufZufuehrungAusgesetzt":{"type":"object","properties":{"befund":{"type":"string","enum":["zufuehrung_ausgesetzt"]},"mandatId":{"type":"string","format":"uuid"},"grund":{"type":"string","enum":["hausgeld_nicht_bezahlt","hausgeld_unterdeckung","verguetung_ausstehend","mietgutschrift_fehlt","deckung_fehlt"]}},"required":["befund","mandatId","grund"]},"SevHausgeldZahlungResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"der Monat im Format JJJJ-MM","example":"2025-06"},"zahlungen":{"type":"array","items":{"$ref":"#/components/schemas/SevHausgeldZahlung"},"description":"je Mandat mit Belastung > 0 genau eine Zahlung; leer, solange das Hausgeld nicht bezahlt ist"},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/SevHausgeldBefund"}},"uebersprungen":{"type":"array","items":{"$ref":"#/components/schemas/SevHausgeldUebersprungen"}},"hausgeldStatus":{"type":"string","enum":["bezahlt","nicht_bestaetigt","neu_zu_bestaetigen"],"description":"bezahlt = Runde 2 hat gezahlt; nicht_bestaetigt = Runde 1 ohne Hausgeld-Hash — `hausgeldVorschlag` ist zu bestätigen"},"hausgeldVorschlag":{"anyOf":[{"$ref":"#/components/schemas/SevHausgeldVorschlagResponse"},{"type":"null"}],"description":"der Hausgeld-Vorschlag NACH der Vergütung samt `vorschlagHash` (ihn bestätigt Runde 2); null nach der Zahlung"},"verguetungen":{"type":"array","items":{"$ref":"#/components/schemas/SevVerguetungBuchungResponse"},"description":"je in diesem Aufruf bestätigtem Mandat das Ergebnis der Vergütungsbuchung (Netto, USt, Brutto als Ganzzahl-Strings), nach Mandat sortiert"},"sonderruecklage":{"type":"array","items":{"$ref":"#/components/schemas/SevMonatslaufSonderruecklage"},"description":"je Mandat, dem nach dem Hausgeld zugeführt wurde, das Ergebnis; nach Mandat sortiert"},"sonderruecklageBefunde":{"type":"array","items":{"$ref":"#/components/schemas/SevMonatslaufZufuehrungAusgesetzt"},"description":"je Mandat ohne Zuführung ein Befund `zufuehrung_ausgesetzt` mit Grund — nie still"},"currency":{"type":"string","enum":["EUR"]}},"required":["propertyId","monat","zahlungen","befunde","uebersprungen","hausgeldStatus","hausgeldVorschlag","verguetungen","sonderruecklage","sonderruecklageBefunde","currency"]},"SevMietgutschriftLaufRequest":{"type":"object","properties":{"monate":{"type":"array","items":{"type":"string","description":"ein Monat im Format JJJJ-MM","example":"2025-03"},"description":"die Periode: ein Monat (monatlich) oder mehrere lückenlose Monate (z. B. ein Quartal), höchstens zwölf"}},"required":["monate"],"description":"Legt die Mietgutschriften der SEV-Mandate des Objekts für die Periode als Vorschläge vor — Σ der Einzelmonate, idempotent je Mandat und Monat. Verweigert sich mit dem fehlenden Schritt, solange die Miet-Sollstellung eines Monats nicht abgeschlossen ist."},"SevMietgutschriftLaufResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monate":{"type":"array","items":{"type":"string","description":"ein Monat im Format JJJJ-MM","example":"2025-03"}},"text":{"type":"string","description":"der Buchungstext der Periode, z. B. „Mietgutschrift März 2025\""},"gutschriften":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"vorlageId":{"type":["string","null"],"format":"uuid","description":"der angelegte Vorschlag; null bei bereits_vorgelegt"},"ausgang":{"type":"string","enum":["vorgelegt","bereits_vorgelegt"],"description":"vorgelegt = dieser Aufruf hat den Vorschlag angelegt; bereits_vorgelegt = ein gleichzeitiger Lauf war schneller, nichts angelegt"},"betragCents":{"type":"string","description":"der vorgeschlagene Betrag (Differenz zum bereits Gutgeschriebenen) in ganzen Cents"},"erreichterGesamtbetragCents":{"type":"string","description":"der danach erreichte Gesamtbetrag der Periode in ganzen Cents"},"inhaltsHash":{"type":"string","description":"sha256-Hex über den Inhalt des Vorschlags; die Freigabe bestätigt ihn"},"art":{"type":"string","description":"die vereinbarte Grundlage (ist | soll | festbetrag)"},"bemessung":{"type":"array","items":{"type":"object","properties":{"monat":{"type":"string","description":"ein Monat im Format JJJJ-MM","example":"2025-03"},"art":{"type":"string"},"betragCents":{"type":"string","description":"der Monatswert in ganzen Cents"},"grundlagen":{"type":"integer","description":"Anzahl der eingegangenen Grundlagen (Zahlungen bzw. Sollstellungen)"}},"required":["monat","art","betragCents","grundlagen"]}}},"required":["mandatId","vorlageId","ausgang","betragCents","erreichterGesamtbetragCents","inhaltsHash","art","bemessung"]}},"uebersprungen":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"grund":{"type":"string","enum":["kein_mietinkasso","mietberechnung_keine","kein_neuer_betrag","garantie_kaltmiete_fehlt","eigentuemer_gewechselt"],"description":"kein_mietinkasso = SEV ohne Mietbuchhaltung; mietberechnung_keine = keine Gutschrift vereinbart; kein_neuer_betrag = schon gutgeschrieben; garantie_kaltmiete_fehlt = Garantie auf Basis kalt, aber die Kaltmiete ist nicht ermittelbar (kein Vorschlag für dieses Mandat); eigentuemer_gewechselt = der Eigentümer der Wohnung hat gewechselt, ohne dass das Mandat passend beendet wurde — mindestens ein Monat wird nicht an den bisherigen Eigentümer gutgeschrieben (Befund: GET /api/objekt/{id}/sev-eigentuemerwechsel)"}},"required":["mandatId","grund"]}},"rueckbelastungen":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"ein Monat im Format JJJJ-MM","example":"2025-03"},"bisherCents":{"type":"string","description":"bereits gutgeschrieben"},"neuCents":{"type":"string","description":"was die Bemessung jetzt ergibt"},"differenzCents":{"type":"string","description":"neu − bisher (negativ); vorgelegt, nicht gebucht"}},"required":["mandatId","monat","bisherCents","neuCents","differenzCents"]}}},"required":["propertyId","monate","text","gutschriften","uebersprungen","rueckbelastungen"]},"SevMietgutschriftFreigabeRequest":{"type":"object","properties":{"inhaltsHash":{"type":"string","description":"der `inhaltsHash` des GESEHENEN Vorschlags; weicht er ab ⇒ 409, nichts gebucht"}},"required":["inhaltsHash"],"description":"Gibt einen Mietgutschrift-Vorschlag frei: je Monat mit Anteil eine Buchung (Art Mietgutschrift) auf dem Verrechnungskonto."},"SevMietgutschriftFreigabeResponse":{"type":"object","properties":{"vorlageId":{"type":"string","format":"uuid"},"mandatId":{"type":"string","format":"uuid"},"betragCents":{"type":"string","description":"der gebuchte Betrag in ganzen Cents"},"buchungen":{"type":"array","items":{"type":"object","properties":{"monat":{"type":"string","description":"ein Monat im Format JJJJ-MM","example":"2025-03"},"entryId":{"type":"string","format":"uuid","description":"der Satz im SEV-Geldkreis (journal_entries.id)"},"betragCents":{"type":"string","description":"der Anteil des Monats in ganzen Cents"},"buchungsdatum":{"type":"string","format":"date","description":"der Monatsletzte (im laufenden Monat: heute)"}},"required":["monat","entryId","betragCents","buchungsdatum"]}}},"required":["vorlageId","mandatId","betragCents","buchungen"]},"SevMietgutschriftAblehnungResponse":{"type":"object","properties":{"vorlageId":{"type":"string","format":"uuid"},"mandatId":{"type":"string","format":"uuid"},"monate":{"type":"array","items":{"type":"string","description":"ein Monat im Format JJJJ-MM","example":"2025-03"},"description":"die Monate, deren Reservierung gelöst wurde"}},"required":["vorlageId","mandatId","monate"]},"SevGarantieAbstimmZeile":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"unitNo":{"type":"string","description":"die Wohnungsbezeichnung (units.unit_no)"},"art":{"type":"string","enum":["garantiemiete","mindestmiete"],"description":"garantiemiete = Gutschrift ist der Garantiebetrag; mindestmiete = Gutschrift ist max(erzielte Miete, Mindestbetrag)"},"basis":{"type":"string","enum":["kalt","warm"],"description":"kalt oder warm — welche erzielte Miete dem Betrag gegenübersteht"},"garantiegeberPersonId":{"type":"string","format":"uuid","description":"der Garantiegeber (persons.id)"},"garantiertCents":{"type":"string","description":"Σ der zugesicherten Beträge (Garantie- bzw. Mindestbetrag je Monat) in ganzen Cents"},"erzieltCents":{"type":"string","description":"Σ der erzielten Miete (Ist, nach Buchungsperiode, auf der Basis der Garantie) in ganzen Cents"},"differenzCents":{"type":"string","description":"erzielt − garantiert in ganzen Cents (vorzeichenbehaftet)"},"gutschriftCents":{"type":"string","description":"Σ dessen, was dem Eigentümer zusteht, in ganzen Cents"},"belastungGarantiegeberCents":{"type":"string","description":"gutschrift − erzielt in ganzen Cents — positiv: der Garantiegeber zahlt; negativ: er erhält den Mehrerlös"}},"required":["mandatId","unitId","unitNo","art","basis","garantiegeberPersonId","garantiertCents","erzieltCents","differenzCents","gutschriftCents","belastungGarantiegeberCents"],"description":"EIN Mandat (eine Wohnung) mit Garantie über den Zeitraum — nur die Monate, in denen das Mandat wirkt."},"SevGarantieAbstimmlisteResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monate":{"type":"array","items":{"type":"string","description":"ein Monat im Format JJJJ-MM","example":"2025-03"},"description":"der abgefragte Zeitraum: lückenlose Monatsfolge in Kalenderfolge"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/SevGarantieAbstimmZeile"},"description":"je Mandat MIT Garantie, das im Zeitraum wirkt, eine Zeile — aufsteigend nach unitNo"},"summen":{"type":"object","properties":{"garantiertCents":{"type":"string","description":"Σ der zugesicherten Beträge (Garantie- bzw. Mindestbetrag je Monat) in ganzen Cents"},"erzieltCents":{"type":"string","description":"Σ der erzielten Miete (Ist, nach Buchungsperiode, auf der Basis der Garantie) in ganzen Cents"},"differenzCents":{"type":"string","description":"erzielt − garantiert in ganzen Cents (vorzeichenbehaftet)"},"gutschriftCents":{"type":"string","description":"Σ dessen, was dem Eigentümer zusteht, in ganzen Cents"},"belastungGarantiegeberCents":{"type":"string","description":"gutschrift − erzielt in ganzen Cents — positiv: der Garantiegeber zahlt; negativ: er erhält den Mehrerlös"}},"required":["garantiertCents","erzieltCents","differenzCents","gutschriftCents","belastungGarantiegeberCents"],"description":"Σ der Zeilen je Spalte, centgenau"},"nichtBemessbar":{"type":"array","items":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"unitNo":{"type":"string","description":"die Wohnungsbezeichnung (units.unit_no)"},"grund":{"type":"string","enum":["garantie_kaltmiete_fehlt"],"description":"garantie_kaltmiete_fehlt = Garantie auf Basis kalt, aber die Kaltmiete ist nicht ermittelbar — kein Rückfall auf die Warmmiete"}},"required":["mandatId","unitId","unitNo","grund"]},"description":"Garantiemandate, die im Zeitraum nicht bemessen werden konnten, mit Grund — nicht in zeilen und nicht in den Summen; aufsteigend nach unitNo"}},"required":["propertyId","monate","zeilen","summen","nichtBemessbar"],"description":"Abstimmliste der Garantiemieten eines Objekts: garantierte gegen erzielte Miete je Wohnung, die Differenz, die Gutschrift an den Eigentümer und die Belastung des Garantiegebers — gerechnet aus dem Bestand, unabhängig davon, ob die Gutschrift schon vorgelegt oder freigegeben ist."},"SevEigentuemerabrechnungPosition":{"type":"object","properties":{"art":{"type":"string","enum":["mietgutschrift","mehrerloes_garantiemiete","mietzuschuss","garantiegeber","sonstige_einnahme","verwalterverguetung","hausgeld_an_weg","zufuehrung_sonderruecklage","entnahme_an_eigentuemer","sonstige_ausgabe","entnahme_sonderruecklage","ertragsumbuchung_abgang","ertragsumbuchung_zugang"],"description":"die SEV-Buchungsart der Position (jede außer anfangsbestand — der steht im Geldbestand); ertragsumbuchung_abgang/_zugang = Umbuchung von Mieterträgen zwischen altem und neuem Eigentümer (#5228)"},"gruppe":{"type":"string","enum":["miete","umlagen","sonstige_einnahmen","umlagefaehige_kosten","instandhaltung","verwaltung","sonstige_werbungskosten","kaution","durchlaufend","ruecklage","eigentuemer"],"description":"die Kostengruppe der Art — dieselbe Gruppierung wie die Einnahmen-Überschuss-Aufstellung"},"betragCents":{"type":"string","description":"Betrag in der Richtung des Blocks in ganzen Cents (Einnahme = Σ Saldowirkung, Ausgabe/Auszahlung = −Σ Saldowirkung); ein Storno mindert ihn"},"anzahlBuchungen":{"type":"integer","description":"Anzahl der Buchungen dieser Art im Zeitraum (Stornos zählen mit)"}},"required":["art","gruppe","betragCents","anzahlBuchungen"],"description":"EINE Position eines Blocks — alle Buchungen EINER Art im Zeitraum."},"SevEigentuemerabrechnungBlock":{"type":"object","properties":{"positionen":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SevEigentuemerabrechnungPosition"},"description":"je Buchungsart mit mindestens einer Buchung im Zeitraum eine Position, in der Ordnung des Buchungsvokabulars; null NUR beim ausgeblendeten Auszahlungsblock (mitAuszahlung=false)"},"summeCents":{"type":"string","description":"Σ der Positionen in ganzen Cents, exakt — steht auch bei ausgeblendeten Positionen"}},"required":["positionen","summeCents"],"description":"Ein Block der Abrechnung (Einnahmen, Ausgaben oder Auszahlungen)."},"SevEigentuemerabrechnungEmpfaenger":{"type":"object","properties":{"personId":{"type":"string","format":"uuid","description":"der Eigentümer des Mandats (persons.id)"},"anrede":{"type":"string","description":"die Briefanrede (persons.contact.briefanrede, sonst der Vorschlag aus Anrede und Name); nie leer"},"name":{"type":"string","description":"der Personenname des Eigentümers — die Zustellanweisung ersetzt den Briefkasten, nie den Empfänger; nie leer"},"anschrift":{"type":"array","items":{"type":"string"},"description":"die Anschriftzeilen: mit Zustellanweisung die abweichende Adresse (samt Empfängername), sonst Straße Hausnummer, PLZ Ort, Land aus persons.contact; nie leer"}},"required":["personId","anrede","name","anschrift"],"description":"Der Empfänger der Abrechnung — der Eigentümer mit der Zustellanweisung seiner Eigentümerzeile."},"SevEigentuemerabrechnungResponse":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"zeitraum":{"type":"object","properties":{"von":{"type":"string","format":"date","description":"erster Tag des Zeitraums (INKLUSIV)"},"bis":{"type":"string","format":"date","description":"letzter Tag des Zeitraums (INKLUSIV)"}},"required":["von","bis"],"description":"der abgerechnete Zeitraum nach Buchungsdatum, beide Grenzen inklusiv"},"mitAuszahlung":{"type":"boolean","description":"false = die Positionen des Auszahlungsblocks sind ausgeblendet (Summe und Geldbestand zählen sie trotzdem)"},"currency":{"type":"string","enum":["EUR"]},"empfaenger":{"$ref":"#/components/schemas/SevEigentuemerabrechnungEmpfaenger"},"einnahmen":{"$ref":"#/components/schemas/SevEigentuemerabrechnungBlock"},"ausgaben":{"$ref":"#/components/schemas/SevEigentuemerabrechnungBlock"},"auszahlungen":{"$ref":"#/components/schemas/SevEigentuemerabrechnungBlock"},"miete":{"type":"object","properties":{"sollCents":{"type":["string","null"],"description":"die sollgestellte Miete im Zeitraum in ganzen Cents; null = keine Sollstellung bekannt"},"istCents":{"type":"string","description":"Σ der Mietgutschriften im Zeitraum in ganzen Cents"},"ausfallCents":{"type":["string","null"],"description":"soll − ist in ganzen Cents (vorzeichenbehaftet, nicht auf 0 geklemmt); null ohne Soll"},"ertragJeQmCents":{"type":["string","null"],"description":"ist je m² Wohnfläche in ganzen Cents, kaufmännisch gerundet; null ohne Wohnfläche"}},"required":["sollCents","istCents","ausfallCents","ertragJeQmCents"],"description":"Mieteinnahmen: Soll, Ist, Ausfall und Mietertrag je m²"},"kosten":{"type":"object","properties":{"hausgeld":{"type":["object","null"],"properties":{"zeilen":{"type":"array","items":{"type":"object","properties":{"kostenart":{"type":"string","description":"die Kostenart der Hausgeld-Einzelabrechnung"},"betragCents":{"type":"string","description":"der Anteil dieser Wohnung in ganzen Cents"},"umlagefaehig":{"type":"boolean","description":"auf den Mieter umlegbar"}},"required":["kostenart","betragCents","umlagefaehig"]},"description":"in der Reihenfolge der Einzelabrechnung"},"umlagefaehigCents":{"type":"string","description":"Σ der umlagefähigen Zeilen in ganzen Cents"},"nichtUmlagefaehigCents":{"type":"string","description":"Σ der nicht umlagefähigen Zeilen in ganzen Cents"},"kostenanteilCents":{"type":"string","description":"der Kostenanteil der Einzelabrechnung = umlagefähig + nicht umlagefähig, in ganzen Cents"},"sollVorschuesseCents":{"type":"string","description":"die Soll-Vorschüsse der Einzelabrechnung in ganzen Cents"},"abrechnungsspitzeCents":{"type":"string","description":"die Abrechnungsspitze der Einzelabrechnung in ganzen Cents"}},"required":["zeilen","umlagefaehigCents","nichtUmlagefaehigCents","kostenanteilCents","sollVorschuesseCents","abrechnungsspitzeCents"],"description":"die eingebundene Hausgeldabrechnung, aufgeteilt nach Umlagefähigkeit; null ohne eingebundene Hausgeldabrechnung"},"verwalterverguetungCents":{"type":"string","description":"Ausgabe-Betrag der Art verwalterverguetung im Zeitraum in ganzen Cents"},"aufMieterUmlegbarCents":{"type":["string","null"],"description":"Hausgeld umlagefähig in ganzen Cents; null ohne Hausgeldabrechnung"},"beimEigentuemerCents":{"type":["string","null"],"description":"Hausgeld nicht umlagefähig + Verwaltervergütung in ganzen Cents; null ohne Hausgeldabrechnung"}},"required":["hausgeld","verwalterverguetungCents","aufMieterUmlegbarCents","beimEigentuemerCents"],"description":"Kosten der Wohnung: Hausgeld und Verwaltervergütung, aufgeteilt in „auf den Mieter umlegbar\" und „bleibt beim Eigentümer\""},"geldbestand":{"type":"object","properties":{"anfangsbestandCents":{"type":"string","description":"Σ Saldowirkung vor von plus der Übernahme aus dem Altbestand im Zeitraum, in ganzen Cents"},"einnahmenCents":{"type":"string","description":"= einnahmen.summeCents"},"ausgabenCents":{"type":"string","description":"= ausgaben.summeCents"},"auszahlungenCents":{"type":"string","description":"= auszahlungen.summeCents — IMMER enthalten, auch ohne Mietauszahlung"},"endbestandCents":{"type":"string","description":"anfangsbestand + einnahmen − ausgaben − auszahlungen in ganzen Cents"},"saldoVerrechnungskontoCents":{"type":"string","description":"der unabhängig gelesene Saldo des Verrechnungskontos zu bis = endbestand (die Probe)"}},"required":["anfangsbestandCents","einnahmenCents","ausgabenCents","auszahlungenCents","endbestandCents","saldoVerrechnungskontoCents"],"description":"die Entwicklung des Geldbestands — die Probe als Felder"},"sonderruecklage":{"type":"object","properties":{"anfangsbestandCents":{"type":"string","description":"Σ Wirkung aller Bewegungen der Rücklage vor von (samt Altbestand vor Migration 0298), in ganzen Cents"},"zufuehrungenCents":{"type":"string","description":"Σ der Zuführungen im Zeitraum in ganzen Cents; ein Storno mindert sie und wird nie zur Entnahme"},"entnahmen":{"type":"array","items":{"type":"object","properties":{"anlass":{"type":"string","enum":["unterdeckung_hausgeld","unterdeckung_verguetung","reparatur"],"description":"der Anlass der Entnahme"},"bezeichnung":{"type":"string","description":"die Anzeige-Bezeichnung des Anlasses"},"betragCents":{"type":"string","description":"entnommen im Zeitraum in ganzen Cents (positiv = entnommen; ein Storno mindert ihn)"},"anzahlBewegungen":{"type":"integer","description":"Anzahl der Bewegungen dieses Anlasses im Zeitraum (Stornos zählen mit)"}},"required":["anlass","bezeichnung","betragCents","anzahlBewegungen"]},"description":"je Anlass mit Bewegung im Zeitraum EINE Position, in der Ordnung der Anlässe (unterdeckung_hausgeld, unterdeckung_verguetung, reparatur)"},"entnahmenSummeCents":{"type":"string","description":"Σ der Entnahme-Positionen in ganzen Cents, exakt"},"endbestandCents":{"type":"string","description":"anfangsbestand + zufuehrungen − entnahmenSumme in ganzen Cents"},"saldoSonderruecklageCents":{"type":"string","description":"der unabhängig gelesene Saldo der Sonderrücklage zu bis = endbestand (die Probe)"}},"required":["anfangsbestandCents","zufuehrungenCents","entnahmen","entnahmenSummeCents","endbestandCents","saldoSonderruecklageCents"],"description":"der Block „Sonderrücklage des Eigentümers\": Anfangsbestand, Zuführungen, Entnahmen je Anlass und Endbestand mit eigener Probe gegen den Saldo der Rücklage — Geld des Eigentümers, nie die Erhaltungsrücklage der Gemeinschaft. Fehlt, wenn das Mandat keine Sonderrücklage-Regel hat und die Rücklage im oder vor dem Zeitraum keine Bewegung hatte."}},"required":["mandatId","propertyId","unitId","zeitraum","mitAuszahlung","currency","empfaenger","einnahmen","ausgaben","auszahlungen","miete","kosten","geldbestand"],"description":"Jahresabrechnung der Sondereigentumsverwaltung für den Eigentümer über einen Zeitraum: Einnahmen, Ausgaben und Auszahlungen je Buchungsart, Mieteinnahmen (Soll, Ist, Ausfall, Ertrag je m²), Kosten der Wohnung und die Entwicklung des Geldbestands mit Probe gegen das Verrechnungskonto."},"SevRechnungBuchenRequest":{"type":"object","properties":{"rechnungsdatum":{"type":"string","format":"date","description":"Rechnungsdatum YYYY-MM-DD — Stichtag der Mieterabrechnung."},"zahlungsdatum":{"type":"string","format":"date","description":"Buchungsdatum der Belastung; Vorgabe: das Rechnungsdatum. Zukunft ⇒ 400."},"betragCents":{"type":"string","description":"Rechnungsbetrag brutto in ganzen Cents als positiver Ziffern-String (nie eine JSON-number)."},"kreditor":{"type":"string","description":"Der Rechnungssteller (Handwerker, Dienstleister)."},"rechnungsnummer":{"type":"string","description":"Rechnungsnummer des Kreditors — mit dem Kreditor der Schlüssel der Rechnung je Mandat."},"kostenart":{"type":"string","description":"Kostenart-Schlüssel (BetrKV-Katalog oder Sonderschlüssel)."},"umlagefaehig":{"type":"boolean","description":"Auf den Mieter der Wohnung umlagefähig?"},"beiUnterdeckung":{"type":"string","enum":["einziehen","nicht_zahlen","sonderruecklage"],"description":"Entscheid bei fehlender Deckung; ohne ihn ⇒ 400."},"documentId":{"type":["string","null"],"format":"uuid","description":"Optionaler Bezug auf die Eingangsrechnung im Posteingang (documents.id)."}},"required":["rechnungsdatum","betragCents","kreditor","rechnungsnummer","kostenart","umlagefaehig"],"description":"Gibt eine Rechnung des Sondereigentums zur Zahlung aus der Miete des Eigentümers frei: Belastung des Verrechnungskontos, Kennzeichen Kostenart + umlagefähig. Nie in der Abrechnung der Gemeinschaft."},"SevRechnungBefund":{"type":"object","properties":{"massnahme":{"type":"string","enum":["einziehen","nicht_zahlen","sonderruecklage"]},"fehlbetragCents":{"type":"string","description":"Fehlbetrag in Cents (Betrag − Guthaben)."},"entnahmeSonderruecklageCents":{"type":"string","description":"aus der Sonderrücklage entnommen, Cents"},"restFehlbetragCents":{"type":"string","description":"beim Eigentümer offen, Cents"}},"required":["massnahme","fehlbetragCents","entnahmeSonderruecklageCents","restFehlbetragCents"]},"SevRechnungBuchenResponse":{"type":"object","properties":{"ergebnis":{"type":"string","enum":["gebucht","nicht_bezahlt","unveraendert"]},"sevRechnungId":{"type":"string","format":"uuid"},"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid","description":"die Einheit des Mandats (der Kostenträger)"},"entryId":{"type":["string","null"],"format":"uuid","description":"der Satz auf dem Verrechnungskonto; null bei nicht_bezahlt"},"betragCents":{"type":"string","description":"Rechnungsbetrag, Cents"},"belastetCents":{"type":"string","description":"dem Verrechnungskonto belastet, Cents (\"0\" bei nicht_bezahlt)"},"kostenart":{"type":"string"},"umlagefaehig":{"type":"boolean"},"befund":{"allOf":[{"$ref":"#/components/schemas/SevRechnungBefund"},{"type":["object","null"]}]},"currency":{"type":"string","enum":["EUR"]}},"required":["ergebnis","sevRechnungId","mandatId","unitId","entryId","betragCents","belastetCents","kostenart","umlagefaehig","befund","currency"]},"SevRechnung":{"type":"object","properties":{"sevRechnungId":{"type":"string","format":"uuid"},"mandatId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"rechnungsdatum":{"type":"string","format":"date"},"kreditor":{"type":"string"},"rechnungsnummer":{"type":"string"},"betragCents":{"type":"string","description":"Rechnungsbetrag, Cents"},"kostenart":{"type":"string"},"umlagefaehig":{"type":"boolean"},"status":{"type":"string","enum":["bezahlt","nicht_bezahlt","storniert"]},"entryId":{"type":["string","null"],"format":"uuid"},"documentId":{"type":["string","null"],"format":"uuid"},"befund":{"allOf":[{"$ref":"#/components/schemas/SevRechnungBefund"},{"type":["object","null"]}]},"currency":{"type":"string","enum":["EUR"]}},"required":["sevRechnungId","mandatId","unitId","rechnungsdatum","kreditor","rechnungsnummer","betragCents","kostenart","umlagefaehig","status","entryId","documentId","befund","currency"]},"SevRechnungListResponse":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"rechnungen":{"type":"array","items":{"$ref":"#/components/schemas/SevRechnung"}}},"required":["mandatId","rechnungen"]},"SevMieterKostenposition":{"type":"object","properties":{"sevRechnungId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"rechnungsdatum":{"type":"string","format":"date"},"kreditor":{"type":"string"},"rechnungsnummer":{"type":"string"},"kostenart":{"type":"string"},"betragCents":{"type":"string","description":"Rechnungsbetrag, Cents"},"currency":{"type":"string","enum":["EUR"]}},"required":["sevRechnungId","unitId","rechnungsdatum","kreditor","rechnungsnummer","kostenart","betragCents","currency"]},"SevMieterKostenResponse":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date","description":"Beginn des Zeitraums (inklusiv)"},"bis":{"type":"string","format":"date","description":"Ende des Zeitraums (inklusiv)"},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/SevMieterKostenposition"}}},"required":["unitId","von","bis","positionen"]},"BeschlussGegenstand":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"beschlussId":{"type":"string","format":"uuid"},"lfdNr":{"type":"integer","description":"laufende Nummer INNERHALB des Beschlusses, ab 1"},"bezeichnung":{"type":"string"},"wortlaut":{"type":["string","null"],"description":"null ⇒ nicht gesondert überliefert (nicht: leer)"},"bezugArt":{"type":["string","null"],"description":"worauf sich der Teil bezieht (ruecklage | wirtschaftsplan | …); null ⇒ kein Bezug"},"bezugRef":{"type":["string","null"],"format":"uuid"},"wpGegenstaende":{"type":"array","items":{"type":"string","enum":["vorschuesse","ruecklagenzufuehrung","wirtschaftsplan_als_ganzes"]},"description":"getragene Wirtschaftsplan-Teil-Gegenstände; leer ⇒ trägt keinen Plan"},"wpFortgeltung":{"type":"boolean","description":"Fortgeltung beschlossen (nur an einem Teil mit vorschuesse)"},"ref":{"type":"string","description":"kanonische Referenzform `beschluss-gegenstand:<uuid>`"}},"required":["id","beschlussId","lfdNr","bezeichnung","wortlaut","bezugArt","bezugRef","wpGegenstaende","wpFortgeltung","ref"]},"Beschluss":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"lfdNr":{"type":"integer","description":"Ordnungszahl der Sammlung JE OBJEKT (§ 24 Abs. 7 WEG), ab 1"},"top":{"type":["string","null"],"description":"Tagesordnungspunkt (`2.3`); null beim Umlaufbeschluss"},"thema":{"type":"string"},"wortlaut":{"type":["string","null"],"description":"null ⇒ im Altbestand nicht überliefert (nicht: leerer Wortlaut)"},"kategorie":{"type":["string","null"],"description":"Kompetenzgrundlage — FREITEXT, konfigurierbarer Default, kein geschlossenes Vokabular"},"quelle":{"type":"string","description":"etv | umlauf | alt_import"},"beschlussDatum":{"type":["string","null"],"format":"date"},"status":{"type":"string","description":"angenommen | abgelehnt | angefochten | bestandskraeftig | aufgehoben | nichtig"},"statusSeit":{"type":"string","format":"date-time"},"stimmenJa":{"type":["string","null"],"description":"Kopfzahl als Dezimalstring; null ⇒ nicht überliefert (≠ 0)"},"stimmenNein":{"type":["string","null"]},"stimmenEnthaltung":{"type":["string","null"]},"anteileJa":{"type":["string","null"],"description":"Anteilssumme in Zehntausendsteln als Dezimalstring; null ⇒ nicht überliefert"},"anteileNein":{"type":["string","null"]},"anteileEnthaltung":{"type":["string","null"]},"importVermerk":{"type":["string","null"],"description":"was der Alt-Import an dieser Zeile entschieden hat"},"gegenstaende":{"type":"array","items":{"$ref":"#/components/schemas/BeschlussGegenstand"}},"versammlungId":{"type":["string","null"],"format":"uuid","description":"Herkunft: die Versammlung, aus der der Beschluss übernommen wurde; null ⇒ ohne Versammlung (Alt-Import, erfasse_beschluss)"},"versammlungDatum":{"type":["string","null"],"format":"date","description":"Datum der Herkunfts-Versammlung; null ⇒ ohne Versammlung"},"verkuendetAm":{"type":["string","null"],"format":"date","description":"Verkündungsdatum der Versammlung; null ⇒ ohne Versammlung oder noch nicht verkündet"},"anfechtungsfristEnde":{"type":["string","null"],"format":"date","description":"Ende der Anfechtungsfrist (§ 45 WEG, ein Monat ab Verkündung, Wochenende verschoben; Feiertage nicht berücksichtigt); aus dem Fachkern berechnet, nicht gespeichert"}},"required":["id","propertyId","lfdNr","top","thema","wortlaut","kategorie","quelle","beschlussDatum","status","statusSeit","stimmenJa","stimmenNein","stimmenEnthaltung","anteileJa","anteileNein","anteileEnthaltung","importVermerk","gegenstaende","versammlungId","versammlungDatum","verkuendetAm","anfechtungsfristEnde"]},"BeschlussListResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"status":{"type":"array","items":{"type":"string"},"description":"der angewandte Status-Filter; LEER ⇒ die vollständige Sammlung"},"beschluesse":{"type":"array","items":{"$ref":"#/components/schemas/Beschluss"}}},"required":["propertyId","status","beschluesse"]},"BeschlussErfasseRequest":{"type":"object","properties":{"lfdNr":{"type":"integer","description":"Ordnungszahl der Sammlung, ab 1 — je Objekt eindeutig"},"top":{"type":"string"},"thema":{"type":"string"},"wortlaut":{"type":["string","null"]},"kategorie":{"type":"string"},"quelle":{"type":"string","description":"etv | umlauf | alt_import"},"beschlussDatum":{"type":"string","format":"date"},"status":{"type":"string","description":"Anfangsstatus — NUR ein Verkündungszustand (angenommen | abgelehnt); Default angenommen"},"stimmenJa":{"type":"integer"},"stimmenNein":{"type":"integer"},"stimmenEnthaltung":{"type":"integer"},"anteileJa":{"type":"integer","description":"Anteilssumme in Zehntausendsteln"},"anteileNein":{"type":"integer"},"anteileEnthaltung":{"type":"integer"},"importVermerk":{"type":"string"},"gegenstaende":{"type":"array","items":{"type":"object","properties":{"lfdNr":{"type":"integer"},"bezeichnung":{"type":"string"},"wortlaut":{"type":["string","null"]},"bezugArt":{"type":"string"},"bezugRef":{"type":"string","format":"uuid"},"wpGegenstaende":{"type":"array","items":{"type":"string","enum":["vorschuesse","ruecklagenzufuehrung","wirtschaftsplan_als_ganzes"]},"minItems":1,"description":"Wirtschaftsplan-Teil-Gegenstände, die dieser Teil trägt; mindestens einer, keine Dubletten"},"wpFortgeltung":{"type":"boolean","description":"Fortgeltung beschlossen; Default false; nur zusammen mit wpGegenstaende ⊇ vorschuesse"}},"required":["lfdNr","bezeichnung"]},"description":"mindestens EIN Teil-Gegenstand — sonst kann keine Teilanfechtung darauf zeigen"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["lfdNr","thema","quelle","gegenstaende"],"description":"Erfasst EINEN Beschluss samt Teil-Gegenständen. Ein Änderungsweg existiert bewusst nicht — Korrektur ist ein Zweitbeschluss."},"BeschlussErfasseResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"lfdNr":{"type":"integer"},"status":{"type":"string"},"statusEventId":{"type":"string","format":"uuid","description":"das Anlage-Ereignis im append-only-Verlauf"},"gegenstaende":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"lfdNr":{"type":"integer"},"bezeichnung":{"type":"string"},"wpGegenstaende":{"type":"array","items":{"type":"string","enum":["vorschuesse","ruecklagenzufuehrung","wirtschaftsplan_als_ganzes"]}},"wpFortgeltung":{"type":"boolean"},"ref":{"type":"string"}},"required":["id","lfdNr","bezeichnung","wpGegenstaende","wpFortgeltung","ref"]}}},"required":["id","propertyId","lfdNr","status","statusEventId","gegenstaende"]},"BeschlussStatusRequest":{"type":"object","properties":{"nachStatus":{"type":"string","description":"der ZIEL-Zustand; der Ist-Zustand wird gelesen, nie mitgegeben"},"grund":{"type":"string"},"wirksamAb":{"type":"string","format":"date","description":"Wirksamkeitsdatum, falls es vom Erfassungszeitpunkt abweicht (Fristablauf liegt in der Vergangenheit)"},"uebergangsOptionen":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Einstellungen der KONFIGURIERBAREN Kanten (Instanzrechtsprechung/Praxis). Harte Nichtigkeits-/BGH-Riegel lassen sich hierüber NICHT öffnen."}},"required":["nachStatus"],"description":"Schreibt einen Statuswechsel fort: neue Zeile im append-only-Verlauf plus Projektion, in EINER Transaktion."},"VersammlungHinweis":{"type":"object","properties":{"code":{"type":"string","description":"einladungsfrist-unterschritten | einladung-nicht-erfasst"},"text":{"type":"string"},"istTage":{"type":"integer","description":"Ist-Tage zwischen Einladung und Versammlung (nur bei Unterschreitung)"}},"required":["code","text"]},"Versammlung":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"art":{"type":"string","description":"ordentlich | ausserordentlich | umlauf"},"status":{"type":"string","description":"entwurf | durchgefuehrt | abgeschlossen | abgesagt"},"versammlungsdatum":{"type":"string","format":"date","description":"bei Art umlauf: das Datum der Beschlussfassung"},"einladungsdatum":{"type":["string","null"],"format":"date","description":"null beim Umlaufbeschluss und wenn nicht erfasst"},"einladungsfristBegruendung":{"type":["string","null"]},"stimmprinzip":{"type":["string","null"],"description":"koepfe | mea | objekt; null beim Umlaufbeschluss (wird dort nicht geführt)"},"beschlussfaehig":{"type":["boolean","null"],"description":"null beim Umlaufbeschluss (wird dort nicht geführt)"},"beschlussfaehigkeitNotiz":{"type":["string","null"]},"verkuendetAm":{"type":["string","null"],"format":"date"},"anfechtungsfristEnde":{"type":["string","null"],"format":"date","description":"nur mit verkuendetAm (Anfechtungsfrist § 45 WEG); sonst null"},"anfechtungsfristEndeRechnerisch":{"type":["string","null"],"format":"date","description":"rechnerisches Fristende nach § 188 Abs. 2 BGB, vor der Verschiebung auf einen Werktag; nur mit verkuendetAm, sonst null"},"anfechtungsfristHinweis":{"type":["string","null"],"description":"Hinweis zur Fristberechnung (Feiertage nicht berücksichtigt); nur mit verkuendetAm, sonst null"},"beschluesseGeneriertAm":{"type":["string","null"],"format":"date-time","description":"gesetzt ⇒ die Versammlung ist abgeschlossen und unveränderlich"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","art","status","versammlungsdatum","einladungsdatum","einladungsfristBegruendung","stimmprinzip","beschlussfaehig","beschlussfaehigkeitNotiz","verkuendetAm","anfechtungsfristEnde","anfechtungsfristEndeRechnerisch","anfechtungsfristHinweis","beschluesseGeneriertAm","createdAt"]},"VersammlungListResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"versammlungen":{"type":"array","items":{"$ref":"#/components/schemas/Versammlung"}}},"required":["propertyId","versammlungen"]},"VersammlungAnlegenRequest":{"type":"object","properties":{"art":{"type":"string","description":"ordentlich | ausserordentlich | umlauf"},"versammlungsdatum":{"type":"string","format":"date"},"einladungsdatum":{"type":"string","format":"date","description":"nicht beim Umlaufbeschluss; ohne Angabe ⇒ Hinweis einladung-nicht-erfasst"},"einladungsfristBegruendung":{"type":"string","description":"Pflicht, wenn die Einladung weniger als 3 Wochen vor der Versammlung liegt"},"stimmprinzip":{"type":"string","description":"koepfe (Default) | mea | objekt; nicht beim Umlaufbeschluss"},"beschlussfaehig":{"type":"boolean","description":"Default true; nicht beim Umlaufbeschluss"},"beschlussfaehigkeitNotiz":{"type":"string"}},"required":["art","versammlungsdatum"],"description":"Legt eine Versammlung an. Unter 3 Wochen Einladungsfrist: Warnung (Hinweis) und Begründung Pflicht, aber keine Sperre. Der Umlaufbeschluss ist nur eine Art; die Abstimmung läuft nicht über casa.ai."},"VersammlungAendernRequest":{"type":"object","properties":{"versammlungsdatum":{"type":"string","format":"date"},"einladungsdatum":{"type":["string","null"],"format":"date"},"einladungsfristBegruendung":{"type":["string","null"]},"stimmprinzip":{"type":"string"},"beschlussfaehig":{"type":"boolean"},"beschlussfaehigkeitNotiz":{"type":["string","null"]},"status":{"type":"string","description":"nur entwurf → durchgefuehrt und entwurf|durchgefuehrt → abgesagt; abgeschlossen setzt allein „Beschlüsse generieren“"}},"description":"Ändert eine Versammlung. art und propertyId sind nicht änderbar; ab beschluesse_generiert_am ist sie unveränderlich (409)."},"VersammlungSchreibResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"art":{"type":"string"},"status":{"type":"string"},"versammlungsdatum":{"type":"string","format":"date"},"einladungsdatum":{"type":["string","null"],"format":"date"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/VersammlungHinweis"}}},"required":["id","propertyId","art","status","versammlungsdatum","einladungsdatum","hinweise"]},"VersammlungTop":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"lfdNr":{"type":"integer","description":"laufende TOP-Nummer ab 1, je Versammlung eindeutig; die Reihenfolge ändert sich nie"},"bezeichnung":{"type":"string"},"topArt":{"type":"string","description":"beschluss | geschaeftsordnung | notiz"},"beschlusstext":{"type":["string","null"]},"kategorie":{"type":["string","null"]},"ergebnis":{"type":["string","null"],"description":"angenommen | abgelehnt; null = noch nicht erfasst (und bei Nicht-Beschluss-TOPs immer)"},"stimmenJa":{"type":["integer","null"],"description":"Köpfe; null = nicht genannt"},"stimmenNein":{"type":["integer","null"]},"stimmenEnthaltung":{"type":["integer","null"]},"anteileJa":{"type":["integer","null"],"description":"Anteile in Zehntausendsteln; null = nicht genannt"},"anteileNein":{"type":["integer","null"]},"anteileEnthaltung":{"type":["integer","null"]}},"required":["id","lfdNr","bezeichnung","topArt","beschlusstext","kategorie","ergebnis","stimmenJa","stimmenNein","stimmenEnthaltung","anteileJa","anteileNein","anteileEnthaltung"]},"VersammlungTeilnehmer":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"personName":{"type":"string","description":"Anzeigename aus dem Personenstamm (personenbezogen)"},"personType":{"type":"string","description":"Personenart aus dem Personenstamm"},"anwesenheit":{"type":"string","description":"praesent | online | vertreten"},"stimmgewicht":{"type":"integer","description":"koepfe: 1; mea: Zehntausendstel; objekt: Anzahl der Einheiten"},"vertretenDurch":{"type":["string","null"],"description":"Freitext (personenbezogen)"}},"required":["id","personId","personName","personType","anwesenheit","stimmgewicht","vertretenDurch"]},"VersammlungDetail":{"allOf":[{"$ref":"#/components/schemas/Versammlung"},{"type":"object","properties":{"tops":{"type":"array","items":{"$ref":"#/components/schemas/VersammlungTop"},"description":"nach laufender Nummer"},"teilnehmer":{"type":"array","items":{"$ref":"#/components/schemas/VersammlungTeilnehmer"}},"summeStimmgewicht":{"type":"integer","description":"reine Summe der Stimmgewichte aller erfassten Teilnehmer, ohne Quorum-Urteil"},"anzahlTeilnehmer":{"type":"integer"}},"required":["tops","teilnehmer","summeStimmgewicht","anzahlTeilnehmer"]}],"description":"Die Beschlussfähigkeit wird nicht berechnet: `beschlussfaehig` bleibt wie gespeichert (Änderung über PATCH /api/versammlung/{id})."},"VersammlungTopErfassenRequest":{"type":"object","properties":{"bezeichnung":{"type":"string"},"topArt":{"type":"string","description":"beschluss (Default) | geschaeftsordnung | notiz"},"beschlusstext":{"type":"string"},"kategorie":{"type":"string"},"lfdNr":{"type":"integer","description":"nur wenn ausdrücklich gewünscht; ohne Angabe vergibt der Server die nächste freie Nummer. Vergeben ⇒ 409"}},"required":["bezeichnung"],"description":"Erfasst einen TOP. Beim Umlaufbeschluss genau ein TOP (umlauf-genau-ein-top). Abgeschlossene Versammlung ⇒ 409."},"VersammlungTopAendernRequest":{"type":"object","properties":{"bezeichnung":{"type":"string"},"topArt":{"type":"string"},"beschlusstext":{"type":["string","null"]},"kategorie":{"type":["string","null"]}},"description":"Ändert Text und Art eines TOP; die laufende Nummer (Reihenfolge) ist nicht änderbar."},"VersammlungTeilnehmerErfassenRequest":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"anwesenheit":{"type":"string","description":"praesent | online | vertreten"},"stimmgewicht":{"type":"integer","description":"koepfe: nur 1 (Default); mea: Zehntausendstel (> 0, Pflicht); objekt: Anzahl der Einheiten (> 0, Pflicht)"},"vertretenDurch":{"type":"string"}},"required":["personId","anwesenheit"],"description":"Setzt den Teilnehmer (Upsert je Person: erneutes Setzen überschreibt). Ein Entfernen gibt es nicht; wer nicht erschienen ist, wird nicht erfasst. Ob die Person Eigentümer ist, prüft casa.ai nicht (Gäste, Vertreter, Verwalter sind Teilnehmer). Umlaufbeschluss ⇒ umlauf-ohne-teilnehmer."},"VersammlungTopSchreibResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versammlungId":{"type":"string","format":"uuid"},"lfdNr":{"type":"integer"},"bezeichnung":{"type":"string"},"topArt":{"type":"string"}},"required":["id","versammlungId","lfdNr","bezeichnung","topArt"]},"VersammlungTeilnehmerSchreibResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versammlungId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"anwesenheit":{"type":"string"},"stimmgewicht":{"type":"integer"},"angelegt":{"type":"boolean","description":"true: neu erfasst; false: die bestehende Zeile dieser Person wurde überschrieben"}},"required":["id","versammlungId","personId","anwesenheit","stimmgewicht","angelegt"]},"VersammlungTopErgebnisRequest":{"type":"object","properties":{"ergebnis":{"type":"string","description":"angenommen | abgelehnt — die Feststellung; sie wird nie aus den Zahlen abgeleitet"},"stimmenJa":{"type":"integer","description":"Köpfe, ganze Zahl >= 0; nicht genannt ⇒ null"},"stimmenNein":{"type":"integer"},"stimmenEnthaltung":{"type":"integer"},"anteileJa":{"type":"integer","description":"Anteile in Zehntausendsteln, ganze Zahl >= 0; nicht genannt ⇒ null"},"anteileNein":{"type":"integer"},"anteileEnthaltung":{"type":"integer"}},"required":["ergebnis"],"description":"Setzt Feststellung und Zahlen EINES Beschluss-TOP; erneutes Setzen überschreibt (nicht genannte Zahlen werden null), solange die Versammlung nicht abgeschlossen ist. Geschäftsordnungs- und Notiz-TOPs ⇒ top-ohne-abstimmung. Beim Umlaufbeschluss sind die Zahlen optional, die Feststellung ist Pflicht."},"VersammlungTopErgebnisResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versammlungId":{"type":"string","format":"uuid"},"lfdNr":{"type":"integer"},"ergebnis":{"type":"string"},"stimmenJa":{"type":["integer","null"]},"stimmenNein":{"type":["integer","null"]},"stimmenEnthaltung":{"type":["integer","null"]},"anteileJa":{"type":["integer","null"]},"anteileNein":{"type":["integer","null"]},"anteileEnthaltung":{"type":["integer","null"]},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/VersammlungHinweis"},"description":"ergebnis-widerspricht-zahlen: angenommen bei mehr Nein- als Ja-Stimmen — gespeichert wird trotzdem wie festgestellt"}},"required":["id","versammlungId","lfdNr","ergebnis","stimmenJa","stimmenNein","stimmenEnthaltung","anteileJa","anteileNein","anteileEnthaltung","hinweise"]},"VersammlungVerkuendenRequest":{"type":"object","properties":{"verkuendetAm":{"type":"string","format":"date","description":"Datum der Verkündung; nicht vor dem Versammlungsdatum, nicht in der Zukunft"}},"required":["verkuendetAm"],"description":"Verkündet die Versammlung (setzt verkuendet_am EINMAL). Voraussetzung: Status durchgefuehrt, mindestens ein Beschluss-TOP, jeder Beschluss-TOP hat ein Ergebnis. Zweites Verkünden ⇒ 409 bereits-verkuendet."},"VersammlungVerkuendungResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"art":{"type":"string"},"status":{"type":"string"},"versammlungsdatum":{"type":"string","format":"date"},"verkuendetAm":{"type":"string","format":"date"},"anfechtungsfristEnde":{"type":"string","format":"date","description":"Ende der Anfechtungsfrist: ein Monat ab Verkündung (§ 45 WEG), auf einen Werktag verschoben; berechnet, nicht gespeichert"},"anfechtungsfristEndeRechnerisch":{"type":"string","format":"date","description":"rechnerisches Fristende nach § 188 Abs. 2 BGB, vor der Verschiebung"},"anfechtungsfristHinweis":{"type":"string","description":"Feiertage sind nicht berücksichtigt"}},"required":["id","propertyId","art","status","versammlungsdatum","verkuendetAm","anfechtungsfristEnde","anfechtungsfristEndeRechnerisch","anfechtungsfristHinweis"]},"VersammlungBeschluesseGenerierenRequest":{"type":"object","properties":{},"description":"Übernimmt die verkündeten Beschluss-TOPs in die Beschluss-Sammlung des Objekts (genau einmal). Leerer Body `{}`. Voraussetzung: verkündet, mindestens ein Beschluss-TOP, jeder Beschluss-TOP hat ein Ergebnis. Geschäftsordnungs- und Notiz-TOPs werden nicht übernommen."},"VersammlungBeschluesseGenerierenResponse":{"type":"object","properties":{"versammlungId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"beschluesse":{"type":"array","items":{"type":"object","properties":{"topNr":{"type":"integer","description":"laufende TOP-Nummer in der Versammlung"},"beschlussId":{"type":"string","format":"uuid"},"lfdNr":{"type":"integer","description":"laufende Nummer in der Beschluss-Sammlung des Objekts"},"status":{"type":"string","description":"angenommen | abgelehnt — das Ergebnis des TOP"}},"required":["topNr","beschlussId","lfdNr","status"]},"description":"übernommene Beschlüsse in TOP-Reihenfolge"},"uebersprungen":{"type":"array","items":{"type":"object","properties":{"topNr":{"type":"integer"},"topArt":{"type":"string"},"grund":{"type":"string"}},"required":["topNr","topArt","grund"]},"description":"nicht übernommene TOPs (Geschäftsordnung, Notiz) mit Grund"},"anzahl":{"type":"integer","description":"Anzahl übernommener Beschlüsse"}},"required":["versammlungId","propertyId","beschluesse","uebersprungen","anzahl"]},"UmlaufEroeffnenRequest":{"type":"object","properties":{"fristEnde":{"type":"string","format":"date","description":"Ende der Antwortfrist; nicht vor dem Eröffnungstag. Keine Ausschlussfrist: Antworten bis zur Feststellung zählen."},"mehrheitsregel":{"type":"string","enum":["allstimmig","mehrheit_abgegebene"],"description":"allstimmig (Default: alle Eigentümer in Textform, § 23 Abs. 3 S. 1 WEG) | mehrheit_abgegebene (§ 23 Abs. 3 S. 2 WEG)"},"absenkungBeschlussId":{"type":"string","format":"uuid","description":"Pflicht bei mehrheit_abgegebene: der vorher gefasste, tragende Beschluss (angenommen oder bestandskraeftig); ob er sich auf diesen Gegenstand bezieht, prüft das System nicht"},"stimmgewichte":{"type":"array","items":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"stimmgewicht":{"type":"integer","exclusiveMinimum":0}},"required":["personId","stimmgewicht"]},"description":"Eingegebenes Stimmgewicht je Eigentümer-Person (Köpfe: 1, mea: Zehntausendstel, objekt: Zahl der Einheiten)"}},"required":["fristEnde"],"description":"Eröffnet den Umlauf einer Versammlung der Art umlauf (Status entwurf, genau ein Beschluss-TOP): legt je Eigentümer-Person eine Rücklaufzeile an. Allstimmigkeit ist der Default. versammlungId steht im Pfad, im Body ist es ein Fehler."},"UmlaufEroeffnetResponse":{"type":"object","properties":{"versammlungId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"mehrheitsregel":{"type":"string","description":"allstimmig | mehrheit_abgegebene"},"fristEnde":{"type":"string","format":"date"},"eroeffnetAm":{"type":"string","format":"date"},"absenkungBeschlussId":{"type":["string","null"],"format":"uuid"},"stimmprinzip":{"type":"string","description":"koepfe | mea | objekt — das Stimmprinzip der Versammlung"},"anzahlRuecklaeufe":{"type":"integer","description":"Zahl der angelegten Rücklaufzeilen (eine je Eigentümer-Person)"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/VersammlungHinweis"},"description":"frist-kurz | gegenstandsbezug-nicht-geprueft"}},"required":["versammlungId","propertyId","mehrheitsregel","fristEnde","eroeffnetAm","absenkungBeschlussId","stimmprinzip","anzahlRuecklaeufe","hinweise"]},"UmlaufRuecklaufRequest":{"type":"object","properties":{"personId":{"type":"string","format":"uuid","description":"Die Eigentümer-Person auf der Rücklaufliste"},"antwort":{"type":"string","enum":["ja","nein","enthaltung"]},"eingegangenAm":{"type":"string","format":"date","description":"Eingangsdatum der Antwort; nicht vor der Eröffnung, nicht in der Zukunft"},"eingangskanal":{"type":"string","enum":["portal","email","post","sonstiges"]},"textformBestaetigt":{"type":"boolean","description":"Zustimmung (ja) gilt nur in Textform; Vorgabe false"},"notiz":{"type":"string","description":"Freitext der Verwaltung"}},"required":["personId","antwort","eingegangenAm","eingangskanal"],"description":"Erfasst die Antwort EINER Person; eine spätere Antwort überschreibt die frühere, solange nicht festgestellt ist. Eine Antwort nach dem Fristende wird gespeichert (Hinweis nach-fristablauf). versammlungId steht im Pfad."},"UmlaufZwischenstand":{"type":"object","properties":{"stimmenJa":{"type":"integer"},"stimmenNein":{"type":"integer"},"stimmenEnthaltung":{"type":"integer"},"anteileJa":{"type":"string","description":"Summe der Stimmgewichte als Integer-String"},"anteileNein":{"type":"string","description":"Summe der Stimmgewichte als Integer-String"},"anteileEnthaltung":{"type":"string","description":"Summe der Stimmgewichte als Integer-String"},"ausstehend":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Personen ohne Antwort"},"fristAbgelaufen":{"type":"boolean"},"feststellbar":{"type":"boolean"}},"required":["stimmenJa","stimmenNein","stimmenEnthaltung","anteileJa","anteileNein","anteileEnthaltung","ausstehend","fristAbgelaufen","feststellbar"]},"UmlaufRuecklaufResponse":{"type":"object","properties":{"versammlungId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"antwort":{"type":"string","description":"ja | nein | enthaltung"},"eingegangenAm":{"type":"string","format":"date"},"eingangskanal":{"type":"string","description":"portal | email | post | sonstiges"},"textformBestaetigt":{"type":"boolean"},"vorherigeAntwort":{"type":["string","null"],"description":"die überschriebene Antwort; null bei der ersten Antwort"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/VersammlungHinweis"},"description":"nach-fristablauf: die Frist ist keine Ausschlussfrist"},"zaehlung":{"$ref":"#/components/schemas/UmlaufZwischenstand"}},"required":["versammlungId","personId","antwort","eingegangenAm","eingangskanal","textformBestaetigt","vorherigeAntwort","hinweise","zaehlung"]},"UmlaufZaehlung":{"allOf":[{"$ref":"#/components/schemas/UmlaufZwischenstand"},{"type":"object","properties":{"feststellung":{"type":"string","description":"offen | angenommen | abgelehnt | nicht_zustande_gekommen"},"gruende":{"type":"array","items":{"type":"string"},"description":"feste Gründe des Fachkerns"}},"required":["feststellung","gruende"]}]},"UmlaufRuecklaufZeile":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"name":{"type":"string","description":"Anzeigename der Eigentümer-Person"},"stimmgewicht":{"type":"string","description":"Stimmgewicht als Integer-String"},"antwort":{"type":["string","null"],"description":"ja | nein | enthaltung; null ⇒ noch keine Antwort"},"eingegangenAm":{"type":["string","null"],"format":"date"},"eingangskanal":{"type":["string","null"],"description":"portal | email | post | sonstiges"},"textformBestaetigt":{"type":"boolean"},"notiz":{"type":["string","null"],"description":"Freitext der Erfassung; null ⇒ keine Notiz"}},"required":["personId","name","stimmgewicht","antwort","eingegangenAm","eingangskanal","textformBestaetigt","notiz"]},"UmlaufVorgang":{"type":"object","properties":{"versammlungId":{"type":"string","format":"uuid"},"mehrheitsregel":{"type":"string","description":"allstimmig | mehrheit_abgegebene"},"fristEnde":{"type":"string","format":"date"},"absenkungBeschlussId":{"type":["string","null"],"format":"uuid"},"eroeffnetAm":{"type":"string","format":"date"},"festgestelltAm":{"type":["string","null"],"format":"date-time"},"feststellung":{"type":["string","null"],"description":"angenommen | abgelehnt | nicht_zustande_gekommen; null ⇒ noch nicht festgestellt"},"mitteilungAm":{"type":["string","null"],"format":"date"},"mitteilungForm":{"type":["string","null"],"description":"textform | brief"}},"required":["versammlungId","mehrheitsregel","fristEnde","absenkungBeschlussId","eroeffnetAm","festgestelltAm","feststellung","mitteilungAm","mitteilungForm"]},"UmlaufStandResponse":{"type":"object","properties":{"vorgang":{"$ref":"#/components/schemas/UmlaufVorgang"},"ruecklauf":{"type":"array","items":{"$ref":"#/components/schemas/UmlaufRuecklaufZeile"},"description":"nach Name"},"zaehlung":{"$ref":"#/components/schemas/UmlaufZaehlung"},"fristAbgelaufen":{"type":"boolean"},"feststellbar":{"type":"boolean","description":"wahr, wenn die Feststellung jetzt möglich ist"},"ausstehend":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Personen ohne Antwort"}},"required":["vorgang","ruecklauf","zaehlung","fristAbgelaufen","feststellbar","ausstehend"]},"UmlaufFeststellenRequest":{"type":"object","properties":{},"description":"Stellt das Ergebnis des Umlaufs fest (einmalig): friert die Zählung ein und schreibt das Ergebnis in den TOP. Leerer Body {}. Feststellbar, sobald alle geantwortet haben (Allstimmigkeit: auch bei einem Nein) oder das Fristende vorbei ist; ein nicht zustande gekommener Umlauf geht als abgelehnt in die Sammlung."},"UmlaufFeststellungResponse":{"type":"object","properties":{"versammlungId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"feststellung":{"type":"string","description":"angenommen | abgelehnt | nicht_zustande_gekommen"},"festgestelltAm":{"type":"string","format":"date-time"},"topErgebnis":{"type":"string","description":"angenommen | abgelehnt — wie im Beschluss-TOP (nicht zustande gekommen ⇒ abgelehnt)"},"topId":{"type":"string","format":"uuid"},"versammlungsdatum":{"type":"string","format":"date","description":"Datum der Beschlussfassung"},"zaehlung":{"$ref":"#/components/schemas/UmlaufZaehlung"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/VersammlungHinweis"}}},"required":["versammlungId","propertyId","feststellung","festgestelltAm","topErgebnis","topId","versammlungsdatum","zaehlung","hinweise"]},"UmlaufVerkuendenRequest":{"type":"object","properties":{"verkuendetAm":{"type":"string","format":"date","description":"Datum der Verkündung; nicht vor dem Versammlungsdatum, nicht in der Zukunft"},"mitteilungForm":{"type":"string","enum":["textform","brief"],"description":"Form der Mitteilung an die Eigentümer"}},"required":["verkuendetAm","mitteilungForm"],"description":"Verkündet den festgestellten Umlauf (einmalig) und hält Mitteilungsdatum und -form fest. Ohne Verkündung gibt es keinen Beschluss in der Sammlung. Auch ein nicht zustande gekommener Umlauf wird verkündet."},"UmlaufVerkuendungResponse":{"allOf":[{"$ref":"#/components/schemas/VersammlungVerkuendungResponse"},{"type":"object","properties":{"feststellung":{"type":"string","description":"angenommen | abgelehnt | nicht_zustande_gekommen"},"mitteilungAm":{"type":"string","format":"date"},"mitteilungForm":{"type":"string","description":"textform | brief"}},"required":["feststellung","mitteilungAm","mitteilungForm"]}]},"BeschlussImportUebersprungen":{"type":"object","properties":{"quellRef":{"type":"string","description":"Rückverweis in den Altbestand: `ONR/VERNR/ID`"},"thema":{"type":"string"},"grund":{"type":"string"}},"required":["quellRef","thema","grund"]},"BeschlussImportBefund":{"type":"object","properties":{"art":{"type":"string","description":"status_geraten | status_nicht_uebernommen | datum_fehlt | wortlaut_fehlt | stimmen_widerspruch"},"quellRef":{"type":"string"},"text":{"type":"string"}},"required":["art","quellRef","text"]},"BeschlussImportFehlschlag":{"type":"object","properties":{"quellRef":{"type":"string"},"lfdNr":{"type":"integer"},"grund":{"type":"string"}},"required":["quellRef","lfdNr","grund"]},"BeschlussImportResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"onr":{"type":"string","description":"die übernommene Objektnummer des Altbestands"},"importiert":{"type":"integer","description":"Anzahl wirklich geschriebener Beschlüsse"},"uebersprungen":{"type":"array","items":{"$ref":"#/components/schemas/BeschlussImportUebersprungen"},"description":"Tagesordnungspunkte ohne Abstimmung — kein Beschluss"},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/BeschlussImportBefund"}},"fehlgeschlagen":{"type":"array","items":{"$ref":"#/components/schemas/BeschlussImportFehlschlag"}}},"required":["propertyId","onr","importiert","uebersprungen","befunde","fehlgeschlagen"]},"BeschlussStatusResponse":{"type":"object","properties":{"beschlussId":{"type":"string","format":"uuid"},"vonStatus":{"type":"string"},"nachStatus":{"type":"string"},"statusEventId":{"type":"string","format":"uuid"}},"required":["beschlussId","vonStatus","nachStatus","statusEventId"]},"Einheitengruppe":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"name":{"type":"string"},"groupKind":{"type":"string","description":"Art (OFFENES Vokabular): untergemeinschaft | wirtschaftseinheit | liegenschaft | … — die Spalte hat keinen CHECK."},"archivedAt":{"type":["string","null"],"format":"date-time","description":"null ⇒ aktiv"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","name","groupKind","archivedAt","createdAt"]},"EinheitengruppeMitglied":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitGroupId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"unitNo":{"type":["string","null"],"description":"Einheitennummer (LEFT JOIN); null, wenn die Kette reißt"},"validFrom":{"type":["string","null"],"format":"date","description":"Beginn INKLUSIV; null ⇒ unbegrenzt in die Vergangenheit"},"validTo":{"type":["string","null"],"format":"date","description":"Ende EXKLUSIV; null ⇒ laufend"},"validRange":{"type":"string","description":"Rohes daterange-Literal, z. B. [2026-01-01,)"},"active":{"type":"boolean","description":"Ist die Mitgliedschaft am Stichtag (asOf) wirksam?"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","unitGroupId","unitId","unitNo","validFrom","validTo","validRange","active","createdAt"]},"EinheitengruppeListResponse":{"type":"object","properties":{"einheitengruppe":{"type":"array","items":{"$ref":"#/components/schemas/Einheitengruppe"}}},"required":["einheitengruppe"]},"EinheitengruppeDetailResponse":{"type":"object","properties":{"einheitengruppe":{"$ref":"#/components/schemas/Einheitengruppe"},"asOf":{"type":"string","format":"date","description":"der wirksame Stichtag, gegen den `active` je Mitgliedschaft gemessen wurde"},"mitglied":{"type":"array","items":{"$ref":"#/components/schemas/EinheitengruppeMitglied"}}},"required":["einheitengruppe","asOf","mitglied"]},"EinheitengruppeCreateRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"name":{"type":"string"},"groupKind":{"type":"string","description":"untergemeinschaft | wirtschaftseinheit | liegenschaft | … (offenes Vokabular)"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["propertyId","name","groupKind"]},"EinheitengruppeUpdateRequest":{"type":"object","properties":{"name":{"type":"string"},"groupKind":{"type":"string"}},"description":"Mindestens ein Feld muss gesetzt sein (leerer Patch ⇒ 400)."},"EinheitengruppeMitgliedAddRequest":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"validFrom":{"type":"string","format":"date","description":"Beginn INKLUSIV — das „ab\" der Aufnahme"},"validTo":{"type":"string","format":"date","description":"optionales Ende (EXKLUSIV); ohne Angabe laufend"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["unitId","validFrom"],"description":"Nimmt eine Einheit „ab validFrom\" in den Kreis auf (SCD-2 je (Kreis, Einheit)). Eine offene Vorgänger-Scheibe derselben Einheit wird an validFrom abgeschlossen; Überschneidungen derselben Einheit IM SELBEN Kreis werden abgelehnt (400)."},"EinheitengruppeMitgliedEndRequest":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"endDate":{"type":"string","format":"date","description":"Tag, ab dem die Mitgliedschaft NICHT mehr gilt (EXKLUSIV)"}},"required":["unitId","endDate"],"description":"Beendet die offene Mitgliedschaft einer Einheit zum Stichtag (obere Bereichsgrenze setzen)."},"EinheitengruppeMitgliedAddResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitGroupId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"validFrom":{"type":"string","format":"date"},"validTo":{"type":["string","null"],"format":"date"},"validRange":{"type":"string"},"supersededPriorSlice":{"type":"boolean","description":"true ⇒ eine zuvor offene Scheibe derselben Einheit wurde an validFrom abgeschlossen."}},"required":["id","unitGroupId","unitId","validFrom","validTo","validRange","supersededPriorSlice"]},"EinheitengruppeMitgliedEndResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"unitGroupId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"endDate":{"type":"string","format":"date"},"validRange":{"type":"string"},"alreadyEnded":{"type":"boolean","description":"true ⇒ war bereits beendet; endDate trägt das URSPRÜNGLICHE Ende."}},"required":["id","unitGroupId","unitId","endDate","validRange","alreadyEnded"]},"Umlageschluessel":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"unitGroupId":{"type":["string","null"],"format":"uuid","description":"Abrechnungskreis-Scope; null ⇒ objektweit"},"keyType":{"type":"string","description":"Grundtyp (OFFENES Vokabular): festbetrag | flaeche | personen_zeit | verbrauch | extern | …"},"name":{"type":"string"},"config":{"type":"object","additionalProperties":{},"description":"strukturierter JSON-Wert (leeres Objekt zulässig)"},"archivedAt":{"type":["string","null"],"format":"date-time","description":"null ⇒ aktiv"},"createdAt":{"type":"string","format":"date-time"},"keyNo":{"type":["integer","null"],"description":"Nummer des Schlüssels im Objekt (#5551, allocation_keys.key_no) — je Objekt eindeutig (DB-UNIQUE); null ⇒ noch nicht vergeben"}},"required":["id","propertyId","unitGroupId","keyType","name","config","archivedAt","createdAt","keyNo"]},"UmlageschluesselListResponse":{"type":"object","properties":{"umlageschluessel":{"type":"array","items":{"$ref":"#/components/schemas/Umlageschluessel"}}},"required":["umlageschluessel"]},"UmlageschluesselCreateRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"keyType":{"type":"string","description":"festbetrag | flaeche | personen_zeit | verbrauch | extern | … (offenes Vokabular)"},"name":{"type":"string"},"config":{"type":"object","additionalProperties":{},"description":"strukturierter JSON-Wert (leer zulässig)"},"unitGroupId":{"type":"string","format":"uuid","description":"optionaler Abrechnungskreis-Scope schon bei der Anlage (muss zum selben Objekt gehören)"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["propertyId","keyType","name"]},"UmlageschluesselUpdateRequest":{"type":"object","properties":{"keyType":{"type":"string"},"name":{"type":"string"},"config":{"type":"object","additionalProperties":{}}},"description":"Mindestens ein Feld muss gesetzt sein (leerer Patch ⇒ 400). Der Scope wird NICHT hier gesetzt (⇒ /scope)."},"UmlageschluesselScopeRequest":{"type":"object","properties":{"unitGroupId":{"type":["string","null"],"format":"uuid","description":"Ziel-Abrechnungskreis oder null (objektweit)"}},"required":["unitGroupId"],"description":"Setzt (unitGroupId) oder löst (null) den Abrechnungskreis-Scope. Der Kreis muss zum selben Objekt wie der Schlüssel gehören."},"UmlageschluesselScopeResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"unitGroupId":{"type":["string","null"],"format":"uuid"}},"required":["id","propertyId","unitGroupId"]},"UmlageArchiveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":"string","format":"date-time"},"alreadyArchived":{"type":"boolean"}},"required":["id","archivedAt","alreadyArchived"]},"MessdienstImportZeile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"externalRef":{"type":"string","description":"Roh-Kennung der Messdienst-Quellzeile (Nutzer-/Objektnummer), für die Rückverfolgung."},"contractId":{"type":["string","null"],"format":"uuid"},"unitId":{"type":["string","null"],"format":"uuid"},"amountCents":{"type":"string","description":"Festbetrag in ganzen Cents als ZIFFERN-STRING (bigint-Cents, GG3/INV-MONEY-01) — nie eine JSON-Zahl."},"matched":{"type":"boolean","description":"false ⇒ die Zeile ist bewusst unaufgelöst (kein Vertrag/keine Einheit)."}},"required":["id","externalRef","contractId","unitId","amountCents","matched"]},"MessdienstCo2Energiemix":{"type":"object","properties":{"art":{"type":"string","description":"Energieträger-Schlüssel (01 Braunkohle … 06 Erneuerbare, 99 Sonstige)."},"prozent":{"type":"string","description":"Prozentanteil als Ziffern-String mit (2,1) impliziten Stellen — „035\" bedeutet 3,5 %."},"faktor":{"type":"string","description":"CO2-Emissionsfaktor kg/kWh als Ziffern-String mit (6,3) impliziten Stellen."}},"required":["art","prozent","faktor"]},"MessdienstCo2Position":{"type":"object","properties":{"id":{"type":["string","null"],"format":"uuid","description":"Die GESPEICHERTE Ausweis-Zeile (#1602); null, falls dieser Ausweis nicht persistiert wurde."},"kostenartSchluessel":{"type":"string","description":"Schlüssel der Kostenart des tragenden K-Satzes."},"kostenbezeichnung":{"type":"string"},"emissionsart":{"type":["string","null"],"description":"01 = kg/kWh, 02 = t/MWh, 03 = kg gesamt; null, wenn die Datei nichts ausweist."},"emission":{"type":["string","null"],"description":"CO2-Emission als Ziffern-String mit (6,3) impliziten Stellen."},"menge":{"type":["string","null"],"description":"CO2-Emissionsmenge in kg als Ziffern-String mit (6,3) impliziten Stellen (ab Standard 3.10)."},"kostenBruttoCents":{"type":["string","null"],"description":"CO2-Kosten brutto in ganzen Cents als ZIFFERN-STRING (nie eine JSON-Zahl)."},"kostenNettoCents":{"type":["string","null"],"description":"CO2-Kosten netto in ganzen Cents als ZIFFERN-STRING (nie eine JSON-Zahl)."},"energiemix":{"type":"array","items":{"$ref":"#/components/schemas/MessdienstCo2Energiemix"}}},"required":["id","kostenartSchluessel","kostenbezeichnung","emissionsart","emission","menge","kostenBruttoCents","kostenNettoCents","energiemix"]},"MessdienstImportResponse":{"type":"object","properties":{"importBatchId":{"type":"string","format":"uuid","description":"Kennung DIESES Batches — append-only, jeder Aufruf legt einen neuen an (Korrektur = Re-Import, K5)."},"propertyId":{"type":"string","format":"uuid"},"allocationKeyId":{"type":"string","format":"uuid","description":"Der befüllte Umlageschlüssel; er MUSS vom Typ „extern\" sein."},"period":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"],"description":"Die GESPEICHERTE Abrechnungsperiode (beide Grenzen einschließlich) — gegen die eigene Abrechnungsperiode halten."},"rowCount":{"type":"integer"},"unmatchedCount":{"type":"integer","description":"Zeilen ohne aufgelösten Vertrag/Einheit (bewusst unaufgelöst, kein Fehler)."},"emissionCount":{"type":"integer","description":"Anzahl GESPEICHERTER CO2-Ausweis-Zeilen (#1602) — nicht Teil von rowCount: ein Ausweis ist kein Festbetrag eines Mieters."},"rows":{"type":"array","items":{"$ref":"#/components/schemas/MessdienstImportZeile"}},"co2":{"type":"array","items":{"$ref":"#/components/schemas/MessdienstCo2Position"},"description":"Die CO2-Angaben, die die ARGE-Datei AUSGEWIESEN hat (W1 übernimmt den Messdienst-Ausweis, keine Eigenberechnung). Seit #1602 werden sie GESPEICHERT; je Position steht die id der gespeicherten Zeile dabei. Beim CSV-Import immer leer."}},"required":["importBatchId","propertyId","allocationKeyId","period","rowCount","unmatchedCount","emissionCount","rows","co2"]},"VertragTermPayment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"componentId":{"type":"string","format":"uuid"},"componentName":{"type":["string","null"],"description":"Name der Komponente (LEFT JOIN); null, wenn die Kette reißt"},"amountCents":{"type":["string","null"],"description":"Betrag in Cents als Ziffern-String (GG3: nie Float/number)"},"currency":{"type":["string","null"]}},"required":["id","componentId","componentName","amountCents","currency"]},"VertragTerm":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kaltmieteCents":{"type":["string","null"],"description":"Kaltmiete in Cents als Ziffern-String (GG3)"},"currency":{"type":["string","null"]},"ustOption":{"type":["boolean","null"]},"ustRate":{"type":["string","null"],"description":"USt-Satz der Scheibe in Prozent, Spaltenform mit zwei Nachkommastellen (z. B. `19.00`); null ohne USt-Option (#5988)"},"dueRule":{"type":["string","null"],"enum":["monatserster","monatsdritter-werktag","quartalsbeginn","fester-tag",null],"description":"Fälligkeitsregel (geschlossenes Vokabular): monatserster = fällig am 1. des Monats, monatsdritter-werktag = 3. Werktag (§ 556b BGB, braucht das Bundesland des Objekts), quartalsbeginn = 1. Tag des Quartals, fester-tag = am Tag dueDay des Monats (in kürzeren Monaten der Monatsletzte; braucht dueDay)."},"dueDay":{"type":["integer","null"],"minimum":1,"maximum":31,"description":"Fälligkeitstag 1–31 der Regel fester-tag; null bei jeder anderen Regel"},"paymentMethod":{"type":["string","null"]},"mahnsperre":{"type":["boolean","null"]},"validFrom":{"type":["string","null"],"format":"date","description":"inklusiv; null ⇒ unbegrenzt in die Vergangenheit"},"validTo":{"type":["string","null"],"format":"date","description":"EXKLUSIV; null ⇒ offen (laufend)"},"validRange":{"type":"string","description":"das rohe Postgres-daterange-Literal, z. B. `[2026-01-01,)`"},"archivedAt":{"type":["string","null"],"format":"date-time"},"payments":{"type":"array","items":{"$ref":"#/components/schemas/VertragTermPayment"}}},"required":["id","kaltmieteCents","currency","ustOption","ustRate","dueRule","dueDay","paymentMethod","mahnsperre","validFrom","validTo","validRange","archivedAt","payments"]},"Vertrag":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"propertyNo":{"type":["string","null"],"description":"Objektnummer des Elternobjekts (LEFT JOIN)"},"contractNo":{"type":"string","description":"Ordnungsnummer ohne erzwungene Eindeutigkeit (s. #416); Identität ist id"},"startDate":{"type":["string","null"],"format":"date","description":"Beginn (inklusiv); null ⇒ unbegrenzt in die Vergangenheit"},"endDate":{"type":["string","null"],"format":"date","description":"Ende (exklusiv); null ⇒ laufend"},"endReason":{"type":["string","null"]},"depositCents":{"type":["string","null"],"description":"Kaution in Cents als Ziffern-String (dokumentarisch in 1.0, GG3)"},"depositCurrency":{"type":["string","null"]},"archivedAt":{"type":["string","null"],"format":"date-time","description":"ANDERE Achse als endDate (K5)"},"createdAt":{"type":"string","format":"date-time"},"terms":{"type":"array","items":{"$ref":"#/components/schemas/VertragTerm"},"description":"nur im Detail (GET /{id}) gefüllt; in der Liste leer"}},"required":["id","propertyId","propertyNo","contractNo","startDate","endDate","endReason","depositCents","depositCurrency","archivedAt","createdAt","terms"]},"VertragListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","aktiv","beendet"],"description":"der wirksame 3-Wege-GÜLTIGKEITS-Filter (gemessen an end_date). ACHTUNG: aktiv ∪ beendet ≠ alle."},"asOf":{"type":"string","format":"date","description":"der wirksame Stichtag, gegen den aktiv/beendet gemessen wurde"},"vertraege":{"type":"array","items":{"$ref":"#/components/schemas/Vertrag"}}},"required":["status","asOf","vertraege"]},"VertragCreatePayment":{"type":"object","properties":{"componentId":{"type":"string","format":"uuid","description":"muss existieren und aktiv sein (Prüfung im Tool-Layer)"},"amountCents":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"Betrag in Cents, GANZZAHLIG (kein Float): ganze Zahl ODER Ziffern-String"},"currency":{"type":"string"}},"required":["componentId","amountCents","currency"]},"VertragCreateRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid","description":"das Objekt; MUSS aktiv sein (sonst 404)"},"contractNo":{"type":"string"},"startDate":{"type":"string","format":"date","description":"Vertragsbeginn = untere Grenze der initialen Zeitscheibe; ohne Angabe unbegrenzt"},"mieterPersonId":{"type":"string","format":"uuid","description":"die MIETPARTEI des Vertrags — PFLICHT seit #1965 (wortgleich zu MieterwechselRequest, dieselbe Fachregel). Muss eine aktive Person dieses Mandanten sein (unbekannt, mandantenfremd oder archiviert ⇒ 404, ununterscheidbar). Die party_roles-Zeile entsteht in DERSELBEN Transaktion wie der Vertrag."},"kaltmieteCents":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"Kaltmiete in Cents, GANZZAHLIG (GG3/K4)"},"currency":{"type":"string"},"ustOption":{"type":"boolean"},"ustRate":{"type":"integer","minimum":1,"maximum":99,"description":"USt-Satz in ganzen Prozent, nur bei ustOption true; ohne Angabe bei Option 19. Angeboten wird heute nur 19 (#5988)."},"dueRule":{"type":"string","enum":["monatserster","monatsdritter-werktag","quartalsbeginn","fester-tag"],"description":"Fälligkeitsregel (geschlossenes Vokabular): monatserster = fällig am 1. des Monats, monatsdritter-werktag = 3. Werktag (§ 556b BGB, braucht das Bundesland des Objekts), quartalsbeginn = 1. Tag des Quartals, fester-tag = am Tag dueDay des Monats (in kürzeren Monaten der Monatsletzte; braucht dueDay)."},"dueDay":{"type":"integer","minimum":1,"maximum":31,"description":"Fälligkeitstag 1–31 der Regel fester-tag (in kürzeren Monaten der Monatsletzte). Gesetzt GENAU bei dueRule = fester-tag — fester-tag ohne Tag und ein Tag an einer anderen Regel werden abgewiesen."},"paymentMethod":{"type":"string"},"mahnsperre":{"type":"boolean"},"depositCents":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"vereinbarte Kaution in Cents; depositCurrency dann Pflicht. Ohne Kautionsabrede dokumentarisch (nie sollgestellt)"},"depositCurrency":{"type":"string"},"kautionAnlageform":{"type":"string","enum":["barkaution","buergschaft","verpfaendung"],"description":"Kautionsabrede (#5178): Anlageform der Sicherheit; setzt depositCents voraus"},"kautionRaten":{"type":"integer","minimum":1,"maximum":3,"description":"Raten nach § 551 Abs. 2 BGB (1…3) — Pflicht bei barkaution, sonst verboten (400)"},"kautionAnlagekontoId":{"type":"string","format":"uuid","description":"getrennte Anlage: Bankverbindung der Kontoart kautionskonto am Objekt (nur barkaution; unbekannt/fremd ⇒ 404)"},"payments":{"type":"array","items":{"$ref":"#/components/schemas/VertragCreatePayment"}},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["propertyId","contractNo","mieterPersonId","kaltmieteCents","currency"],"description":"Legt ein Mietverhältnis samt initialer Konditionen-Zeitscheibe (Kaltmiete) + optionalen Zahlungen an. Objekt muss aktiv sein."},"VertragEndRequest":{"type":"object","properties":{"endDate":{"type":"string","format":"date","description":"Tag, ab dem der Vertrag NICHT mehr gilt (exklusive obere Grenze der Zeitscheiben)"},"endReason":{"type":["string","null"],"description":"Grund der Beendigung (optional)"}},"required":["endDate"]},"VertragEndResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endDate":{"type":"string","format":"date"},"endReason":{"type":["string","null"]},"closedTermIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"die IDs der durch diesen Aufruf geschlossenen Konditionen-Zeitscheiben"},"alreadyEnded":{"type":"boolean","description":"true ⇒ der Vertrag war bereits beendet; `endDate` = URSPRÜNGLICHES Ende."}},"required":["id","endDate","endReason","closedTermIds","alreadyEnded"]},"VertragZahlungChangePayment":{"type":"object","properties":{"componentId":{"type":"string","format":"uuid","description":"muss existieren und aktiv sein (Prüfung im Tool-Layer)"},"amountCents":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"Betrag in Cents, GANZZAHLIG (kein Float): ganze Zahl ODER Ziffern-String"},"currency":{"type":"string"}},"required":["componentId","amountCents","currency"]},"VertragZahlungChangeRequest":{"type":"object","properties":{"ab":{"type":"string","format":"date","description":"Wirksamkeitstag: untere Grenze der neuen, exklusive obere Grenze der alten Scheibe"},"kaltmieteCents":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"neue Kaltmiete in Cents, GANZZAHLIG (GG3/K4)"},"currency":{"type":"string"},"ustOption":{"type":"boolean"},"ustRate":{"type":"integer","minimum":1,"maximum":99,"description":"USt-Satz in ganzen Prozent, nur bei ustOption true; ohne Angabe bei Option 19. Angeboten wird heute nur 19 (#5988)."},"dueRule":{"type":"string","enum":["monatserster","monatsdritter-werktag","quartalsbeginn","fester-tag"],"description":"Fälligkeitsregel (geschlossenes Vokabular): monatserster = fällig am 1. des Monats, monatsdritter-werktag = 3. Werktag (§ 556b BGB, braucht das Bundesland des Objekts), quartalsbeginn = 1. Tag des Quartals, fester-tag = am Tag dueDay des Monats (in kürzeren Monaten der Monatsletzte; braucht dueDay)."},"dueDay":{"type":"integer","minimum":1,"maximum":31,"description":"Fälligkeitstag 1–31 der Regel fester-tag (in kürzeren Monaten der Monatsletzte). Gesetzt GENAU bei dueRule = fester-tag — fester-tag ohne Tag und ein Tag an einer anderen Regel werden abgewiesen."},"paymentMethod":{"type":"string"},"mahnsperre":{"type":"boolean"},"payments":{"type":"array","items":{"$ref":"#/components/schemas/VertragZahlungChangePayment"}},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["ab","kaltmieteCents","currency"],"description":"Konditionswechsel als Zeitscheibe (SCD-2). `ab` MUSS echt nach dem Beginn der offenen Scheibe liegen (sonst 400)."},"VertragZahlungChangeResultPayment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"componentId":{"type":"string","format":"uuid"},"amountCents":{"type":"string","description":"Betrag in Cents als Ziffern-String (GG3: nie Float/number/bigint)"},"currency":{"type":"string"}},"required":["id","componentId","amountCents","currency"]},"VertragZahlungChangeResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"der gewechselte Vertrag"},"ab":{"type":"string","format":"date"},"closedTermId":{"type":"string","format":"uuid","description":"die alte, nun auf `ab` geschlossene Scheibe"},"closedValidRange":{"type":"string","description":"daterange der geschlossenen Scheibe"},"newTermId":{"type":"string","format":"uuid","description":"die neu geöffnete Scheibe"},"newValidRange":{"type":"string","description":"daterange der neuen (offenen) Scheibe"},"kaltmieteCents":{"type":"string","description":"neue Kaltmiete in Cents als Ziffern-String (nie bigint an der Grenze, GG3)"},"currency":{"type":"string"},"payments":{"type":"array","items":{"$ref":"#/components/schemas/VertragZahlungChangeResultPayment"},"description":"die vereinbarten Zahlungen der neuen Scheibe"}},"required":["id","ab","closedTermId","closedValidRange","newTermId","newValidRange","kaltmieteCents","currency","payments"]},"VertragPersonen":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"personCount":{"type":"integer","description":"Kopfzahl der Bewohner (Kinder wie Erwachsene), ganzzahlig ≥ 0. 0 = erfasster Leerstand."},"validFrom":{"type":["string","null"],"format":"date","description":"Beginn INKLUSIV; null ⇒ unbegrenzt in die Vergangenheit."},"validTo":{"type":["string","null"],"format":"date","description":"Ende EXKLUSIV (rohe daterange-Grenze); null ⇒ laufend."},"validRange":{"type":"string","description":"Rohes daterange-Literal, z. B. [2025-01-01,)."},"active":{"type":"boolean","description":"Ist die Scheibe am Stichtag (asOf) wirksam (valid_range @> asOf)?"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","contractId","personCount","validFrom","validTo","validRange","active","createdAt"]},"VertragPersonenListResponse":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"asOf":{"type":"string","format":"date","description":"der wirksame Stichtag, gegen den `active` je Scheibe gemessen wurde"},"personen":{"type":"array","items":{"$ref":"#/components/schemas/VertragPersonen"}}},"required":["contractId","asOf","personen"]},"VertragPersonenSetRequest":{"type":"object","properties":{"personCount":{"type":"integer","description":"Kopfzahl, ganzzahlig ≥ 0 (0 ist eine ERFASSTE Aussage, nicht „unbekannt\")"},"validFrom":{"type":"string","format":"date","description":"erster Tag, an dem die Kopfzahl gilt (EINSCHLIESSLICH) — das „ab\" der Änderung"},"validTo":{"type":"string","format":"date","description":"letzter Tag, an dem sie gilt (EINSCHLIESSLICH); ohne Angabe laufend"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["personCount","validFrom"],"description":"Setzt/ändert eine Kopfzahl-Zeitscheibe „ab validFrom\" (SCD-2: eine offene Vorgänger-Scheibe wird abgeschlossen). Beide Grenzen sind EINSCHLIESSLICH; Überschneidungen ⇒ 400."},"VertragPersonenSetResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"personCount":{"type":"integer"},"validFrom":{"type":"string","format":"date","description":"erster Gültigkeitstag (EINSCHLIESSLICH)"},"validTo":{"type":["string","null"],"format":"date","description":"letzter Gültigkeitstag (EINSCHLIESSLICH) oder null (laufend)"},"supersededPriorSlice":{"type":"boolean","description":"true ⇒ eine zuvor offene Scheibe wurde an validFrom abgeschlossen (SCD-2)."}},"required":["id","contractId","personCount","validFrom","validTo","supersededPriorSlice"]},"VertragPersonenRemoveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Id der entfernten (stillgelegten, K5) Scheibe"},"contractId":{"type":"string","format":"uuid"},"predecessorId":{"type":"string","format":"uuid","description":"Id der Vorgänger-Scheibe, die die Lücke wieder deckt"},"predecessorValidTo":{"type":["string","null"],"format":"date","description":"letzter Gültigkeitstag der Vorgängerin nach dem Entfernen (EINSCHLIESSLICH) oder null (wieder laufend — die entfernte Scheibe war die letzte)"}},"required":["id","contractId","predecessorId","predecessorValidTo"]},"VertragKuendigungsVorschlag":{"type":"object","properties":{"vertragsende":{"type":"string","format":"date","description":"errechnetes Vertragsende nach § 573c BGB — LETZTER Tag (einschliesslich), immer ein Monatsletzter"},"fristMonate":{"type":"integer","description":"angewandte Frist in Monaten (Mieter 3; Vermieter 3/6/9 nach 0/5/8 Jahren Überlassung)"},"karenzGewahrt":{"type":"boolean","description":"true ⇒ Zugang spätestens am dritten Werktag des Monats (Samstag zählt mit, BGH VIII ZR 206/04; fällt der dritte Werktag auf einen Samstag, endet die Karenz am nächsten Werktag, § 193 BGB; Sonn- und Landesfeiertage zählen nicht)"}},"required":["vertragsende","fristMonate","karenzGewahrt"]},"VertragKuendigenVorschlag":{"type":"object","properties":{"vertragsende":{"type":["string","null"],"format":"date","description":"errechnetes Vertragsende nach § 573c BGB — LETZTER Tag (einschliesslich), immer ein Monatsletzter; null ⇒ nicht berechnet (nur im No-op eines anders beendeten Vertrags ohne § 573c-Stammdaten)"},"fristMonate":{"type":["integer","null"],"description":"angewandte Frist in Monaten (Mieter 3; Vermieter 3/6/9 nach 0/5/8 Jahren Überlassung); null ⇒ nicht berechnet"},"karenzGewahrt":{"type":["boolean","null"],"description":"true ⇒ Zugang spätestens am dritten Werktag des Monats (Samstag zählt mit, BGH VIII ZR 206/04; fällt der dritte Werktag auf einen Samstag, endet die Karenz am nächsten Werktag, § 193 BGB; Sonn- und Landesfeiertage zählen nicht); null ⇒ nicht berechnet"}},"required":["vertragsende","fristMonate","karenzGewahrt"]},"VertragKuendigungErfasst":{"type":"object","properties":{"zugang":{"type":"string","format":"date","description":"Tag des Zugangs der Kündigung"},"kuendigender":{"type":"string","enum":["mieter","vermieter"],"description":"Wer kündigt (mieter | vermieter)."},"vorgeschlagenesEnde":{"type":"string","format":"date","description":"der bei der Erfassung errechnete Vorschlag (letzter Tag, einschliesslich)"},"vertragsende":{"type":"string","format":"date","description":"das WIRKSAME Vertragsende (letzter Tag, einschliesslich)"},"abweichendVereinbart":{"type":"boolean","description":"true ⇒ das wirksame Ende weicht vom Vorschlag ab („abweichend vereinbart\", z. B. Aufhebungsvertrag)"}},"required":["zugang","kuendigender","vorgeschlagenesEnde","vertragsende","abweichendVereinbart"]},"VertragKuendigungResponse":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"vorschlag":{"allOf":[{"$ref":"#/components/schemas/VertragKuendigungsVorschlag"},{"type":["object","null"],"description":"Vorschlag für die angefragte Kündigung (Query zugang + kuendigender); null, wenn nicht angefragt"}]},"kuendigung":{"allOf":[{"$ref":"#/components/schemas/VertragKuendigungErfasst"},{"type":["object","null"],"description":"die bereits erfasste Kündigung; null, wenn der Vertrag nicht über diesen Weg gekündigt ist"}]}},"required":["contractId","vorschlag","kuendigung"]},"VertragKuendigenRequest":{"type":"object","properties":{"zugang":{"type":"string","format":"date","description":"Tag des Zugangs der Kündigung"},"kuendigender":{"type":"string","enum":["mieter","vermieter"],"description":"Wer kündigt (mieter | vermieter)."},"vereinbartesEnde":{"type":"string","format":"date","description":"abweichend vereinbartes Vertragsende (LETZTER Tag, einschliesslich), z. B. aus einem Aufhebungsvertrag; fehlt es, gilt der Vorschlag"}},"required":["zugang","kuendigender"]},"VertragKuendigenResponse":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"zugang":{"type":"string","format":"date"},"kuendigender":{"type":"string","enum":["mieter","vermieter"],"description":"Wer kündigt (mieter | vermieter)."},"vorschlag":{"$ref":"#/components/schemas/VertragKuendigenVorschlag"},"vertragsende":{"type":"string","format":"date","description":"das WIRKSAME Vertragsende (letzter Tag, einschliesslich)"},"endDate":{"type":"string","format":"date","description":"vertragsende + 1 Tag — das exklusive Ende am Vertrag (wie endDate bei /end)"},"abweichendVereinbart":{"type":"boolean","description":"true ⇒ vereinbartesEnde war gesetzt UND weicht vom Vorschlag ab"},"alreadyEnded":{"type":"boolean","description":"true ⇒ der Vertrag war bereits beendet; nichts geschrieben, vertragsende/endDate = BESTEHENDES Ende"}},"required":["contractId","zugang","kuendigender","vorschlag","vertragsende","endDate","abweichendVereinbart","alreadyEnded"]},"MieterwechselPayment":{"type":"object","properties":{"componentId":{"type":"string","format":"uuid","description":"muss existieren und aktiv sein (Prüfung im Tool-Layer)"},"amountCents":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"Betrag in Cents, GANZZAHLIG (kein Float): ganze Zahl ODER Ziffern-String"},"currency":{"type":"string"}},"required":["componentId","amountCents","currency"]},"MieterwechselRequest":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid","description":"die Einheit, auf der gewechselt wird; das Objekt folgt aus ihr (kein eigenes Feld)"},"altVertragId":{"type":"string","format":"uuid","description":"der noch LAUFENDE Altvertrag (bereits beendet ⇒ 409)"},"endDate":{"type":"string","format":"date","description":"erster Tag OHNE den Altmieter (EXKLUSIVE obere Grenze seiner Zeitscheiben). Kündigung zum 30.06. ⇒ 2026-07-01. Gleiche Bedeutung wie endDate in POST /api/vertrag/{id}/end."},"endReason":{"type":["string","null"],"description":"Grund der Beendigung (optional)"},"startDate":{"type":"string","format":"date","description":"erster Tag MIT dem Neumieter (INKLUSIVE untere Grenze). Ohne Angabe = endDate, also nahtlos. Kleiner als endDate ⇒ Überlappung (400). Größer ⇒ Leerstand, nur mit leerstandAkzeptiert."},"leerstandAkzeptiert":{"type":"boolean","description":"bestätigt einen GEWOLLTEN Leerstand zwischen Alt- und Neuvertrag (sonst 400)"},"contractNo":{"type":"string","description":"Vertragsnummer des Neuvertrags (Ordnungsnummer ohne erzwungene Eindeutigkeit, #416)"},"mieterPersonId":{"type":"string","format":"uuid","description":"die MIETPARTEI des Neuvertrags — PFLICHT seit #1910. Muss eine aktive Person dieses Mandanten sein (unbekannt, mandantenfremd oder archiviert ⇒ 404, ununterscheidbar). Die party_roles-Zeile entsteht in DERSELBEN Transaktion wie der Neuvertrag."},"kaltmieteCents":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"Kaltmiete des Neuvertrags in Cents, GANZZAHLIG (GG3/K4)"},"currency":{"type":"string"},"ustOption":{"type":"boolean"},"ustRate":{"type":"integer","minimum":1,"maximum":99,"description":"USt-Satz in ganzen Prozent, nur bei ustOption true; ohne Angabe bei Option 19. Angeboten wird heute nur 19 (#5988)."},"dueRule":{"type":"string","enum":["monatserster","monatsdritter-werktag","quartalsbeginn","fester-tag"],"description":"Fälligkeitsregel (geschlossenes Vokabular): monatserster = fällig am 1. des Monats, monatsdritter-werktag = 3. Werktag (§ 556b BGB, braucht das Bundesland des Objekts), quartalsbeginn = 1. Tag des Quartals, fester-tag = am Tag dueDay des Monats (in kürzeren Monaten der Monatsletzte; braucht dueDay)."},"dueDay":{"type":"integer","minimum":1,"maximum":31,"description":"Fälligkeitstag 1–31 der Regel fester-tag (in kürzeren Monaten der Monatsletzte). Gesetzt GENAU bei dueRule = fester-tag — fester-tag ohne Tag und ein Tag an einer anderen Regel werden abgewiesen."},"paymentMethod":{"type":"string"},"mahnsperre":{"type":"boolean"},"depositCents":{"anyOf":[{"type":"integer"},{"type":"string"}],"description":"Kaution in Cents (dokumentarisch); depositCurrency dann Pflicht"},"depositCurrency":{"type":"string"},"payments":{"type":"array","items":{"$ref":"#/components/schemas/MieterwechselPayment"}},"rentShare":{"type":"string","description":"Miet-Anteil der Einheit am Neuvertrag als Dezimal-STRING (kein number — numeric-Spalte)"},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["unitId","altVertragId","endDate","contractNo","mieterPersonId","kaltmieteCents","currency"],"description":"Mieterwechsel auf EINER Einheit als EIN Kommando: Altvertrag beenden, Neuvertrag anlegen, Konditions- und Belegungs-Zeitscheiben fortschreiben — alles in EINER Transaktion."},"MieterwechselAltVertrag":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"endDate":{"type":"string","format":"date","description":"erster Tag ohne den Altmieter (exklusive obere Grenze)"},"endReason":{"type":["string","null"]},"closedTermIds":{"type":"array","items":{"type":"string","format":"uuid"}},"closedUnitLinkId":{"type":["string","null"],"format":"uuid","description":"die geschlossene Belegungs-Zeitscheibe; null, wenn der Altvertrag auf dieser Einheit keine offene hatte"}},"required":["id","endDate","endReason","closedTermIds","closedUnitLinkId"]},"MieterwechselMietpartei":{"type":"object","properties":{"partyRoleId":{"type":"string","format":"uuid","description":"Id der party_roles-Zeile"},"personId":{"type":"string","format":"uuid","description":"die Person, die den Neuvertrag als Mietpartei trägt"},"role":{"type":"string","description":"immer \"mieter\" — ein Mieterwechsel erzeugt genau diese Rolle"},"validRange":{"type":"string","description":"daterange der Rolle, z. B. [2026-07-01,) — untere Grenze = Beginn des Neuvertrags"}},"required":["partyRoleId","personId","role","validRange"],"description":"die Mietpartei, die MIT dem Neuvertrag entstanden ist (#1910) — in derselben Transaktion geschrieben"},"MieterwechselNeuerVertrag":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"contractNo":{"type":"string"},"startDate":{"type":"string","format":"date","description":"erster Tag mit dem Neumieter (inklusive untere Grenze)"},"termId":{"type":"string","format":"uuid"},"kaltmieteCents":{"type":"string","description":"Kaltmiete in Cents als Ziffern-String (nie bigint/number an der Grenze, GG3)"},"currency":{"type":"string"},"termValidRange":{"type":"string","description":"daterange der initialen Konditions-Scheibe, z. B. [2026-07-01,)"},"unitLinkId":{"type":"string","format":"uuid"},"unitValidRange":{"type":"string","description":"daterange der neuen Belegung, z. B. [2026-07-01,)"},"payments":{"type":"array","items":{"$ref":"#/components/schemas/VertragZahlungChangeResultPayment"}},"mietpartei":{"$ref":"#/components/schemas/MieterwechselMietpartei"}},"required":["id","contractNo","startDate","termId","kaltmieteCents","currency","termValidRange","unitLinkId","unitValidRange","payments","mietpartei"]},"MieterwechselVacancy":{"type":"object","properties":{"days":{"type":"integer","description":"Tage ohne Belegung (0 ⇒ nahtlos)"},"akzeptiert":{"type":"boolean","description":"wurde eine Lücke ausdrücklich bestätigt? (false bei days = 0)"}},"required":["days","akzeptiert"],"description":"die Naht zwischen Alt und Neu"},"MieterwechselSepa":{"type":"object","properties":{"altMandateIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"noch gültige (pending/active) Mandate des Altvertrags"},"neuerVertragHatMandat":{"type":"boolean"},"hinweis":{"type":"string"}},"required":["altMandateIds","neuerVertragHatMandat","hinweis"],"description":"rein informativ — dieser Vorgang ändert KEINEN Mandatsstatus"},"MieterwechselResponse":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid","description":"das Objekt, das aus der Einheit folgt"},"altVertrag":{"$ref":"#/components/schemas/MieterwechselAltVertrag"},"neuerVertrag":{"$ref":"#/components/schemas/MieterwechselNeuerVertrag"},"vacancy":{"$ref":"#/components/schemas/MieterwechselVacancy"},"sepa":{"$ref":"#/components/schemas/MieterwechselSepa"}},"required":["unitId","propertyId","altVertrag","neuerVertrag","vacancy","sepa"]},"Mandat":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"contractId":{"type":["string","null"],"format":"uuid"},"contractNo":{"type":["string","null"],"description":"Vertragsnummer des zugehörigen Vertrags (LEFT JOIN)"},"personId":{"type":["string","null"],"format":"uuid"},"personName":{"type":["string","null"],"description":"Name des Zahlungspflichtigen (LEFT JOIN)"},"mandateRef":{"type":"string","description":"Mandatsreferenz (UMR), je Tenant eindeutig"},"glaeubigerId":{"type":["string","null"]},"mandateType":{"type":["string","null"],"enum":["core","b2b",null],"description":"core = Basis-Lastschrift, b2b = Firmen-Lastschrift"},"status":{"type":"string","enum":["pending","active","revoked","expired"]},"signedAt":{"type":["string","null"],"format":"date-time"},"lastUsedAt":{"type":["string","null"],"format":"date-time"},"restrictedToCategories":{"type":["array","null"],"items":{"type":"string"},"description":"Kategorie-Scope; null ⇒ kein Scope"},"archivedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","contractId","contractNo","personId","personName","mandateRef","glaeubigerId","mandateType","status","signedAt","lastUsedAt","restrictedToCategories","archivedAt","createdAt"]},"MandatListResponse":{"type":"object","properties":{"status":{"type":"string","enum":["alle","pending","active","revoked","expired"],"description":"der wirksame Status-Filter (alle ODER genau ein Status). Unbekannter Wert ⇒ 400."},"mandate":{"type":"array","items":{"$ref":"#/components/schemas/Mandat"}}},"required":["status","mandate"]},"MandatCreateRequest":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid","description":"der Vertrag; MUSS aktiv sein (sonst 404)"},"personId":{"type":["string","null"],"format":"uuid","description":"Zahlungspflichtiger (optional; wird geprüft, wenn gesetzt)"},"mandateRef":{"type":"string","description":"Mandatsreferenz (UMR), je Tenant eindeutig (Dublette ⇒ 400)"},"glaeubigerId":{"type":["string","null"]},"mandateType":{"type":["string","null"],"enum":["core","b2b",null]},"signedAt":{"type":["string","null"],"format":"date-time","description":"Unterzeichnungszeitpunkt (ISO 8601)"},"restrictedToCategories":{"type":["array","null"],"items":{"type":"string"}},"sourceSystem":{"type":["string","null"]},"sourceRef":{"type":["string","null"]}},"required":["contractId","mandateRef"],"description":"Legt ein SEPA-Mandat zu einem AKTIVEN Vertrag an (Status pending). Übergänge laufen über den Status-Endpunkt."},"MandatStatusRequest":{"type":"object","properties":{"status":{"type":"string","enum":["active","revoked","expired"],"description":"Ziel-Status. pending ist rein initial und kein gültiges Ziel. Ungültiger Übergang ⇒ 400."}},"required":["status"]},"MandatStatusResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","active","revoked","expired"],"description":"der jetzt wirksame Status"},"previousStatus":{"type":"string","enum":["pending","active","revoked","expired"],"description":"der Status vor diesem Aufruf"},"changed":{"type":"boolean","description":"true ⇒ dieser Aufruf hat den Status geändert (sonst No-op/Replay)."}},"required":["id","status","previousStatus","changed"]},"PosteingangVorschlag":{"type":"object","properties":{"documentId":{"type":"string","format":"uuid"},"proposalId":{"type":"string","format":"uuid"},"proposalVersion":{"type":"integer","description":"monoton steigende Version des Vorschlags (P12.6)"},"ampel":{"type":"string","enum":["gruen","gelb","rot"],"description":"P12.3-Ampel (Review-Aufwand) — die UI gruppiert hiernach"},"kreditorId":{"type":["string","null"]},"konto":{"type":["string","null"]},"betragCents":{"type":["string","null"],"description":"Brutto in Cents als Ziffern-String (GG3: nie Float/number)"},"betragCurrency":{"type":["string","null"]},"provenanceCounts":{"type":"object","additionalProperties":{"type":"integer"},"description":"Anzahl entscheidungsrelevanter Felder je Herkunft (origin), z. B. { regel: 1, struktur: 1, modell: 1 }"},"createdAt":{"type":"string","format":"date-time"}},"required":["documentId","proposalId","proposalVersion","ampel","kreditorId","konto","betragCents","betragCurrency","provenanceCounts","createdAt"]},"PosteingangListResponse":{"type":"object","properties":{"vorschlaege":{"type":"array","items":{"$ref":"#/components/schemas/PosteingangVorschlag"}}},"required":["vorschlaege"]},"AusnahmeDocument":{"type":"object","properties":{"subject":{"type":["string","null"]},"sender":{"type":["string","null"]},"source":{"type":"string","description":"Eingangskanal des Belegs (mail | upload) — stabiler Code"},"filename":{"type":["string","null"]}},"required":["subject","sender","source","filename"]},"Ausnahme":{"type":"object","properties":{"exceptionId":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid"},"exceptionClass":{"type":"string","description":"Ausnahmeklasse (9 Fachklassen + unroutable) — stabiler Code"},"reason":{"type":"string","description":"maschinenlesbarer Grund-Code (nie freier Text)"},"createdAt":{"type":"string","format":"date-time"},"document":{"allOf":[{"$ref":"#/components/schemas/AusnahmeDocument"},{"type":["object","null"],"description":"Dokument-Metadaten (Betreff/Absender/Kanal/Dateiname); null, wenn der Beleg im Scope nicht sichtbar ist"}]},"history":{"type":"object","properties":{"resolvedCount":{"type":"integer"},"lastResolvedAt":{"type":["string","null"],"format":"date-time"},"lastResolvedClass":{"type":["string","null"]}},"required":["resolvedCount","lastResolvedAt","lastResolvedClass"],"description":"Lebenszyklus-Historie desselben Belegs: bereits erledigte Ausnahmen (Count + letzte)"}},"required":["exceptionId","documentId","exceptionClass","reason","createdAt","document","history"]},"AusnahmenListResponse":{"type":"object","properties":{"ausnahmen":{"type":"array","items":{"$ref":"#/components/schemas/Ausnahme"}}},"required":["ausnahmen"]},"BankZugangCreateRequest":{"type":"object","properties":{"bezeichnung":{"type":"string","maxLength":120,"description":"frei vergebene Bezeichnung; leer ⇒ „Bitte eine Bezeichnung erfassen.\""},"bank":{"type":"string","maxLength":200,"description":"Name der kontoführenden Bank; leer ⇒ „Bitte die Bank erfassen.\""},"iban":{"type":"string","description":"IBAN — wird normalisiert und geprüft (alle SEPA-Länder, mod-97); ungültig ⇒ 400. Schon verbunden ⇒ „Diese IBAN ist bereits als Bankkonto verbunden.\""},"anbindung":{"type":"string","enum":["api","datei"],"description":"`api` (Bankanbindung) oder `datei` (Kontoauszug-Import)"},"objektIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Objekte des Zugangs — je Objekt entsteht ein Objektkonto derselben IBAN. Weglassen ⇒ Zugang ohne Objekt."}},"required":["bezeichnung","bank","iban","anbindung"]},"BankZugangCreateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"der angelegte Zugang (bank_zugaenge.id)"},"status":{"type":"string","enum":["wartet"],"description":"ein neuer Zugang wartet immer auf Bestätigung"},"objektkonten":{"type":"array","items":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid","description":"das Objekt (properties.id)"},"objektkontoId":{"type":"string","format":"uuid","description":"das Objektkonto dieses Zugangs am Objekt (bank_accounts.id)"}},"required":["objektId","objektkontoId"]},"description":"die Objektkonten in der Reihenfolge von `objektIds`"}},"required":["id","status","objektkonten"]},"BankZugangUpdateRequest":{"type":"object","properties":{"bezeichnung":{"type":"string","maxLength":120},"bank":{"type":"string","maxLength":200},"iban":{"type":"string","description":"wird normalisiert und geprüft. Ein Wechsel schreibt die neue IBAN in alle Objektkonten und lässt die Bestätigung verfallen (Status `wartet`). Gehört sie einem anderen Zugang ⇒ „Diese IBAN gehört bereits zu einem anderen Bankkonto.\""},"bic":{"type":["string","null"],"maxLength":50,"description":"null oder leer ⇒ keine BIC; weglassen ⇒ unverändert"}},"required":["bezeichnung","bank","iban"],"description":"Das ganze Formular: Bezeichnung, Bank und IBAN immer, BIC optional."},"BankZugangUpdateResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"ibanGeaendert":{"type":"boolean","description":"true ⇒ die IBAN hat gewechselt; der Zugang wartet wieder auf Bestätigung"}},"required":["id","ibanGeaendert"]},"BankZugangObjekteRequest":{"type":"object","properties":{"objektIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"die ZIELMENGE der Objekte. Hinzugefügt ⇒ neues Objektkonto (der Zugang wartet wieder); entfernt ⇒ Objektkonto archiviert — nur wenn unbenutzt, sonst „Objekt {Nr} verwendet dieses Konto noch ({Gründe}).\""}},"required":["objektIds"]},"BankZugangObjekteResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"hinzugefuegt":{"type":"array","items":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid","description":"das Objekt (properties.id)"},"objektkontoId":{"type":"string","format":"uuid","description":"das Objektkonto dieses Zugangs am Objekt (bank_accounts.id)"}},"required":["objektId","objektkontoId"]},"description":"neu angelegte Objektkonten"},"entfernt":{"type":"array","items":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid","description":"das Objekt (properties.id)"},"objektkontoId":{"type":"string","format":"uuid","description":"das Objektkonto dieses Zugangs am Objekt (bank_accounts.id)"}},"required":["objektId","objektkontoId"]},"description":"archivierte Objektkonten (keine Zeile wird gelöscht)"}},"required":["id","hinzugefuegt","entfernt"]},"BankZugangArchiveResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":"string","format":"date-time","description":"Zeitpunkt der Archivierung (UI „Löschen\" — keine Zeile wird physisch gelöscht)"},"objektkonten":{"type":"array","items":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid","description":"das Objekt (properties.id)"},"objektkontoId":{"type":"string","format":"uuid","description":"das Objektkonto dieses Zugangs am Objekt (bank_accounts.id)"}},"required":["objektId","objektkontoId"]},"description":"die mitarchivierten Objektkonten"}},"required":["id","archivedAt","objektkonten"]},"BankZugangHauptkontoRequest":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid","description":"das Objekt, dessen Hauptkonto das Objektkonto dieses Zugangs wird; ohne Objektkonto dort ⇒ „Dieses Bankkonto ist nicht mit dem Objekt verknüpft.\""}},"required":["objektId"]},"BankZugangConfirmRequest":{"type":"object","properties":{"gesehenIban":{"type":"string","description":"die IBAN, die die bestätigende Person gesehen hat (beliebige Schreibweise, kanonisch verglichen). Weicht sie vom aktuellen Stand ab ⇒ abgewiesen."},"gesehenObjektIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"die Objekte, die die bestätigende Person gesehen hat — als MENGE verglichen. Weicht sie vom aktuellen Stand ab ⇒ abgewiesen."}},"required":["gesehenIban","gesehenObjektIds"],"description":"Vier-Augen-Bestätigung: verlangt das Recht `bankverbindung.bestaetigen`. Wer den Stand erfasst hat (Anlage, IBAN-Wechsel, Objekt hinzugefügt), bestätigt ihn bei aktivem Vier-Augen-Prinzip und mindestens zwei Berechtigten nicht selbst."},"BankZugangConfirmResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"der bestätigte Zugang (bank_zugaenge.id)"},"bestaetigtVon":{"type":"string","description":"Kennung der bestätigenden Person (der Aufrufer)"},"bestaetigtAm":{"type":"string","format":"date-time","description":"Zeitpunkt der Bestätigung"},"ohneVierAugen":{"type":"boolean","description":"true ⇒ die erfassende Person hat selbst bestätigt (Schalter aus oder höchstens eine berechtigte Person) — Audit-Spur"}},"required":["id","bestaetigtVon","bestaetigtAm","ohneVierAugen"]},"BankZugangDisconnectResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"getrenntAm":{"type":"string","format":"date-time","description":"Zeitpunkt der Trennung; die Bestätigung gilt damit nicht mehr"},"bankfreigabeGetrennt":{"type":"boolean","description":"true ⇒ in derselben Aktion wurde eine verknüpfte Bankfreigabe getrennt (Anbindung `api`)"}},"required":["id","getrenntAm","bankfreigabeGetrennt"]},"BankZugangRecheckResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"zuletztGeprueftAm":{"type":"string","format":"date-time","description":"Zeitpunkt der Prüfung; der Zugang wartet danach auf eine neue Bestätigung"}},"required":["id","zuletztGeprueftAm"]},"Bankzugang":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"connectionId":{"type":"string","format":"uuid","description":"BANKSapi-Verbindung, unter der der Zugang hängt (tenant-intern)"},"bankAccountId":{"type":["string","null"],"format":"uuid","description":"zugeordnete Bankverbindung (Stammdatum); null, solange keine zugeordnet ist"},"providerBankId":{"type":["string","null"],"description":"Bank-Kennung beim Anbieter; null, solange der Anbieter keine geliefert hat"},"accessKind":{"type":"string","enum":["xs2a","ebics"],"description":"Zugangsweg"},"status":{"type":"string","enum":["ausstehend","aktiv","wartet_auf_bank","fehler","getrennt"],"description":"Lebenszyklus-Status des Zugangs"},"consentValidUntil":{"type":["string","null"],"format":"date-time","description":"Ablauf der Einwilligung; null, solange keine vorliegt"},"scaRequired":{"type":"boolean","description":"true ⇒ der Zugang wartet auf eine starke Kundenauthentifizierung"},"lastSyncAt":{"type":["string","null"],"format":"date-time","description":"letzter Status-Nachzug beim Anbieter; null bis zum ersten"},"lastIssueCodes":{"type":"array","items":{"type":"string"},"description":"letzte Anbieter-Meldungscodes (z. B. BA1011, USER_CANCELLED); leer ⇒ keine"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","connectionId","bankAccountId","providerBankId","accessKind","status","consentValidUntil","scaRequired","lastSyncAt","lastIssueCodes","createdAt"]},"BankzugangListResponse":{"type":"object","properties":{"bankzugaenge":{"type":"array","items":{"$ref":"#/components/schemas/Bankzugang"}}},"required":["bankzugaenge"]},"Option":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scopeType":{"type":"string","enum":["tenant","objekt","einheit","vertrag"],"description":"Scope-Ebene (Spezifitäts-Leiter)"},"scopeId":{"type":["string","null"],"format":"uuid","description":"Ziel-UUID der Ebene; NULL beim tenant-globalen Default"},"key":{"type":"string"},"value":{"description":"beliebiges JSON (jsonb)"},"valueType":{"type":["string","null"],"description":"optionaler Typ-Hinweis (z. B. boolean/string)"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","scopeType","scopeId","key","valueType","createdAt"]},"OptionListResponse":{"type":"object","properties":{"filter":{"type":"object","properties":{"scopeType":{"type":["string","null"],"enum":["tenant","objekt","einheit","vertrag",null]},"scopeId":{"type":["string","null"],"format":"uuid"},"key":{"type":["string","null"]}},"required":["scopeType","scopeId","key"],"description":"der WIRKSAME Filter (die Antwort sagt, was sie zeigt)"},"options":{"type":"array","items":{"$ref":"#/components/schemas/Option"}}},"required":["filter","options"]},"OptionSetRequest":{"type":"object","properties":{"scopeType":{"type":"string","enum":["tenant","objekt","einheit","vertrag"]},"scopeId":{"type":["string","null"],"format":"uuid","description":"Pflicht für objekt/einheit/vertrag; beim tenant-Scope weglassen."},"key":{"type":"string"},"value":{"description":"beliebiges NICHT-NULL JSON. null UND fehlend ⇒ 400; false/0/\"\"/{}/[] sind erlaubt."},"valueType":{"type":["string","null"]}},"required":["scopeType","key"]},"OptionSetResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"scopeType":{"type":"string","enum":["tenant","objekt","einheit","vertrag"]},"scopeId":{"type":["string","null"],"format":"uuid"},"key":{"type":"string"},"value":{"description":"der wirksam gewordene Wert (beliebiges JSON)"},"valueType":{"type":["string","null"]},"created":{"type":"boolean","description":"true ⇒ neu angelegt; false ⇒ bestehender Wert überschrieben"}},"required":["id","scopeType","scopeId","key","valueType","created"]},"OptionResolveResponse":{"type":"object","properties":{"key":{"type":"string"},"found":{"type":"boolean","description":"false ⇒ auf keiner berücksichtigten Ebene gesetzt"},"value":{"description":"effektiver Wert (beliebiges JSON) oder null, wenn nicht gefunden"},"valueType":{"type":["string","null"]},"scopeType":{"type":["string","null"],"enum":["tenant","objekt","einheit","vertrag",null],"description":"der GEWINNENDE (spezifischste vorhandene) Scope; null ⇒ nicht gefunden"},"scopeId":{"type":["string","null"],"format":"uuid"}},"required":["key","found","valueType","scopeType","scopeId"]},"ErgebnisMoney":{"type":"object","properties":{"cents":{"type":"string","description":"Betrag in Cent als Dezimal-Integer-STRING (nie number, nie gerundet, nie mit Dezimalpunkt)."},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"]},"ErgebnisRecipient":{"oneOf":[{"type":"object","properties":{"art":{"type":"string","enum":["mieter"]},"contractId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"}},"required":["art","contractId","unitId"],"additionalProperties":false},{"type":"object","properties":{"art":{"type":"string","enum":["eigentuemer_leerstand"]},"unitId":{"type":"string","format":"uuid"}},"required":["art","unitId"],"additionalProperties":false}],"description":"Leerstand gehört dem EIGENTÜMER und wird EXPLIZIT ausgewiesen: ohne diese Unterscheidung wäre „Σ Mieteranteile ≠ Gesamtbetrag\" nicht erklärbar. Bei art = mieter ist contractId PFLICHT; bei art = eigentuemer_leerstand gibt es keinen."},"UmlageResultLine":{"type":"object","properties":{"costItemId":{"type":"string","format":"uuid"},"recipient":{"$ref":"#/components/schemas/ErgebnisRecipient"},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"netto":{"$ref":"#/components/schemas/ErgebnisMoney"},"ustRatePercent":{"type":["string","null"],"description":"USt-Satz in ganzen Prozent als Integer-STRING oder null (Wohnraum hat KEINEN Satz — das ist etwas anderes als 0 %)."},"ustAmount":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"brutto":{"$ref":"#/components/schemas/ErgebnisMoney"}},"required":["costItemId","recipient","from","to","netto","ustRatePercent","ustAmount","brutto"]},"UmlageResult":{"type":"object","properties":{"lines":{"type":"array","items":{"$ref":"#/components/schemas/UmlageResultLine"}},"totalUmlagefaehig":{"$ref":"#/components/schemas/ErgebnisMoney"},"totalVerteiltNetto":{"$ref":"#/components/schemas/ErgebnisMoney"},"skippedNichtUmlagefaehig":{"type":"array","items":{"type":"string"},"description":"ids der NICHT verteilten Positionen — ohne sie wäre „Σ verteilt < Σ gebucht\" nicht erklärbar."}},"required":["lines","totalUmlagefaehig","totalVerteiltNetto","skippedNichtUmlagefaehig"]},"ContractOffset":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"gewerblich":{"type":"boolean"},"ustRatePercent":{"type":["string","null"],"description":"Integer-STRING oder null (kein Gewerbe)."},"kostenNetto":{"$ref":"#/components/schemas/ErgebnisMoney"},"kostenUst":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"kostenBrutto":{"$ref":"#/components/schemas/ErgebnisMoney"},"sollVzBk":{"$ref":"#/components/schemas/ErgebnisMoney"},"sollVzHk":{"$ref":"#/components/schemas/ErgebnisMoney"},"sollVz":{"$ref":"#/components/schemas/ErgebnisMoney"},"sollVzBkNetto":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"sollVzHkNetto":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"sollVzNetto":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"istVzBk":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"],"description":"Geleistete BK-Vorauszahlung (brutto); null im Modus soll."}]},"istVzHk":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"],"description":"Geleistete HK-Vorauszahlung (brutto); null im Modus soll."}]},"istVz":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"],"description":"istVzBk + istVzHk; null im Modus soll."}]},"istVzBkNetto":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"istVzHkNetto":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"istVzNetto":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"offeneVz":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"],"description":"sollVz − istVz: > 0 offene, < 0 überzahlte Vorauszahlung. Die cent-genaue Erklärung der Modus-Differenz; null im Modus soll."}]},"saldo":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"description":"kostenBrutto − der VERWENDETEN VZ-Seite (soll: sollVz, ist: istVz); das VORZEICHEN bleibt erhalten (Guthaben ist negativ)."}]},"art":{"type":"string","enum":["nachforderung","guthaben","ausgeglichen"]}},"required":["contractId","gewerblich","ustRatePercent","kostenNetto","kostenUst","kostenBrutto","sollVzBk","sollVzHk","sollVz","sollVzBkNetto","sollVzHkNetto","sollVzNetto","istVzBk","istVzHk","istVz","istVzBkNetto","istVzHkNetto","istVzNetto","offeneVz","saldo","art"]},"VzGegenrechnungResult":{"type":"object","properties":{"vzModus":{"type":"string","enum":["soll","ist"],"description":"Gegen WELCHE Vorauszahlungen gerechnet wurde: soll = sollgestellt (Default), ist = geleistet. Der Modus ist eine Option DES LAUFS, kein globaler Zustand."},"vertraege":{"type":"array","items":{"$ref":"#/components/schemas/ContractOffset"}},"totalKostenBrutto":{"$ref":"#/components/schemas/ErgebnisMoney"},"totalSollVz":{"$ref":"#/components/schemas/ErgebnisMoney"},"totalIstVz":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"totalOffeneVz":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"type":["object","null"]}]},"totalNachforderung":{"$ref":"#/components/schemas/ErgebnisMoney"},"totalGuthaben":{"$ref":"#/components/schemas/ErgebnisMoney"},"istStichtag":{"type":["string","null"],"format":"date","description":"Bis zu welchem WERTSTELLUNGSDATUM eine Zahlung als geleistet gilt; null im Modus soll."}},"required":["vzModus","vertraege","totalKostenBrutto","totalSollVz","totalIstVz","totalOffeneVz","totalNachforderung","totalGuthaben","istStichtag"]},"AbrechnungErgebnisRun":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"unitGroupId":{"type":["string","null"],"format":"uuid"},"periodFrom":{"type":"string","format":"date"},"periodTo":{"type":"string","format":"date"},"status":{"type":"string","enum":["entwurf","berechnet"]},"bindingContentHash":{"type":"string","description":"Bindungs-Hash BEIDER Geld-Seiten des Laufs (INV-TIME-01, seit #1812): Umlage-Eingabe UND VZ-Seite (payment_components, contract_term_payments, im Ist-Modus zusätzlich die zugeordneten Zahlungen). Gleicher Hash belegt, dass zwei Lesungen dieselbe Eingabe hatten — auch die der gegenrechnung. EINZIGE Ausnahme: ein vor #1812 gebundener ALT-Lauf trägt keinen vz-Zweig im Snapshot; seine VZ-Seite wird weiterhin live gelesen und ist von diesem Hash nicht gedeckt."},"bindingBoundAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","unitGroupId","periodFrom","periodTo","status","bindingContentHash","bindingBoundAt"]},"AbrechnungErgebnisResponse":{"type":"object","properties":{"run":{"$ref":"#/components/schemas/AbrechnungErgebnisRun"},"rechenbar":{"type":"boolean","description":"ABGELEITET: umlage !== null && gegenrechnung !== null. Nie unabhängig gesetzt."},"umlage":{"allOf":[{"$ref":"#/components/schemas/UmlageResult"},{"type":["object","null"]}]},"umlageFehler":{"type":["string","null"],"description":"Klartext des fail-closed-Abbruchs oder null (kein leerer String)."},"gegenrechnung":{"allOf":[{"$ref":"#/components/schemas/VzGegenrechnungResult"},{"type":["object","null"],"description":"VZ-Gegenrechnung. SNAPSHOT-GEBUNDEN wie die Umlage-Seite (seit #1812): die VZ-Stammdaten (payment_components, contract_term_payments) stehen als eigener vz-Zweig im gebundenen Snapshot und gehen in den bindingContentHash ein. Eine nachträgliche Änderung an ihnen verschiebt die Zahlen DIESES Laufs nicht; zwei Messungen mit gleichem bindingContentHash hatten dieselbe VZ-Eingabe. EINZIGE Ausnahme: ein vor #1812 gebundener ALT-Lauf hat keinen vz-Zweig im Snapshot und wird weiterhin live hydratisiert — für ihn gilt die alte Einschränkung. Erkennbar ist das am fehlenden vz-Zweig des binding_snapshot, nicht an dieser Antwort."}]},"gegenrechnungFehler":{"type":["string","null"]},"readinessFindings":{"description":"Readiness-Befunde des Startzeitpunkts — der GRUND eines null-Ergebnisses, ohne einen zweiten Endpunkt zu fragen."}},"required":["run","rechenbar","umlage","umlageFehler","gegenrechnung","gegenrechnungFehler"]},"S35aBescheinigungKategorie":{"type":"object","properties":{"kategorie":{"type":"string","enum":["beschaeftigungsverhaeltnis","haushaltsnah","handwerker"]},"betrag":{"$ref":"#/components/schemas/ErgebnisMoney"}},"required":["kategorie","betrag"]},"S35aBescheinigung":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"contractNo":{"type":"string","description":"Vertragsnummer zur Anzeige."},"unitIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Einheiten des Vertrags im Lauf, aufsteigend, ohne Dubletten."},"zeitraum":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"],"description":"Nutzungszeitraum im Abrechnungszeitraum (beide Grenzen einschließlich)."},"kategorien":{"type":"array","items":{"$ref":"#/components/schemas/S35aBescheinigungKategorie"},"description":"Je Kategorie mit Betrag > 0 eine Zeile; Mehrfachbuchungen sind summiert."},"summe":{"$ref":"#/components/schemas/ErgebnisMoney"}},"required":["contractId","contractNo","unitIds","zeitraum","kategorien","summe"]},"S35aNichtBescheinigt":{"type":"object","properties":{"costItemId":{"type":"string","format":"uuid"},"kategorie":{"type":"string","enum":["beschaeftigungsverhaeltnis","haushaltsnah","handwerker"]},"betrag":{"$ref":"#/components/schemas/ErgebnisMoney"},"grund":{"type":"string","enum":["gesamtausweis","ohne_wohnraum_verteilbasis"]}},"required":["costItemId","kategorie","betrag","grund"]},"S35aBescheinigungenResponse":{"type":"object","properties":{"laufId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"period":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}},"required":["from","to"]},"bescheinigungen":{"type":"array","items":{"$ref":"#/components/schemas/S35aBescheinigung"}},"nichtBescheinigt":{"type":"array","items":{"$ref":"#/components/schemas/S35aNichtBescheinigt"}},"summeS35aKosten":{"$ref":"#/components/schemas/ErgebnisMoney"},"summeBescheinigungen":{"$ref":"#/components/schemas/ErgebnisMoney"},"summeNichtBescheinigt":{"$ref":"#/components/schemas/ErgebnisMoney"}},"required":["laufId","propertyId","period","bescheinigungen","nichtBescheinigt","summeS35aKosten","summeBescheinigungen","summeNichtBescheinigt"]},"AbrechnungStartResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["entwurf","berechnet"]},"propertyId":{"type":"string","format":"uuid"},"unitGroupId":{"type":["string","null"],"format":"uuid"},"periodFrom":{"type":"string","format":"date"},"periodTo":{"type":"string","format":"date"},"bindingContentHash":{"type":"string"},"bindingBoundAt":{"type":"string","format":"date-time"}},"required":["id","status","propertyId","unitGroupId","periodFrom","periodTo","bindingContentHash","bindingBoundAt"]},"AbrechnungBerechnetResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["entwurf","berechnet"]}},"required":["id","status"]},"OffenerPosten":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"journal_entries.id der Sollstellung — bei einer freien Zahlung die der Zahlung."},"quelle":{"type":"string","enum":["sollstellung","freie-zahlung"]},"propertyId":{"type":"string","format":"uuid"},"propertyNo":{"type":["string","null"],"description":"Objekt-Nummer zur Anzeige; null, falls nicht auflösbar."},"contractId":{"type":["string","null"],"format":"uuid","description":"Debitor-Dimension; null bei objektbezogenen Posten ohne Vertrag."},"forderungsart":{"type":"string","enum":["kosten","zinsen","hauptforderung"]},"geldkreis":{"type":"string","enum":["miete","weg_hausgeld","sev"]},"faelligAm":{"type":"string","format":"date"},"nominalbetragCents":{"type":"string","description":"WAS GESTELLT WURDE (signiert)."},"zugeordnetCents":{"type":"string","description":"Summe der wirksamen Zuordnungen, im Vorzeichen des Nominalbetrags."},"restbetragCents":{"type":"string","description":"WAS NOCH OFFEN IST (signiert) — nie mit nominalbetragCents verwechseln."},"currency":{"type":"string"},"status":{"type":"string","enum":["offen","teilweise","erledigt"]},"richtung":{"type":"string","enum":["forderung","guthaben","verbindlichkeit"]},"tageUeberfaellig":{"type":"integer","description":"Tage seit Fälligkeit am Stichtag; <= 0, solange nicht fällig."}},"required":["id","quelle","propertyId","propertyNo","contractId","forderungsart","geldkreis","faelligAm","nominalbetragCents","zugeordnetCents","restbetragCents","currency","status","richtung","tageUeberfaellig"]},"OffenePostenSummen":{"type":"object","properties":{"rueckstandCents":{"type":"string","description":"Σ Restbetrag der FORDERUNGEN, vorzeichenlos."},"guthabenCents":{"type":"string","description":"Σ |Restbetrag| der GUTHABEN, vorzeichenlos."},"verbindlichkeitenCents":{"type":["string","null"],"description":"Σ |Restbetrag| der VERBINDLICHKEITEN; null, wenn der Read sie nicht ausweist."},"saldoCents":{"type":"string","description":"rueckstand − guthaben, signiert — die EINZIGE gegenrechnende Zahl."},"nominalForderungenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"nominalGuthabenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"nominalVerbindlichkeitenCents":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"anzahlForderungen":{"type":"integer"},"anzahlGuthaben":{"type":"integer"},"anzahlVerbindlichkeiten":{"type":["integer","null"]}},"required":["rueckstandCents","guthabenCents","verbindlichkeitenCents","saldoCents","nominalForderungenCents","nominalGuthabenCents","nominalVerbindlichkeitenCents","currency","anzahlForderungen","anzahlGuthaben","anzahlVerbindlichkeiten"]},"OffenePostenListResponse":{"type":"object","properties":{"posten":{"type":"array","items":{"$ref":"#/components/schemas/OffenerPosten"}},"summen":{"$ref":"#/components/schemas/OffenePostenSummen"}},"required":["posten","summen"]},"SaldenlisteSumme":{"type":"object","properties":{"vortragCents":{"type":"string","description":"Σ der vorzeichenbehafteten Anfangsbestände."},"sollCents":{"type":"string","description":"Σ SOLL des Zeitraums (vorzeichenlos)."},"habenCents":{"type":"string","description":"Σ HABEN des Zeitraums (vorzeichenlos)."},"saldoCents":{"type":"string","description":"Σ der vorzeichenbehafteten Endsalden."},"currency":{"type":"string"}},"required":["vortragCents","sollCents","habenCents","saldoCents","currency"]},"SaldenlisteZeile":{"type":"object","properties":{"glAccountNo":{"type":"string","description":"Kontonummer am Objekt — nur JE OBJEKT eindeutig."},"name":{"type":"string"},"kontenklasse":{"type":"string","description":"Gruppierungsschlüssel (`gl_accounts.kontotyp`, ADR 0014)."},"vortragCents":{"type":"string","description":"ANFANGSBESTAND: Saldo aller Sätze VOR `von`."},"vortragSeite":{"type":"string","enum":["S","H"]},"sollCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"habenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"saldoCents":{"type":"string","description":"ENDSALDO = Vortrag + Soll − Haben."},"saldoSeite":{"type":"string","enum":["S","H"]},"currency":{"type":"string"},"bewegungen":{"type":"integer","description":"Buchungszeilen auf diesem Konto IM Zeitraum. 0 ⇒ keine Bewegung (und genau diese Zeilen entfernt `nurBewegt`)."}},"required":["glAccountNo","name","kontenklasse","vortragCents","vortragSeite","sollCents","habenCents","saldoCents","saldoSeite","currency","bewegungen"]},"SaldenlisteKlasse":{"type":"object","properties":{"kontenklasse":{"type":"string"},"bezeichnung":{"type":"string","description":"Überschrift der Klasse in der Liste."},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/SaldenlisteZeile"}},"summe":{"$ref":"#/components/schemas/SaldenlisteSumme"}},"required":["kontenklasse","bezeichnung","zeilen","summe"]},"SaldenlisteZeitraum":{"type":"object","properties":{"von":{"type":"string","format":"date"},"bis":{"type":"string","format":"date"}},"required":["von","bis"]},"AuswertungSpalte":{"type":"object","properties":{"schluessel":{"type":"string","description":"Stabiler Maschinenname der Spalte; die Überschrift darf sich ändern, dieser Name nicht."},"titel":{"type":"string","description":"Deutsche Überschrift — sie steht in der CSV-Kopfzeile."},"typ":{"type":"string","enum":["text","betrag","zahl","datum"],"description":"Wie die Zellen dieser Spalte zu lesen sind. `betrag` ⇒ vorzeichenbehafteter Integer-Cent-STRING."}},"required":["schluessel","titel","typ"]},"AuswertungQuelle":{"type":"object","properties":{"mandant":{"type":"string","format":"uuid","description":"Mandant, für den die Auswertung gilt — aus der Session, nie aus der Anfrage."},"objektId":{"type":["string","null"],"format":"uuid","description":"Objekt (Buchungskreis); `null` nur bei objektübergreifenden Auswertungen."},"objektNr":{"type":["string","null"],"description":"Objekt-Nummer zur Anzeige; `null`, falls nicht auflösbar."},"zeitraumVon":{"type":["string","null"],"format":"date"},"zeitraumBis":{"type":["string","null"],"format":"date"},"stichtag":{"type":["string","null"],"format":"date","description":"Stichtag, falls die Auswertung einen kennt (Verzugstage, Vermögensstand)."},"letzteBuchung":{"type":["string","null"],"format":"date","description":"Buchungsdatum der LETZTEN berücksichtigten Buchung; `null`, wenn im Fenster keine liegt."},"letzteBuchungNr":{"type":["string","null"],"description":"Lückenlose Buchungsnummer derselben Buchung (Integer-STRING) — macht den Datenstand nennbar und prüfbar."},"buchungen":{"type":"integer","description":"Zahl der berücksichtigten Buchungssätze."},"abgefragtAm":{"type":"string","format":"date-time","description":"Zeitpunkt des Abrufs. Sagt, WANN gefragt wurde — der Datenstand sagt, WORAUF."}},"required":["mandant","objektId","objektNr","zeitraumVon","zeitraumBis","stichtag","letzteBuchung","letzteBuchungNr","buchungen","abgefragtAm"]},"AuswertungResponse":{"type":"object","properties":{"name":{"type":"string","description":"Katalog-Name der Auswertung (Pfadsegment)."},"titel":{"type":"string"},"waehrung":{"type":"string","description":"Währung ALLER Betrags-Zellen (ISO-4217). Eine Tabelle, zwei Währungen gibt es nicht."},"quelle":{"$ref":"#/components/schemas/AuswertungQuelle"},"spalten":{"type":"array","items":{"$ref":"#/components/schemas/AuswertungSpalte"}},"zeilen":{"type":"array","items":{"type":"array","items":{"type":["string","null"]}},"description":"Zeilen in Spaltenordnung; jede Zelle ein String oder `null` (leere Zelle). Sorte laut `spalten[i].typ`."}},"required":["name","titel","waehrung","quelle","spalten","zeilen"]},"AuswertungKatalogEintrag":{"type":"object","properties":{"name":{"type":"string"},"titel":{"type":"string"},"beschreibung":{"type":"string","description":"Wozu der Bericht gut ist, in einem Satz."},"zeitbezug":{"type":"string","enum":["zeitraum","zeitraum-und-stichtag"],"description":"Welche Zeitachsen die Auswertung kennt — damit Bedienfläche und Agent die richtigen Felder anbieten."},"waehrung":{"type":"string"},"spalten":{"type":"array","items":{"$ref":"#/components/schemas/AuswertungSpalte"}}},"required":["name","titel","beschreibung","zeitbezug","waehrung","spalten"]},"AuswertungKatalogResponse":{"type":"object","properties":{"auswertungen":{"type":"array","items":{"$ref":"#/components/schemas/AuswertungKatalogEintrag"}}},"required":["auswertungen"]},"SaldenlisteResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"zeitraum":{"$ref":"#/components/schemas/SaldenlisteZeitraum"},"klassen":{"type":"array","items":{"$ref":"#/components/schemas/SaldenlisteKlasse"}},"summe":{"$ref":"#/components/schemas/SaldenlisteSumme"},"ausgeglichen":{"type":"boolean","description":"KONTROLLSUMME der Doppik: Σ Soll = Σ Haben. Wird AUSGEWIESEN statt erzwungen — eine Schieflage soll sichtbar sein, nicht die Antwort verhindern."},"nurBewegteKonten":{"type":"boolean"},"gefilterteKonten":{"type":"integer","description":"Zahl der wegen fehlender Bewegung NICHT ausgewiesenen Konten — damit die Liste sagen kann, was sie verschweigt."}},"required":["propertyId","zeitraum","klassen","summe","ausgeglichen","nurBewegteKonten","gefilterteKonten"]},"GeldkontoBewegung":{"type":"object","properties":{"entryId":{"type":"string","format":"uuid","description":"Der Buchungssatz, aus dem diese Bewegung kommt — der Provenienz-Anker der Zeile."},"entryNo":{"type":"string","description":"Lückenlose Buchungsnummer je Objekt als Integer-STRING (bigint in der DB)."},"lineNo":{"type":"integer","description":"1-basierte Position im Satz."},"buchungsdatum":{"type":"string","format":"date","description":"Die AUSWAHL-Achse: nur Sätze mit Buchungsdatum im Zeitraum sind Bewegungen."},"wertstellung":{"type":"string","format":"date","description":"Die ORDNUNGS-Achse: die Liste steht in aufsteigender Wertstellung (`accrual_date`)."},"belegnummer":{"type":["string","null"]},"zugangCents":{"type":"string","description":"SOLL auf dem Geldkonto, vorzeichenlos. Genau eines von zugang/abgang ist > 0."},"abgangCents":{"type":"string","description":"HABEN auf dem Geldkonto, vorzeichenlos."},"laufenderSaldoCents":{"type":"string","description":"Der Saldo NACH dieser Bewegung, signiert (Soll − Haben) und beim Anfangsbestand beginnend. Der LETZTE ist der Endbestand."},"gegenkonten":{"type":"array","items":{"type":"string"},"description":"Die übrigen Kontonummern des Satzes, ohne Dubletten — woher das Geld kam bzw. wohin es ging. Leer nur bei einer Umbuchung innerhalb desselben Geldkontos."}},"required":["entryId","entryNo","lineNo","buchungsdatum","wertstellung","belegnummer","zugangCents","abgangCents","laufenderSaldoCents","gegenkonten"]},"GeldkontoEntwicklung":{"type":"object","properties":{"glAccountNo":{"type":"string","description":"Kontonummer am Objekt — nur JE OBJEKT eindeutig."},"name":{"type":"string"},"anfangsbestandCents":{"type":"string","description":"Saldo aller Sätze VOR `von`, signiert."},"anfangsbestandSeite":{"type":"string","enum":["S","H"]},"zugaengeCents":{"type":"string","description":"Σ SOLL im Zeitraum (vorzeichenlos)."},"abgaengeCents":{"type":"string","description":"Σ HABEN im Zeitraum (vorzeichenlos)."},"endbestandCents":{"type":"string","description":"Saldo aller Sätze bis `bis`, signiert = Anfangsbestand + Zugänge − Abgänge."},"endbestandSeite":{"type":"string","enum":["S","H"]},"bewegungen":{"type":"array","items":{"$ref":"#/components/schemas/GeldkontoBewegung"}},"stimmt":{"type":"boolean","description":"Anfangsbestand + Zugänge − Abgänge = Endbestand für DIESES Konto. Wird AUSGEWIESEN statt erzwungen — eine Schieflage soll sichtbar sein, nicht die Antwort verhindern."}},"required":["glAccountNo","name","anfangsbestandCents","anfangsbestandSeite","zugaengeCents","abgaengeCents","endbestandCents","endbestandSeite","bewegungen","stimmt"]},"GeldkontenEntwicklung":{"type":"object","properties":{"zeitraum":{"$ref":"#/components/schemas/SaldenlisteZeitraum"},"konten":{"type":"array","items":{"$ref":"#/components/schemas/GeldkontoEntwicklung"},"description":"Ein Block je Geldkonto (`gl_accounts.kontotyp = bank`), nach Kontonummer geordnet — auch unbebuchte."},"anfangsbestandCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"zugaengeCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"abgaengeCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"endbestandCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"stimmt":{"type":"boolean","description":"`stimmt` gilt für JEDES Konto."}},"required":["zeitraum","konten","anfangsbestandCents","zugaengeCents","abgaengeCents","endbestandCents","currency","stimmt"]},"VermoegensuebersichtPosition":{"type":"object","properties":{"glAccountNo":{"type":"string"},"name":{"type":"string"},"kontotyp":{"type":"string","enum":["bank","debitor","kreditor"],"description":"Sachkonten sind KEINE Positionen — sie sind die Gegenseite (s. `sachkontenSaldoCents`)."},"art":{"type":"string","enum":["geldkonto","forderung","verbindlichkeit","guthaben"],"description":"Bei Personenkonten die zum Stichtag ABGELEITETE Ausweisrichtung (ADR 0014, § 266 HGB) — ein Kreditorkonto im Soll ist ein DEBITORISCHER KREDITOR und damit `forderung`, nicht eine negative Verbindlichkeit."},"seite":{"type":"string","enum":["aktiva","passiva"]},"saldoCents":{"type":"string","description":"Der signierte Kontosaldo zum Stichtag (Soll − Haben)."},"saldoSeite":{"type":"string","enum":["S","H"]},"betragCents":{"type":"string","description":"Der vorzeichenlose Betrag, mit dem die Position in ihre Seite eingeht (`|saldo|`)."}},"required":["glAccountNo","name","kontotyp","art","seite","saldoCents","saldoSeite","betragCents"]},"Vermoegensuebersicht":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"Der Tag, ZU DEM diese Aussage gilt — EINSCHLIESSLICH."},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/VermoegensuebersichtPosition"},"description":"Geordnet: Seite (aktiva zuerst), Art, Kontonummer. Geldkonten stehen auch mit Saldo 0 darin, Personenkonten nur mit Saldo ≠ 0."},"geldkontenCents":{"type":"string","description":"Σ der SIGNIERTEN Geldkonto-Salden (eine Überziehung mindert sie)."},"forderungenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"verbindlichkeitenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"guthabenCents":{"type":"string","description":"Was wir Mietern/Eigentümern schulden — getrennt ausgewiesen, weil es verrechnet und nicht bezahlt wird."},"reinvermoegenCents":{"type":"string","description":"Geldkonten + offene Forderungen − offene Verbindlichkeiten. Die offenen Verbindlichkeiten sind beide Habenseiten der Personenkonten, einzeln ausgewiesen als `verbindlichkeitenCents` (Lieferanten) und `guthabenCents` (Mieter/Eigentümer)."},"sachkontenSaldoCents":{"type":"string","description":"Σ der SIGNIERTEN Sachkonten-Salden — die Gegenseite, die keine Position ist. Sie steht hier, weil sie die Rechnung überprüfbar macht."},"currency":{"type":"string"},"bilanzgleichgewicht":{"type":"boolean","description":"Reinvermögen + Σ Sachkonten = 0 (Doppik). Wird AUSGEWIESEN statt erzwungen — eine Schieflage soll sichtbar sein, nicht die Antwort verhindern."}},"required":["stichtag","positionen","geldkontenCents","forderungenCents","verbindlichkeitenCents","guthabenCents","reinvermoegenCents","sachkontenSaldoCents","currency","bilanzgleichgewicht"]},"FinanzstatusResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"Der Stichtag der Vermögensübersicht: der angefragte `stichtag` oder — im Zeitraum-Modus — `bis`."},"entwicklung":{"allOf":[{"$ref":"#/components/schemas/GeldkontenEntwicklung"},{"type":["object","null"],"description":"Die Geldkonten-Entwicklung; `null` im Stichtags-Modus (ohne Zeitraum gibt es keinen Anfangsbestand und damit keine Entwicklung)."}]},"vermoegen":{"$ref":"#/components/schemas/Vermoegensuebersicht"}},"required":["propertyId","stichtag","entwicklung","vermoegen"]},"HonorarBasiswerte":{"type":"object","properties":{"sollmieteCents":{"type":"string","description":"Mietforderungen (Sollstellungen) mit fachlicher Periode im Monat (accrual_date) abzüglich Storno und Gutschrift; ohne Kosten, Zinsen und sonstige Geldkreise."},"istmieteCents":{"type":"string","description":"Wirksam einer Mietforderung zugeordnete Bankeingänge mit Zahlungsdatum im Monat (Zahlungszuordnungen ohne Zuordnungsstornos; ohne stornierte Zahlungen). Zahlungen auf Kosten, Hausgeld oder ohne Zuordnung zählen nicht."},"currency":{"type":"string"}},"required":["sollmieteCents","istmieteCents","currency"]},"HonorarEinheit":{"type":"object","properties":{"einheitId":{"type":"string","format":"uuid"},"bezeichnung":{"type":"string","description":"Einheitennummer (`units.unit_no`)."},"einheitentyp":{"type":"string","description":"`unit_kind` — offenes Vokabular (wohnung, gewerbe, stellplatz, …)."},"belegt":{"type":"boolean","description":"Am Monatsletzten durch einen laufenden Vertrag belegt. `false` ⇒ Leerstandsregel greift."}},"required":["einheitId","bezeichnung","einheitentyp","belegt"]},"HonorarPosition":{"type":"object","properties":{"art":{"type":"string","enum":["grundverguetung","leerstand","mindestbetrag","hoechstbetrag","zuschlag"],"description":"grundverguetung | leerstand | mindestbetrag | hoechstbetrag | zuschlag — Deckel sind eigene Zeilen, keine stille Korrektur."},"bezeichnung":{"type":"string"},"einheitId":{"type":["string","null"],"format":"uuid","description":"null ⇒ objektweite Zeile (Prozentbetrag, Deckel)."},"einheitentyp":{"type":["string","null"]},"anzahl":{"type":"integer","description":"Wie oft der Einzelbetrag zählt (Zuschlag: Zahl der Ereignisse)."},"nettoCents":{"type":"string","description":"NEGATIV bei `hoechstbetrag` (Kürzung) — die Aufstellung bleibt addierbar."},"currency":{"type":"string"}},"required":["art","bezeichnung","einheitId","einheitentyp","anzahl","nettoCents","currency"]},"HonorarSonderleistungPosition":{"type":"object","properties":{"sonderleistungId":{"type":"string","format":"uuid"},"leistungsdatum":{"type":"string","format":"date","description":"Tag der Leistung — bestimmt den Honorarmonat; eine Leistung gehört genau EINEM Monat."},"schluessel":{"type":"string","description":"Schlüssel der Leistung im Katalog des Objekts (`mahnbescheid`, `bescheinigung_35a`, …)."},"bezeichnung":{"type":"string","description":"Anzeigetext aus dem Katalog zum Erfassungszeitpunkt."},"preisart":{"type":"string","enum":["fest","je_stunde","je_einheit"],"description":"fest | je_stunde | je_einheit."},"menge":{"type":"string","description":"Dezimal-STRING mit Punkt (`\"1\"`, `\"1.25\"`), nie eine JSON-number."},"einheitId":{"type":["string","null"],"format":"uuid","description":"Bezug auf eine Einheit des Objekts; null ⇒ objektweite Leistung."},"einzelpreisCents":{"type":"string","description":"Netto-Preis je Vorgang/Stunde/Einheit aus dem Katalog zum Erfassungszeitpunkt."},"nettoCents":{"type":"string","description":"Einzelpreis × Menge, kaufmännisch auf den Cent gerundet."},"umsatzsteuersatzProzent":{"type":"string","description":"Ganze Prozent als Integer-STRING aus dem Katalogeintrag."},"umsatzsteuerCents":{"type":"string","description":"USt dieser Position, je Position gerundet."},"bruttoCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"}},"required":["sonderleistungId","leistungsdatum","schluessel","bezeichnung","preisart","menge","einheitId","einzelpreisCents","nettoCents","umsatzsteuersatzProzent","umsatzsteuerCents","bruttoCents","currency"]},"HonorarVorschauResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"Abrechnungsmonat `JJJJ-MM` (Echo der Anfrage)."},"von":{"type":"string","format":"date"},"bis":{"type":"string","format":"date"},"gueltigAb":{"type":"string","format":"date","description":"Beginn der Zeitscheibe, die gerechnet hat — der Nachweis bei einem Satzwechsel."},"gueltigBis":{"type":["string","null"],"format":"date","description":"Letzter Tag der Zeitscheibe (EINSCHLIESSLICH); null ⇒ läuft weiter."},"berechnungsart":{"type":"string","enum":["pauschal_je_einheit","prozent_sollmiete","prozent_istmiete"]},"basiswerte":{"$ref":"#/components/schemas/HonorarBasiswerte"},"einheiten":{"type":"array","items":{"$ref":"#/components/schemas/HonorarEinheit"}},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/HonorarPosition"},"description":"In Rechenreihenfolge: Grundvergütung → Leerstand → Deckel → Zuschläge."},"grundverguetungCents":{"type":"string","description":"Nach Mindest-/Höchstbetrag, VOR Zuschlägen."},"zuschlaegeCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"sonderleistungen":{"type":"array","items":{"$ref":"#/components/schemas/HonorarSonderleistungPosition"},"description":"Die nicht stornierten Sonderleistungen des Monats (#5189), je Erfassung eine Position mit eigener USt, nach Leistungsdatum."},"sonderleistungenNettoCents":{"type":"string","description":"Σ Netto der Sonderleistungen."},"sonderleistungenUmsatzsteuerCents":{"type":"string","description":"Σ USt der Sonderleistungen (je Position gerundet)."},"nettoCents":{"type":"string","description":"Σ aller Positionen einschließlich der Sonderleistungen."},"umsatzsteuersatzProzent":{"type":"string","description":"Ganze Prozent als Integer-STRING (\"19\"). 0 ist eine Vereinbarung (§ 19 UStG), keine fehlende Angabe."},"umsatzsteuerCents":{"type":"string","description":"USt der Grundvergütung (Satz der Vereinbarung) plus USt der Sonderleistungen (Satz je Position)."},"bruttoCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"mindestbetragGegriffen":{"type":"boolean"},"hoechstbetragGegriffen":{"type":"boolean"}},"required":["propertyId","monat","von","bis","gueltigAb","gueltigBis","berechnungsart","basiswerte","einheiten","positionen","grundverguetungCents","zuschlaegeCents","sonderleistungen","sonderleistungenNettoCents","sonderleistungenUmsatzsteuerCents","nettoCents","umsatzsteuersatzProzent","umsatzsteuerCents","bruttoCents","currency","mindestbetragGegriffen","hoechstbetragGegriffen"]},"RentabilitaetMonat":{"type":"object","properties":{"monat":{"type":"string","description":"Monat `JJJJ-MM`."},"ertragNettoCents":{"type":["string","null"],"description":"Honorar netto des Monats (Sonderleistungen mit); null, wenn der Monat kein Honorar trägt."},"grund":{"type":["string","null"],"enum":["vereinbarung-fehlt","eigenbestand","ausserhalb-verwaltungszeitraum",null]},"gueltigAb":{"type":["string","null"],"format":"date","description":"Beginn der Zeitscheibe, die gerechnet hat; null ohne Honorar."}},"required":["monat","ertragNettoCents","grund","gueltigAb"]},"RentabilitaetResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"von":{"type":"string","description":"Erster Monat `JJJJ-MM` (Echo)."},"bis":{"type":"string","description":"Letzter Monat `JJJJ-MM` (Echo)."},"urteil":{"type":"string","enum":["wirtschaftlich","unwirtschaftlich","nicht-beurteilbar"]},"gruende":{"type":"array","items":{"type":"string","enum":["keine-zeit-erfasst","kein-honorar"]}},"ertragNetto":{"type":["string","null"],"description":"Σ Honorar netto in Cent; null ohne jedes Honorar im Zeitraum."},"aufwand":{"type":"string","description":"Erfasste Zeit mal Kalkulationssatz in Cent."},"deckungsbeitrag":{"type":"string","description":"Ertrag minus Aufwand in Cent, vorzeichenbehaftet."},"margeBasispunkte":{"type":["string","null"],"description":"Deckungsbeitrag je Ertrag in Basispunkten (kaufmännisch gerundet); null ohne Ertrag."},"minuten":{"type":"string","description":"Erfasste Minuten als Integer-STRING."},"kapazitaetsanteilBasispunkte":{"type":"string","description":"Anteil der produktiven Zeit in Basispunkten."},"currency":{"type":"string"},"monate":{"type":"array","items":{"$ref":"#/components/schemas/RentabilitaetMonat"}},"kalkulation":{"type":"object","properties":{"stundensatzCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"produktiveStundenJeMonat":{"type":"string"},"quelle":{"type":"string","enum":["mandant","vorgabe"],"description":"mandant = Option verwalterhonorar.kalkulation; vorgabe = Default ohne Option."}},"required":["stundensatzCents","produktiveStundenJeMonat","quelle"]}},"required":["propertyId","von","bis","urteil","gruende","ertragNetto","aufwand","deckungsbeitrag","margeBasispunkte","minuten","kapazitaetsanteilBasispunkte","currency","monate","kalkulation"]},"HonorarvereinbarungScheibe":{"type":"object","properties":{"gueltigAb":{"type":"string","format":"date"},"gueltigBis":{"type":["string","null"],"format":"date","description":"Letzter Tag der Scheibe (einschließlich); null ⇒ läuft weiter."},"berechnungsart":{"type":"string"},"pauschaleJeEinheitentyp":{"type":"object","additionalProperties":{"type":"object","properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"}},"required":["cents","currency"]},"description":"Pauschale je Einheitentyp als { cents, currency }."},"satzBasispunkte":{"type":["string","null"],"description":"Prozentsatz in Basispunkten als Integer-STRING; null bei Pauschalen."},"mindestbetrag":{"type":["object","null"],"properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"}},"required":["cents","currency"]},"hoechstbetrag":{"type":["object","null"],"properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"}},"required":["cents","currency"]},"leerstandMindestbetrag":{"type":["object","null"],"properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"}},"required":["cents","currency"]},"zuschlaege":{"type":"array","items":{"type":"object","properties":{"art":{"type":"string"},"bezeichnung":{"type":"string"},"betrag":{"type":"object","properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"}},"required":["cents","currency"]}},"required":["art","bezeichnung","betrag"]}},"umsatzsteuersatzProzent":{"type":"string","description":"Ganze Prozent als Integer-STRING."}},"required":["gueltigAb","gueltigBis","berechnungsart","pauschaleJeEinheitentyp","satzBasispunkte","mindestbetrag","hoechstbetrag","leerstandMindestbetrag","zuschlaege","umsatzsteuersatzProzent"]},"HonorarAnpassungPauschale":{"type":"object","properties":{"einheitentyp":{"type":"string"},"alt":{"type":["object","null"],"properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"}},"required":["cents","currency"]},"neu":{"type":["object","null"],"properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"}},"required":["cents","currency"]},"aenderungBasispunkte":{"type":["string","null"],"description":"Kaufmännisch gerundete Änderung in Basispunkten als Integer-STRING; null ohne tragfähige Basis."}},"required":["einheitentyp","alt","neu","aenderungBasispunkte"]},"HonorarAnpassungVergleich":{"type":"object","properties":{"berechnungsartAlt":{"type":"string"},"berechnungsartNeu":{"type":"string"},"pauschalen":{"type":"array","items":{"$ref":"#/components/schemas/HonorarAnpassungPauschale"}},"satzBasispunkte":{"type":"object","properties":{"alt":{"type":["string","null"]},"neu":{"type":["string","null"]}},"required":["alt","neu"]}},"required":["berechnungsartAlt","berechnungsartNeu","pauschalen","satzBasispunkte"]},"HonorarAnpassungHinweis":{"type":"object","properties":{"code":{"type":"string"},"text":{"type":"string"}},"required":["code","text"]},"HonorarAnpassungResponse":{"type":"object","properties":{"anpassungId":{"type":"string","format":"uuid"},"neueScheibe":{"$ref":"#/components/schemas/HonorarvereinbarungScheibe"},"geschlosseneScheibe":{"allOf":[{"$ref":"#/components/schemas/HonorarvereinbarungScheibe"},{"description":"Die bisher laufende Scheibe, nun mit Ende am Vortag der Wirksamkeit."}]},"vergleich":{"$ref":"#/components/schemas/HonorarAnpassungVergleich"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/HonorarAnpassungHinweis"}}},"required":["anpassungId","neueScheibe","geschlosseneScheibe","vergleich","hinweise"]},"HonorarAnpassungZeile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"wirksamAb":{"type":"string","format":"date"},"grundlage":{"type":"string","enum":["beschluss","zustimmung","klausel"]},"beschlussId":{"type":["string","null"],"format":"uuid"},"zustimmungAm":{"type":["string","null"],"format":"date"},"begruendung":{"type":"string"},"scheibeAlt":{"$ref":"#/components/schemas/HonorarvereinbarungScheibe"},"scheibeNeu":{"$ref":"#/components/schemas/HonorarvereinbarungScheibe"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","wirksamAb","grundlage","beschlussId","zustimmungAm","begruendung","scheibeAlt","scheibeNeu","createdAt"]},"HonorarAnpassungenResponse":{"type":"object","properties":{"anpassungen":{"type":"array","items":{"$ref":"#/components/schemas/HonorarAnpassungZeile"}}},"required":["anpassungen"]},"ZeitHinweis":{"type":"object","properties":{"code":{"type":"string"},"timerIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Nur bei `timer-an-anderem-objekt`: die laufenden Timer an anderen Objekten."}},"required":["code"]},"ZeitErfasstResponse":{"type":"object","properties":{"zeitId":{"type":"string","format":"uuid"},"dauerMinuten":{"type":"integer"},"leistungsdatum":{"type":"string","format":"date"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/ZeitHinweis"}}},"required":["zeitId","dauerMinuten","leistungsdatum","hinweise"]},"ZeitGestartetResponse":{"type":"object","properties":{"zeitId":{"type":"string","format":"uuid"},"beginn":{"type":"string","format":"date-time"},"leistungsdatum":{"type":"string","format":"date"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/ZeitHinweis"}}},"required":["zeitId","beginn","leistungsdatum","hinweise"]},"ZeitGestopptResponse":{"type":"object","properties":{"zeitId":{"type":"string","format":"uuid"},"ende":{"type":"string","format":"date-time"},"dauerMinuten":{"type":"integer"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/ZeitHinweis"}}},"required":["zeitId","ende","dauerMinuten","hinweise"]},"ZeitStorniertResponse":{"type":"object","properties":{"zeitId":{"type":"string","format":"uuid"},"storniert":{"type":"boolean","enum":[true]}},"required":["zeitId","storniert"]},"Zeiteintrag":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"bezugArt":{"type":"string","enum":["objekt","anliegen","sonderleistung"]},"bezugId":{"type":["string","null"],"format":"uuid"},"taetigkeitsart":{"type":"string","enum":["telefonat","aussendienst","schriftverkehr","versammlung","verwaltung","sonstiges"]},"quelle":{"type":"string","enum":["timer","manuell"]},"leistungsdatum":{"type":"string","format":"date"},"beginn":{"type":["string","null"],"format":"date-time","description":"Nur Timer."},"ende":{"type":["string","null"],"format":"date-time","description":"null ⇒ der Timer läuft noch (oder manueller Eintrag)."},"dauerMinuten":{"type":["integer","null"],"description":"null ⇒ der Timer läuft noch."},"notiz":{"type":["string","null"]},"storniertAm":{"type":["string","null"],"format":"date-time"},"stornoGrund":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","bezugArt","bezugId","taetigkeitsart","quelle","leistungsdatum","beginn","ende","dauerMinuten","notiz","storniertAm","stornoGrund","createdAt"]},"ZeiteintraegeResponse":{"type":"object","properties":{"eintraege":{"type":"array","items":{"$ref":"#/components/schemas/Zeiteintrag"}}},"required":["eintraege"]},"ZeitLaufendResponse":{"type":"object","properties":{"timer":{"type":"array","items":{"$ref":"#/components/schemas/Zeiteintrag"}}},"required":["timer"]},"PasseHonorarvereinbarungAnRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"wirksamAb":{"type":"string","format":"date","description":"Monatserster, ab dem die neue Scheibe gilt."},"neueVereinbarung":{"type":"object","properties":{"berechnungsart":{"type":"string","minLength":1,"maxLength":100},"pauschaleJeEinheitentyp":{"type":"object","additionalProperties":{"type":"object","properties":{"cents":{"type":"string","pattern":"^(0|-?[1-9]\\d*)$"},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"],"additionalProperties":false}},"satzBasispunkte":{"type":["string","null"],"pattern":"^(0|-?[1-9]\\d*)$"},"mindestbetrag":{"type":["object","null"],"properties":{"cents":{"type":"string","pattern":"^(0|-?[1-9]\\d*)$"},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"],"additionalProperties":false},"hoechstbetrag":{"type":["object","null"],"properties":{"cents":{"type":"string","pattern":"^(0|-?[1-9]\\d*)$"},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"],"additionalProperties":false},"leerstandMindestbetrag":{"type":["object","null"],"properties":{"cents":{"type":"string","pattern":"^(0|-?[1-9]\\d*)$"},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"],"additionalProperties":false},"zuschlaege":{"type":"array","items":{"type":"object","properties":{"art":{"type":"string","minLength":1,"maxLength":100},"bezeichnung":{"type":"string","maxLength":500},"betrag":{"type":"object","properties":{"cents":{"type":"string","pattern":"^(0|-?[1-9]\\d*)$"},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"],"additionalProperties":false}},"required":["art","bezeichnung","betrag"],"additionalProperties":false},"maxItems":100},"umsatzsteuersatzProzent":{"type":"string","pattern":"^(0|-?[1-9]\\d*)$"}},"required":["berechnungsart","pauschaleJeEinheitentyp","satzBasispunkte","mindestbetrag","hoechstbetrag","leerstandMindestbetrag","zuschlaege","umsatzsteuersatzProzent"],"additionalProperties":false,"description":"Die neue Vereinbarung ohne gueltigAb/gueltigBis; Beträge als { cents: Integer-STRING, currency: \"EUR\" }, Sätze als Integer-STRINGS."},"grundlage":{"type":"string","enum":["beschluss","zustimmung","klausel"]},"beschlussId":{"type":["string","null"],"format":"uuid","description":"Genau bei grundlage = beschluss."},"zustimmungAm":{"type":["string","null"],"format":"date"},"begruendung":{"type":"string","minLength":1,"maxLength":500}},"required":["propertyId","wirksamAb","neueVereinbarung","grundlage","begruendung"],"additionalProperties":false},"ErfasseZeitRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"leistungsdatum":{"type":"string","format":"date","description":"Tag der Leistung, nicht in der Zukunft."},"dauerMinuten":{"type":"integer","minimum":1,"maximum":1440,"description":"Ganze Minuten, 1 bis 1440."},"taetigkeitsart":{"type":"string","enum":["telefonat","aussendienst","schriftverkehr","versammlung","verwaltung","sonstiges"]},"bezugArt":{"type":"string","enum":["objekt","anliegen","sonderleistung"]},"bezugId":{"type":["string","null"],"format":"uuid","description":"Genau bei bezugArt anliegen oder sonderleistung."},"notiz":{"type":["string","null"],"maxLength":1000}},"required":["propertyId","leistungsdatum","dauerMinuten","taetigkeitsart"],"additionalProperties":false},"StarteZeitRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"taetigkeitsart":{"type":"string","enum":["telefonat","aussendienst","schriftverkehr","versammlung","verwaltung","sonstiges"]},"bezugArt":{"type":"string","enum":["objekt","anliegen","sonderleistung"]},"bezugId":{"type":["string","null"],"format":"uuid"},"notiz":{"type":["string","null"],"maxLength":1000}},"required":["propertyId","taetigkeitsart"],"additionalProperties":false},"KorrigiereZeitRequest":{"type":"object","properties":{"dauerMinuten":{"type":"integer","minimum":1,"maximum":1440,"description":"Ganze Minuten, 1 bis 1440."},"leistungsdatum":{"type":"string","format":"date"},"taetigkeitsart":{"type":"string","enum":["telefonat","aussendienst","schriftverkehr","versammlung","verwaltung","sonstiges"]},"notiz":{"type":["string","null"],"maxLength":1000}},"additionalProperties":false,"minProperties":1},"StorniereZeitRequest":{"type":"object","properties":{"grund":{"type":"string","minLength":1,"maxLength":500}},"required":["grund"],"additionalProperties":false},"KautionslisteZeile":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"contractNo":{"type":"string"},"propertyId":{"type":"string","format":"uuid"},"propertyNo":{"type":["string","null"],"description":"Objektnummer (LEFT JOIN); null, wenn die Kette unerwartet reisst"},"mietpartei":{"type":"string","description":"Mietpartei(en) für Anzeige und Sortierung; ohne erfasste `mieter`-Rolle die Vertragsnummer. PERSONENBEZOGEN."},"vereinbartCents":{"type":["string","null"],"description":"vereinbarte Kaution; null ⇒ keine vereinbart"},"currency":{"type":["string","null"]},"erhaltenCents":{"type":"string","description":"Σ der bis zum Stichtag auf der getrennten Anlage EINGEGANGENEN Beträge abzüglich stornierter Eingänge; Auszahlungen mindern erhalten NICHT"},"offenCents":{"type":"string","description":"vereinbart − erhalten; POSITIV = Rückstand, NEGATIV = Überzahlung"},"status":{"type":"string","enum":["keine","eingang-unbekannt","offen","teilweise-erhalten","vollstaendig-erhalten"],"description":"Eingangsstatus. `eingang-unbekannt` = dokumentarisch übernommen, Eingang in casa.ai nicht bekannt — dieser Rest wird NICHT gemahnt (§ 551, Bestandsübernahme)."},"mahnbarerRestCents":{"type":"string","description":"der Teil von offenCents, der gemahnt werden darf; \"0\" beim übernommenen Bestand"},"anlageform":{"type":["string","null"],"enum":["barkaution","buergschaft","verpfaendung"],"description":"Anlageform der Sicherheit; null ⇒ im Bestand nicht erfasst"},"anlagekontoId":{"type":["string","null"],"format":"uuid","description":"Bankverbindung der getrennten Anlage (Kontoart kautionskonto); null ⇒ keine am Objekt"},"anlagekontoIban":{"type":["string","null"],"description":"IBAN der getrennten Anlage; null ⇒ keine"},"abrechnung":{"type":["object","null"],"properties":{"abgerechnetAm":{"type":"string","format":"date","description":"Kalendertag (Europe/Berlin), an dem die geltende Abrechnung erfasst wurde"},"gueltigBis":{"type":"string","format":"date","description":"Abrechnungstag (Stichtag der Abrechnung, nicht der Erfassungstag): die Kaution gilt bis dahin als aufgelöst, auch bei gehaltenem Rückbehalt (#7138)"},"rueckbehaltStatus":{"type":"string","enum":["keiner","gehalten","teilfreigegeben","freigegeben"]},"rueckbehaltCents":{"type":"string","description":"Rückbehalt der Abrechnung; \"0\" bei `keiner`"},"rueckbehaltRestCents":{"type":"string","description":"noch gehaltener Rest des Rückbehalts (#6900): Rückbehalt − Σ Teilfreigaben, \"0\" bei `freigegeben`; fehlt bei `keiner`"},"rueckbehaltTeilfreigaben":{"type":"array","items":{"type":"object","properties":{"teilfreigabeId":{"type":"string","format":"uuid"},"betragCents":{"type":"string","description":"freigegebener Teilbetrag (> 0)"},"verrechnetCents":{"type":"string","description":"davon gegen fällige Posten verrechnet"},"verrechnungEntryId":{"type":["string","null"],"format":"uuid","description":"Verrechnungssatz des Schritts; null ohne Verrechnung"},"paymentOrderId":{"type":["string","null"],"format":"uuid","description":"Zahlungsauftrag des Schritts; null ohne Auszahlung"},"freigegebenAm":{"type":"string","description":"Zeitpunkt der Freigabe (ISO-8601, UTC)"},"freigegebenVon":{"type":"string","description":"Akteur, der den Schritt ausgeführt hat (PERSONENBEZOGEN)"}},"required":["teilfreigabeId","betragCents","verrechnetCents","verrechnungEntryId","paymentOrderId","freigegebenAm","freigegebenVon"]},"description":"die Teilfreigaben des Rückbehalts (#6900) in Freigabe-Reihenfolge, dieselbe Form wie im Abrechnungsstand; leer ohne Teilfreigabe; fehlt bei `keiner`"}},"required":["abgerechnetAm","gueltigBis","rueckbehaltStatus","rueckbehaltCents"],"description":"Abrechnungsstand (#6897): die NICHT stornierte Kautionsabrechnung; null ⇒ nicht abgerechnet (auch nach dem Storno, und immer bei einer Sicherheit ohne Geldfluss — Bürgschaft, Verpfändung)."}},"required":["contractId","contractNo","propertyId","propertyNo","mietpartei","vereinbartCents","currency","erhaltenCents","offenCents","status","mahnbarerRestCents","anlageform","anlagekontoId","anlagekontoIban","abrechnung"]},"KautionslisteSummen":{"type":"object","properties":{"vereinbartCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"erhaltenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"offenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"mahnbarerRestCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"anzahlVertraege":{"type":"integer"}},"required":["vereinbartCents","erhaltenCents","offenCents","mahnbarerRestCents","currency","anzahlVertraege"]},"KautionslisteResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"Stichtag, auf den `erhalten` gemessen wurde"},"propertyId":{"type":["string","null"],"format":"uuid","description":"die wirksame Objekt-Eingrenzung (null = alle Objekte des Mandanten)"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/KautionslisteZeile"}},"summen":{"$ref":"#/components/schemas/KautionslisteSummen"},"summenFremdwaehrung":{"type":"array","items":{"$ref":"#/components/schemas/KautionslisteSummen"},"description":"Summen der Zeilen in ANDEREN Währungen als EUR, je Währung eine Summenzeile (z. B. ein dokumentarisch übernommener CHF-Bestand). Nie in `summen` addiert; leer im Normalfall."},"anlagenOhneSachkonto":{"type":"array","items":{"type":"string"},"description":"IBANs von Kautionskonten OHNE zugeordnetes Bank-Sachkonto — ihre Eingänge konnten NICHT mitgezählt werden. Leer heisst: alles gezählt."}},"required":["stichtag","propertyId","zeilen","summen","summenFremdwaehrung","anlagenOhneSachkonto"]},"KautionsabrechnungStandResponse":{"type":"object","properties":{"kautionsabrechnungId":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"Abrechnungsstichtag"},"guthabenCents":{"type":"string","description":"Kaution + Zinsen"},"verrechnetCents":{"type":"string","description":"mit offenen Posten verrechneter Teil"},"auszahlungCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"restforderungCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"rueckbehaltCents":{"type":"string","description":"\"0\" bei Rückbehalt-Status `keiner`"},"rueckbehaltBegruendung":{"type":["string","null"],"description":"Freitext eines Menschen (PERSONENBEZOGEN); null ohne Rückbehalt"},"rueckbehaltStatus":{"type":"string","enum":["keiner","gehalten","teilfreigegeben","freigegeben"]},"paymentOrderId":{"type":["string","null"],"format":"uuid","description":"Zahlungsauftrag der Auszahlung; null bei Auszahlung 0"},"rueckbehaltPaymentOrderId":{"type":["string","null"],"format":"uuid","description":"Auftrag aus der Rückbehalt-Freigabe (bei Teilfreigaben: der des letzten Schritts); null solange nicht (oder ohne Auszahlung) freigegeben"},"rueckbehaltRestCents":{"type":"string","description":"noch gehaltener Rest des Rückbehalts (#6900): Rückbehalt − Σ Teilfreigaben; \"0\" bei `keiner` und `freigegeben`"},"rueckbehaltTeilfreigaben":{"type":"array","items":{"type":"object","properties":{"teilfreigabeId":{"type":"string","format":"uuid"},"betragCents":{"type":"string","description":"freigegebener Teilbetrag (> 0)"},"verrechnetCents":{"type":"string","description":"davon gegen fällige Posten verrechnet"},"verrechnungEntryId":{"type":["string","null"],"format":"uuid","description":"Verrechnungssatz des Schritts; null ohne Verrechnung"},"paymentOrderId":{"type":["string","null"],"format":"uuid","description":"Zahlungsauftrag des Schritts; null ohne Auszahlung"},"freigegebenAm":{"type":"string","description":"Zeitpunkt der Freigabe (ISO-8601, UTC)"},"freigegebenVon":{"type":"string","description":"Akteur, der den Schritt ausgeführt hat (PERSONENBEZOGEN)"}},"required":["teilfreigabeId","betragCents","verrechnetCents","verrechnungEntryId","paymentOrderId","freigegebenAm","freigegebenVon"]},"description":"die Teilfreigaben des Rückbehalts (#6900) in Freigabe-Reihenfolge; leer ohne Teilfreigabe (auch bei einer ganz in einem Schritt freigegebenen Abrechnung)"},"rueckbehalte":{"type":"array","items":{"type":"object","properties":{"rueckbehaltZeileId":{"type":"string","format":"uuid"},"grundart":{"type":"string","enum":["bk-nachzahlung","sonstiges"],"description":"Grundart: BK-Nachzahlung (höchstens eine, gedeckelt) oder Sonstiges (frei, Begründung Pflicht)"},"zeileBetragCents":{"type":"string","description":"zurückbehaltener Betrag dieser Zeile (> 0)"},"deckelCents":{"type":["string","null"],"description":"Deckel der Zeile (letzte BK-Nachzahlung, ohne Aufschlag); nur bei `bk-nachzahlung`, sonst null"},"begruendung":{"type":["string","null"],"description":"Freitext eines Menschen (PERSONENBEZOGEN); Pflicht bei `sonstiges`, bei `bk-nachzahlung` optional"}},"required":["rueckbehaltZeileId","grundart","zeileBetragCents","deckelCents","begruendung"]},"description":"die Rückbehalt-Zeilen mit Grundart (#7134) in der Reihenfolge der Erfassung; `rueckbehaltCents` ist ihre Summe. Leer ohne Rückbehalt (und bei einer vor #7134 abgerechneten Abrechnung ohne Rückbehalt)."}},"required":["kautionsabrechnungId","contractId","stichtag","guthabenCents","verrechnetCents","auszahlungCents","restforderungCents","rueckbehaltCents","rueckbehaltBegruendung","rueckbehaltStatus","paymentOrderId","rueckbehaltPaymentOrderId","rueckbehaltRestCents","rueckbehaltTeilfreigaben","rueckbehalte"]},"KautionszinsGutschrift":{"type":"object","properties":{"von":{"type":"string","format":"date","description":"erster Tag des Zinszeitraums (einschliesslich)"},"bis":{"type":"string","format":"date","description":"letzter Tag des Zinszeitraums (einschliesslich)"},"bankTransactionId":{"type":["string","null"],"format":"uuid","description":"die Zinsgutschrift der Bank auf dem Kautions-Anlagekonto; null beim Jahreszinslauf (31.12., ohne Bankumsatz)"},"betragCents":{"type":"string","description":"Zinsanteil dieser Kaution"},"currency":{"type":"string"},"entryIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"die Buchungssätze dieser Gutschrift"}},"required":["von","bis","bankTransactionId","betragCents","currency","entryIds"]},"KautionszinsenResponse":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"gutschriften":{"type":"array","items":{"$ref":"#/components/schemas/KautionszinsGutschrift"},"description":"aufsteigend nach Zeitraum; stornierte Gutschriften erscheinen nicht"}},"required":["contractId","gutschriften"]},"KautionRueckbehaltFrist":{"type":"object","properties":{"kautionsabrechnungId":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"abrechnungsdatum":{"type":"string","format":"date","description":"Abrechnungsdatum der Kautionsabrechnung — Beginn der Frist"},"rueckbehaltStatus":{"type":"string","enum":["gehalten","teilfreigegeben"]},"rueckbehaltCents":{"type":"string","description":"gesamter Rückbehalt in Cent"},"restCents":{"type":"string","description":"noch gehaltener Rest in Cent (bei teilfreigegeben kleiner als der Rückbehalt)"},"fristEnde":{"type":"string","format":"date","description":"beim Buchen gespeicherter Termin (Wiedervorlage am): Abrechnungsdatum + Frist des Mandanten zum Buchungszeitpunkt, kalendermonatsgenau mit Monatsende-Kappung; eine spätere Änderung der Frist wirkt nur auf neue Abrechnungen"},"ueberfaellig":{"type":"boolean","description":"true ⇒ fristEnde liegt vor dem Stichtag"},"tageUeberfaellig":{"type":"integer","description":"Tage seit dem Fristende; 0, solange nicht überfällig"}},"required":["kautionsabrechnungId","contractId","propertyId","abrechnungsdatum","rueckbehaltStatus","rueckbehaltCents","restCents","fristEnde","ueberfaellig","tageUeberfaellig"]},"KautionRueckbehaltFristenResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"der verwendete Stichtag (Vorgabe: heute, Server-Uhr)"},"fristMonate":{"type":"integer","description":"die für den Mandanten geltende Frist in Monaten"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/KautionRueckbehaltFrist"},"description":"nur Rückbehalte der Objekte, für die der Aufrufer zuständig ist; aufsteigend nach Fristende"}},"required":["stichtag","fristMonate","zeilen"]},"InstandhaltungObjektVerweis":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"name":{"type":"string"}},"required":["propertyId","name"]},"InstandhaltungEinheitVerweis":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"einheitNr":{"type":"string"}},"required":["unitId","einheitNr"]},"InstandhaltungPersonVerweis":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"anzeigename":{"type":["string","null"]}},"required":["personId","anzeigename"]},"InstandhaltungBefund":{"type":"object","properties":{"code":{"type":"string","enum":["weniger-als-mindestangebote","gestattungsbeschluss-fehlt","kostenobergrenze-ohne-angebot","freistellung-fehlt","freistellung-abgelaufen","freistellung-anderer-auftrag","rechnung-ueber-auftrag","rechnung-kreditor-abweichend"]},"schwere":{"type":"string","enum":["hinweis","warnung"]},"text":{"type":"string"}},"required":["code","schwere","text"]},"InstandhaltungVorgangListenZeile":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"titel":{"type":"string"},"typSchluessel":{"type":"string"},"dringlichkeit":{"type":"string","enum":["sofort","kurzfristig","langfristig"]},"status":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]},"statusSeit":{"type":"string","format":"date-time"},"objekt":{"$ref":"#/components/schemas/InstandhaltungObjektVerweis"},"einheit":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungEinheitVerweis"},{"type":["object","null"]}]},"auftragswert":{"type":["string","null"],"description":"Auftragswert des lebenden Auftrags in Cent als Integer-STRING; null ohne lebenden Auftrag"},"auftragsnummer":{"type":["string","null"]},"offeneBefunde":{"type":"integer","description":"Zahl der aktuellen Befunde des Vorgangs plus gespeicherter Befunde seiner Rechnungen"}},"required":["vorgangId","nummer","titel","typSchluessel","dringlichkeit","status","statusSeit","objekt","einheit","auftragswert","auftragsnummer","offeneBefunde"]},"InstandhaltungListeResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"der verwendete Stichtag (Berliner Tag der Server-Uhr)"},"limit":{"type":"integer"},"offset":{"type":"integer"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungVorgangListenZeile"},"description":"nur Vorgänge der Objekte, für die der Aufrufer zuständig ist; leer ohne Vorgänge"}},"required":["stichtag","limit","offset","zeilen"]},"InstandhaltungEreignis":{"type":"object","properties":{"ereignisId":{"type":"string","format":"uuid"},"vonStatus":{"type":["string","null"],"enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert",null]},"nachStatus":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]},"grund":{"type":["string","null"]},"akteurArt":{"type":"string"},"am":{"type":"string","format":"date-time"}},"required":["ereignisId","vonStatus","nachStatus","grund","akteurArt","am"]},"InstandhaltungAngebot":{"type":"object","properties":{"angebotId":{"type":"string","format":"uuid"},"dienstleister":{"$ref":"#/components/schemas/InstandhaltungPersonVerweis"},"status":{"type":"string","enum":["angefragt","vorliegend","gewaehlt","verworfen"]},"betragCents":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"gueltigBis":{"type":["string","null"],"format":"date"},"realisierungAb":{"type":["string","null"],"format":"date"},"dokumentId":{"type":["string","null"],"format":"uuid"},"angefragtAm":{"type":"string","format":"date-time"}},"required":["angebotId","dienstleister","status","betragCents","gueltigBis","realisierungAb","dokumentId","angefragtAm"]},"InstandhaltungAuftrag":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid"},"version":{"type":"integer"},"status":{"type":"string","enum":["zur_freigabe","freigegeben","abgelehnt","erteilt","ausgefuehrt","storniert"]},"lebend":{"type":"boolean"},"angebotId":{"type":["string","null"],"format":"uuid"},"dienstleister":{"$ref":"#/components/schemas/InstandhaltungPersonVerweis"},"betragCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"kostenobergrenzeCents":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"costCategoryId":{"type":["string","null"],"format":"uuid"},"auftragsnummer":{"type":["string","null"]},"erteiltAm":{"type":["string","null"],"format":"date-time"},"ausgefuehrtAm":{"type":["string","null"],"format":"date-time"}},"required":["auftragId","version","status","lebend","angebotId","dienstleister","betragCents","kostenobergrenzeCents","costCategoryId","auftragsnummer","erteiltAm","ausgefuehrtAm"]},"InstandhaltungStufenStand":{"type":"object","properties":{"stufe":{"type":"string","enum":["verwalter","zweit"]},"entscheidung":{"type":"string","enum":["approved","rejected","offen"]}},"required":["stufe","entscheidung"]},"InstandhaltungFreigabeStand":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid"},"version":{"type":"integer"},"erforderlicheStufen":{"type":"array","items":{"type":"string","enum":["verwalter","zweit"]}},"zweitstufeNichtWirksam":{"type":"boolean"},"stufen":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungStufenStand"}},"offeneStufen":{"type":"array","items":{"type":"string","enum":["verwalter","zweit"]}},"abgelehnteStufen":{"type":"array","items":{"type":"string","enum":["verwalter","zweit"]}},"vollstaendig":{"type":"boolean","description":"alle erforderlichen Stufen stehen auf approved (zum aktuellen Inhalts-Hash)"}},"required":["auftragId","version","erforderlicheStufen","zweitstufeNichtWirksam","stufen","offeneStufen","abgelehnteStufen","vollstaendig"]},"InstandhaltungZahlungsstand":{"type":"object","properties":{"stand":{"type":"string","enum":["nicht-gebucht","nicht-ermittelbar","offen","ausgeglichen"]},"restbetragCents":{"type":["string","null"],"description":"offener Restbetrag in Cent; nur bei stand offen, sonst null"}},"required":["stand","restbetragCents"]},"InstandhaltungRechnung":{"type":"object","properties":{"rechnungId":{"type":"string","format":"uuid"},"auftragId":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid"},"bookingProposalId":{"type":["string","null"],"format":"uuid"},"rechnungsdatum":{"type":"string","format":"date"},"betragCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"auftragswertCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"abweichungCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"befunde":{"type":"array","items":{"type":"string","enum":["weniger-als-mindestangebote","gestattungsbeschluss-fehlt","kostenobergrenze-ohne-angebot","freistellung-fehlt","freistellung-abgelaufen","freistellung-anderer-auftrag","rechnung-ueber-auftrag","rechnung-kreditor-abweichend"]},"description":"beim Verknüpfen gespeicherte Befund-Codes"},"zahlungsstand":{"$ref":"#/components/schemas/InstandhaltungZahlungsstand"}},"required":["rechnungId","auftragId","documentId","bookingProposalId","rechnungsdatum","betragCents","auftragswertCents","abweichungCents","befunde","zahlungsstand"]},"InstandhaltungVorgangResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"titel":{"type":"string"},"beschreibung":{"type":["string","null"]},"typSchluessel":{"type":"string"},"dringlichkeit":{"type":"string","enum":["sofort","kurzfristig","langfristig"]},"status":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]},"statusSeit":{"type":"string","format":"date-time"},"objekt":{"$ref":"#/components/schemas/InstandhaltungObjektVerweis"},"einheit":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungEinheitVerweis"},{"type":["object","null"]}]},"melder":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungPersonVerweis"},{"type":["object","null"]}]},"baulichVeraendernd":{"type":"boolean"},"abschlussBegruendung":{"type":["string","null"]},"verlauf":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungEreignis"}},"angebote":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungAngebot"}},"auftraege":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungAuftrag"}},"freigabe":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungFreigabeStand"},{"type":["object","null"],"description":"Freigabestand des lebenden Auftrags; null ohne lebenden Auftrag"}]},"rechnungen":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungRechnung"}},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungBefund"}},"naechsteSchritte":{"type":"array","items":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]},"description":"Status, in die der Vorgang als Nächstes wechseln darf"}},"required":["vorgangId","nummer","titel","beschreibung","typSchluessel","dringlichkeit","status","statusSeit","objekt","einheit","melder","baulichVeraendernd","abschlussBegruendung","verlauf","angebote","auftraege","freigabe","rechnungen","befunde","naechsteSchritte"]},"InstandhaltungKatalogTyp":{"type":"object","properties":{"schluessel":{"type":"string"},"bezeichnung":{"type":"string"},"ohneAngebotErlaubt":{"type":"boolean"},"aktiv":{"type":"boolean"},"vorgabe":{"type":"boolean"}},"required":["schluessel","bezeichnung","ohneAngebotErlaubt","aktiv","vorgabe"]},"InstandhaltungKatalogResponse":{"type":"object","properties":{"typen":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungKatalogTyp"},"description":"nur aktive Typen; mit auchInaktive=true alle"}},"required":["typen"]},"InstandhaltungEinstellungResponse":{"type":"object","properties":{"zweitfreigabeAbCents":{"type":["string","null"],"description":"Auftragswert in Cent, ab dem eine Zweitfreigabe nötig ist; null ⇒ nie"},"vergleichsangeboteAbCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"mindestangebote":{"type":"integer"},"herkunft":{"type":"string","enum":["vorgabe","mandant"]},"geaendertVon":{"type":["string","null"]},"geaendertAm":{"type":["string","null"],"format":"date-time"}},"required":["zweitfreigabeAbCents","vergleichsangeboteAbCents","mindestangebote","herkunft","geaendertVon","geaendertAm"]},"InstandhaltungAufgabe":{"type":"object","properties":{"schluessel":{"type":"string"},"aufgabeArt":{"type":"string","enum":["sofort-unbearbeitet","angebot-ausstehend","freigabe-wartet","rechnung-fehlt"]},"ampel":{"type":["string","null"],"enum":["gruen","gelb","rot",null]},"titel":{"type":"string"},"objektId":{"type":"string","format":"uuid"},"objektNr":{"type":["string","null"]},"frist":{"type":"string","format":"date"},"vorgangId":{"type":"string","format":"uuid"}},"required":["schluessel","aufgabeArt","ampel","titel","objektId","objektNr","frist","vorgangId"]},"InstandhaltungAufgabenResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"der verwendete Stichtag (Berliner Tag der Server-Uhr)"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungAufgabe"}}},"required":["stichtag","zeilen"]},"InstandhaltungGeld":{"type":"object","properties":{"cents":{"type":"string","description":"Cent als Integer-STRING, nie eine JSON-Zahl"},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"]},"InstandhaltungMeldenRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid","description":"Pflicht: das Objekt"},"unitId":{"type":"string","format":"uuid"},"typSchluessel":{"type":"string","description":"Pflicht: Schlüssel eines aktiven Vorgangstyps (Katalog)"},"titel":{"type":"string","description":"Pflicht: 1 bis 140 Zeichen"},"beschreibung":{"type":"string","description":"Pflicht: 10 bis 5000 Zeichen"},"dringlichkeit":{"type":"string","enum":["sofort","kurzfristig","langfristig"]},"melderPersonId":{"type":"string","format":"uuid"},"beginnAm":{"type":"string","format":"date"},"haeufigkeit":{"type":"string","description":"Häufigkeit in Worten, höchstens 200 Zeichen"},"baulichVeraendernd":{"type":"boolean","description":"Vorgabe false"}},"required":["propertyId","typSchluessel","titel","beschreibung","dringlichkeit"]},"InstandhaltungMeldungResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"status":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]},"naechsteSchritte":{"type":"array","items":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]}},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungBefund"}}},"required":["vorgangId","nummer","status","naechsteSchritte","befunde"]},"InstandhaltungQualifizierenRequest":{"type":"object","properties":{"typSchluessel":{"type":"string"},"dringlichkeit":{"type":"string","enum":["sofort","kurzfristig","langfristig"]},"baulichVeraendernd":{"type":"boolean"},"gestattungsBeschlussGegenstandId":{"type":"string","format":"uuid"},"beginnAm":{"type":"string","format":"date"},"haeufigkeit":{"type":"string","description":"Häufigkeit in Worten, höchstens 200 Zeichen"},"beginnUnbekannt":{"type":"boolean","description":"ausdrücklich „Beginn nicht bekannt\""}}},"InstandhaltungQualifizierenResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"status":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]},"naechsteSchritte":{"type":"array","items":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]}},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungBefund"}},"uebergang":{"type":"boolean","description":"true, wenn dieser Aufruf `gemeldet` nach `in_klaerung` gesetzt hat"}},"required":["vorgangId","nummer","status","naechsteSchritte","befunde","uebergang"]},"InstandhaltungEinstellungSetzenRequest":{"type":"object","properties":{"zweitfreigabeAbCents":{"type":["string","null"],"description":"Auftragswert in Cent (Integer-String), ab dem eine Zweitfreigabe nötig ist; null ⇒ nie"},"vergleichsangeboteAbCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"mindestangebote":{"type":"integer"}},"required":["zweitfreigabeAbCents","vergleichsangeboteAbCents","mindestangebote"]},"InstandhaltungEinstellungWerte":{"type":"object","properties":{"zweitfreigabeAbCents":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"vergleichsangeboteAbCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"mindestangebote":{"type":"integer"}},"required":["zweitfreigabeAbCents","vergleichsangeboteAbCents","mindestangebote"]},"InstandhaltungEinstellungSetzenResponse":{"type":"object","properties":{"zweitfreigabeAbCents":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"vergleichsangeboteAbCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"mindestangebote":{"type":"integer"},"vorher":{"$ref":"#/components/schemas/InstandhaltungEinstellungWerte"},"geaendert":{"type":"boolean"},"geaendertVon":{"type":["string","null"]},"geaendertAm":{"type":["string","null"],"format":"date-time"}},"required":["zweitfreigabeAbCents","vergleichsangeboteAbCents","mindestangebote","vorher","geaendert","geaendertVon","geaendertAm"]},"InstandhaltungKatalogSetzenRequest":{"type":"object","properties":{"schluessel":{"type":"string"},"bezeichnung":{"type":"string"},"ohneAngebotErlaubt":{"type":"boolean"},"aktiv":{"type":"boolean"}},"required":["schluessel","bezeichnung","ohneAngebotErlaubt","aktiv"]},"InstandhaltungKatalogSetzenResponse":{"type":"object","properties":{"schluessel":{"type":"string"},"bezeichnung":{"type":"string"},"ohneAngebotErlaubt":{"type":"boolean"},"aktiv":{"type":"boolean"},"geaendert":{"type":"boolean"},"geaendertVon":{"type":"string"},"geaendertAm":{"type":"string","format":"date-time"}},"required":["schluessel","bezeichnung","ohneAngebotErlaubt","aktiv","geaendert","geaendertVon","geaendertAm"]},"InstandhaltungDienstleisterRequest":{"type":"object","properties":{"dienstleisterPersonId":{"type":"string","format":"uuid","description":"Pflicht: die Person mit gültiger Rolle `dienstleister`"}},"required":["dienstleisterPersonId"]},"InstandhaltungAngebotErgebnis":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"vorgangId":{"type":"string","format":"uuid"},"dienstleisterPersonId":{"type":"string","format":"uuid"},"status":{"type":"string"},"betrag":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungGeld"},{"type":["object","null"]}]},"gueltigBis":{"type":["string","null"],"format":"date"},"realisierungAb":{"type":["string","null"],"format":"date"},"dokumentId":{"type":["string","null"],"format":"uuid"},"angefragtAm":{"type":"string","format":"date-time"}},"required":["id","vorgangId","dienstleisterPersonId","status","betrag","gueltigBis","realisierungAb","dokumentId","angefragtAm"]},"InstandhaltungDienstleisterResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"vorgangStatus":{"type":"string"},"angebot":{"$ref":"#/components/schemas/InstandhaltungAngebotErgebnis"}},"required":["vorgangId","vorgangStatus","angebot"]},"InstandhaltungAngebotRequest":{"type":"object","properties":{"dienstleisterPersonId":{"type":"string","format":"uuid"},"betrag":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungGeld"},{"description":"Geld ist ein Objekt `{ cents, currency }`, Cent als Integer-STRING, currency EUR"}]},"gueltigBis":{"type":"string","format":"date"},"realisierungAb":{"type":"string","format":"date"},"dokumentId":{"type":"string","format":"uuid"}},"required":["dienstleisterPersonId","betrag"]},"InstandhaltungAngebotResponse":{"type":"object","properties":{"angebot":{"$ref":"#/components/schemas/InstandhaltungAngebotErgebnis"}},"required":["angebot"]},"InstandhaltungAngebotWaehlenRequest":{"type":"object","properties":{"angebotId":{"type":"string","format":"uuid"}},"required":["angebotId"]},"InstandhaltungAngebotWaehlenResponse":{"type":"object","properties":{"angebot":{"$ref":"#/components/schemas/InstandhaltungAngebotErgebnis"},"anzahlAngebote":{"type":"integer","description":"Angebote im Status vorliegend oder gewaehlt"},"befund":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungBefund"},{"type":["object","null"]}]}},"required":["angebot","anzahlAngebote","befund"]},"InstandhaltungAngebotVerwerfenRequest":{"type":"object","properties":{"angebotId":{"type":"string","format":"uuid"},"grund":{"type":"string","description":"Pflicht: 1 bis 200 Zeichen"}},"required":["angebotId","grund"]},"InstandhaltungFreigabeBeantragenRequest":{"type":"object","properties":{"angebotId":{"type":"string","format":"uuid","description":"das gewählte Angebot; ohne Angebot nur bei Typen mit `ohneAngebotErlaubt`"},"kostenobergrenze":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungGeld"},{"description":"Geld ist ein Objekt `{ cents, currency }`"}]},"dienstleisterPersonId":{"type":"string","format":"uuid"},"costCategoryId":{"type":"string","format":"uuid"}}},"InstandhaltungFreigabeBeantragenResponse":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid"},"version":{"type":"integer"},"betrag":{"$ref":"#/components/schemas/InstandhaltungGeld"},"stufen":{"type":"array","items":{"type":"string","enum":["verwalter","zweit"]}},"zweitstufeNichtWirksam":{"type":"boolean"},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungBefund"}}},"required":["auftragId","version","betrag","stufen","zweitstufeNichtWirksam","befunde"]},"InstandhaltungAblehnung":{"type":"object","properties":{"code":{"type":"string","enum":["zu-teuer","angebot-unklar","beschluss-fehlt","sonstiges"]},"note":{"type":"string","description":"höchstens 500 Zeichen"}},"required":["code"]},"InstandhaltungFreigabeEntscheidenRequest":{"type":"object","properties":{"stufe":{"type":"string","enum":["verwalter","zweit"]},"decision":{"type":"string","enum":["approved","rejected"]},"rejectReason":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungAblehnung"},{"description":"`rejected` verlangt genau einen Grund, `approved` niemals einen"}]}},"required":["stufe","decision"]},"InstandhaltungFreigabeEntscheidenResponse":{"type":"object","properties":{"entschieden":{"type":"string","enum":["approved","rejected"]},"auftragStatus":{"type":"string"},"vorgangStatus":{"type":"string"},"offeneStufen":{"type":"array","items":{"type":"string","enum":["verwalter","zweit"]}},"ohneVierAugen":{"type":"boolean","description":"true, wenn der abgeschaltete Vier-Augen-Schalter die Selbstfreigabe getragen hat"}},"required":["entschieden","auftragStatus","vorgangStatus","offeneStufen","ohneVierAugen"]},"FremdvertragPartner":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"anzeigename":{"type":["string","null"]}},"required":["personId","anzeigename"]},"FremdvertragKonditionen":{"type":"object","properties":{"version":{"type":"integer"},"gueltigAb":{"type":"string","format":"date"},"laufzeitEnde":{"type":["string","null"],"format":"date"},"kuendigungsfristMonate":{"type":"integer"},"verlaengerungStillschweigend":{"type":"boolean"},"verlaengerungMonate":{"type":["integer","null"]},"beitrag":{"type":["string","null"],"description":"Beitrag je Intervall in Cent als Integer-STRING"},"beitragIntervall":{"type":["string","null"]},"jahresbeitrag":{"type":["string","null"],"description":"Jahresbeitrag in Cent als Integer-STRING"},"selbstbehalt":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"bemerkungVorhanden":{"type":"boolean","description":"Der Freitext selbst wird nie ausgegeben, nur das Kennzeichen."}},"required":["version","gueltigAb","laufzeitEnde","kuendigungsfristMonate","verlaengerungStillschweigend","verlaengerungMonate","beitrag","beitragIntervall","jahresbeitrag","selbstbehalt","bemerkungVorhanden"]},"FremdvertragBefund":{"type":"object","properties":{"code":{"type":"string","enum":["laufzeit-fehlt","kuendigungsfrist-verpasst","beitrag-weicht-von-dauerzahlung-ab"]},"bezugEnde":{"type":["string","null"],"format":"date"},"spaetesterZugang":{"type":["string","null"],"format":"date"}},"required":["code","bezugEnde","spaetesterZugang"]},"FremdvertragFristenStand":{"type":"object","properties":{"status":{"type":"string","enum":["ohne-laufzeit","laeuft","gekuendigt","beendet","ausgelaufen"]},"naechstesEnde":{"type":["string","null"],"format":"date"},"spaetesterZugang":{"type":["string","null"],"format":"date","description":"Letzter Tag, an dem die Kündigung dem Vertragspartner zugehen muss"},"aufgabeAb":{"type":["string","null"],"format":"date","description":"Ab diesem Tag steht die Aufgabe offen (Zugangstermin minus Vorlauf)"},"aufgabeOffen":{"type":"boolean"},"verpasstesEnde":{"type":["string","null"],"format":"date"},"verpasstOffen":{"type":"boolean"},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/FremdvertragBefund"}}},"required":["status","naechstesEnde","spaetesterZugang","aufgabeAb","aufgabeOffen","verpasstesEnde","verpasstOffen","befunde"]},"FremdvertragListenZeile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"art":{"type":"string","enum":["versicherung","wartung","dienstleistung","versorgung"]},"bezeichnung":{"type":"string"},"vertragsnummerVorhanden":{"type":"boolean"},"propertyId":{"type":"string","format":"uuid"},"partner":{"$ref":"#/components/schemas/FremdvertragPartner"},"beginn":{"type":"string","format":"date"},"konditionen":{"allOf":[{"$ref":"#/components/schemas/FremdvertragKonditionen"},{"type":["object","null"],"description":"Konditionen zum Stichtag; null, wenn noch keine gelten"}]},"fristen":{"allOf":[{"$ref":"#/components/schemas/FremdvertragFristenStand"},{"type":["object","null"]}]},"beendet":{"type":"boolean"},"dauerzahlungVerknuepft":{"type":"boolean"},"anzahlSchadenfaelle":{"type":"integer"}},"required":["id","art","bezeichnung","vertragsnummerVorhanden","propertyId","partner","beginn","konditionen","fristen","beendet","dauerzahlungVerknuepft","anzahlSchadenfaelle"]},"FremdvertragListeResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"der verwendete Stichtag (Berliner Tag der Server-Uhr)"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/FremdvertragListenZeile"},"description":"nur Verträge der Objekte, für die der Aufrufer zuständig ist; leer ohne Verträge"},"gesamt":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["stichtag","zeilen","gesamt","limit","offset"]},"FremdvertragStamm":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"art":{"type":"string","enum":["versicherung","wartung","dienstleistung","versorgung"]},"bezeichnung":{"type":"string"},"vertragsnummerVorhanden":{"type":"boolean"},"propertyId":{"type":"string","format":"uuid"},"objekt":{"type":["string","null"]},"partner":{"$ref":"#/components/schemas/FremdvertragPartner"},"beginn":{"type":"string","format":"date"},"dauerzahlungId":{"type":["string","null"],"format":"uuid"}},"required":["id","art","bezeichnung","vertragsnummerVorhanden","propertyId","objekt","partner","beginn","dauerzahlungId"]},"FremdvertragEreignis":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"art":{"type":"string"},"bezugEnde":{"type":["string","null"],"format":"date"},"entscheidung":{"type":["string","null"]},"wirksamZum":{"type":["string","null"],"format":"date"},"grundVorhanden":{"type":"boolean"},"am":{"type":"string","format":"date-time"}},"required":["id","art","bezugEnde","entscheidung","wirksamZum","grundVorhanden","am"]},"FremdvertragDauerzahlung":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"gueltigAb":{"type":"string","format":"date"},"betrag":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"rhythmus":{"type":"string"},"jahresbetrag":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."}},"required":["id","gueltigAb","betrag","rhythmus","jahresbetrag"]},"FremdvertragDauerzahlungBefund":{"type":"object","properties":{"code":{"type":"string","enum":["beitrag-weicht-von-dauerzahlung-ab"]},"beitragJahr":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"dauerzahlungJahr":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"differenz":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."}},"required":["code","beitragJahr","dauerzahlungJahr","differenz"]},"FremdvertragDauerzahlungAbgleich":{"type":"object","properties":{"verknuepft":{"type":"boolean"},"dauerzahlung":{"allOf":[{"$ref":"#/components/schemas/FremdvertragDauerzahlung"},{"type":["object","null"]}]},"befund":{"allOf":[{"$ref":"#/components/schemas/FremdvertragDauerzahlungBefund"},{"type":["object","null"]}]}},"required":["verknuepft","dauerzahlung","befund"]},"FremdvertragSchadenfallKurz":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"status":{"type":"string","enum":["erfasst","gemeldet","deckung_zugesagt","deckung_abgelehnt","reguliert","abgeschlossen"]},"schadensdatum":{"type":"string","format":"date"}},"required":["id","nummer","status","schadensdatum"]},"FremdvertragResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date"},"vertrag":{"$ref":"#/components/schemas/FremdvertragStamm"},"beendet":{"type":"boolean"},"konditionen":{"allOf":[{"$ref":"#/components/schemas/FremdvertragKonditionen"},{"type":["object","null"]}]},"historie":{"type":"array","items":{"$ref":"#/components/schemas/FremdvertragKonditionen"}},"ereignisse":{"type":"array","items":{"$ref":"#/components/schemas/FremdvertragEreignis"}},"fristen":{"allOf":[{"$ref":"#/components/schemas/FremdvertragFristenStand"},{"type":["object","null"]}]},"dauerzahlungAbgleich":{"$ref":"#/components/schemas/FremdvertragDauerzahlungAbgleich"},"schadenfaelle":{"type":"array","items":{"$ref":"#/components/schemas/FremdvertragSchadenfallKurz"}}},"required":["stichtag","vertrag","beendet","konditionen","historie","ereignisse","fristen","dauerzahlungAbgleich","schadenfaelle"]},"FremdvertragFristZeile":{"type":"object","properties":{"kategorie":{"type":"string","enum":["kuendigungsfrist","frist-verpasst","ohne-laufzeit"]},"schluessel":{"type":"string"},"titel":{"type":"string"},"objektId":{"type":"string","format":"uuid"},"art":{"type":"string","enum":["versicherung","wartung","dienstleistung","versorgung"]},"partner":{"type":["string","null"]},"vertragsende":{"type":["string","null"],"format":"date"},"spaetesterZugang":{"type":["string","null"],"format":"date"},"aufgabeAb":{"type":["string","null"],"format":"date"},"tageBisFrist":{"type":["integer","null"],"description":"Tage vom Stichtag bis zum Zugangstermin; negativ, wenn er verstrichen ist"},"ampel":{"type":"string","enum":["gruen","gelb","rot"]},"frist":{"type":["string","null"],"format":"date"},"refId":{"type":"string","format":"uuid","description":"der Vertrag"},"offen":{"type":"boolean"}},"required":["kategorie","schluessel","titel","objektId","art","partner","vertragsende","spaetesterZugang","aufgabeAb","tageBisFrist","ampel","frist","refId","offen"]},"FremdvertragFristenResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"der verwendete Stichtag (Berliner Tag der Server-Uhr)"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/FremdvertragFristZeile"},"description":"leer ohne Fristen"}},"required":["stichtag","zeilen"]},"FremdvertragEinstellungResponse":{"type":"object","properties":{"vorlaufTage":{"type":"integer"},"verlaengerungStillschweigendVorgabe":{"type":"boolean"},"verlaengerungMonateVorgabe":{"type":"integer"},"schadenMeldefristTage":{"type":"integer"},"schadenhonorarProzentBp":{"type":"integer","description":"Schadenhonorar in Basispunkten (800 = 8,00 %)"},"schadenhonorarProzentText":{"type":"string"},"schadenhonorarAktiv":{"type":"boolean"},"herkunft":{"type":"string","enum":["vorgabe","mandant"]}},"required":["vorlaufTage","verlaengerungStillschweigendVorgabe","verlaengerungMonateVorgabe","schadenMeldefristTage","schadenhonorarProzentBp","schadenhonorarProzentText","schadenhonorarAktiv","herkunft"]},"SchadenfallBefund":{"type":"object","properties":{"code":{"type":"string","enum":["meldefrist-verstrichen","schaden-ausserhalb-laufzeit","versicherung-fehlt","erstattung-weicht-ab"]},"text":{"type":"string"}},"required":["code","text"]},"SchadenfallListenZeile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"status":{"type":"string","enum":["erfasst","gemeldet","deckung_zugesagt","deckung_abgelehnt","reguliert","abgeschlossen"]},"schadensdatum":{"type":"string","format":"date"},"schadenart":{"type":"string"},"propertyId":{"type":"string","format":"uuid"},"objekt":{"type":["string","null"]},"schadenssumme":{"type":["string","null"],"description":"Schadenssumme in Cent als Integer-STRING; null, wenn unbekannt"},"anzahlBefunde":{"type":"integer"}},"required":["id","nummer","status","schadensdatum","schadenart","propertyId","objekt","schadenssumme","anzahlBefunde"]},"SchadenfallListeResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/SchadenfallListenZeile"},"description":"nur Schadenfälle der Objekte, für die der Aufrufer zuständig ist; leer ohne Fälle"},"gesamt":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["stichtag","zeilen","gesamt","limit","offset"]},"SchadenfallStamm":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"status":{"type":"string","enum":["erfasst","gemeldet","deckung_zugesagt","deckung_abgelehnt","reguliert","abgeschlossen"]},"statusSeit":{"type":"string","format":"date-time"},"propertyId":{"type":"string","format":"uuid"},"objekt":{"type":["string","null"]},"unitId":{"type":["string","null"],"format":"uuid"},"schadensdatum":{"type":"string","format":"date"},"schadenart":{"type":"string"},"beschreibungVorhanden":{"type":"boolean"},"gemeldetAm":{"type":["string","null"],"format":"date"},"versichererAktenzeichenVorhanden":{"type":"boolean"},"deckungAm":{"type":["string","null"],"format":"date"},"selbstbehalt":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"schadenssumme":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"abschlussBegruendungVorhanden":{"type":"boolean"}},"required":["id","nummer","status","statusSeit","propertyId","objekt","unitId","schadensdatum","schadenart","beschreibungVorhanden","gemeldetAm","versichererAktenzeichenVorhanden","deckungAm","selbstbehalt","schadenssumme","abschlussBegruendungVorhanden"]},"SchadenfallVersicherungsvertrag":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"bezeichnung":{"type":"string"},"partner":{"$ref":"#/components/schemas/FremdvertragPartner"}},"required":["id","bezeichnung","partner"]},"SchadenfallVorgangVerweis":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"status":{"type":"string"}},"required":["id","nummer","status"]},"SchadenfallBilanz":{"type":"object","properties":{"schadenssumme":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"selbstbehaltAnteil":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"erwarteteErstattung":{"type":["string","null"],"description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"erstattet":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"differenz":{"type":["string","null"],"description":"erwartet minus erstattet; negativ = mehr erstattet als erwartet"},"befund":{"allOf":[{"$ref":"#/components/schemas/SchadenfallBefund"},{"type":["object","null"]}]}},"required":["schadenssumme","selbstbehaltAnteil","erwarteteErstattung","erstattet","differenz","befund"]},"SchadenfallErstattung":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"betrag":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"eingangAm":{"type":"string","format":"date"},"buchungsstand":{"type":"string","enum":["gebucht","vorgeschlagen"]}},"required":["id","betrag","eingangAm","buchungsstand"]},"SchadenfallHonorarVorschlag":{"type":"object","properties":{"nettoCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"prozentBp":{"type":"integer"},"grundlage":{"type":"string","enum":["schadenssumme"]}},"required":["nettoCents","prozentBp","grundlage"]},"SchadenfallHonorar":{"type":"object","properties":{"vorschlag":{"allOf":[{"$ref":"#/components/schemas/SchadenfallHonorarVorschlag"},{"type":["object","null"]}]},"grund":{"type":["string","null"],"enum":["aus","schadenssumme-unbekannt","noch-nicht-reguliert",null]},"automatischAbgerechnet":{"type":"boolean","enum":[false]},"hinweis":{"type":"string"}},"required":["vorschlag","grund","automatischAbgerechnet","hinweis"]},"SchadenfallResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date"},"schadenfall":{"$ref":"#/components/schemas/SchadenfallStamm"},"versicherungsvertrag":{"allOf":[{"$ref":"#/components/schemas/SchadenfallVersicherungsvertrag"},{"type":["object","null"]}]},"instandhaltungVorgang":{"allOf":[{"$ref":"#/components/schemas/SchadenfallVorgangVerweis"},{"type":["object","null"]}]},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/SchadenfallBefund"}},"bilanz":{"$ref":"#/components/schemas/SchadenfallBilanz"},"erstattungen":{"type":"array","items":{"$ref":"#/components/schemas/SchadenfallErstattung"}},"honorar":{"$ref":"#/components/schemas/SchadenfallHonorar"}},"required":["stichtag","schadenfall","versicherungsvertrag","instandhaltungVorgang","befunde","bilanz","erstattungen","honorar"]},"StaffelmieteStufe":{"type":"object","properties":{"kaltmieteCents":{"type":"string","description":"Kaltmiete der Stufe in Cent"},"currency":{"type":["string","null"],"description":"Währung dieser Stufe (je Stufe geführt; Wechsel der Währung ist ein Stufenwechsel)"},"gueltigAb":{"type":["string","null"],"format":"date","description":"Gültigkeitsbeginn der Stufe; null ⇒ ohne untere Grenze (von Anfang an)"}},"required":["kaltmieteCents","currency","gueltigAb"]},"StaffelmieteListeZeile":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"contractNo":{"type":"string"},"propertyId":{"type":"string","format":"uuid"},"currency":{"type":["string","null"]},"aktuell":{"allOf":[{"$ref":"#/components/schemas/StaffelmieteStufe"},{"description":"die zum Stichtag geltende Stufe (nicht die letzte erfasste)"}]},"vorher":{"allOf":[{"$ref":"#/components/schemas/StaffelmieteStufe"},{"type":["object","null"],"description":"die unmittelbar vorherige Stufe mit abweichender Kaltmiete; null, wenn die Staffel erst später beginnt"}]},"differenzCents":{"type":["string","null"],"description":"aktuell − vorher in Cent (vorzeichenbehaftet); null ohne Vorgänger oder bei Währungswechsel"},"naechste":{"allOf":[{"$ref":"#/components/schemas/StaffelmieteStufe"},{"type":["object","null"],"description":"die nächste künftige Stufe, falls vorhanden"}]},"herkunft":{"type":"string","enum":["anlage","konditionswechsel"],"description":"anlage ⇒ die aktuelle Stufe entstand im Anlage-Kommando des Vertrags; sonst konditionswechsel"}},"required":["contractId","contractNo","propertyId","currency","aktuell","vorher","differenzCents","naechste","herkunft"]},"StaffelmieteListeResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"der verwendete Stichtag (Vorgabe: heute, Server-Uhr)"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/StaffelmieteListeZeile"},"description":"nur Verträge der Objekte, für die der Aufrufer zuständig ist; aufsteigend nach Objekt und Vertragsnummer"}},"required":["stichtag","zeilen"]},"MieterhoehungFaelligParagraph558":{"type":"object","properties":{"status":{"type":"string","enum":["faellig","noch-nicht-faellig","gesperrt"]},"fruehesterTermin":{"type":["string","null"],"format":"date","description":"frühester zulässiger Wirksamkeitstag (letzte Erhöhung + 12 Monate); null ohne Sperrfrist oder bei gesperrt"},"grund":{"type":["string","null"],"enum":["kollision-indexmiete","kollision-staffelmiete",null],"description":"nur bei gesperrt: welche Vereinbarung das Verfahren ausschließt"}},"required":["status","fruehesterTermin","grund"]},"MieterhoehungFaelligParagraph557b":{"type":"object","properties":{"status":{"type":"string","enum":["vorschau","keine-aenderung","vpi-fehlt","basisjahr-abweichend","nicht-berechenbar"],"description":"vpi-fehlt: kein VPI-Monat zum Bezug; basisjahr-abweichend: der aktuelle VPI stammt aus einer anderen Reihe — beides ohne Betrag"},"basisjahr":{"type":"integer","description":"Basisjahr der vereinbarten VPI-Reihe"},"fruehesterTermin":{"type":["string","null"],"format":"date","description":"frühester Anpassungstermin (letzte Änderung + 12 Monate); null, solange nicht gerechnet"},"faellig":{"type":["boolean","null"],"description":"true ⇒ eine Erklärung zum Stichtag wäre nicht zu früh; null, solange nicht gerechnet"},"juengsterVpiMonat":{"type":["string","null"],"description":"jüngster zum Stichtag veröffentlichter VPI-Monat (YYYY-MM)"},"neueKaltmieteCents":{"type":["string","null"],"description":"neue Kaltmiete der Vorschau in Cent; nur bei vorschau / keine-aenderung"},"wirksamAb":{"type":["string","null"],"format":"date","description":"Wirksamkeitstag der Vorschau"},"grund":{"type":["string","null"],"description":"nur bei nicht-berechenbar: Grund-Code der Fachschicht"}},"required":["status","basisjahr","fruehesterTermin","faellig","juengsterVpiMonat","neueKaltmieteCents","wirksamAb","grund"]},"MieterhoehungFaelligVorgang":{"type":"object","properties":{"mieterhoehungId":{"type":"string","format":"uuid"},"zugangAm":{"type":"string","format":"date"},"zustimmungsfristEnde":{"type":"string","format":"date","description":"Zugang + 3 Kalendermonate (§ 558b Abs. 2), nie gespeichert"}},"required":["mieterhoehungId","zugangAm","zustimmungsfristEnde"]},"MieterhoehungFaelligZeile":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"kaltmieteCents":{"type":"string","description":"heute geschuldete Kaltmiete in Cent"},"letzteErhoehungAm":{"type":["string","null"],"format":"date","description":"Wirksamkeitstag der letzten Erhöhung bzw. Vertragsbeginn; null = seit jeher"},"paragraph558":{"$ref":"#/components/schemas/MieterhoehungFaelligParagraph558"},"paragraph557b":{"allOf":[{"$ref":"#/components/schemas/MieterhoehungFaelligParagraph557b"},{"type":["object","null"],"description":"null ohne Indexmiete-Vereinbarung"}]},"offenerVorgang":{"allOf":[{"$ref":"#/components/schemas/MieterhoehungFaelligVorgang"},{"type":["object","null"],"description":"jüngster Vorgang im Zustand versendet; null ohne"}]}},"required":["contractId","propertyId","kaltmieteCents","letzteErhoehungAm","paragraph558","paragraph557b","offenerVorgang"]},"MieterhoehungFaelligResponse":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"der verwendete Stichtag (Vorgabe: heute, Server-Uhr)"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/MieterhoehungFaelligZeile"},"description":"nur laufende Wohnraumverträge der Objekte, für die der Aufrufer zuständig ist"}},"required":["stichtag","zeilen"]},"MahnlaufBearbeiter":{"type":"object","properties":{"name":{"type":["string","null"],"description":"Anzeigename; null, wenn nicht auflösbar (nie die Kennung)"},"ichSelbst":{"type":"boolean","description":"true ⇔ der Aufrufer selbst"}},"required":["name","ichSelbst"]},"MahnlaufFremdInArbeit":{"type":"object","properties":{"name":{"type":["string","null"]},"schritt":{"type":"integer","description":"gespeicherter Schritt + 1 (1…4)"},"anzahlSchritte":{"type":"integer"},"text":{"type":"string","description":"Klartext „… bearbeitet diesen Mahnlauf (Schritt n von 4)\""}},"required":["name","schritt","anzahlSchritte","text"]},"MahnlaufOffenerEintrag":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"bezeichnung":{"type":"string"},"status":{"type":"string","enum":["faellig","in_arbeit"]},"schritt":{"type":"integer","description":"0…3"},"automatisch":{"type":"boolean"},"objektNamen":{"type":"array","items":{"type":"string"}},"inArbeitBei":{"allOf":[{"$ref":"#/components/schemas/MahnlaufBearbeiter"},{"type":["object","null"]}]},"fremdInArbeit":{"allOf":[{"$ref":"#/components/schemas/MahnlaufFremdInArbeit"},{"type":["object","null"]}]}},"required":["vorgangId","stichtag","bezeichnung","status","schritt","automatisch","objektNamen","inArbeitBei","fremdInArbeit"]},"MahnlaufFruehererEintrag":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"bezeichnung":{"type":"string"},"objektNamen":{"type":"array","items":{"type":"string"}},"ausgefuehrtAm":{"type":"string","format":"date-time"},"ausgefuehrtVon":{"type":["string","null"],"description":"Name der ausführenden Person; null, wenn nicht auflösbar"},"ergebnisText":{"type":"string"},"gebucht":{"type":"integer"},"summeCent":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."}},"required":["vorgangId","stichtag","bezeichnung","objektNamen","ausgefuehrtAm","ausgefuehrtVon","ergebnisText","gebucht","summeCent"]},"MahnlaufUebersichtResponse":{"type":"object","properties":{"offene":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufOffenerEintrag"},"description":"offene sichtbare Vorgänge, Stichtag aufsteigend; ausgeführte nie"},"gewaehlt":{"type":["object","null"],"properties":{"vorgangId":{"type":"string","format":"uuid"},"grund":{"type":"string","enum":["deep-link","faellig","eigener-in-arbeit"]}},"required":["vorgangId","grund"],"description":"der Vorgang, den das Register öffnet (Query `lauf` ⇒ deep-link); null, wenn keiner"},"fruehere":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufFruehererEintrag"}},"zuMahnendeDebitoren":{"type":["integer","null"],"description":"nur ohne offenen Vorgang: Zahl der zu mahnenden Debitoren, sonst null"}},"required":["offene","gewaehlt","fruehere","zuMahnendeDebitoren"]},"MahnlaufVorgangKopf":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"bezeichnung":{"type":"string"},"status":{"type":"string","enum":["faellig","in_arbeit","ausgefuehrt"]},"schritt":{"type":"integer"},"automatisch":{"type":"boolean"},"objektNamen":{"type":"array","items":{"type":"string"}},"schreiben":{"type":"integer","description":"buchbare Schreiben (offen: Ableitung; ausgeführt: Ergebnis)"},"summeCent":{"type":"string","description":"Σ Betrag der buchbaren Schreiben, Cent-String"},"ausnahmen":{"type":"integer"},"ausgeschlossen":{"type":"integer"},"inArbeitBei":{"allOf":[{"$ref":"#/components/schemas/MahnlaufBearbeiter"},{"type":["object","null"]}]},"fremdInArbeit":{"allOf":[{"$ref":"#/components/schemas/MahnlaufFremdInArbeit"},{"type":["object","null"]}]},"ausgefuehrtAm":{"type":["string","null"],"format":"date-time"},"ausgefuehrtVon":{"type":["string","null"]}},"required":["vorgangId","stichtag","bezeichnung","status","schritt","automatisch","objektNamen","schreiben","summeCent","ausnahmen","ausgeschlossen","inArbeitBei","fremdInArbeit","ausgefuehrtAm","ausgefuehrtVon"]},"MahnlaufUmfangEinheit":{"type":"object","properties":{"einheitId":{"type":"string","format":"uuid"},"lage":{"type":"string"},"imUmfang":{"type":"boolean","description":"false ⇔ abgewählt"}},"required":["einheitId","lage","imUmfang"]},"MahnlaufObjektBlockiert":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"name":{"type":["string","null"],"description":"Name der bearbeitenden Person; null, wenn niemand oder nicht auflösbar"}},"required":["vorgangId","name"]},"MahnlaufUmfangObjekt":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"name":{"type":"string"},"imUmfang":{"type":"boolean"},"einheiten":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufUmfangEinheit"}},"laeuftBereitsBei":{"allOf":[{"$ref":"#/components/schemas/MahnlaufObjektBlockiert"},{"type":["object","null"]}]},"summeCent":{"type":"string","description":"Gruppensumme der buchbaren Schreiben des Objekts, Cent-String"}},"required":["objektId","name","imUmfang","einheiten","laeuftBereitsBei","summeCent"]},"MahnlaufVorgangPosition":{"type":"object","properties":{"schluessel":{"type":"string","description":"Positionsschlüssel (`mahn:vertrag:<id>`), Eingabe für ausschluss und aufheben"},"status":{"type":"string","description":"Status der Position in der Ableitung (z. B. buchbar, ausnahme, ausgeschlossen)"},"objektId":{"type":"string","format":"uuid"},"objektName":{"type":"string"},"einheitId":{"type":["string","null"],"format":"uuid"},"einheitLage":{"type":["string","null"]},"vertragId":{"type":["string","null"],"format":"uuid"},"personId":{"type":["string","null"],"format":"uuid"},"personName":{"type":["string","null"]},"opIds":{"type":"array","items":{"type":"string","format":"uuid"}},"stufe":{"type":"integer","description":"höchste Mahnstufe vor dem Lauf"},"stufeNachLauf":{"type":"integer"},"offenerBetragCent":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"guthabenVerrechnetCent":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"betragCent":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"grund":{"type":["string","null"]},"reparatur":{"type":["string","null"]},"versandstatus":{"type":["string","null"]},"hinweise":{"type":"array","items":{"type":"string"}},"kanal":{"type":["string","null"],"description":"Vorbelegter Versandkanal der Person (email oder brief, wie die Kanal-Auswahl); null ohne Person"},"zahlungsziel":{"type":["string","null"],"format":"date"}},"required":["schluessel","status","objektId","objektName","einheitId","einheitLage","vertragId","personId","personName","opIds","stufe","stufeNachLauf","offenerBetragCent","guthabenVerrechnetCent","betragCent","grund","reparatur","versandstatus","hinweise","kanal","zahlungsziel"]},"MahnlaufErgebnisSchreiben":{"type":"object","properties":{"schluessel":{"type":"string"},"mahnschreibenId":{"type":"string","format":"uuid"},"objektId":{"type":"string","format":"uuid"},"objektName":{"type":"string"},"einheitId":{"type":["string","null"],"format":"uuid"},"vertragId":{"type":"string","format":"uuid"},"personId":{"type":["string","null"],"format":"uuid"},"anzeige":{"type":"string","description":"„Einheit · Person\""},"betragCent":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"stufe":{"type":["integer","null"]},"versandstatus":{"type":"string"}},"required":["schluessel","mahnschreibenId","objektId","objektName","einheitId","vertragId","personId","anzeige","betragCent","stufe","versandstatus"]},"MahnlaufNichtGemahnt":{"type":"object","properties":{"schluessel":{"type":"string"},"status":{"type":"string","enum":["ausnahme","ausgeschlossen"]},"anzeige":{"type":"string"},"grund":{"type":"string"},"betragCent":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."}},"required":["schluessel","status","anzeige","grund","betragCent"]},"MahnlaufErgebnis":{"type":"object","properties":{"zeitpunkt":{"type":"string","format":"date-time"},"text":{"type":"string"},"schreiben":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufErgebnisSchreiben"}},"fehlgeschlagen":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufErgebnisSchreiben"}},"nichtGemahnt":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufNichtGemahnt"}}},"required":["zeitpunkt","text","schreiben","fehlgeschlagen","nichtGemahnt"]},"MahnlaufVorgangResponse":{"type":"object","properties":{"kopf":{"$ref":"#/components/schemas/MahnlaufVorgangKopf"},"umfang":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufUmfangObjekt"},"description":"Objekte der Zuständigkeit des Aufrufers; Objekte außerhalb erscheinen nie"},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufVorgangPosition"},"description":"offen: Positionen der Ableitung; ausgeführt: leer"},"karenzTage":{"type":["integer","null"]},"mahnwesenAktiv":{"type":"boolean"},"ergebnis":{"allOf":[{"$ref":"#/components/schemas/MahnlaufErgebnis"},{"type":["object","null"],"description":"nur bei ausgeführtem Vorgang"}]}},"required":["kopf","umfang","positionen","karenzTage","mahnwesenAktiv","ergebnis"]},"MahnlaufStartResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"status":{"type":"string","enum":["faellig","in_arbeit","ausgefuehrt"]},"schritt":{"type":"integer"},"automatisch":{"type":"boolean"},"umfangObjektIds":{"type":"array","items":{"type":"string","format":"uuid"}},"abgewaehlteEinheitIds":{"type":"array","items":{"type":"string","format":"uuid"}},"neu":{"type":"boolean","description":"false ⇔ der eigene vorbereitete Vorgang wurde geöffnet, es entstand keiner"}},"required":["vorgangId","stichtag","status","schritt","automatisch","umfangObjektIds","abgewaehlteEinheitIds","neu"]},"MahnlaufVorbereitetResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"status":{"type":"string","enum":["faellig","in_arbeit","ausgefuehrt"]},"schritt":{"type":"integer"},"automatisch":{"type":"boolean"},"umfangObjektIds":{"type":"array","items":{"type":"string","format":"uuid"}},"abgewaehlteEinheitIds":{"type":"array","items":{"type":"string","format":"uuid"}},"geaendert":{"type":"boolean","description":"false ⇔ der Wert war schon so gesetzt, nichts geschrieben"}},"required":["vorgangId","stichtag","status","schritt","automatisch","umfangObjektIds","abgewaehlteEinheitIds","geaendert"]},"MahnlaufAusschlussResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"positionsSchluessel":{"type":"string"},"neu":{"type":"boolean","description":"false ⇔ die Position war schon ausgeschlossen (der jüngere Grund gilt)"}},"required":["vorgangId","positionsSchluessel","neu"]},"MahnlaufAusschlussAufhebenResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"positionsSchluessel":{"type":"string"},"zurueckgeholt":{"type":"boolean","description":"false ⇔ es gab keinen Ausschluss, nichts gelöscht"}},"required":["vorgangId","positionsSchluessel","zurueckgeholt"]},"InkassoUebergabe":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"der Schuldner"},"contractId":{"type":["string","null"],"format":"uuid"},"weg":{"type":"string","enum":["inkasso","gerichtliches-mahnverfahren","klage"]},"status":{"type":"string","enum":["entwurf","uebergeben","zurueckgenommen","abgeschlossen"]},"stichtag":{"type":"string","format":"date"},"zinssatzBasispunkte":{"type":["integer","null"],"description":"Verzugszinssatz in Basispunkten; null = kein Zinsansatz"},"aufstellungHash":{"type":"string","description":"SHA-256 der kanonischen Forderungsaufstellung (Hex)"},"gesamtCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"empfaenger":{"type":["string","null"],"description":"Inkassounternehmen oder Kanzlei (Freitext)"},"begruendungMahnstufe":{"type":["string","null"],"description":"Pflicht für Posten unter Mahnstufe 3 (Freitext)"},"uebergebenAm":{"type":["string","null"],"format":"date"},"uebergebenVon":{"type":["string","null"]},"zurueckgenommenAm":{"type":["string","null"],"format":"date-time"},"zuruecknahmeGrund":{"type":["string","null"]},"abgeschlossenAm":{"type":["string","null"],"format":"date-time"},"abschlussArt":{"type":["string","null"],"enum":["bezahlt","vergleich","uneinbringlich","sonstiges",null]},"abschlussNotiz":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","personId","contractId","weg","status","stichtag","zinssatzBasispunkte","aufstellungHash","gesamtCents","currency","empfaenger","begruendungMahnstufe","uebergebenAm","uebergebenVon","zurueckgenommenAm","zuruecknahmeGrund","abgeschlossenAm","abschlussArt","abschlussNotiz","createdAt"]},"InkassoUebergabeListeResponse":{"type":"object","properties":{"uebergaben":{"type":"array","items":{"$ref":"#/components/schemas/InkassoUebergabe"},"description":"neueste zuerst"}},"required":["uebergaben"]},"InkassoAufstellungGebuehr":{"type":"object","properties":{"stufe":{"type":"string","description":"0, 1, 2, 3 oder anwalt"},"betragCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"gebuchtAm":{"type":"string","format":"date"}},"required":["stufe","betragCents","gebuchtAm"]},"InkassoAufstellungZeile":{"type":"object","properties":{"postenId":{"type":"string","format":"uuid"},"bezeichnung":{"type":"string"},"faelligAm":{"type":"string","format":"date"},"hauptforderungCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"mahnstufe":{"type":"string","description":"0, 1, 2, 3 oder anwalt"},"gebuehren":{"type":"array","items":{"$ref":"#/components/schemas/InkassoAufstellungGebuehr"}},"summeGebuehrenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"verzugszinsenCents":{"type":"string","description":"bis zum Stichtag aufgelaufen"},"summeCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."}},"required":["postenId","bezeichnung","faelligAm","hauptforderungCents","mahnstufe","gebuehren","summeGebuehrenCents","verzugszinsenCents","summeCents"]},"InkassoAufstellungHinweis":{"type":"object","properties":{"art":{"type":"string","enum":["mahnstufe-unter-3","kein-zinsansatz"]},"postenId":{"type":["string","null"],"format":"uuid","description":"nur bei mahnstufe-unter-3"}},"required":["art","postenId"]},"InkassoAufstellung":{"type":"object","properties":{"stichtag":{"type":"string","format":"date"},"schuldner":{"type":"string"},"objekt":{"type":"string"},"vertragsnummer":{"type":"string"},"zinssatzBasispunkte":{"type":["integer","null"]},"currency":{"type":"string"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/InkassoAufstellungZeile"}},"summeHauptforderungCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"summeGebuehrenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"summeVerzugszinsenCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"gesamtCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"tageszinsCents":{"type":["string","null"],"description":"laufender Tageszins ab Stichtag; null ohne Zinssatz"},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/InkassoAufstellungHinweis"}}},"required":["stichtag","schuldner","objekt","vertragsnummer","zinssatzBasispunkte","currency","zeilen","summeHauptforderungCents","summeGebuehrenCents","summeVerzugszinsenCents","gesamtCents","tageszinsCents","hinweise"]},"InkassoUebergabePosten":{"type":"object","properties":{"offenerPostenId":{"type":"string","format":"uuid"},"aktiv":{"type":"boolean","description":"false ⇔ die Übergabe ist zurückgenommen oder abgeschlossen, der Posten frei"}},"required":["offenerPostenId","aktiv"]},"InkassoUebergabeDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid","description":"der Schuldner"},"contractId":{"type":["string","null"],"format":"uuid"},"weg":{"type":"string","enum":["inkasso","gerichtliches-mahnverfahren","klage"]},"status":{"type":"string","enum":["entwurf","uebergeben","zurueckgenommen","abgeschlossen"]},"stichtag":{"type":"string","format":"date"},"zinssatzBasispunkte":{"type":["integer","null"],"description":"Verzugszinssatz in Basispunkten; null = kein Zinsansatz"},"aufstellungHash":{"type":"string","description":"SHA-256 der kanonischen Forderungsaufstellung (Hex)"},"gesamtCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"empfaenger":{"type":["string","null"],"description":"Inkassounternehmen oder Kanzlei (Freitext)"},"begruendungMahnstufe":{"type":["string","null"],"description":"Pflicht für Posten unter Mahnstufe 3 (Freitext)"},"uebergebenAm":{"type":["string","null"],"format":"date"},"uebergebenVon":{"type":["string","null"]},"zurueckgenommenAm":{"type":["string","null"],"format":"date-time"},"zuruecknahmeGrund":{"type":["string","null"]},"abgeschlossenAm":{"type":["string","null"],"format":"date-time"},"abschlussArt":{"type":["string","null"],"enum":["bezahlt","vergleich","uneinbringlich","sonstiges",null]},"abschlussNotiz":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"aufstellung":{"$ref":"#/components/schemas/InkassoAufstellung"},"posten":{"type":"array","items":{"$ref":"#/components/schemas/InkassoUebergabePosten"}}},"required":["id","propertyId","personId","contractId","weg","status","stichtag","zinssatzBasispunkte","aufstellungHash","gesamtCents","currency","empfaenger","begruendungMahnstufe","uebergebenAm","uebergebenVon","zurueckgenommenAm","zuruecknahmeGrund","abgeschlossenAm","abschlussArt","abschlussNotiz","createdAt","aufstellung","posten"]},"InkassoUebergebenPosten":{"type":"object","properties":{"offenerPostenId":{"type":"string","format":"uuid"},"geaendert":{"type":"boolean","description":"false ⇔ der Mahnstatus stand schon auf anwalt"}},"required":["offenerPostenId","geaendert"]},"InkassoUebergabeUebergebenResponse":{"type":"object","properties":{"uebergabeId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["uebergeben"]},"uebergebenAm":{"type":"string","format":"date"},"posten":{"type":"array","items":{"$ref":"#/components/schemas/InkassoUebergebenPosten"}}},"required":["uebergabeId","status","uebergebenAm","posten"]},"InkassoUebergabeZuruecknahmeResponse":{"type":"object","properties":{"uebergabeId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["zurueckgenommen"]},"vorherigerStatus":{"type":"string","enum":["entwurf","uebergeben","zurueckgenommen","abgeschlossen"]},"freigegebenePosten":{"type":"integer"}},"required":["uebergabeId","status","vorherigerStatus","freigegebenePosten"]},"InkassoUebergabeAbschlussResponse":{"type":"object","properties":{"uebergabeId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["abgeschlossen"]},"art":{"type":"string","enum":["bezahlt","vergleich","uneinbringlich","sonstiges"]},"freigegebenePosten":{"type":"integer"}},"required":["uebergabeId","status","art","freigegebenePosten"]},"InkassoDatei":{"type":"object","properties":{"dateiname":{"type":"string","description":"`forderungsaufstellung-<erste 8 Zeichen der Übergabe-Id>-<Stichtag>.csv` — ohne Personenangaben"},"sha256":{"type":"string","description":"SHA-256 der Datei-Bytes (Hex, 64 Zeichen)"},"groesseBytes":{"type":"integer"},"inhaltBase64":{"type":"string","description":"die Datei-Bytes, Base64 (CSV, Semikolon, UTF-8 mit BOM, Dezimalkomma)"}},"required":["dateiname","sha256","groesseBytes","inhaltBase64"]},"InkassoAufstellungDateiResponse":{"type":"object","properties":{"datei":{"$ref":"#/components/schemas/InkassoDatei"},"aufstellungHash":{"type":"string","description":"Hash der kanonischen Aufstellung, wie am Kopf"}},"required":["datei","aufstellungHash"]},"MahnlaufAusfuehrenPosition":{"type":"object","properties":{"schluessel":{"type":"string","description":"Positionsschlüssel (`mahn:vertrag:<id>`)"},"objektId":{"type":["string","null"],"format":"uuid"},"einheitId":{"type":["string","null"],"format":"uuid"},"vertragId":{"type":["string","null"],"format":"uuid"},"personId":{"type":["string","null"],"format":"uuid"},"betragCent":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"status":{"type":"string","description":"gebucht, ausgeschlossen, ausnahme oder fehlgeschlagen"},"grund":{"type":["string","null"],"description":"Klartext-Grund; null bei gebucht"},"versandstatus":{"type":["string","null"],"description":"versendet, download_bereit, heruntergeladen, fehlgeschlagen oder zugestellt; null ohne Schreiben"}},"required":["schluessel","objektId","einheitId","vertragId","personId","betragCent","status","grund","versandstatus"]},"MahnlaufAusfuehrenMarkierung":{"type":"object","properties":{"mahnschreibenId":{"type":"string","format":"uuid"},"schluessel":{"type":"string"},"ampel":{"type":"string","description":"gruen, gelb oder rot (rot ist nicht freigebbar)"},"merkmale":{"type":"array","items":{"type":"string"},"description":"Abweichungs-Merkmale der Heuristik (z. B. erststufe, hoher-betrag)"}},"required":["mahnschreibenId","schluessel","ampel","merkmale"]},"MahnlaufAusfuehrenResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"erstAusfuehrung":{"type":"boolean","description":"false ⇔ der Vorgang war schon ausgeführt, das Erst-Ergebnis kommt zurück"},"zeitpunkt":{"type":"string","format":"date-time"},"gebucht":{"type":"integer","description":"erzeugte Schreiben"},"ausgeschlossen":{"type":"integer"},"ausnahmen":{"type":"integer"},"fehlgeschlagen":{"type":"integer"},"summeCent":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufAusfuehrenPosition"}},"freigegeben":{"type":"array","items":{"type":"string","format":"uuid"},"description":"in DIESEM Aufruf freigegebene Schreiben; leer beim Erst-Ergebnis"},"markiert":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufAusfuehrenMarkierung"},"description":"einzeln freizugebende Schreiben; leer beim Erst-Ergebnis"}},"required":["vorgangId","erstAusfuehrung","zeitpunkt","gebucht","ausgeschlossen","ausnahmen","fehlgeschlagen","summeCent","positionen","freigegeben","markiert"]},"MahnlaufVersandPosition":{"type":"object","properties":{"mahnschreibenId":{"type":"string","format":"uuid"},"ausgang":{"type":"string","enum":["versandt","fehlgeschlagen","uebersprungen","download_bereit"]},"fehlerCode":{"type":["string","null"],"description":"Fehler-Code des Versandwegs bei fehlgeschlagen, sonst null (nie Provider-Rohtext)"},"mahnereignisId":{"type":["string","null"],"format":"uuid","description":"wirksam gewordene Stufe; nur bei versandt"},"gebuehrCent":{"type":["string","null"],"description":"gebuchte Mahngebühr; null ohne Ansatz"},"zinsenCent":{"type":["string","null"],"description":"gebuchter Zins-Zuwachs; null ohne Ansatz"}},"required":["mahnschreibenId","ausgang","fehlerCode","mahnereignisId","gebuehrCent","zinsenCent"]},"MahnlaufVersandErgebnis":{"type":"object","properties":{"versandt":{"type":"integer"},"fehlgeschlagen":{"type":"integer"},"uebersprungen":{"type":"integer"},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/MahnlaufVersandPosition"}}},"required":["versandt","fehlgeschlagen","uebersprungen","positionen"]},"MahnlaufVersandResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"versandweg":{"type":"string","enum":["mail","druck"]},"ergebnis":{"$ref":"#/components/schemas/MahnlaufVersandErgebnis"}},"required":["vorgangId","versandweg","ergebnis"]},"MahnlaufSchreibenFreigabeResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"mahnschreibenId":{"type":"string","format":"uuid"},"entscheidung":{"type":"string","enum":["freigeben","zurueckweisen"]},"ampel":{"type":"string","description":"Ampel der Abweichungs-Heuristik zum Zeitpunkt der Entscheidung"},"versand":{"allOf":[{"$ref":"#/components/schemas/MahnlaufVersandErgebnis"},{"type":["object","null"],"description":"nur bei freigeben: der Versand dieses einen Schreibens; sonst null"}]}},"required":["vorgangId","mahnschreibenId","entscheidung","ampel","versand"]},"MahnlaufZustellungResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"mahnschreibenId":{"type":"string","format":"uuid"},"zustellnachweisId":{"type":"string","format":"uuid"},"kanal":{"type":"string","enum":["brief","einschreiben","persoenliche_uebergabe"]},"zugestelltAm":{"type":"string","format":"date"},"versandstatus":{"type":"string","description":"immer zugestellt"},"mahnereignisIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["vorgangId","mahnschreibenId","zustellnachweisId","kanal","zugestelltAm","versandstatus","mahnereignisIds"]},"MahnlaufErneutResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"mahnschreibenId":{"type":"string","format":"uuid"},"ausgang":{"type":"string","enum":["versandt","fehlgeschlagen"]},"zustellnachweisId":{"type":"string","format":"uuid"},"versandstatus":{"type":"string","description":"versendet oder fehlgeschlagen"}},"required":["vorgangId","mahnschreibenId","ausgang","zustellnachweisId","versandstatus"]},"MahnlaufSchreibenDatei":{"type":"object","properties":{"dateiname":{"type":"string","description":"`Mahnschreiben-<Nachname>-<JJJJ-MM-TT>.pdf`"},"sha256":{"type":"string","description":"SHA-256 der Datei-Bytes (Hex, 64 Zeichen)"},"groesseBytes":{"type":"integer"},"inhaltBase64":{"type":"string","description":"die Datei-Bytes, Base64"}},"required":["dateiname","sha256","groesseBytes","inhaltBase64"]},"MahnlaufSchreibenDateiResponse":{"type":"object","properties":{"datei":{"$ref":"#/components/schemas/MahnlaufSchreibenDatei"}},"required":["datei"]},"IndexanpassungErklaerungResponse":{"type":"object","properties":{"text":{"type":"string","description":"der vollständige Erklärungstext im Standardwortlaut (§ 557b Abs. 3 BGB); nie ein Teiltext"},"vorlageVersion":{"type":"string","description":"Version des Standardwortlauts"},"dokumentHash":{"type":"string","description":"SHA-256 (hex) über den UTF-8-Text"},"zugangErfasst":{"type":"boolean","description":"false ⇒ kein Zugangstag erfasst; der Wirksamkeitsmonat ist die Vorschau auf Basis des geplanten Wirksamkeitstags des Vorgangs"}},"required":["text","vorlageVersion","dokumentHash","zugangErfasst"]},"BuchungsperiodenOeffnung":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"grund":{"type":"string","description":"Pflichtgrund der Öffnung (Freitext, personenbezogen möglich)."},"geoeffnetVon":{"type":"string","format":"uuid","description":"opake Auth-Id dessen, der geöffnet hat"},"geoeffnetAm":{"type":"string","format":"date-time"}},"required":["id","grund","geoeffnetVon","geoeffnetAm"]},"BuchungsperiodenFestschreibung":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date","description":"erster Tag der Periode, eingeschlossen"},"bis":{"type":"string","format":"date","description":"letzter Tag der Periode, eingeschlossen"},"festgeschriebenAm":{"type":"string","format":"date-time"},"festgeschriebenVon":{"type":"string","format":"uuid","description":"opake Auth-Id dessen, der festgeschrieben hat"},"status":{"type":"string","enum":["geltend","geoeffnet"],"description":"geltend = gesperrt (keine Öffnung); geoeffnet = hat eine Öffnung"},"oeffnung":{"allOf":[{"$ref":"#/components/schemas/BuchungsperiodenOeffnung"},{"type":["object","null"],"description":"die Öffnung; null, solange die Festschreibung gilt"}]}},"required":["id","von","bis","festgeschriebenAm","festgeschriebenVon","status","oeffnung"]},"BuchungsperiodenProtokollSatz":{"type":"object","properties":{"journalEntryId":{"type":"string","format":"uuid"},"entryNo":{"type":"string","description":"Buchungsnummer je Objekt (Integer-STRING)"},"entryType":{"type":"string"},"bookingDate":{"type":"string","format":"date"},"accrualDate":{"type":"string","format":"date"},"reversesEntryId":{"type":["string","null"],"format":"uuid","description":"gesetzt bei einem Storno-Satz: der stornierte Satz"},"erfasstAm":{"type":"string","format":"date-time"}},"required":["journalEntryId","entryNo","entryType","bookingDate","accrualDate","reversesEntryId","erfasstAm"]},"BuchungsperiodenProtokollEintrag":{"type":"object","properties":{"festschreibungId":{"type":"string","format":"uuid"},"oeffnungId":{"type":"string","format":"uuid"},"neuFestgeschriebenAm":{"type":["string","null"],"format":"date-time","description":"Zeitpunkt der Neu-Festschreibung derselben Periode; null = noch offen"},"saetze":{"type":"array","items":{"$ref":"#/components/schemas/BuchungsperiodenProtokollSatz"},"description":"nur Journalsätze mit Buchungs- oder Abgrenzungsdatum in der Periode, in der Öffnungszeit; sortiert nach Buchungsnummer"}},"required":["festschreibungId","oeffnungId","neuFestgeschriebenAm","saetze"]},"BuchungsperiodenResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"aktiv":{"type":"boolean","description":"Schalter des Objekts, sonst Mandanten-Vorgabe, sonst false; sperrt nichts Bestehendes"},"schalterObjekt":{"type":["boolean","null"],"description":"eigene Einstellung des Objekts; null = keine"},"schalterMandant":{"type":["boolean","null"],"description":"Mandanten-Vorgabe; null = keine"},"wirtschaftsjahrBeginn":{"type":"string","description":"`kalenderjahr`, `abweichend_MM-DD` oder `unklar`"},"festschreibungen":{"type":"array","items":{"$ref":"#/components/schemas/BuchungsperiodenFestschreibung"},"description":"alle Festschreibungen des Objekts, nach Beginn sortiert"},"protokoll":{"type":"array","items":{"$ref":"#/components/schemas/BuchungsperiodenProtokollEintrag"},"description":"je Öffnung die Journalsätze; nur Journalsätze, keine offenen Posten"}},"required":["propertyId","aktiv","schalterObjekt","schalterMandant","wirtschaftsjahrBeginn","festschreibungen","protokoll"]},"BuchungsperiodeFestschreibungRequest":{"type":"object","properties":{"von":{"type":"string","format":"date","description":"Beginn der Periode; Pflicht nur bei der ersten Festschreibung, ein Wirtschaftsjahr-Beginn"}}},"BuchungsperiodeFestschreibungResponse":{"type":"object","properties":{"festschreibungId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date"},"bis":{"type":"string","format":"date"},"neuFestgeschrieben":{"type":"boolean","description":"true ⇒ eine geöffnete Periode wurde mit genau ihrem Zeitraum neu festgeschrieben"}},"required":["festschreibungId","propertyId","von","bis","neuFestgeschrieben"]},"BuchungsperiodeOeffnungRequest":{"type":"object","properties":{"festschreibungId":{"type":"string","format":"uuid","description":"die zu öffnende Festschreibung DIESES Objekts"},"grund":{"type":"string","description":"Pflichtgrund, getrimmt nicht leer (Freitext)"}},"required":["festschreibungId","grund"]},"BuchungsperiodeOeffnungResponse":{"type":"object","properties":{"oeffnungId":{"type":"string","format":"uuid"},"festschreibungId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date"},"bis":{"type":"string","format":"date"}},"required":["oeffnungId","festschreibungId","propertyId","von","bis"]},"DatevBuchungsstapelRequest":{"type":"object","properties":{"objekte":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"description":"die Objekte des Stapels, mindestens eines (\"alle\" ist eine Wahl, kein Vorgabewert)"},"jahr":{"type":"integer","description":"Kalenderjahr: Zeitraum ist JJJJ-01-01 bis JJJJ-12-31, mit abweichendem wirtschaftsjahrBeginn nur der Teil des Jahres, der im Wirtschaftsjahr liegt (Schnitt leer ⇒ 400)"},"beraternummer":{"type":"string","description":"1 bis 7 Ziffern, ohne führende Null"},"mandantennummer":{"type":"string","description":"1 bis 5 Ziffern, ohne führende Null"},"sachkontenlaenge":{"type":"integer","description":"4 bis 8"},"kontenrahmen":{"type":"string","enum":["skr03","skr04"]},"festschreibung":{"anyOf":[{"type":"number","enum":[0]},{"type":"number","enum":[1]}],"description":"Festschreibekennzeichen im Kopfsatz (GoBD-Angabe an DATEV), Pflicht, kein Vorgabewert; der Export löst KEINE Festschreibung in casa.ai aus"},"wirtschaftsjahrBeginn":{"type":"string","format":"date","description":"Beginn des Wirtschaftsjahres; Vorgabe JJJJ-01-01 des Jahres. Ein abweichender Beginn grenzt den Zeitraum auf Wirtschaftsjahr und Kalenderjahr ein: zwei Stapel (zwei Aufrufe)"},"ustDarstellung":{"type":"string","enum":["automatikkonto","ust_schluessel"]}},"required":["objekte","jahr","beraternummer","mandantennummer","sachkontenlaenge","kontenrahmen","festschreibung"]},"DatevBuchungsstapelDatei":{"type":"object","properties":{"dateiname":{"type":"string"},"sha256":{"type":"string"},"groesseBytes":{"type":"integer"},"inhaltBase64":{"type":"string"}},"required":["dateiname","sha256","groesseBytes","inhaltBase64"]},"DatevBuchungsstapelResponse":{"type":"object","properties":{"laufId":{"type":["string","null"],"format":"uuid","description":"Zeile in der Export-Historie"},"dateiname":{"type":"string"},"sha256":{"type":"string"},"buchungszeilen":{"type":"integer"},"buchungssaetze":{"type":"integer"},"summeCents":{"type":"string","description":"Integer-String in Cent"},"exportiertAm":{"type":"string","format":"date-time"},"hinweise":{"type":"array","items":{"type":"string"},"description":"Hinweise auf nicht festgeschriebene Perioden; leer = vollständig festgeschrieben. Hinweis, kein Abweis."},"datei":{"$ref":"#/components/schemas/DatevBuchungsstapelDatei"}},"required":["laufId","dateiname","sha256","buchungszeilen","buchungssaetze","summeCents","exportiertAm","hinweise","datei"]},"DatevDebKredRequest":{"type":"object","properties":{"objekte":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"description":"die Objekte des Stapels, mindestens eines (\"alle\" ist eine Wahl, kein Vorgabewert)"},"jahr":{"type":"integer","description":"Kalenderjahr: Zeitraum ist JJJJ-01-01 bis JJJJ-12-31, mit abweichendem wirtschaftsjahrBeginn nur der Teil des Jahres, der im Wirtschaftsjahr liegt (Schnitt leer ⇒ 400)"},"beraternummer":{"type":"string","description":"1 bis 7 Ziffern, ohne führende Null"},"mandantennummer":{"type":"string","description":"1 bis 5 Ziffern, ohne führende Null"},"sachkontenlaenge":{"type":"integer","description":"4 bis 8"},"kontenrahmen":{"type":"string","enum":["skr03","skr04"]},"festschreibung":{"anyOf":[{"type":"number","enum":[0]},{"type":"number","enum":[1]}],"description":"Festschreibekennzeichen im Kopfsatz (GoBD-Angabe an DATEV), Pflicht, kein Vorgabewert; der Export löst KEINE Festschreibung in casa.ai aus"},"wirtschaftsjahrBeginn":{"type":"string","format":"date","description":"Beginn des Wirtschaftsjahres; Vorgabe JJJJ-01-01 des Jahres. Ein abweichender Beginn grenzt den Zeitraum auf Wirtschaftsjahr und Kalenderjahr ein: zwei Stapel (zwei Aufrufe)"},"ustDarstellung":{"type":"string","enum":["automatikkonto","ust_schluessel"]},"umfang":{"type":"string","enum":["buchungsstapel","alle-aktiven"],"description":"Pflicht, kein Vorgabewert: \"buchungsstapel\" = genau die Personenkonten des Stapels desselben Zeitraums; \"alle-aktiven\" = zusätzlich jedes nicht archivierte Personenkonto der Objekte (plus alle Kreditoren des Mandanten)"}},"required":["objekte","jahr","beraternummer","mandantennummer","sachkontenlaenge","kontenrahmen","festschreibung","umfang"]},"DatevDebKredResponse":{"type":"object","properties":{"dateiname":{"type":"string"},"sha256":{"type":"string"},"personenkonten":{"type":"integer"},"mitBankverbindung":{"type":"integer","description":"Anzahl der Personenkonten mit bestätigter Bankverbindung (eine Zahl, keine IBAN)"},"exportiertAm":{"type":"string","format":"date-time"},"hinweise":{"type":"array","items":{"type":"string"},"description":"u. a. \"nicht in der Historie abgelegt, Datei jetzt sichern\": die Datei ist nicht erneut abrufbar"},"datei":{"$ref":"#/components/schemas/DatevBuchungsstapelDatei"}},"required":["dateiname","sha256","personenkonten","mitBankverbindung","exportiertAm","hinweise","datei"]},"DatevBelegpaketRequest":{"type":"object","properties":{"objekte":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"description":"die Objekte des Stapels, mindestens eines (\"alle\" ist eine Wahl, kein Vorgabewert)"},"jahr":{"type":"integer","description":"Kalenderjahr: Zeitraum ist JJJJ-01-01 bis JJJJ-12-31, mit abweichendem wirtschaftsjahrBeginn nur der Teil des Jahres, der im Wirtschaftsjahr liegt (Schnitt leer ⇒ 400)"},"beraternummer":{"type":"string","description":"1 bis 7 Ziffern, ohne führende Null"},"mandantennummer":{"type":"string","description":"1 bis 5 Ziffern, ohne führende Null"},"sachkontenlaenge":{"type":"integer","description":"4 bis 8"},"kontenrahmen":{"type":"string","enum":["skr03","skr04"]},"festschreibung":{"anyOf":[{"type":"number","enum":[0]},{"type":"number","enum":[1]}],"description":"Festschreibekennzeichen im Kopfsatz (GoBD-Angabe an DATEV), Pflicht, kein Vorgabewert; der Export löst KEINE Festschreibung in casa.ai aus"},"wirtschaftsjahrBeginn":{"type":"string","format":"date","description":"Beginn des Wirtschaftsjahres; Vorgabe JJJJ-01-01 des Jahres. Ein abweichender Beginn grenzt den Zeitraum auf Wirtschaftsjahr und Kalenderjahr ein: zwei Stapel (zwei Aufrufe)"},"ustDarstellung":{"type":"string","enum":["automatikkonto","ust_schluessel"]}},"required":["objekte","jahr","beraternummer","mandantennummer","sachkontenlaenge","kontenrahmen","festschreibung"]},"DatevBelegpaketDatei":{"type":"object","properties":{"dateiname":{"type":"string"},"sha256":{"type":"string"},"groesseBytes":{"type":"integer"},"belege":{"type":"integer","description":"Anzahl der Belege (Belegdateien) im Paket"},"inhaltBase64":{"type":"string"}},"required":["dateiname","sha256","groesseBytes","belege","inhaltBase64"]},"DatevBuchungOhneBeleg":{"type":"object","properties":{"zeilenNr":{"type":"integer","description":"1-basierte Nummer der Buchungszeile im Stapel (ohne Kopf- und Spaltenzeile)"},"grund":{"type":"string","enum":["kein_beleg","quarantaene","original_fehlt","original_beschaedigt","dateityp_nicht_uebertragbar"]}},"required":["zeilenNr","grund"]},"DatevBelegpaketResponse":{"type":"object","properties":{"stapel":{"allOf":[{"$ref":"#/components/schemas/DatevBuchungsstapelResponse"},{"description":"der Buchungsstapel mit Beleglinks (Metadaten, laufId, hinweise aus der Festschreibungs-Prüfung, datei); der Lauf steht in der Export-Historie"}]},"belegpaket":{"allOf":[{"$ref":"#/components/schemas/DatevBelegpaketDatei"},{"type":["object","null"],"description":"null, wenn keine Buchung einen übertragbaren Beleg hat; das ZIP wird NICHT in der Historie abgelegt und ist nur in dieser Antwort abrufbar"}]},"ohneBeleg":{"type":"array","items":{"$ref":"#/components/schemas/DatevBuchungOhneBeleg"},"description":"alle Buchungszeilen ohne Beleg im Paket, aufsteigend nach zeilenNr"},"hinweis":{"type":["string","null"],"description":"Klartext genau dann, wenn belegpaket null ist"}},"required":["stapel","belegpaket","ohneBeleg","hinweis"]},"DatevHistorieEintrag":{"type":"object","properties":{"laufId":{"type":"string","format":"uuid"},"zeitraumVon":{"type":"string","format":"date"},"zeitraumBis":{"type":"string","format":"date"},"objekte":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Alle Objekte des Laufs (ein Lauf über A und B steht in der Liste jedes der beiden Objekte)"},"dateiname":{"type":"string"},"sha256":{"type":"string"},"buchungszeilen":{"type":"integer"},"summeCents":{"type":"string","description":"Integer-String in Cent"},"erzeugtAm":{"type":"string","format":"date-time"},"erzeugtVon":{"type":"string","description":"Opake Id der erzeugenden Person"},"erzeugtVonArt":{"type":"string","description":"user | agent | system"}},"required":["laufId","zeitraumVon","zeitraumBis","objekte","dateiname","sha256","buchungszeilen","summeCents","erzeugtAm","erzeugtVon","erzeugtVonArt"]},"DatevHistorieListResponse":{"type":"object","properties":{"eintraege":{"type":"array","items":{"$ref":"#/components/schemas/DatevHistorieEintrag"}},"weiter":{"type":["string","null"],"description":"Opaker Cursor für die nächste Seite (Query weiter); null = Historie zu Ende"}},"required":["eintraege","weiter"]},"DatevHistorieDateiResponse":{"type":"object","properties":{"laufId":{"type":"string","format":"uuid"},"datei":{"$ref":"#/components/schemas/DatevBuchungsstapelDatei"}},"required":["laufId","datei"]},"FestschreibungSchalterRequest":{"type":"object","properties":{"propertyId":{"type":["string","null"],"format":"uuid","description":"das Objekt; null = Mandanten-Vorgabe"},"aktiv":{"type":"boolean"}},"required":["propertyId","aktiv"]},"FestschreibungSchalterResponse":{"type":"object","properties":{"propertyId":{"type":["string","null"],"format":"uuid"},"aktiv":{"type":"boolean"}},"required":["propertyId","aktiv"]},"KautionEinstellungResponse":{"type":"object","properties":{"rueckbehaltFristMonate":{"type":"integer","minimum":1,"maximum":36,"description":"Frist des Rückbehalts in Monaten (beginnt mit dem Abrechnungsdatum der Kautionsabrechnung)"},"istVorgabe":{"type":"boolean","description":"true ⇒ keine eigene Einstellung, es gilt die Vorgabe (6 Monate)"}},"required":["rueckbehaltFristMonate","istVorgabe"]},"KautionZinsstandUmsatz":{"type":"object","properties":{"bankTransactionId":{"type":"string","format":"uuid","description":"der Bankumsatz — die Bankgutschrift wird später gegen die Zinsforderung zugeordnet (der Jahreszinslauf liest keinen Umsatz)"},"betragCents":{"type":"string","description":"Haben-Betrag, streng positiv"},"currency":{"type":"string"},"wertstellung":{"type":["string","null"],"format":"date","description":"Wertstellungstag; null, wenn die Bank keinen lieferte"}},"required":["bankTransactionId","betragCents","currency","wertstellung"]},"KautionZinsstandKonto":{"type":"object","properties":{"anlagekontoId":{"type":"string","format":"uuid","description":"Bankverbindung der Kontoart kautionskonto"},"propertyId":{"type":"string","format":"uuid"},"von":{"type":["string","null"],"format":"date","description":"Beginn des zuletzt verzinsten Zeitraums; null ohne gebuchten Zinslauf"},"bis":{"type":["string","null"],"format":"date","description":"Ende des zuletzt verzinsten Zeitraums (einschliesslich); null ohne gebuchten Zinslauf"},"anzahlBarkautionen":{"type":"integer","description":"Zahl der Barkautionen auf diesem Konto"},"festzinsBasispunkte":{"type":["integer","null"],"description":"der am Stichtag (Vorgabe: heute) gültige Satz der Satzhistorie in Basispunkten (150 = 1,50 %); null = an diesem Tag gilt kein Satz. Nur Anzeige."},"unverteilteUmsaetze":{"type":"array","items":{"$ref":"#/components/schemas/KautionZinsstandUmsatz"},"description":"unbeanspruchte Haben-Umsätze, aufsteigend nach Wertstellung — Kandidaten, nicht festgestellte Zinsen"},"gebuchteJahre":{"type":"array","items":{"type":"integer"},"description":"Kalenderjahre mit wirksam gebuchtem Zinslauf, aufsteigend (Jahreszinslauf und alter Bankumsatz-Lauf)"},"naechstesOffenesJahr":{"type":["integer","null"],"description":"das nächste zu buchende Zinsjahr (höchstes gebuchtes + 1, ohne gebuchtes Jahr das Jahr des ersten Kautionseingangs) — die Eingabe jahr des Zinslauf-Vorschlags (POST /api/kaution/zinsen/vorschlag); null ohne Kautionseingang"}},"required":["anlagekontoId","propertyId","von","bis","anzahlBarkautionen","festzinsBasispunkte","unverteilteUmsaetze","gebuchteJahre","naechstesOffenesJahr"]},"KautionZinsstandResponse":{"type":"object","properties":{"konten":{"type":"array","items":{"$ref":"#/components/schemas/KautionZinsstandKonto"},"description":"nur Anlagekonten der Objekte, für die der Aufrufer zuständig ist"}},"required":["konten"]},"KautionZinssatz":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"gueltigAb":{"type":"string","format":"date","description":"erster Tag, an dem der Satz gilt (inklusiv)"},"basispunkte":{"type":"integer","minimum":0,"maximum":2000,"description":"Satz in Basispunkten (150 = 1,50 %)"},"erfasstVon":{"type":"string","description":"opake Akteurs-Id; migration für die Bestandsübernahme"},"erfasstAm":{"type":"string","format":"date-time","description":"Zeitpunkt der Erfassung"}},"required":["id","gueltigAb","basispunkte","erfasstVon","erfasstAm"]},"KautionZinssaetzeResponse":{"type":"object","properties":{"bankAccountId":{"type":"string","format":"uuid","description":"Bankverbindung der Kontoart kautionskonto"},"saetze":{"type":"array","items":{"$ref":"#/components/schemas/KautionZinssatz"},"description":"Satzhistorie aufsteigend nach gueltigAb; leer für ein fremdes, unbekanntes oder nicht zuständiges Konto"}},"required":["bankAccountId","saetze"]},"BauabzugAnmeldungMonat":{"type":"object","properties":{"anmeldemonat":{"type":"string","description":"JJJJ-MM"},"faelligAm":{"type":"string","format":"date","description":"10. des Folgemonats"},"summeCents":{"type":"string","description":"Summe der Einbehalte des Monats"},"currency":{"type":"string"},"anzahl":{"type":"integer"}},"required":["anmeldemonat","faelligAm","summeCents","currency","anzahl"]},"BauabzugAnmeldungResponse":{"type":"object","properties":{"jahr":{"type":"integer"},"monate":{"type":"array","items":{"$ref":"#/components/schemas/BauabzugAnmeldungMonat"},"description":"aufsteigend nach Monat; Monate ohne Einbehalt erscheinen nicht"}},"required":["jahr","monate"]},"BauabzugBescheinigungsBefund":{"type":"object","properties":{"status":{"type":"string","enum":["gueltig","fehlt","abgelaufen","anderer-auftrag"]},"nummer":{"type":["string","null"]},"gueltigBis":{"type":["string","null"],"format":"date"},"auftragsbezug":{"type":["string","null"]}},"required":["status","nummer","gueltigBis","auftragsbezug"]},"BauabzugPruefung":{"type":"object","properties":{"paymentOrderId":{"type":"string","format":"uuid"},"openItemId":{"type":"string"},"kreditorPersonId":{"type":"string","format":"uuid"},"grund":{"type":"string","enum":["vermieter-hoechstens-zwei-wohnungen","bescheinigung-gueltig","unter-bagatellgrenze","volle-zahlung-begruendet","einbehalt"]},"rechnungsbetragCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"auszahlungCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"einbehaltCents":{"type":"string","description":"bei grund einbehalt die Verbindlichkeit gegenüber dem Finanzamt"},"currency":{"type":"string"},"zahlungstag":{"type":"string","format":"date"},"faelligAm":{"type":["string","null"],"format":"date"},"anmeldemonat":{"type":["string","null"]},"bescheinigung":{"$ref":"#/components/schemas/BauabzugBescheinigungsBefund"},"volleZahlungBegruendung":{"type":["string","null"]},"volleZahlungErlaubtVon":{"type":["string","null"]}},"required":["paymentOrderId","openItemId","kreditorPersonId","grund","rechnungsbetragCents","auszahlungCents","einbehaltCents","currency","zahlungstag","faelligAm","anmeldemonat","bescheinigung","volleZahlungBegruendung","volleZahlungErlaubtVon"]},"BauabzugPruefungenResponse":{"type":"object","properties":{"pruefungen":{"type":"array","items":{"$ref":"#/components/schemas/BauabzugPruefung"},"description":"nach Zahlungstag und Posten geordnet"}},"required":["pruefungen"]},"Freistellungsbescheinigung":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kreditorPersonId":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"gueltigBis":{"type":"string","format":"date"},"umfang":{"type":"string","enum":["allgemein","auftragsbezogen"]},"auftragsbezug":{"type":["string","null"]},"finanzamt":{"type":"string"}},"required":["id","kreditorPersonId","nummer","gueltigBis","umfang","auftragsbezug","finanzamt"]},"FreistellungsbescheinigungenResponse":{"type":"object","properties":{"kreditorPersonId":{"type":"string","format":"uuid"},"bescheinigungen":{"type":"array","items":{"$ref":"#/components/schemas/Freistellungsbescheinigung"},"description":"absteigend nach Gültigkeit"}},"required":["kreditorPersonId","bescheinigungen"]},"AltbestandPosten":{"type":"object","properties":{"quellSchluessel":{"type":"string","description":"Der Schlüssel der Quellzeile im Altsystem — Herkunftsnachweis UND Dubletten-Anker."},"art":{"type":"string","enum":["op","mahnung","zahlung"],"description":"'op' wurde gebucht; 'mahnung'/'zahlung' bewusst NICHT."},"datum":{"type":"string","format":"date","description":"Originalfälligkeit, Mahndatum oder Zahltag — je nach art."},"betragCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"contractId":{"type":"string","format":"uuid"},"journalEntryId":{"type":["string","null"],"format":"uuid","description":"Die Eröffnungs-Sollstellung, die aus dieser Zeile entstanden ist — null für Mahn- und Zahlhistorie. Genau dieses Feld macht die beiden Sichten unterscheidbar, ohne dass der Leser die Bedeutung von art kennen müsste."}},"required":["quellSchluessel","art","datum","betragCents","currency","contractId","journalEntryId"]},"AltbestandPostenListResponse":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"posten":{"type":"array","items":{"$ref":"#/components/schemas/AltbestandPosten"},"description":"Aufsteigend nach (datum, quellSchluessel) — die Ordnung ist Vertrag: eine Auskunft, deren Reihenfolge zwischen zwei Aufrufen wechselt, ist gegen einen Widerspruch nicht verwendbar. Ein fremder Vertrag liefert eine LEERE Liste wie ein nie existierter (kein Existenz-Orakel)."}},"required":["contractId","posten"]},"EroeffnungsProvenienz":{"type":"object","properties":{"journalEntryId":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"quellSchluessel":{"type":"string","description":"Die einzelne Quellzeile — ohne sie wäre in einem 2.778-Zeilen-Lauf nur die Datei bekannt."},"uebernahmestichtag":{"type":"string","format":"date","description":"Der EINGEGEBENE Übernahmestichtag, unverändert."},"quellsystem":{"type":"string","description":"Das Altsystem, z. B. 'win-casa'."},"exportiertAm":{"type":"string","format":"date-time","description":"Der EXPORT aus dem Altsystem, nicht der Import."},"dateiHash":{"type":"string","description":"SHA-256 der Sicherungsdatei, 64 Hex, kleingeschrieben."}},"required":["journalEntryId","contractId","quellSchluessel","uebernahmestichtag","quellsystem","exportiertAm","dateiHash"]},"AltbestandProvenienzResponse":{"type":"object","properties":{"journalEntryId":{"type":"string","format":"uuid"},"provenienz":{"allOf":[{"$ref":"#/components/schemas/EroeffnungsProvenienz"},{"type":["object","null"],"description":"null ist BEWUSST die Antwort für drei ununterscheidbare Lagen: fremder Mandant, nie existiert, oder eine Buchung, die nicht aus einer Übernahme stammt. Ein 404 für eine davon wäre genau das Existenz-Orakel, das es nicht geben darf."}]}},"required":["journalEntryId","provenienz"]},"UebernahmeAbrechnungLauf":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"periodFrom":{"type":"string","format":"date"},"periodTo":{"type":"string","format":"date"},"status":{"type":"string","description":"Status des Laufs; ein übernommener Lauf ist `festgeschrieben`."},"herkunft":{"type":["string","null"],"description":"`uebernahme` = als Bestand übernommen (nicht gerechnet); `null` = eigener, in casa.ai gerechneter Lauf."},"uebernommen":{"type":"boolean","description":"true ⇔ herkunft = `uebernahme`. Ein übernommener Lauf kennt keine § 35a-Bescheinigung und keinen Einwand (409)."},"createdAt":{"type":"string","format":"date-time"}},"required":["id","propertyId","periodFrom","periodTo","status","herkunft","uebernommen","createdAt"]},"UebernahmeAbrechnungVorschauPosten":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"art":{"type":"string","enum":["sollstellung","gutschrift"]},"nominalCents":{"type":"string","description":"Integer-STRING in Cent, signiert."},"originalFaelligkeit":{"type":"string","format":"date"}},"required":["contractId","art","nominalCents","originalFaelligkeit"]},"UebernahmeAbrechnungVorschauResponse":{"type":"object","properties":{"pruefung":{"type":"boolean","enum":[true]},"geschrieben":{"type":"boolean","enum":[false]},"propertyId":{"type":"string","format":"uuid"},"periodFrom":{"type":"string","format":"date"},"periodTo":{"type":"string","format":"date"},"uebernahmestichtag":{"type":"string","format":"date"},"bindingContentHash":{"type":"string","description":"SHA-256 (hex) über den Snapshot aller übergebenen Werte — derselbe, den die Übernahme siegelt."},"anzahlVertraege":{"type":"integer"},"summeNachzahlungCents":{"type":"string","description":"Integer-STRING in Cent; Summe der Ergebnisse > 0."},"summeGuthabenCents":{"type":"string","description":"Integer-STRING in Cent (negativ); Summe der Ergebnisse < 0."},"eroeffnungsposten":{"type":"array","items":{"$ref":"#/components/schemas/UebernahmeAbrechnungVorschauPosten"}}},"required":["pruefung","geschrieben","propertyId","periodFrom","periodTo","uebernahmestichtag","bindingContentHash","anzahlVertraege","summeNachzahlungCents","summeGuthabenCents","eroeffnungsposten"]},"UebernahmeAbrechnungEroeffnungsbuchung":{"type":"object","properties":{"sourceKey":{"type":"string","description":"Quellschlüssel der Zeile (`bk-bestand:<Lauf-Id>:<Vertrags-Id>`), Grundlage der Wiederholungssicherheit."},"journalEntryId":{"type":"string","format":"uuid"},"accrualDate":{"type":"string","format":"date"},"bruttoCents":{"type":"string","description":"Integer-STRING in Cent, signiert."},"replay":{"type":"boolean","description":"true ⇔ der Posten existierte schon (Wiederholung), es wurde nichts neu gebucht."}},"required":["sourceKey","journalEntryId","accrualDate","bruttoCents","replay"]},"UebernahmeAbrechnungUebernommenResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"laufId":{"type":"string","format":"uuid"},"periodFrom":{"type":"string","format":"date"},"periodTo":{"type":"string","format":"date"},"status":{"type":"string","enum":["festgeschrieben"]},"herkunft":{"type":"string","enum":["uebernahme"]},"uebernahmestichtag":{"type":"string","format":"date"},"bindingContentHash":{"type":"string","description":"SHA-256 (hex) über den Snapshot aller übergebenen Werte (das Siegel)."},"anzahlVertraege":{"type":"integer"},"anzahlEroeffnungsposten":{"type":"integer"},"eroeffnung":{"type":["object","null"],"properties":{"gebucht":{"type":"array","items":{"$ref":"#/components/schemas/UebernahmeAbrechnungEroeffnungsbuchung"}},"anzahlNeu":{"type":"integer"},"anzahlReplay":{"type":"integer"}},"required":["gebucht","anzahlNeu","anzahlReplay"],"description":"null, wenn kein Vertrag als „offen\" gekennzeichnet war (nichts über die Migrationsnaht gebucht)."}},"required":["propertyId","laufId","periodFrom","periodTo","status","herkunft","uebernahmestichtag","bindingContentHash","anzahlVertraege","anzahlEroeffnungsposten","eroeffnung"]},"UebernahmeAbrechnungenListResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"laeufe":{"type":"array","items":{"$ref":"#/components/schemas/UebernahmeAbrechnungLauf"},"description":"Neueste zuerst. Ein fremdes oder unbekanntes Objekt liefert eine LEERE Liste (kein Existenz-Orakel)."}},"required":["propertyId","laeufe"]},"BankabgleichVorlageResponse":{"type":"object","properties":{"bankTransactionId":{"type":"string","format":"uuid"},"proposalId":{"type":"string","format":"uuid"},"version":{"type":"integer"},"contentHash":{"type":"string","description":"Der Inhalts-Hash, an den die Freigabe bindet (INV-APPROVAL-01)."},"ampel":{"type":"string"},"propertyId":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"allocatedCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"allocationCount":{"type":"integer"}},"required":["bankTransactionId","proposalId","version","contentHash","ampel","propertyId","contractId","allocatedCents","currency","allocationCount"]},"BankabgleichVerbuchungZeile":{"type":"object","properties":{"bankTransactionId":{"type":"string","format":"uuid"},"proposalId":{"type":"string","format":"uuid"},"buchungsanspruchId":{"type":"string","format":"uuid","description":"GENAU EIN wirksamer Buchungsanspruch je Umsatz (INV-BANK-01)."},"allocatedCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"creditBalanceCents":{"type":"string","description":"Der nicht verrechnete Teil — BERICHTET, nicht als eigene Zeile gebucht."}},"required":["bankTransactionId","proposalId","buchungsanspruchId","allocatedCents","creditBalanceCents"]},"BankabgleichVerbuchungResponse":{"type":"object","properties":{"modus":{"type":"string","enum":["einzeln","sammel"]},"anzahl":{"type":"integer"},"ergebnisse":{"type":"array","items":{"$ref":"#/components/schemas/BankabgleichVerbuchungZeile"}}},"required":["modus","anzahl","ergebnisse"]},"SollstellungslaufStartResponse":{"type":"object","properties":{"sollstellungslaufId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["geplant"]},"vorschlaege":{"type":"object","properties":{"neu":{"type":"integer"},"storno":{"type":"integer"},"ersatz":{"type":"integer"}},"required":["neu","storno","ersatz"]},"uebersprungen":{"type":"integer"},"uebergangen":{"type":"boolean","description":"true, wenn offene Readiness-Befunde MIT Begründung übergangen wurden (auditiert)."}},"required":["sollstellungslaufId","status","vorschlaege","uebersprungen","uebergangen"]},"SollstellungFreigabeEintrag":{"type":"object","properties":{"approvalId":{"type":"string","format":"uuid"},"proposalId":{"type":"string","format":"uuid"},"version":{"type":"integer"},"contentHash":{"type":"string"}},"required":["approvalId","proposalId","version","contentHash"]},"SollstellungFreigabeResponse":{"type":"object","properties":{"decision":{"type":"string","enum":["approved"]},"count":{"type":"integer"},"approvals":{"type":"array","items":{"$ref":"#/components/schemas/SollstellungFreigabeEintrag"}}},"required":["decision","count","approvals"]},"SollstellungVorschlag":{"type":"object","properties":{"proposalId":{"type":"string","format":"uuid","description":"GENAU die id, die `POST /api/sollstellung/freigabe` in `proposalIds` erwartet."},"version":{"type":"integer","description":"Fassung des Vorschlags — nach einer Korrektur die NEUE (die Kette ist aufgelöst)."},"bindungId":{"type":"string","format":"uuid","description":"Die Planungs-Bindung dahinter — der Gegenstand einer Herausnahme aus dem Lauf."},"art":{"type":"string","enum":["neu","storno","ersatz"]},"contractId":{"type":"string","format":"uuid"},"contractNo":{"type":["string","null"],"description":"Vertragsnummer zur Anzeige; null, falls nicht auflösbar."},"periodeVon":{"type":"string","format":"date"},"periodeBis":{"type":"string","format":"date"},"faelligAm":{"type":"string","format":"date"},"betragCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string"},"ampel":{"type":"string","description":"Aus dem Lauf gelesen, hier nie gerechnet. ALL-GREEN: ein nicht-grüner Vorschlag lässt die Freigabe scheitern."},"entschieden":{"type":"boolean","description":"Liegt bereits eine Entscheidung (Freigabe/Ablehnung) vor? Sagt NICHT, ob sie den aktuellen Stand noch bindet."},"bindetAktuellenStand":{"type":"boolean","description":"true ⇔ die Entscheidung hängt an der AKTUELLEN Fassung. false bei „noch offen\" UND bei „durch Korrektur ungültig\"."}},"required":["proposalId","version","bindungId","art","contractId","contractNo","periodeVon","periodeBis","faelligAm","betragCents","currency","ampel","entschieden","bindetAktuellenStand"]},"SollstellungBefund":{"type":"object","properties":{"klasse":{"type":"string"},"contractId":{"type":"string","format":"uuid"},"contractNo":{"type":["string","null"]},"periodeVon":{"type":["string","null"],"format":"date"},"periodeBis":{"type":["string","null"],"format":"date"},"meldung":{"type":"string"}},"required":["klasse","contractId","contractNo","periodeVon","periodeBis","meldung"]},"SollstellungVorschlaegeResponse":{"type":"object","properties":{"sollstellungslaufId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"status":{"type":"string"},"uebergangen":{"type":"boolean","description":"true, wenn der Start nur durch ein auditiertes Übergehen zustande kam."},"vorschlaege":{"type":"array","items":{"$ref":"#/components/schemas/SollstellungVorschlag"}},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/SollstellungBefund"}}},"required":["sollstellungslaufId","propertyId","stichtag","status","uebergangen","vorschlaege","befunde"]},"BankUmsatz":{"type":"object","properties":{"transaktionId":{"type":"string","format":"uuid","description":"GENAU die id, die `POST /api/bankabgleich/vorlegen` als `bankTransactionId` erwartet."},"bankAccountId":{"type":"string","format":"uuid"},"quelle":{"type":"string","description":"Herkunft der Zeile (`camt` · `banksapi` · …)."},"providerId":{"type":["string","null"],"description":"Die eindeutige Referenz der BANK (bei camt `AcctSvcrRef`) — der Schlüssel, über den ein Auszug wiederfindbar ist."},"betragCents":{"type":"string","description":"SIGNIERT: > 0 Eingang, < 0 Ausgang."},"currency":{"type":"string"},"buchungsdatum":{"type":["string","null"],"format":"date"},"wertstellungsdatum":{"type":["string","null"],"format":"date"},"verwendungszweck":{"type":["string","null"]},"buchungstext":{"type":["string","null"]},"gegenkontoIban":{"type":["string","null"]},"gegenkontoInhaber":{"type":["string","null"]},"gvCode":{"type":["string","null"]},"endToEndId":{"type":["string","null"]},"mandateId":{"type":["string","null"]},"correlationId":{"type":["string","null"],"description":"Der Import-Lauf, dem sich der Umsatz zuschreibt."},"gebucht":{"type":"boolean","description":"Zeigt auf den Umsatz ein WIRKSAMER Buchungsanspruch? Dasselbe Prädikat wie Arbeitsliste und Reconciliation."},"importiertAm":{"type":"string","format":"date-time","description":"Wann die Zeile ENTSTAND — die Import-Zeit, nicht die Bankzeit."}},"required":["transaktionId","bankAccountId","quelle","providerId","betragCents","currency","buchungsdatum","wertstellungsdatum","verwendungszweck","buchungstext","gegenkontoIban","gegenkontoInhaber","gvCode","endToEndId","mandateId","correlationId","gebucht","importiertAm"]},"BankUmsatzListResponse":{"type":"object","properties":{"bankAccountId":{"type":"string","format":"uuid"},"iban":{"type":"string"},"propertyId":{"type":"string","format":"uuid"},"stillgelegt":{"type":"boolean","description":"Auskunft, kein Filter: eine stillgelegte Verbindung liefert ihren Bestand weiter aus."},"importAusgeschlossen":{"type":"boolean","description":"Ist die Verbindung vom automatisierten Import ausgenommen?"},"menge":{"type":"string","enum":["alle","offen","gebucht"]},"umsaetze":{"type":"array","items":{"$ref":"#/components/schemas/BankUmsatz"}},"abgeschnitten":{"type":"boolean","description":"GEMESSEN, nicht geraten: true ⇔ es gibt mehr Zeilen als `limit`."}},"required":["bankAccountId","iban","propertyId","stillgelegt","importAusgeschlossen","menge","umsaetze","abgeschnitten"]},"AbschlussLauf":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"wirtschaftsjahr":{"type":"integer","description":"Das Wirtschaftsjahr, dessen Abschluss dieser Lauf trägt."},"art":{"type":"string","enum":["abschluss","korrektur"],"description":"abschluss = der erste Lauf eines Jahres; korrektur = der Nachfolger eines stornierten."},"beschlussRef":{"type":"string","description":"Kanonische Beschluss-Teilgegenstands-Referenz `beschluss-gegenstand:<uuid>` (S12-T02) — die Rechtsgrundlage des Laufs."},"beschlussStatus":{"type":"string","enum":["angenommen","abgelehnt","angefochten","bestandskraeftig","aufgehoben","nichtig"],"description":"Der Status, unter dem der Lauf steht; `bestandskraeftig` ⇒ Freeze (§ 28 Abs. 2 WEG)."},"snapshotHash":{"type":["string","null"],"description":"Der Festschreibungs-Anker (Muster F7), 64 Hex-Zeichen klein. `null`, solange nichts festgeschrieben ist — ein erfundener Anker wäre schlimmer als keiner."},"storniert":{"type":"boolean"},"storniertAm":{"type":["string","null"],"format":"date","description":"Der Tag des Stornos; `null` ohne Storno. Er kommt vom Aufrufer, nie aus der Uhr des Servers (BP §8)."},"stornoGrund":{"type":["string","null"],"description":"Warum storniert wurde — ein Storno ohne Begründung ist im Audit wertlos."},"ersetztLaufId":{"type":["string","null"],"format":"uuid","description":"Der Lauf, den DIESER ersetzt; `null` beim ersten Lauf eines Jahres."},"ausgeloestVon":{"type":["string","null"],"description":"WER den Korrekturlauf ausgelöst hat; bei `art = abschluss` `null` (ein anonymer Korrekturlauf ist keiner)."}},"required":["id","propertyId","wirtschaftsjahr","art","beschlussRef","beschlussStatus","snapshotHash","storniert","storniertAm","stornoGrund","ersetztLaufId","ausgeloestVon"]},"AbschlussLaufListResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"jahr":{"type":["integer","null"],"description":"Das gefilterte Wirtschaftsjahr (Echo) oder `null` für „alle Jahre\"."},"laeufe":{"type":"array","items":{"$ref":"#/components/schemas/AbschlussLauf"}}},"required":["propertyId","jahr","laeufe"]},"AbschlussFreezeResponse":{"type":"object","properties":{"laufId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"zustand":{"type":"string","enum":["offen","festgeschrieben"],"description":"festgeschrieben = bestandskräftiger Beschluss; offen = alles andere."},"beschlussRef":{"type":"string","description":"Der tragende Beschluss — auch im Zustand `offen` benannt, denn er trägt den Lauf."},"korrekturweg":{"type":"string","enum":["storno"],"description":"Der EINZIGE Weg zur Korrektur, unabhängig vom Zustand."},"snapshotGeprueft":{"type":"boolean","description":"Wurde die ZWEITE Hälfte von F7 gefahren? `true` nur, wenn der Aufrufer mit `snapshotHash` den am AKTUELLEN Stand gebildeten Hash mitgegeben hat. Ohne ihn beantwortet die Route allein die Status-Frage — sie behauptet nicht, den Stand geprüft zu haben."}},"required":["laufId","propertyId","jahr","zustand","beschlussRef","korrekturweg","snapshotGeprueft"]},"AbschlussStornoRequest":{"type":"object","properties":{"grund":{"type":"string","description":"Warum storniert wird — nie leer; steht später im Audit."},"stichtag":{"type":"string","format":"date","description":"Der Tag des Stornos, striktes `YYYY-MM-DD`. INJIZIERT — kein Server liest hier eine Uhr (BP §8)."}},"required":["grund","stichtag"]},"AbschlussStornoResponse":{"type":"object","properties":{"laufId":{"type":"string","format":"uuid"},"storniert":{"type":"boolean","enum":[true],"description":"Immer `true`: der einzige Ausgang eines erfolgreichen Stornos. Ein zweites Storno endet mit 409."},"stichtag":{"type":"string","format":"date"}},"required":["laufId","storniert","stichtag"]},"AbschlussKorrekturRequest":{"type":"object","properties":{"ungueltigerBeschlussRef":{"type":"string","description":"Der rechtskräftig für ungültig erklärte Schlüssel-Beschluss, kanonische Referenz aus S12-T02."},"verrechnungsjahr":{"type":"integer","description":"Das Jahr, in dessen NEUER Abrechnung die Differenzen verrechnet werden."},"betroffeneJahre":{"type":"array","items":{"type":"integer"},"description":"Die Jahre der KASKADE, aus `bildeKorrekturkaskade` (S12-T13a) — Pflichtangabe und nie leer. Sie wird ausdrücklich NICHT aus dem Bestand abgeleitet: „jeder aktive Lauf vor dem Verrechnungsjahr\" überschritte die Kaskade, sobald das Objekt Läufe aus Jahren VOR der Wirksamkeit des aufgehobenen Beschlusses führt."},"idempotenzSchluessel":{"type":"string","description":"Der Schlüssel des GANZEN Dispatches, vom Aufrufer gebildet (`abschlussKorrekturSchluessel`). Zwei Aufrufe am selben Schlüssel ergeben GENAU EINE Kette."},"grund":{"type":"string","description":"Warum korrigiert wird — nie leer."},"stichtag":{"type":"string","format":"date","description":"Der Tag des Stornos, striktes `YYYY-MM-DD` (BP §8)."},"entscheidungen":{"type":"array","items":{},"description":"Die Gate-Entscheidungen der neuen Läufe, aus `entscheideAbschlussVerrechnung` (S12-T13a) ÜBERNOMMEN — hier wird nicht gerechnet (INV-ROUND-01). Pflichtfeld, aber die LEERE Liste ist zulässig: sie ist dann eine Aussage („dieser Vorgang hat über keine Einheit entschieden\") und kein Versehen. Jede Entscheidung muss zu einem Jahr gehören, das in dieser Kaskade auch einen neuen Lauf bekommt."}},"required":["ungueltigerBeschlussRef","verrechnungsjahr","betroffeneJahre","idempotenzSchluessel","grund","stichtag","entscheidungen"]},"AbschlussKettenZeile":{"type":"object","properties":{"jahr":{"type":"integer"},"stornierterLaufId":{"type":"string","format":"uuid"},"neuerLaufId":{"type":"string","format":"uuid"}},"required":["jahr","stornierterLaufId","neuerLaufId"]},"AbschlussKorrekturResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["geschrieben","bereits_ausgefuehrt"]},"kette":{"type":"array","items":{"$ref":"#/components/schemas/AbschlussKettenZeile"},"description":"Je betroffenem Jahr GENAU EIN Paar; bei `bereits_ausgefuehrt` leer."}},"required":["ausgang","kette"]},"HausgeldSchuldner":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"ownershipId":{"type":"string","format":"uuid"},"anteil":{"type":"string","description":"Anteil am Innenverhältnis (§ 426 BGB) in ZEHNTAUSENDSTELN als Integer-STRING — KEIN Geld, INV-MONEY-01 ist nicht berührt."}},"required":["personId","ownershipId","anteil"]},"HausgeldSollPosition":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"Der Fachkern-Monat `YYYY-MM` — nie der Monatserste `YYYY-MM-01`, nie ein Zeitstempel."},"art":{"type":"string","enum":["vorschuss","differenz"],"description":"vorschuss = der laufende Monat aus dem Plan; differenz = eine QUITTIERTE Rückwirkung."},"betragCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"hausgeldAnteilCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"ruecklagenAnteilCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"schuldner":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldSchuldner"},"description":"Die Eigentümer DER PERIODE, gesamtschuldnerisch (§ 421 BGB), deterministisch nach ownershipId sortiert."},"kontenkreis":{"type":"string","description":"Träger der Geldkreis-Trennung (S2-T21) — endet auf `:weg_hausgeld`."},"beschlussRef":{"type":"string","description":"Kanonische Beschluss-Teilgegenstands-Referenz `beschluss-gegenstand:<uuid>` (S12-T02)."},"planVersion":{"type":"integer"}},"required":["unitId","monat","art","betragCents","hausgeldAnteilCents","ruecklagenAnteilCents","schuldner","kontenkreis","beschlussRef","planVersion"]},"HausgeldDifferenzVorschlag":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"Der betroffene Fachkern-Monat `YYYY-MM`."},"bisherCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"neuCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"differenzCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"hausgeldAnteilCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"ruecklagenAnteilCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"schuldner":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldSchuldner"}},"planVersion":{"type":"integer"},"quittungsSchluessel":{"type":"string","description":"Der Idempotenz-Schlüssel, unter dem GENAU DIESER Vorschlag quittiert wird."}},"required":["unitId","monat","bisherCents","neuCents","differenzCents","hausgeldAnteilCents","ruecklagenAnteilCents","schuldner","planVersion","quittungsSchluessel"]},"HausgeldBefund":{"type":"object","properties":{"regel":{"type":"string"},"fundort":{"type":"string","description":"WO der Befund sitzt, maschinenlesbar, z. B. `einzelplan:ENR1`."},"meldung":{"type":"string","description":"Der Satz für den Menschen — nennt die verletzte Zusage, nie einen Fremdwert roh (BP §4)."}},"required":["regel","fundort","meldung"]},"HausgeldSollZeile":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"monat":{"type":"string","description":"Der Fachkern-Monat `YYYY-MM`."},"art":{"type":"string","enum":["vorschuss","differenz"]},"betragCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"ruecklagenAnteilCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."}},"required":["unitId","monat","art","betragCents","ruecklagenAnteilCents"]},"HausgeldSollListResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"jahr":{"type":"integer","description":"Das abgefragte WIRTSCHAFTSJAHR (Echo) — bei einem Rumpfjahr nicht das Kalenderjahr."},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldSollZeile"}}},"required":["propertyId","jahr","zeilen"]},"HausgeldSollRequest":{"type":"object","properties":{"jahr":{"type":"integer","description":"Das WIRTSCHAFTSJAHR des Plans."},"geldkreis":{"type":"string","description":"Bewusst freier Text: `resolveAbrechnungslaufScope` (S2-T21) ist die eine Instanz, die über Geldkreise urteilt."},"wirtschaftsplanId":{"type":"string","format":"uuid"},"planVersion":{"type":"integer","description":"Die Plan-Version, aus der die Zellen stammen; > 0."},"beschlussRef":{"type":"string","description":"Kanonische Beschluss-Teilgegenstands-Referenz (S12-T02)."},"wirtschaftsjahr":{"type":"object","additionalProperties":{},"description":"Das geprüfte Wirtschaftsjahr aus S12-T08 — Form: Fachkern."},"zellen":{"type":"array","items":{},"description":"Die Monatszellen je Einzelplan, aus S12-T08 ÜBERNOMMEN — hier wird nicht gerechnet."},"episoden":{"type":"array","items":{},"description":"Die Abrechnungs-Episoden je Einheit (S12-T01) — der Schuldner DER PERIODE."},"stand":{"type":"object","additionalProperties":{},"description":"Der zu buchende Plan-Stand; geht UNVERÄNDERT an das Buchungs-Gate aus S12-T09."}},"required":["jahr","geldkreis","wirtschaftsplanId","planVersion","beschlussRef","wirtschaftsjahr","zellen","episoden","stand"]},"HausgeldSollResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["ausgefuehrt","bereits_ausgefuehrt"]},"schluessel":{"type":"string","description":"Der Idempotenz-Schlüssel des Laufs, wie der Fachkern ihn gebildet hat."},"geldkreis":{"type":"string"},"kontenkreis":{"type":"string"},"beschlussRef":{"type":"string","description":"Die Rechtsgrundlage, wie die FREIGABE sie gemeldet hat — nie aus der Eingabe."},"beschlussStatus":{"type":"string"},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldSollPosition"},"description":"Die GESTELLTEN Positionen, Art `vorschuss`."},"differenzVorschlaege":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldDifferenzVorschlag"},"description":"Die rückwirkenden Differenzen als VORSCHLAG — NICHT gebucht; leer statt fehlend."},"warnungen":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldBefund"}}},"required":["ausgang","schluessel","geldkreis","kontenkreis","beschlussRef","beschlussStatus","positionen","differenzVorschlaege","warnungen"]},"HausgeldDifferenzRequest":{"type":"object","properties":{"jahr":{"type":"integer"},"wirtschaftsplanId":{"type":"string","format":"uuid"},"beschlussRef":{"type":"string"},"vorschlaege":{"type":"array","items":{},"description":"Die zu buchenden Vorschläge, wie der Lauf sie geliefert hat. MINDESTENS EINER — ein leerer Stapel hätte nichts freizugeben."},"quittiertVon":{"type":"string","description":"WER quittiert. Ein anonymer Freigabeschritt ist keiner (GoBD)."},"quittiertAm":{"type":"string","format":"date","description":"WANN, striktes `YYYY-MM-DD`. INJIZIERT — kein Server liest hier eine Uhr (BP §8)."}},"required":["jahr","wirtschaftsplanId","beschlussRef","vorschlaege","quittiertVon","quittiertAm"]},"HausgeldDifferenzResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["ausgefuehrt","bereits_ausgefuehrt"]},"schluessel":{"type":"string"},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldSollPosition"},"description":"Die gebuchten Positionen — Art `differenz`."}},"required":["ausgang","schluessel","positionen"]},"HausgeldZahlungResponse":{"type":"object","properties":{"sollstellungId":{"type":"string","format":"uuid"},"zuordnung":{"type":"string","enum":["nachrangig","quotal"],"description":"Die ANGEWANDTE Regel (Präzedenz Objekt > Tenant > Default) — immer mitgeliefert, damit ein Beleg entsteht."},"hausgeldCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"ruecklageCents":{"type":"string","description":"Der TATSÄCHLICH vereinnahmte Rücklagenanteil — nur er wird später zugeführt."},"unverteiltCents":{"type":"string","description":"Überzahlung, die keiner der beiden Forderungen zufällt."},"position":{"$ref":"#/components/schemas/HausgeldSollPosition"}},"required":["sollstellungId","zuordnung","hausgeldCents","ruecklageCents","unverteiltCents","position"]},"RuecklagenGeld":{"type":"object","properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"]},"RuecklagenKatalogEintrag":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"art":{"type":"string","enum":["erhaltung","zweckgebunden"],"description":"erhaltung = Erhaltungsrücklage · zweckgebunden = Rücklage mit Zweckbindung."},"bezeichnung":{"type":"string"},"zweckbindung":{"type":["string","null"]},"aktivKontoId":{"type":"string","format":"uuid","description":"das aktive Bestandskonto (gl_accounts.id)"},"passivKontoId":{"type":"string","format":"uuid","description":"das passive Rücklagenkonto (gl_accounts.id)"},"verteilerschluessel":{"type":"string"},"unitGroupId":{"type":["string","null"],"format":"uuid"},"kontoinhaberArt":{"type":"string","enum":["gdwe","verwalter","dritter"]},"kontoinhaberName":{"type":"string"},"istBestand":{"anyOf":[{"$ref":"#/components/schemas/RuecklagenGeld"},{"type":"null"}],"description":"Ist-Bestand (Summe der Bewegungen bis einschließlich Stichtag); null, wenn kein `stichtag` angefragt wurde — der Server rät keinen."},"aufgeloest":{"type":"boolean","description":"true, sobald die Rücklage aufgelöst wurde; sie bleibt im Katalog."}},"required":["id","art","bezeichnung","zweckbindung","aktivKontoId","passivKontoId","verteilerschluessel","unitGroupId","kontoinhaberArt","kontoinhaberName","istBestand","aufgeloest"]},"RuecklagenKatalogResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":["string","null"],"format":"date","description":"Echo des angefragten Stichtags (INKLUSIV); null, wenn keiner angefragt wurde."},"ruecklagen":{"type":"array","items":{"$ref":"#/components/schemas/RuecklagenKatalogEintrag"}}},"required":["propertyId","stichtag","ruecklagen"]},"RuecklagenSollIstZeile":{"type":"object","properties":{"ruecklageId":{"type":"string","format":"uuid"},"soll":{"$ref":"#/components/schemas/RuecklagenGeld"},"ist":{"$ref":"#/components/schemas/RuecklagenGeld"},"istVereinnahmt":{"$ref":"#/components/schemas/RuecklagenGeld"},"istKorrekturen":{"$ref":"#/components/schemas/RuecklagenGeld"},"rueckstand":{"$ref":"#/components/schemas/RuecklagenGeld"}},"required":["ruecklageId","soll","ist","istVereinnahmt","istKorrekturen","rueckstand"]},"RuecklagenSollIstResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"Echo des Stichtags (INKLUSIV)."},"ruecklagen":{"type":"array","items":{"$ref":"#/components/schemas/RuecklagenSollIstZeile"},"description":"Alle Rücklagen des Objekts, oder genau die angefragte; eine unbekannte oder fremde `ruecklageId` ist ein 404."}},"required":["propertyId","stichtag","ruecklagen"]},"RuecklagenAbstimmungZeile":{"type":"object","properties":{"ruecklageId":{"type":"string","format":"uuid"},"aktiv":{"$ref":"#/components/schemas/RuecklagenGeld"},"passiv":{"$ref":"#/components/schemas/RuecklagenGeld"},"differenz":{"$ref":"#/components/schemas/RuecklagenGeld"}},"required":["ruecklageId","aktiv","passiv","differenz"]},"RuecklagenAbstimmungBefund":{"type":"object","properties":{"klasse":{"type":"string","enum":["umbuchung_giro_festgeld_fehlt","konto_ohne_gegenstueck"]},"betroffeneRuecklagen":{"type":"array","items":{"type":"string","format":"uuid"}},"betrag":{"$ref":"#/components/schemas/RuecklagenGeld"}},"required":["klasse","betroffeneRuecklagen","betrag"]},"RuecklagenAbstimmungResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"Stichtag (INKLUSIV), zu dem abgestimmt wurde."},"abgestimmt":{"type":"boolean"},"aktivBestand":{"$ref":"#/components/schemas/RuecklagenGeld"},"passivBestand":{"$ref":"#/components/schemas/RuecklagenGeld"},"differenz":{"$ref":"#/components/schemas/RuecklagenGeld"},"jeRuecklage":{"type":"array","items":{"$ref":"#/components/schemas/RuecklagenAbstimmungZeile"}},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/RuecklagenAbstimmungBefund"}}},"required":["propertyId","stichtag","abgestimmt","aktivBestand","passivBestand","differenz","jeRuecklage","befunde"]},"RuecklagenWiedervorlage":{"type":"object","properties":{"bewegungId":{"type":"string","format":"uuid"},"ruecklageId":{"type":"string","format":"uuid"},"faelligAm":{"type":"string","format":"date"},"fristMonate":{"type":"integer"},"betrag":{"$ref":"#/components/schemas/RuecklagenGeld"},"beschlussRef":{"type":["string","null"],"description":"Kanonische Beschluss-Referenz; null bei Altbestand ohne Beschluss."},"ueberfaellig":{"type":"boolean","description":"true, wenn die Fälligkeit VOR `bis` liegt. Auskunft, keine Sperre."}},"required":["bewegungId","ruecklageId","faelligAm","fristMonate","betrag","beschlussRef","ueberfaellig"]},"RuecklagenWiedervorlagenResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"bis":{"type":"string","format":"date","description":"Echo des Bezugstags für `ueberfaellig`."},"wiedervorlagen":{"type":"array","items":{"$ref":"#/components/schemas/RuecklagenWiedervorlage"}}},"required":["propertyId","bis","wiedervorlagen"]},"RuecklageAnlegenRequest":{"type":"object","properties":{"art":{"type":"string","enum":["erhaltung","zweckgebunden"],"description":"erhaltung = die Erhaltungsrücklage (je Objekt genau eine) · zweckgebunden = Rücklage mit Zweckbindung."},"bezeichnung":{"type":"string"},"zweckbindung":{"type":["string","null"],"description":"Pflicht bei `zweckgebunden`, verboten bei `erhaltung`."},"verteilerschluessel":{"type":"string","description":"Vorgabe: Miteigentumsanteil."},"unitGroupId":{"type":["string","null"],"format":"uuid","description":"optionale Untergruppe desselben Objekts"},"kontoinhaberArt":{"type":"string","enum":["gdwe","verwalter","dritter"]},"kontoinhaberName":{"type":"string"},"aktivKontoId":{"type":["string","null"],"format":"uuid","description":"ein bestehendes Bestandskonto (Bank) des Objekts; ohne Angabe wird eines angelegt."}},"required":["art","bezeichnung","kontoinhaberArt","kontoinhaberName"]},"RuecklageAnlegenResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["angelegt","bereits_ausgefuehrt"],"description":"bereits_ausgefuehrt = derselbe Aufruf (Idempotenz-Schlüssel) wurde wiederholt; das gespeicherte Erstergebnis, nichts neu angelegt."},"ruecklageId":{"type":"string","format":"uuid"},"art":{"type":"string","enum":["erhaltung","zweckgebunden"]},"aktivKontoId":{"type":"string","format":"uuid"},"aktivKontoNummer":{"type":["string","null"],"description":"null, wenn ein bestehendes aktives Konto genannt war (dann wurde keines angelegt)."},"passivKontoId":{"type":"string","format":"uuid"},"passivKontoNummer":{"type":"string"},"verteilerschluessel":{"type":"string"},"kontoinhaberArt":{"type":"string","enum":["gdwe","verwalter","dritter"]}},"required":["ausgang","ruecklageId","art","aktivKontoId","aktivKontoNummer","passivKontoId","passivKontoNummer","verteilerschluessel","kontoinhaberArt"]},"RuecklagenSollRequest":{"type":"object","properties":{"ruecklageId":{"type":"string","format":"uuid"},"beschlussGegenstandRef":{"type":"string","description":"Kanonische Beschluss-Teilgegenstands-Referenz `beschluss-gegenstand:<uuid>`; ohne sie 400."},"betragCents":{"type":"string","description":"Soll-Zuführung in Cent als Ziffern-String, > 0 (z. B. \"120000\" = 1.200,00 €)."},"faelligZum":{"type":"string","format":"date"}},"required":["ruecklageId","beschlussGegenstandRef","betragCents","faelligZum"]},"RuecklagenSollResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["festgelegt","bereits_ausgefuehrt"],"description":"bereits_ausgefuehrt = derselbe Aufruf (Idempotenz-Schlüssel) wurde wiederholt; das gespeicherte Erstergebnis, nichts neu festgelegt."},"sollZufuehrungId":{"type":"string","format":"uuid"},"ruecklageId":{"type":"string","format":"uuid"},"beschlussGegenstandRef":{"type":"string"},"betrag":{"$ref":"#/components/schemas/RuecklagenGeld"},"faelligZum":{"type":"string","format":"date"}},"required":["ausgang","sollZufuehrungId","ruecklageId","beschlussGegenstandRef","betrag","faelligZum"]},"RuecklagenBuchungRequest":{"type":"object","properties":{"ruecklageId":{"type":"string","format":"uuid"},"betragCents":{"type":"string","description":"Vorzeichenbehaftet in Cent als Ziffern-String: \"5000\" = Zuführung von 50,00 €, \"-5000\" = Entnahme von 50,00 €."},"buchungsdatum":{"type":"string","format":"date","description":"Buchungstag; der Server liest keine Uhr für ein fehlendes Datum."},"gegenkontoId":{"type":"string","format":"uuid","description":"Gegenkonto (gl_accounts.id) am Objekt; nicht Teil des Rücklagenpaars."},"periode":{"type":["string","null"],"description":"Nur Zuführung, Format YYYY-MM: dieselbe Periode wird nur EINMAL gebucht (zweite Antwort `bereits_gebucht`)."},"zweck":{"type":["string","null"],"enum":["wartung","inspektion","instandsetzung","modernisierende_instandsetzung","bauliche_veraenderung","modernisierung",null],"description":"Pflicht bei einer Entnahme, verboten bei Zuführung und Korrektur."},"beschlussGegenstandRef":{"type":["string","null"],"description":"Nur Entnahme: tragender Beschluss-Teilgegenstand."},"umwidmungsBeschlussRef":{"type":["string","null"],"description":"Nur Entnahme: Pflicht, sobald der Zweck bauliche_veraenderung oder modernisierung ist."},"korrigiertBewegungId":{"type":["string","null"],"format":"uuid","description":"Gesetzt ⇒ diese Bewegung ist die Gegenbewegung zu der genannten."}},"required":["ruecklageId","betragCents","buchungsdatum","gegenkontoId"]},"RuecklagenBuchungResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["gebucht","bereits_gebucht"],"description":"bereits_gebucht = die Periode war schon gebucht oder derselbe Aufruf (Idempotenz-Schlüssel) wurde wiederholt; es entstand KEIN zweiter Journalsatz."},"bewegungId":{"type":"string","format":"uuid"},"kategorie":{"type":"string","description":"zufuehrung · entnahme · korrektur"},"journalEntryId":{"type":"string","format":"uuid"}},"required":["ausgang","bewegungId","kategorie","journalEntryId"]},"RuecklagenZinsRequest":{"type":"object","properties":{"ruecklageId":{"type":"string","format":"uuid"},"bruttoCents":{"type":"string","description":"Bruttozins in Cent als Ziffern-String, > 0; Steuer, Soli und netto werden aufgeteilt."},"buchungsdatum":{"type":"string","format":"date"},"zinsKontoId":{"type":"string","format":"uuid","description":"Zins-Sachkonto des Objekts, ohne Verteilerschlüssel"},"steuerKontoId":{"type":"string","format":"uuid","description":"Sachkonto für Kapitalertragsteuer und Solidaritätszuschlag"}},"required":["ruecklageId","bruttoCents","buchungsdatum","zinsKontoId","steuerKontoId"]},"RuecklagenZinsResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["gebucht","bereits_gebucht"],"description":"bereits_gebucht = derselbe Aufruf (Idempotenz-Schlüssel) wurde wiederholt; keine zweite Bewegung."},"ruecklageId":{"type":"string","format":"uuid"},"journalEntryId":{"type":"string","format":"uuid"},"bewegungId":{"type":"string","format":"uuid"},"brutto":{"$ref":"#/components/schemas/RuecklagenGeld"},"kapitalertragsteuer":{"$ref":"#/components/schemas/RuecklagenGeld"},"solidaritaetszuschlag":{"$ref":"#/components/schemas/RuecklagenGeld"},"netto":{"$ref":"#/components/schemas/RuecklagenGeld"}},"required":["ausgang","ruecklageId","journalEntryId","bewegungId","brutto","kapitalertragsteuer","solidaritaetszuschlag","netto"]},"RuecklagenZwischenfinanzierungRequest":{"type":"object","properties":{"ruecklageId":{"type":"string","format":"uuid"},"betragCents":{"type":"string","description":"Entnommener Betrag in Cent als POSITIVER Ziffern-String."},"entnahmeDatum":{"type":"string","format":"date"},"beschlussRef":{"type":"string","description":"Tragender Beschluss-Teilgegenstand; ohne ihn 400."},"fristMonate":{"type":"integer","description":"überschreibt die Policy-Frist (Objekt vor Mandant vor 3 Monaten); ganze Zahl ≥ 1"},"gegenkontoId":{"type":["string","null"],"format":"uuid","description":"ohne Angabe geht die Gegenbuchung auf das Bestandskonto der Rücklage"}},"required":["ruecklageId","betragCents","entnahmeDatum","beschlussRef"]},"RuecklagenZwischenfinanzierungResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["entnommen","bereits_ausgefuehrt"],"description":"bereits_ausgefuehrt = derselbe Aufruf (Idempotenz-Schlüssel) wurde wiederholt; keine zweite Bewegung."},"bewegungId":{"type":"string","format":"uuid"},"journalEntryId":{"type":"string","format":"uuid"},"faelligAm":{"type":"string","format":"date"},"fristMonate":{"type":"integer"},"beschlussRef":{"type":"string"}},"required":["ausgang","bewegungId","journalEntryId","faelligAm","fristMonate","beschlussRef"]},"RuecklagenRueckfuehrungRequest":{"type":"object","properties":{"ruecklageId":{"type":"string","format":"uuid"},"zwischenfinanzierungBewegungId":{"type":"string","format":"uuid"},"buchungsdatum":{"type":"string","format":"date"},"gegenkontoId":{"type":"string","format":"uuid"}},"required":["ruecklageId","zwischenfinanzierungBewegungId","buchungsdatum","gegenkontoId"]},"RuecklagenRueckfuehrungResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["zurueckgefuehrt","bereits_ausgefuehrt"],"description":"bereits_ausgefuehrt = derselbe Aufruf (Idempotenz-Schlüssel) wurde wiederholt; keine zweite Bewegung."},"bewegungId":{"type":"string","format":"uuid"},"journalEntryId":{"type":"string","format":"uuid"},"betrag":{"$ref":"#/components/schemas/RuecklagenGeld"}},"required":["ausgang","bewegungId","journalEntryId","betrag"]},"RuecklagenAufloesungRequest":{"type":"object","properties":{"ruecklageId":{"type":"string","format":"uuid"},"aufhebungsBeschlussRef":{"type":"string","description":"Aufhebungsbeschluss (Teilgegenstands-Referenz); ohne ihn 400."},"aufgeloestAm":{"type":"string","format":"date"}},"required":["ruecklageId","aufhebungsBeschlussRef","aufgeloestAm"]},"RuecklagenAufloesungResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["aufgeloest","bereits_ausgefuehrt"],"description":"bereits_ausgefuehrt = derselbe Aufruf (Idempotenz-Schlüssel) wurde wiederholt; keine zweite Auflösung."},"aufloesungId":{"type":"string","format":"uuid"},"ruecklageId":{"type":"string","format":"uuid"},"aufgeloestAm":{"type":"string","format":"date"}},"required":["ausgang","aufloesungId","ruecklageId","aufgeloestAm"]},"SonderumlageListenEintrag":{"type":"object","properties":{"sonderumlageId":{"type":"string","format":"uuid"},"zweck":{"type":"string"},"betrag":{"$ref":"#/components/schemas/RuecklagenGeld"},"zahlweise":{"type":"string","enum":["einmalzahlung","raten"]},"faelligkeit":{"type":"string","format":"date","description":"Bei Raten die Fälligkeit der ersten Rate."},"faelligkeiten":{"type":"array","items":{"type":"string","format":"date"},"description":"Alle Raten-Fälligkeiten aufsteigend; leer ohne Raten."},"gestellt":{"type":"boolean","description":"true, sobald das Soll gestellt ist (Lauf vorhanden)."},"zufuehrungsSchluessel":{"type":"string"},"entnahmeSchluessel":{"type":["string","null"]},"schluesselAbweichung":{"type":"boolean","description":"Tatsache, keine Warnung: beide Schlüssel gesetzt und verschieden."}},"required":["sonderumlageId","zweck","betrag","zahlweise","faelligkeit","faelligkeiten","gestellt","zufuehrungsSchluessel","entnahmeSchluessel","schluesselAbweichung"]},"SonderumlageListeResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"sonderumlagen":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageListenEintrag"}}},"required":["propertyId","sonderumlagen"]},"SonderumlageSollSchuldner":{"type":"object","properties":{"ownershipId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"anteil":{"type":"string","description":"Innenverhältnis in Zehntausendsteln als Ziffern-String — KEIN Geld."}},"required":["ownershipId","personId","anteil"]},"SonderumlageSollZeile":{"type":"object","properties":{"sollstellungId":{"type":"string","format":"uuid"},"rateNr":{"type":"integer"},"faelligkeit":{"type":"string","format":"date"},"betrag":{"$ref":"#/components/schemas/RuecklagenGeld"},"schuldner":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageSollSchuldner"}}},"required":["sollstellungId","rateNr","faelligkeit","betrag","schuldner"]},"SonderumlageSollEinheit":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"gesamtanteil":{"$ref":"#/components/schemas/RuecklagenGeld"},"summe":{"$ref":"#/components/schemas/RuecklagenGeld"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageSollZeile"}}},"required":["unitId","gesamtanteil","summe","zeilen"]},"SonderumlageSollResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"sonderumlageId":{"type":"string","format":"uuid"},"gesamtsumme":{"$ref":"#/components/schemas/RuecklagenGeld"},"einheiten":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageSollEinheit"}}},"required":["propertyId","sonderumlageId","gesamtsumme","einheiten"]},"SonderumlageAnlegenRequest":{"type":"object","properties":{"beschlussGegenstandRef":{"type":"string","description":"Kanonische Beschluss-Teilgegenstands-Referenz `beschluss-gegenstand:<uuid>`; ohne sie 400."},"zweck":{"type":"string","description":"Zweck laut Beschluss (Pflichtinhalt)."},"faelligkeit":{"type":"string","format":"date","description":"Fälligkeit; bei Raten der Termin der ersten Rate."},"zahlweise":{"type":"string","enum":["einmalzahlung","raten"]},"ratenFaelligkeiten":{"type":"array","items":{"type":"string","format":"date"},"description":"Pflicht bei `raten`, verboten bei `einmalzahlung`."},"betragCents":{"type":"string","description":"Gesamtbetrag in Cent als Ziffern-String, > 0 (z. B. \"1200000\" = 12.000,00 €)."},"zufuehrungsSchluessel":{"type":"string","description":"Vorgabe: mea (Miteigentumsanteil)."},"entnahmeSchluessel":{"type":["string","null"]},"abweichungsBeschlussRef":{"type":["string","null"],"description":"Beschluss, der einen abweichenden Entnahmeschlüssel trägt."}},"required":["beschlussGegenstandRef","zweck","faelligkeit","zahlweise","betragCents"]},"SonderumlageRate":{"type":"object","properties":{"nr":{"type":"integer"},"faelligkeit":{"type":"string","format":"date"}},"required":["nr","faelligkeit"]},"SonderumlageGapWarnung":{"type":"object","properties":{"klasse":{"type":"string","enum":["zufuehrung_entnahme_schluessel_weichen_ab"]},"zufuehrungsSchluessel":{"type":"string"},"entnahmeSchluessel":{"type":"string"},"beschlussRefFehlt":{"type":"boolean"},"meldung":{"type":"string"}},"required":["klasse","zufuehrungsSchluessel","entnahmeSchluessel","beschlussRefFehlt","meldung"]},"SonderumlageAnlegenResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["angelegt","bereits_ausgefuehrt"],"description":"bereits_ausgefuehrt = derselbe Aufruf (Idempotenz-Schlüssel) wurde wiederholt; das gespeicherte Erstergebnis, nichts neu angelegt."},"sonderumlageId":{"type":"string","format":"uuid"},"sonderkontoId":{"type":"string","format":"uuid"},"sonderkontoNummer":{"type":"string"},"beschlussGegenstandRef":{"type":"string"},"betrag":{"$ref":"#/components/schemas/RuecklagenGeld"},"raten":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageRate"}},"warnungen":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageGapWarnung"}}},"required":["ausgang","sonderumlageId","sonderkontoId","sonderkontoNummer","beschlussGegenstandRef","betrag","raten","warnungen"]},"SonderumlageSollStellenRequest":{"type":"object","properties":{"sonderumlageId":{"type":"string","format":"uuid"},"laufTyp":{"type":"string","enum":["sonderzufuehrung","umbuchung_abrechnungsspitze"],"description":"Vorgabe sonderzufuehrung; umbuchung_abrechnungsspitze ist (noch) nicht verdrahtet und ergibt 409."},"abweichungsBeschlussRef":{"type":["string","null"]}},"required":["sonderumlageId"]},"SonderumlageSollStellenRate":{"type":"object","properties":{"nr":{"type":"integer"},"faelligkeit":{"type":"string","format":"date"},"betrag":{"$ref":"#/components/schemas/RuecklagenGeld"}},"required":["nr","faelligkeit","betrag"]},"SonderumlageSollStellenEinheit":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"gesamtanteil":{"$ref":"#/components/schemas/RuecklagenGeld"},"raten":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageSollStellenRate"}}},"required":["unitId","gesamtanteil","raten"]},"SonderumlageSollStellenResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["ausgefuehrt","bereits_ausgefuehrt"],"description":"bereits_ausgefuehrt = das Soll stand schon (oder derselbe Idempotenz-Schlüssel wurde wiederholt); es wurde nichts neu gestellt."},"laufId":{"type":"string","format":"uuid"},"schluessel":{"type":"string"},"warnungen":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageGapWarnung"}},"einheiten":{"type":"array","items":{"$ref":"#/components/schemas/SonderumlageSollStellenEinheit"}}},"required":["ausgang","laufId","schluessel","warnungen","einheiten"]},"EigentumZeile":{"type":"object","properties":{"ownershipId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"anteil":{"type":"string","description":"Miteigentumsanteil in Zehntausendsteln als Integer-String (10000 = 100 %)."},"von":{"type":["string","null"],"format":"date"},"endeExklusiv":{"type":["string","null"],"format":"date","description":"Erster Tag OHNE Eigentum; `null` = unbefristet."},"anschreibenEmpfaenger":{"type":"boolean"},"bevollmaechtigterPersonId":{"type":["string","null"],"format":"uuid"},"bevollmaechtigungVon":{"type":["string","null"],"format":"date"},"bevollmaechtigungEndeExklusiv":{"type":["string","null"],"format":"date"},"ustOption":{"type":["boolean","null"],"description":"`null` = nicht erfasst (nie still `false`)."},"hatZustellanweisung":{"type":"boolean","description":"Kennzeichen, dass eine abweichende Zustellanschrift hinterlegt ist; die Anschrift selbst verlässt das Haus nicht."},"istGegenwart":{"type":"boolean","description":"true, wenn die Zeile am Stichtag wirksam ist."}},"required":["ownershipId","unitId","personId","anteil","von","endeExklusiv","anschreibenEmpfaenger","bevollmaechtigterPersonId","bevollmaechtigungVon","bevollmaechtigungEndeExklusiv","ustOption","hatZustellanweisung","istGegenwart"]},"EigentumEinheit":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"anteilssumme":{"type":["string","null"],"description":"Summe der am Stichtag wirksamen Anteile in Zehntausendsteln als Integer-String."},"befunde":{"type":"array","items":{"type":"string","enum":["anteilssumme_ungleich_10000"]},"description":"Tatsachen, keine Fehler: die Anteile ergeben am Stichtag nicht 10000."},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/EigentumZeile"}}},"required":["unitId","anteilssumme","befunde","zeilen"]},"EigentumListeResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"historie":{"type":"boolean","description":"true ⇒ auch abgelaufene und künftige Zeilen (`istGegenwart` markiert die wirksamen)."},"einheiten":{"type":"array","items":{"$ref":"#/components/schemas/EigentumEinheit"}}},"required":["propertyId","stichtag","historie","einheiten"]},"EigentumZustellanweisung":{"type":"object","properties":{"empfaengerName":{"type":["string","null"]},"adresse":{"type":"string","description":"Zustellanschrift als Freitext (1 bis 500 Zeichen)."}},"required":["adresse"]},"EigentumVollmachtFenster":{"type":"object","properties":{"von":{"type":"string","format":"date"},"bisExklusiv":{"type":["string","null"],"format":"date"}},"required":["von"]},"EigentumBevollmaechtigungRequest":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"fenster":{"$ref":"#/components/schemas/EigentumVollmachtFenster"},"vollmachtDokumentRef":{"type":["string","null"],"format":"uuid"}},"required":["personId","fenster"]},"EigentumErfassenRequest":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"anteil":{"type":"string","description":"Miteigentumsanteil in Zehntausendsteln als Integer-String, > 0."},"von":{"type":"string","format":"date"},"bisExklusiv":{"type":["string","null"],"format":"date","description":"Erster Tag OHNE Eigentum; fehlt ⇒ unbefristet."},"anschreibenEmpfaenger":{"type":"boolean","description":"Fehlt ⇒ Vorbelegung nach der Zustell-Regel."},"zustellanweisung":{"$ref":"#/components/schemas/EigentumZustellanweisung"},"bevollmaechtigung":{"$ref":"#/components/schemas/EigentumBevollmaechtigungRequest"},"ustOption":{"type":["boolean","null"]}},"required":["personId","anteil","von"]},"EigentumBevollmaechtigungAntwort":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date"},"bisExklusiv":{"type":["string","null"],"format":"date"},"vollmachtDokumentRef":{"type":["string","null"],"format":"uuid"}},"required":["personId","von","bisExklusiv","vollmachtDokumentRef"]},"EigentumAnteilssummeBefund":{"type":"object","properties":{"art":{"type":"string","enum":["anteilssumme"]},"stichtag":{"type":"string","format":"date"},"summe":{"type":"string"},"soll":{"type":"string"}},"required":["art","stichtag","summe","soll"]},"EigentumErfassenResponse":{"type":"object","properties":{"ownershipId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"anteil":{"type":"string"},"von":{"type":"string","format":"date"},"bisExklusiv":{"type":["string","null"],"format":"date"},"anschreibenEmpfaenger":{"type":"boolean"},"hatZustellanweisung":{"type":"boolean"},"bevollmaechtigung":{"allOf":[{"$ref":"#/components/schemas/EigentumBevollmaechtigungAntwort"},{"type":["object","null"]}]},"ustOption":{"type":["boolean","null"]},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/EigentumAnteilssummeBefund"}}},"required":["ownershipId","unitId","personId","anteil","von","bisExklusiv","anschreibenEmpfaenger","hatZustellanweisung","bevollmaechtigung","ustOption","befunde"]},"EigentumBeendenRequest":{"type":"object","properties":{"endeExklusiv":{"type":"string","format":"date","description":"Erster Tag OHNE Eigentum: „zum 30.06. beendet\" ⇒ 2025-07-01."}},"required":["endeExklusiv"]},"EigentumBeendenResponse":{"type":"object","properties":{"ownershipId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date"},"bisExklusiv":{"type":"string","format":"date"},"beendet":{"type":"boolean","description":"false = dasselbe Ende lag schon vor (Erfolg ohne Änderung)."}},"required":["ownershipId","unitId","personId","von","bisExklusiv","beendet"]},"EigentuemerwechselAbgehendRequest":{"type":"object","properties":{"ownershipId":{"type":"string","format":"uuid"}},"required":["ownershipId"]},"EigentuemerwechselNeuRequest":{"type":"object","properties":{"personId":{"type":"string","format":"uuid"},"anteil":{"type":"string","description":"Miteigentumsanteil in Zehntausendsteln als Integer-String, > 0."},"anschreibenEmpfaenger":{"type":"boolean"},"zustellanweisung":{"$ref":"#/components/schemas/EigentumZustellanweisung"},"bevollmaechtigung":{"$ref":"#/components/schemas/EigentumBevollmaechtigungRequest"},"ustOption":{"type":["boolean","null"]}},"required":["personId","anteil"]},"EigentuemerwechselErfassenRequest":{"type":"object","properties":{"grundbuchEintragungAm":{"type":"string","format":"date","description":"Stichtag des Wechsels ist die Eintragung im Grundbuch, Abteilung I — nicht der Notartermin."},"abgehend":{"type":"array","items":{"$ref":"#/components/schemas/EigentuemerwechselAbgehendRequest"},"description":"1 bis 50 abgehende Eigentumszeilen der Einheit."},"neu":{"type":"array","items":{"$ref":"#/components/schemas/EigentuemerwechselNeuRequest"},"description":"1 bis 50 neue Eigentumszeilen; ihre Anteilssumme muss der der abgehenden gleichen."},"verwalterzustimmungAm":{"type":["string","null"],"format":"date"},"verwalterzustimmungDokumentRef":{"type":["string","null"],"format":"uuid"}},"required":["grundbuchEintragungAm","abgehend","neu"]},"EigentuemerwechselAbgehendZeile":{"type":"object","properties":{"ownershipId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"anteil":{"type":"string"},"endeExklusiv":{"type":"string","format":"date"}},"required":["ownershipId","personId","anteil","endeExklusiv"]},"EigentuemerwechselNeuZeile":{"type":"object","properties":{"ownershipId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"anteil":{"type":"string"},"von":{"type":"string","format":"date"}},"required":["ownershipId","personId","anteil","von"]},"EigentuemerwechselSevMandatOffen":{"type":"object","properties":{"mandatId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"ohneEigentumAb":{"type":"string","format":"date"}},"required":["mandatId","personId","ohneEigentumAb"]},"EigentuemerwechselErfassenResponse":{"type":"object","properties":{"wechselId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"grundbuchEintragungAm":{"type":"string","format":"date"},"verwalterzustimmungAm":{"type":["string","null"],"format":"date"},"verwalterzustimmungDokumentRef":{"type":["string","null"],"format":"uuid"},"abgehend":{"type":"array","items":{"$ref":"#/components/schemas/EigentuemerwechselAbgehendZeile"}},"neu":{"type":"array","items":{"$ref":"#/components/schemas/EigentuemerwechselNeuZeile"}},"sevMandateOffen":{"type":"array","items":{"$ref":"#/components/schemas/EigentuemerwechselSevMandatOffen"},"description":"Laufende SEV-Mandate abgehender Eigentümer; sie werden NICHT automatisch beendet."}},"required":["wechselId","unitId","grundbuchEintragungAm","verwalterzustimmungAm","verwalterzustimmungDokumentRef","abgehend","neu","sevMandateOffen"]},"EigentuemerwechselVorgang":{"type":"object","properties":{"wechselId":{"type":"string","format":"uuid"},"unitId":{"type":"string","format":"uuid"},"grundbuchEintragungAm":{"type":"string","format":"date"},"verwalterzustimmungAm":{"type":["string","null"],"format":"date"},"verwalterzustimmungDokumentRef":{"type":["string","null"],"format":"uuid"},"abgehendeOwnershipIds":{"type":"array","items":{"type":"string","format":"uuid"}},"neueOwnershipIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["wechselId","unitId","grundbuchEintragungAm","verwalterzustimmungAm","verwalterzustimmungDokumentRef","abgehendeOwnershipIds","neueOwnershipIds"]},"EigentuemerwechselListeResponse":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"wechsel":{"type":"array","items":{"$ref":"#/components/schemas/EigentuemerwechselVorgang"}}},"required":["unitId","wechsel"]},"VermoegensberichtReadinessBefund":{"type":"object","properties":{"regel":{"type":"string","description":"geldkonto_ohne_iban · geldkonto_ohne_bic · fremdsystem_kollision."},"fundort":{"type":"string","description":"WO der Befund sitzt, maschinenlesbar, z. B. `konto:K-giro`."},"hinweis":{"type":"string","description":"Der Satz für den Menschen — nennt den Mangel, nie einen Rohwert (BP §4)."}},"required":["regel","fundort","hinweis"]},"VermoegensberichtKonsistenzBefund":{"type":"object","properties":{"regel":{"type":"string","description":"ruecklage_bericht_gegen_konto · ruecklage_aktiv_gegen_passiv · forderung_/verbindlichkeit_gegen_jahresabrechnung."},"position":{"type":"string","description":"DIE BENANNTE Position, z. B. `ruecklage:RL-998` — „inkonsistent\" ohne Fundort ist keine Aussage."},"differenz":{"allOf":[{"$ref":"#/components/schemas/ErgebnisMoney"},{"description":"`berichtsbetrag − vergleichsbetrag`, vorzeichenbehaftet und cent-genau."}]}},"required":["regel","position","differenz"]},"VermoegensberichtStandListeneintrag":{"type":"object","properties":{"standId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"Der Tag, zu dem der Bestand ausgewiesen ist."},"standNr":{"type":"integer","description":"Die VERSION je Objekt und Stichtag, `1`-basiert. Ältere Stände verschwinden nicht (GoBD)."},"schluessel":{"type":"string","description":"Die Adresse aus `vermoegensberichtSchluessel` (Mandant × Objekt × Stichtag)."},"erstelltAm":{"type":"string","format":"date-time","description":"Der Ausführungszeitpunkt der Ablage — NICHT Teil des Berichts."},"konsistent":{"type":"boolean","description":"Die AUSKUNFT des Checks, wie sie abgelegt wurde — hier nicht neu abgeleitet."},"readinessBefunde":{"type":"array","items":{"$ref":"#/components/schemas/VermoegensberichtReadinessBefund"}},"konsistenzBefunde":{"type":"array","items":{"$ref":"#/components/schemas/VermoegensberichtKonsistenzBefund"}}},"required":["standId","propertyId","stichtag","standNr","schluessel","erstelltAm","konsistent","readinessBefunde","konsistenzBefunde"]},"VermoegensberichtStandListResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":["string","null"],"format":"date","description":"Echo des `?stichtag`-Filters; `null` heisst „alle Stichtage\"."},"staende":{"type":"array","items":{"$ref":"#/components/schemas/VermoegensberichtStandListeneintrag"},"description":"Jüngster Stichtag zuerst, innerhalb dessen der aktuelle Stand vor seinen Vorgängern."}},"required":["propertyId","stichtag","staende"]},"VermoegensberichtStandResponse":{"type":"object","properties":{"standId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"Der Tag, zu dem der Bestand ausgewiesen ist."},"standNr":{"type":"integer","description":"Die VERSION je Objekt und Stichtag, `1`-basiert. Ältere Stände verschwinden nicht (GoBD)."},"schluessel":{"type":"string","description":"Die Adresse aus `vermoegensberichtSchluessel` (Mandant × Objekt × Stichtag)."},"erstelltAm":{"type":"string","format":"date-time","description":"Der Ausführungszeitpunkt der Ablage — NICHT Teil des Berichts."},"konsistent":{"type":"boolean","description":"Die AUSKUNFT des Checks, wie sie abgelegt wurde — hier nicht neu abgeleitet."},"readinessBefunde":{"type":"array","items":{"$ref":"#/components/schemas/VermoegensberichtReadinessBefund"}},"konsistenzBefunde":{"type":"array","items":{"$ref":"#/components/schemas/VermoegensberichtKonsistenzBefund"}},"serialisat":{"type":"string","description":"Der Bericht als byte-stabiler JSON-TEXT (#3006). Cent-Beträge stehen darin als Dezimaltext, nie als JSON-number."}},"required":["standId","propertyId","stichtag","standNr","schluessel","erstelltAm","konsistent","readinessBefunde","konsistenzBefunde","serialisat"]},"VermoegensberichtAblageRequest":{"type":"object","properties":{"stichtag":{"type":"string","format":"date","description":"Der Stichtag des Berichts, `YYYY-MM-DD`."},"idempotenzSchluessel":{"type":"string","description":"Der Ausschluss gegen den Doppel-Dispatch. Kommt vom AUFRUFER (BP §8), nie aus einer Uhr — sonst wäre ein Retry ein zweiter Stand."},"auftrag":{"type":"object","additionalProperties":{},"description":"Die Bestände, aus denen der Rechenkern den Bericht bildet — Form: Fachkern. OHNE `scope`."}},"required":["stichtag","idempotenzSchluessel","auftrag"]},"VermoegensberichtAblageResponse":{"type":"object","properties":{"standId":{"type":"string","format":"uuid"},"standNr":{"type":"integer"},"schluessel":{"type":"string"},"stichtag":{"type":"string","format":"date"},"konsistent":{"type":"boolean","description":"ABGELEITET aus den Befunden des Kerns, nie neu entschieden."},"readinessBefunde":{"type":"array","items":{"$ref":"#/components/schemas/VermoegensberichtReadinessBefund"}},"konsistenzBefunde":{"type":"array","items":{"$ref":"#/components/schemas/VermoegensberichtKonsistenzBefund"}}},"required":["standId","standNr","schluessel","stichtag","konsistent","readinessBefunde","konsistenzBefunde"]},"MigrationsvergleichKorpusfall":{"type":"object","properties":{"format":{"type":"string","enum":["casa-migrationsvergleich-korpusfall/v1"]},"fachbereich":{"type":"string","enum":["salden","offene-posten","nk-abrechnung","hausgeldabrechnung","vermoegensbericht","ruecklagen","mahnliste"]},"procedure":{"type":"string","description":"die WinCASA-Auswertung (gespeicherte Prozedur), aus der der Wert stammt"},"params":{"type":"object","additionalProperties":{},"description":"die Parameter des Aufrufs, anonymisiert: Zahlen, Daten und J/N-Schalter wie im Satz, jeder andere Text ersetzt"},"onr":{"type":"integer"},"jahr":{"type":"integer"},"schluessel":{"type":"string"},"feld":{"type":"string"},"konto":{"type":["string","null"]},"erwartetCents":{"type":["string","null"],"description":"WinCASA-Wert in Cent als Ganzzahl-Text; null, wenn die Position dort fehlt"},"istCents":{"type":["string","null"],"description":"casa.ai-Wert in Cent als Ganzzahl-Text; null, wenn die Position dort fehlt"},"differenzCents":{"type":["string","null"],"description":"ist − erwartet in Cent als Ganzzahl-Text; null, wenn eine Seite fehlt"},"zeilen":{"type":"array","items":{"type":"object","additionalProperties":{"type":["string","null"]}},"description":"die WinCASA-Zeilen dieses Aufrufs, ANONYMISIERT (jede Textzelle, die weder Zahl noch Datum ist, ist ersetzt)"}},"required":["format","fachbereich","procedure","params","onr","jahr","schluessel","feld","konto","erwartetCents","istCents","differenzCents","zeilen"]},"MigrationsvergleichAbweichung":{"type":"object","properties":{"fachbereich":{"type":"string","enum":["salden","offene-posten","nk-abrechnung","hausgeldabrechnung","vermoegensbericht","ruecklagen","mahnliste"]},"procedure":{"type":"string"},"onr":{"type":"integer","description":"WinCASA-Objektnummer (ONR) = properties.property_no"},"jahr":{"type":"integer"},"schluessel":{"type":"string","description":"die Identität der Position innerhalb von Auswertung, Objekt und Jahr (z. B. knr=200100)"},"feld":{"type":"string"},"konto":{"type":["string","null"],"description":"das Konto (WinCASA-KNR als Text); null, wenn die Position an keinem Konto hängt"},"person":{"type":["object","null"],"properties":{"konto":{"type":"string"},"name":{"type":"string"}},"required":["konto","name"],"description":"Inhaber, wenn konto ein Personenkonto des casa.ai-Bestands ist; sonst null"},"erwartetCents":{"type":["string","null"],"description":"WinCASA-Wert in Cent als Ganzzahl-Text; null ⇔ die Position fehlt auf der WinCASA-Seite"},"istCents":{"type":["string","null"],"description":"casa.ai-Wert in Cent als Ganzzahl-Text; null ⇔ die Position fehlt auf der casa.ai-Seite"},"differenzCents":{"type":["string","null"],"description":"ist − erwartet in Cent als Ganzzahl-Text; null, wenn eine Seite fehlt"},"erklaerung":{"type":["string","null"],"description":"Begründung aus dem Erklärungs-Register; null ⇔ unerklärt"},"korpusfall":{"$ref":"#/components/schemas/MigrationsvergleichKorpusfall"}},"required":["fachbereich","procedure","onr","jahr","schluessel","feld","konto","person","erwartetCents","istCents","differenzCents","erklaerung","korpusfall"]},"MigrationsvergleichFachbereich":{"type":"object","properties":{"fachbereich":{"type":"string","enum":["salden","offene-posten","nk-abrechnung","hausgeldabrechnung","vermoegensbericht","ruecklagen","mahnliste"]},"status":{"type":"string","enum":["gleich","abweichend","nicht-vergleichbar"],"description":"gleich ⇔ Positionen > 0 ohne Abweichung; abweichend ⇔ mindestens eine Abweichung; nicht-vergleichbar ⇔ keine Position (dann grund + grundText)"},"positionen":{"type":"integer","description":"verglichene Positionen (Vereinigung beider Seiten, nur zugeordnete Objekte)"},"gleich":{"type":"integer","description":"davon centgenau gleich"},"abweichungen":{"type":"array","items":{"$ref":"#/components/schemas/MigrationsvergleichAbweichung"}},"unerklaert":{"type":"integer","description":"Zahl der Abweichungen ohne Erklärung"},"nichtZugeordnet":{"type":"array","items":{"type":"integer"},"description":"ONRs mit WinCASA-Werten, die keinem casa.ai-Objekt zugeordnet sind"},"grund":{"type":["string","null"],"enum":["keine-vergleichswerte","auswertung-fehlt","zuordnung-fehlt",null]},"grundText":{"type":["string","null"]}},"required":["fachbereich","status","positionen","gleich","abweichungen","unerklaert","nichtZugeordnet","grund","grundText"]},"MigrationsvergleichResponse":{"type":"object","properties":{"importId":{"type":"string","format":"uuid","description":"der Import-Vorgang (Kanal direktimport)"},"satzId":{"type":"string","format":"uuid","description":"der verglichene (jüngste) Satz WinCASA-Vergleichswerte"},"satzVersion":{"type":"integer"},"objekte":{"type":"array","items":{"type":"object","properties":{"onr":{"type":"integer"},"zugeordnet":{"type":"boolean"}},"required":["onr","zugeordnet"]},"description":"jede ONR des Satzes, aufsteigend, mit ihrer Zuordnung"},"fachbereiche":{"type":"array","items":{"$ref":"#/components/schemas/MigrationsvergleichFachbereich"},"description":"alle sieben Fachbereiche in fester Reihenfolge"},"abgenommen":{"type":"boolean","description":"„Alt = Neu maschinell belegt\": jedes Objekt des Satzes zugeordnet, keine unerklärte Abweichung und jeder Paritäts-Fachbereich gleich oder erklärt abweichend"}},"required":["importId","satzId","satzVersion","objekte","fachbereiche","abgenommen"]},"UstListeZeile":{"type":"object","properties":{"kontoNr":{"type":"string"},"kontoBezeichnung":{"type":"string"},"seite":{"type":"string","enum":["ausgang","eingang"]},"satzProzent":{"type":"string","description":"USt-Satz in ganzen Prozent als String, z. B. \"19\"."},"sollBruttoCents":{"type":"string","description":"Σ SOLL der Zeilen dieser Zelle, vorzeichenlos."},"habenBruttoCents":{"type":"string","description":"Σ HABEN der Zeilen dieser Zelle, vorzeichenlos."},"bruttoCents":{"type":"string","description":"Seitenrichtiges Brutto (ausgang: Haben−Soll, eingang: Soll−Haben) — kann negativ sein."},"nettoCents":{"type":"string","description":"Bemessungsgrundlage (Entgelt)."},"ustCents":{"type":"string","description":"brutto − netto: Umsatzsteuer (ausgang) bzw. abziehbare Vorsteuer (eingang)."},"buchungen":{"type":"integer","description":"Anzahl der eingeflossenen Buchungszeilen."}},"required":["kontoNr","kontoBezeichnung","seite","satzProzent","sollBruttoCents","habenBruttoCents","bruttoCents","nettoCents","ustCents","buchungen"]},"UstListeSatzSumme":{"type":"object","properties":{"seite":{"type":"string","enum":["ausgang","eingang"]},"satzProzent":{"type":"string","description":"USt-Satz in ganzen Prozent als String, z. B. \"19\"."},"nettoCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"ustCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"bruttoCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."}},"required":["seite","satzProzent","nettoCents","ustCents","bruttoCents"]},"UstListePeriode":{"type":"object","properties":{"von":{"type":"string","format":"date"},"bis":{"type":"string","format":"date"},"label":{"type":"string","description":"Beschriftung: \"2024-03\" (Monat), \"2024-Q1\" (Quartal), \"2024\" (Jahr)."},"umsatzsteuerCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"vorsteuerCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"zahllastCents":{"type":"string","description":"umsatzsteuer − vorsteuer; negativ = Erstattungsanspruch."},"saetze":{"type":"array","items":{"$ref":"#/components/schemas/UstListeSatzSumme"}}},"required":["von","bis","label","umsatzsteuerCents","vorsteuerCents","zahllastCents","saetze"]},"UstListeBefund":{"type":"object","properties":{"code":{"type":"string","enum":["steuerschluessel_fehlt","satz_weicht_vom_konto_ab"]},"kontoNr":{"type":"string"},"kontoBezeichnung":{"type":"string"},"seite":{"type":"string","enum":["ausgang","eingang"]},"satzProzent":{"type":["string","null"],"description":"Gebuchter Satz; null bei fehlendem Steuerschlüssel."},"kontoSatzProzent":{"type":["string","null"],"description":"Satz am Konto (Stammdatum); null, wenn dort nicht gepflegt."},"bruttoCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"zeilen":{"type":"array","items":{"type":"string"},"description":"Kennungen der betroffenen Buchungszeilen."},"hinweis":{"type":"string"}},"required":["code","kontoNr","kontoBezeichnung","seite","satzProzent","kontoSatzProzent","bruttoCents","zeilen","hinweis"]},"UstListeKontoSeite":{"type":"object","properties":{"kontoNr":{"type":"string"},"kontoBezeichnung":{"type":"string"},"seite":{"type":"string","enum":["ausgang","eingang"]},"herkunft":{"type":"string","enum":["vorgabe","deklariert","abgeleitet"]}},"required":["kontoNr","kontoBezeichnung","seite","herkunft"]},"UstListeResponse":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date"},"bis":{"type":"string","format":"date"},"rhythmus":{"type":"string","enum":["monat","quartal","jahr"]},"umsatzsteuerpflichtig":{"type":"boolean","description":"false ⇒ leere Liste; `hinweis` sagt warum."},"hinweis":{"type":["string","null"],"description":"\"keine umsatzsteuerpflichtigen Umsätze\" bei leerer Liste, sonst null."},"umsatzsteuerCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"vorsteuerCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"zahllastCents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"perioden":{"type":"array","items":{"$ref":"#/components/schemas/UstListePeriode"}},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/UstListeBefund"}},"zeilen":{"type":["array","null"],"items":{"$ref":"#/components/schemas/UstListeZeile"},"description":"Detail je Konto und Satz — null, wenn nicht angefordert (`jeKonto`); [] = angefordert und leer."},"kontoSeiten":{"type":"array","items":{"$ref":"#/components/schemas/UstListeKontoSeite"},"description":"Wie die Seite jedes beteiligten Kontos aufgelöst wurde."}},"required":["objektId","von","bis","rhythmus","umsatzsteuerpflichtig","hinweis","umsatzsteuerCents","vorsteuerCents","zahllastCents","perioden","befunde","zeilen","kontoSeiten"]},"EinnahmenAusgabenSumme":{"type":"object","properties":{"bruttoCents":{"type":"string","description":"Σ Brutto (mit USt), vorzeichenlos."},"ustCents":{"type":"string","description":"Σ USt-Anteil."},"nettoCents":{"type":"string","description":"Σ Brutto − Σ USt."},"anzahl":{"type":"integer","description":"Anzahl der Positionen in dieser Summe (eine Summe ohne Zähler ist nicht prüfbar)."}},"required":["bruttoCents","ustCents","nettoCents","anzahl"]},"EinnahmenAusgabenPosition":{"type":"object","properties":{"buchungId":{"type":"string","format":"uuid","description":"Der Buchungssatz, aus dem diese Zeile stammt (`journal_entries.id`)."},"datum":{"type":"string","format":"date","description":"Buchungsdatum — die Zeitachse des Geldflusses."},"geldkonten":{"type":"array","items":{"type":"string"},"description":"Die Geldkonten, über die diese Zeile gelaufen ist — in der Regel GENAU EINES. Mehrere nur bei mehreren Bankzeilen im Satz; dort wäre die Benennung EINES Kontos eine Erfindung. Nie leer: bei `verrechnet` steht hier das Konto, gegen das verrechnet wurde."},"verrechnet":{"type":"boolean","description":"true = die Zeile stand der Geldkonto-Seite nicht unmittelbar gegenüber, sondern wurde INNERHALB des Satzes gegen sie verrechnet (Einbehalt, Abzug). Der Betrag ist über die genannten Geldkonten gelaufen, nur saldiert mit der Gegenzeile desselben Satzes — er zählt deshalb voll als Einnahme bzw. Ausgabe (§ 4 Abs. 3 EStG kennt keine Netto-Einnahme)."},"gegenkonto":{"type":"string","description":"Das Gegenkonto der Zeile (Erlös-, Kosten- oder Personenkonto)."},"richtung":{"type":"string","enum":["zufluss","abfluss"],"description":"zufluss = Einnahme (Geld kam herein), abfluss = Ausgabe."},"bruttoCents":{"type":"string","description":"Betrag der Gegenzeile, vorzeichenlos — Brutto (mit USt)."},"ustCents":{"type":"string","description":"USt-Anteil; \"0\", wenn die Zeile keinen nennt."},"nettoCents":{"type":"string","description":"brutto − ust."},"ustSatz":{"type":["string","null"],"description":"USt-Satz der Zeile als Dezimalstring (`19.00`); `null` = keiner erfasst."},"ustHerkunft":{"type":"string","enum":["gebucht","abgeleitet","ohne"],"description":"GG7, feldweise Provenienz: `gebucht` = der Betrag stand an der Buchungszeile, `abgeleitet` = aus dem Satz gerechnet (kaufmännisch auf den Cent), `ohne` = weder Betrag noch Satz."},"belegnummer":{"type":["string","null"],"description":"Belegnummer des Satzes; `null` = keine erfasst."},"belegId":{"type":["string","null"],"format":"uuid","description":"Das verknüpfte Belegdokument (`documents.id`); `null` = die Beleg-Kette löst nicht auf."}},"required":["buchungId","datum","geldkonten","verrechnet","gegenkonto","richtung","bruttoCents","ustCents","nettoCents","ustSatz","ustHerkunft","belegnummer","belegId"]},"EinnahmenAusgabenGegenkontoSumme":{"type":"object","properties":{"gegenkonto":{"type":"string"},"zufluss":{"$ref":"#/components/schemas/EinnahmenAusgabenSumme"},"abfluss":{"$ref":"#/components/schemas/EinnahmenAusgabenSumme"}},"required":["gegenkonto","zufluss","abfluss"]},"EinnahmenAusgabenUmbuchung":{"type":"object","properties":{"buchungId":{"type":"string","format":"uuid"},"datum":{"type":"string","format":"date"},"vonGeldkonten":{"type":"array","items":{"type":"string"},"description":"Geldkonten im HABEN des Satzes (Abgang)."},"nachGeldkonten":{"type":"array","items":{"type":"string"},"description":"Geldkonten im SOLL des Satzes (Zugang)."},"betragCents":{"type":"string","description":"Übertragener Betrag = min(Σ Soll, Σ Haben) der Geldzeilen."}},"required":["buchungId","datum","vonGeldkonten","nachGeldkonten","betragCents"]},"EinnahmenAusgabenResponse":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date","description":"Erster Tag des Zeitraums (Echo, inklusive)."},"bis":{"type":"string","format":"date","description":"Letzter Tag des Zeitraums (Echo, inklusive)."},"gegenkonto":{"type":["string","null"],"description":"Das angefragte EINE Gegenkonto (Echo) oder `null` für „alle Gegenkonten\"."},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/EinnahmenAusgabenPosition"}},"jeGegenkonto":{"type":"array","items":{"$ref":"#/components/schemas/EinnahmenAusgabenGegenkontoSumme"},"description":"Summen je Gegenkonto, nach Kontonummer geordnet."},"einnahmen":{"$ref":"#/components/schemas/EinnahmenAusgabenSumme"},"ausgaben":{"$ref":"#/components/schemas/EinnahmenAusgabenSumme"},"umbuchungen":{"type":"array","items":{"$ref":"#/components/schemas/EinnahmenAusgabenUmbuchung"}},"eroeffnungen":{"type":"array","items":{"$ref":"#/components/schemas/EinnahmenAusgabenPosition"},"description":"BESTANDSVORTRÄGE des Zeitraums (`entry_type = eroeffnung`) in derselben Form wie eine Position — ausdrücklich NICHT in `einnahmen`, `ausgaben` oder `jeGegenkonto`: ein Anfangsbestand sieht aus wie eine Einnahme und ist keine, das Geld war schon da. Sie stehen hier, damit die Geldkonten-Entwicklung (Anfangsbestand + Einnahmen − Ausgaben = Endbestand) aufgeht, ohne den Anfangsbestand aus der Differenz zu erraten. `richtung` sagt, auf welcher Seite der Vortrag stand — nicht, dass Geld geflossen wäre."},"ohneGeldkontoSeite":{"type":"integer","description":"Sätze des Zeitraums OHNE jede Geldkonto-Zeile (Sollstellung, Bestandsvortrag ohne Bank) — die ehrliche Differenz zum Buchungsjournal, nicht verschwiegen."}},"required":["objektId","von","bis","gegenkonto","positionen","jeGegenkonto","einnahmen","ausgaben","umbuchungen","eroeffnungen","ohneGeldkontoSeite"]},"SevBetrag":{"type":"object","properties":{"stand":{"type":"string","enum":["bekannt","offen","nicht-verfuegbar"],"description":"bekannt = es gibt einen Betrag; offen = die Quelle steht, hat für diesen Monat aber noch keinen Wert; nicht-verfuegbar = die Quelle ist noch nicht gebaut."},"cents":{"type":["string","null"],"description":"Betrag in Cent als Integer-STRING — und `null`, sobald `stand` nicht `bekannt` ist. Ausdrücklich NIE `\"0\"` für einen unbekannten Wert: eine Geldanzeige, die „nicht gemessen\" und „null Euro\" zusammenfallen lässt, meldet einen ausgeglichenen Eigentümer, wo niemand nachgesehen hat."},"text":{"type":"string","description":"Anzeigetext — „1.234,56 €\", „nicht verfügbar\" oder „noch nicht gelaufen\"."},"grund":{"type":["string","null"],"description":"Warum kein Betrag dasteht; `null`, wenn einer dasteht."}},"required":["stand","cents","text","grund"]},"SevSchritt":{"type":"object","properties":{"schritt":{"type":"string","enum":["mietgutschrift","verguetung","hausgeld","sonderruecklage","auszahlung"],"description":"Der Schritt — in der PFLICHT-REIHENFOLGE aus UC-SEV-001."},"bezeichnung":{"type":"string","description":"Kundentaugliche Bezeichnung des Schritts (keine interne Kennung)."},"stand":{"type":"string","enum":["erledigt","offen","nicht-verfuegbar"],"description":"erledigt | offen | nicht-verfuegbar. `nicht-verfuegbar` heisst: die Quelle dieses Schritts ist noch nicht gebaut — ausdrücklich NICHT „erledigt\"."},"text":{"type":"string","description":"Der Satz, der dem Verwalter angezeigt wird."},"hinweis":{"type":["string","null"],"description":"Zusatz zum Schritt; `null`, wenn keiner vorliegt."}},"required":["schritt","bezeichnung","stand","text","hinweis"]},"SevUnterdeckung":{"type":"object","properties":{"bezeichnung":{"type":"string","description":"Wofür die Deckung fehlt, kundentauglich (z. B. „Hausgeld Oktober\")."},"wohnung":{"type":"string","description":"Die Wohnung, zu der die Unterdeckung gehört — an JEDER Zeile, damit sie aus dem Zusammenhang gerissen (Export, Mail) noch stimmt."},"betragCents":{"type":"string","description":"Der fehlende Betrag in Cent als Integer-STRING."},"betragText":{"type":"string","description":"Derselbe Betrag als deutscher Anzeigetext („245,00 €\")."},"text":{"type":"string","description":"Der vollständige Satz: Betrag, Anlass und Wohnung."}},"required":["bezeichnung","wohnung","betragCents","betragText","text"]},"SevNaechsterSchritt":{"type":"object","properties":{"art":{"type":"string","enum":["schritt","nicht-ermittelbar","keiner"],"description":"schritt = dieser Schritt ist als Nächstes fällig; nicht-ermittelbar = die Pflicht-Reihenfolge stösst auf einen Schritt, dessen Quelle fehlt (weder er noch der danach darf genannt werden); keiner = der Monat ist durch."},"schritt":{"type":["string","null"],"enum":["mietgutschrift","verguetung","hausgeld","sonderruecklage","auszahlung",null],"description":"Der Schritt; `null` bei `nicht-ermittelbar` und `keiner`."},"bezeichnung":{"type":["string","null"],"description":"Seine kundentaugliche Bezeichnung; `null` wie oben."},"text":{"type":"string","description":"Der Satz, der dem Verwalter angezeigt wird."}},"required":["art","schritt","bezeichnung","text"]},"SevWohnungStand":{"type":"object","properties":{"wohnung":{"type":"string","description":"Bezeichnung der Wohnung — keine UUID, keine interne Kennung (Abnahme 4 von #5229)."},"eigentuemer":{"type":"string","description":"Name des Eigentümers — keine UUID, keine interne Kennung."},"schritte":{"type":"array","items":{"$ref":"#/components/schemas/SevSchritt"},"description":"ALLE Schritte in der Pflicht-Reihenfolge, nie gefiltert — eine Liste ohne einen Schritt sähe aus wie eine Kette ohne ihn."},"saldo":{"allOf":[{"$ref":"#/components/schemas/SevBetrag"},{"description":"Saldo des Eigentümer-Verrechnungskontos."}]},"sockel":{"allOf":[{"$ref":"#/components/schemas/SevBetrag"},{"description":"Vereinbarter Sockelbetrag, der auf dem Konto stehen bleibt."}]},"sonderruecklage":{"allOf":[{"$ref":"#/components/schemas/SevBetrag"},{"description":"Bestand der Sonderrücklage."}]},"unterdeckungenStand":{"type":"string","enum":["bekannt","offen","nicht-verfuegbar"],"description":"`bekannt` mit LEERER Liste heisst „geprüft, keine\" — eine andere Aussage als „nicht nachgesehen\" und deshalb ein eigener Stand."},"unterdeckungen":{"type":"array","items":{"$ref":"#/components/schemas/SevUnterdeckung"}},"unterdeckungenText":{"type":"string","description":"Zusammenfassung der Unterdeckungen als Anzeigetext."},"naechsterSchritt":{"$ref":"#/components/schemas/SevNaechsterSchritt"}},"required":["wohnung","eigentuemer","schritte","saldo","sockel","sonderruecklage","unterdeckungenStand","unterdeckungen","unterdeckungenText","naechsterSchritt"]},"SevMonatsstandResponse":{"type":"object","properties":{"objekt":{"type":"string","description":"Anzeigename des Objekts — keine Kennung (die UUID kennt der Aufrufer, er hat sie gefragt)."},"monat":{"type":"string","description":"Der angefragte Monat als `JJJJ-MM` (Echo).","example":"2026-10"},"monatText":{"type":"string","description":"Derselbe Monat als Anzeigetext („Oktober 2026\")."},"wohnungen":{"type":"array","items":{"$ref":"#/components/schemas/SevWohnungStand"},"description":"Je SEV-Mandat eine Zeile, in der Ordnung der Quelle. LEER, solange die SEV-Kette (#5216–#5223) nicht gebaut ist — dann steht der Grund in `hinweise` und `vollstaendig` ist `false`. Eine leere Liste ist hier NIE die Aussage „dieses Objekt hat keine Sondereigentumsverwaltung\"."},"hinweise":{"type":"array","items":{"type":"string"},"description":"Grundsätzliche, kundentaugliche Hinweise zum ganzen Objekt."},"vollstaendig":{"type":"boolean","description":"`false`, sobald IRGENDEIN Wert oder Schritt nicht verfügbar ist — die eine Angabe, an der ein Aufrufer erkennt, dass die Auskunft unvollständig ist."}},"required":["objekt","monat","monatText","wohnungen","hinweise","vollstaendig"]},"CliLoginStartRequest":{"type":"object","properties":{"state":{"type":"string","description":"Zufälliger Bindungsnachweis dieser Anmelderunde, URL-sicher, 32–256 Zeichen. KEIN Secret im Token-Sinn — er darf in der Browser-URL stehen. Ein fehlender, fremder oder wiedereingespielter state liefert fail-closed keinen Token; serverseitig ist eine Runde genau einmal bestätigbar und zehn Minuten gültig."},"redirectUri":{"type":"string","description":"Rückruf-Adresse des kurzlebigen Servers, den die CLI auf der Loopback-Schnittstelle geöffnet hat. Zulässig ist ausschließlich ein Loopback-Name mit Schema http und explizitem Port; alles andere wird fail-closed abgewiesen."},"frisch":{"type":"boolean","description":"Verlangt eine FRISCHE Browser-Anmeldung (Admin-Step-up, #7110). Ist die Browser-Sitzung älter als 900 Sekunden, schickt die Freigabe-Seite zuerst auf die Sicherheits-Rückfrage (`/login?stepUp=1`); erst eine frische Sitzung bekommt „Freigeben\", und nur dann merkt sich der Server die Browser-Freigabe an dieser Sitzung. Fehlt das Feld, gilt `false` (bisheriges Verhalten). Ein Wert, der kein Boolean ist, ergibt 400 `invalid_request`."}},"required":["state","redirectUri"]},"ZaehlerZeile":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"objektId":{"type":"string","format":"uuid"},"einheitId":{"type":["string","null"],"format":"uuid","description":"null ⇒ Allgemein-Zähler des Objekts."},"einheitNr":{"type":["string","null"],"description":"Einheitsnummer; null bei Allgemein-Zählern."},"zaehlerart":{"type":"string"},"zaehlernummer":{"type":["string","null"]},"masseinheit":{"type":["string","null"]},"ersetztZaehlerId":{"type":["string","null"],"format":"uuid","description":"Vorgänger bei Zählertausch; null ⇒ kein Tausch."},"archiviertAm":{"type":["string","null"],"format":"date-time","description":"null ⇒ aktiv."},"angelegtAm":{"type":"string","format":"date-time"}},"required":["id","objektId","einheitId","einheitNr","zaehlerart","zaehlernummer","masseinheit","ersetztZaehlerId","archiviertAm","angelegtAm"]},"ZaehlerListeResponse":{"type":"object","properties":{"zaehler":{"type":"array","items":{"$ref":"#/components/schemas/ZaehlerZeile"}}},"required":["zaehler"]},"ZaehlerAblesung":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"zaehlerId":{"type":"string","format":"uuid"},"zaehlerstand":{"type":["string","null"],"description":"null bei defektem Bestand.","example":"161.700"},"abgelesenAm":{"type":["string","null"],"format":"date-time"},"quelle":{"type":["string","null"]},"anlass":{"type":["string","null"]},"plausibilitaet":{"type":["string","null"]},"erfasstAm":{"type":"string","format":"date-time"}},"required":["id","zaehlerId","zaehlerstand","abgelesenAm","quelle","anlass","plausibilitaet","erfasstAm"]},"ZaehlerAblesungenResponse":{"type":"object","properties":{"zaehlerId":{"type":"string","format":"uuid"},"ablesungen":{"type":"array","items":{"$ref":"#/components/schemas/ZaehlerAblesung"}}},"required":["zaehlerId","ablesungen"]},"ZaehlerVerbrauchZaehler":{"type":"object","properties":{"zaehlerId":{"type":"string","format":"uuid"},"einheitId":{"type":["string","null"],"format":"uuid"},"einheitNr":{"type":["string","null"]},"zaehlerart":{"type":"string"},"zaehlernummer":{"type":["string","null"]},"masseinheit":{"type":["string","null"]},"ersetztZaehlerId":{"type":["string","null"],"format":"uuid"},"anfangsstand":{"type":["object","null"],"properties":{"zaehlerstand":{"type":"string","description":"Dezimal-STRING mit Punkt, Skala 3 (z. B. \"161.700\"). Nie eine JSON-number.","example":"161.700"},"abgelesenAm":{"type":"string","format":"date-time"},"anlass":{"type":["string","null"]}},"required":["zaehlerstand","abgelesenAm","anlass"]},"endstand":{"type":["object","null"],"properties":{"zaehlerstand":{"type":"string","description":"Dezimal-STRING mit Punkt, Skala 3 (z. B. \"161.700\"). Nie eine JSON-number.","example":"161.700"},"abgelesenAm":{"type":"string","format":"date-time"},"anlass":{"type":["string","null"]}},"required":["zaehlerstand","abgelesenAm","anlass"]},"verbrauch":{"type":["string","null"],"description":"null, solange eine Grenze fehlt.","example":"161.700"},"vollstaendig":{"type":"boolean"},"fehlend":{"type":"array","items":{"type":"string","enum":["anfangsstand","endstand"]},"description":"Ehrlicher Fehlbestand — nie interpoliert."}},"required":["zaehlerId","einheitId","einheitNr","zaehlerart","zaehlernummer","masseinheit","ersetztZaehlerId","anfangsstand","endstand","verbrauch","vollstaendig","fehlend"]},"ZaehlerVerbrauchEinheit":{"type":"object","properties":{"einheitId":{"type":["string","null"],"format":"uuid"},"einheitNr":{"type":["string","null"]},"zaehlerart":{"type":"string"},"masseinheit":{"type":["string","null"]},"verbrauch":{"type":["string","null"],"description":"Summe der vollständigen Segmente; null, wenn kein Segment vollständig ist.","example":"161.700"},"vollstaendig":{"type":"boolean","description":"true NUR, wenn JEDES beteiligte Segment vollständig ist."},"zaehlerIds":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["einheitId","einheitNr","zaehlerart","masseinheit","verbrauch","vollstaendig","zaehlerIds"]},"ZaehlerVerbrauchResponse":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"von":{"type":"string","format":"date"},"bis":{"type":"string","format":"date"},"vollstaendig":{"type":"boolean","description":"false, sobald irgendein Segment eine Grenze nicht hat (siehe `fehlend` je Zähler)."},"zaehler":{"type":"array","items":{"$ref":"#/components/schemas/ZaehlerVerbrauchZaehler"}},"einheiten":{"type":"array","items":{"$ref":"#/components/schemas/ZaehlerVerbrauchEinheit"}}},"required":["objektId","von","bis","vollstaendig","zaehler","einheiten"]},"ZaehlerZwischenstandStand":{"type":"object","properties":{"abgelesenAm":{"type":"string","format":"date"},"zaehlerstand":{"type":"string","description":"Dezimal-STRING mit Punkt, Skala 3 (z. B. \"161.700\"). Nie eine JSON-number.","example":"161.700"}},"required":["abgelesenAm","zaehlerstand"]},"ZaehlerZwischenstandTage":{"type":"object","properties":{"luecke":{"type":"integer","description":"Kalendertage zwischen dem Stand davor und dem Stand danach."},"bisStichtag":{"type":"integer","description":"Kalendertage zwischen dem Stand davor und dem Stichtag."}},"required":["luecke","bisStichtag"]},"ZaehlerZwischenstandResponse":{"type":"object","properties":{"zaehlerId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"art":{"type":"string","enum":["vorschlag","kein-vorschlag"]},"zaehlerstand":{"type":["string","null"],"description":"Der vorgeschlagene Stand; null bei `kein-vorschlag`. Ein VORSCHLAG, nie ein gebuchter Wert.","example":"161.700"},"vorher":{"allOf":[{"$ref":"#/components/schemas/ZaehlerZwischenstandStand"},{"type":["object","null"]}]},"nachher":{"allOf":[{"$ref":"#/components/schemas/ZaehlerZwischenstandStand"},{"type":["object","null"]}]},"tage":{"allOf":[{"$ref":"#/components/schemas/ZaehlerZwischenstandTage"},{"type":["object","null"]}]},"code":{"type":["string","null"],"enum":["stand-vorhanden","kein-vorher-wert","kein-nachher-wert","stand-faellt","luecke-zu-lang",null],"description":"Warum es keinen Vorschlag gibt; null bei `vorschlag`."},"begruendung":{"type":"string","description":"Klartext: wie der Vorschlag entstand bzw. warum keiner entsteht."},"gebucht":{"type":"boolean","enum":[false],"description":"Immer false: der Vorschlag wird nicht gebucht und ist nie ein Wert des Abrechnungslaufs."}},"required":["zaehlerId","stichtag","art","zaehlerstand","vorher","nachher","tage","code","begruendung","gebucht"]},"ZaehlerPflichtResponse":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"zaehlerart":{"type":"string"},"anzahlWohneinheiten":{"type":"integer","description":"Aktive Einheiten der Art wohnung; Gewerbe zählt nicht mit."},"pflicht":{"type":"string","enum":["ja","nein","ausnahme","nicht-heizkostenv"]},"ausnahmeGrund":{"type":["string","null"],"enum":["unwirtschaftlich","pauschal-wechselnd-belegt",null],"description":"Grund der Objekt-Option `zaehler.erfassungspflicht_ausnahme`; die Begründung bleibt im Objekt."},"hinweise":{"type":"array","items":{"type":"string","enum":["unter-schwelle","kaltwasser-nicht-zwingend","ausnahme-begruendungspflicht","gewerbe-nicht-gezaehlt"]}},"blockiert":{"type":"boolean","enum":[false],"description":"Immer false: die Prüfung ist ein Hinweis und sperrt nichts."}},"required":["objektId","zaehlerart","anzahlWohneinheiten","pflicht","ausnahmeGrund","hinweise","blockiert"]},"BrennstoffkontoZustand":{"type":"object","properties":{"isUmlagefaehig":{"type":["boolean","null"],"description":"Umlagefähig? null = nie gesetzt (gilt als nicht umlagefähig)."},"allocationKeyId":{"type":["string","null"],"format":"uuid","description":"Umlageschlüssel des Kontos; null = ohne Schlüssel."}},"required":["isUmlagefaehig","allocationKeyId"]},"BrennstoffkontoAktiv":{"type":"object","properties":{"glAccountId":{"type":"string","format":"uuid"},"accountNo":{"type":"string","description":"Kontonummer"},"name":{"type":"string"},"zustand":{"allOf":[{"$ref":"#/components/schemas/BrennstoffkontoZustand"},{"description":"Der heutige Zustand des Kontos."}]},"gesetztAm":{"type":"string","format":"date-time"}},"required":["glAccountId","accountNo","name","zustand","gesetztAm"]},"BrennstoffkontoVerlust":{"type":"object","properties":{"umlagefaehig":{"type":"boolean","description":"Das Konto war umlagefähig."},"schluessel":{"type":"boolean","description":"Das Konto trug einen Umlageschlüssel."}},"required":["umlagefaehig","schluessel"]},"BrennstoffkontoBefund":{"type":"object","properties":{"code":{"type":"string","enum":["brennstoffkonto-verteilt-doppelt"]},"glAccountId":{"type":"string","format":"uuid"},"verlust":{"$ref":"#/components/schemas/BrennstoffkontoVerlust"},"text":{"type":"string","description":"Klartext: die Heizkosten würden doppelt verteilt."}},"required":["code","glAccountId","verlust","text"]},"BrennstoffkontoHeizkostenKonto":{"type":"object","properties":{"glAccountId":{"type":"string","format":"uuid"},"accountNo":{"type":"string"},"name":{"type":"string"},"zustand":{"$ref":"#/components/schemas/BrennstoffkontoZustand"},"istBrennstoffkonto":{"type":"boolean","description":"Ist dies das aktive Brennstoffkonto des Objekts?"}},"required":["glAccountId","accountNo","name","zustand","istBrennstoffkonto"]},"BrennstoffkontoHinweis":{"type":"object","properties":{"code":{"type":"string","enum":["vorgaenger-gebucht-nicht-zurueckgesetzt"]},"glAccountId":{"type":"string","format":"uuid"},"text":{"type":"string"}},"required":["code","glAccountId","text"]},"BrennstoffkontoResponse":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"aktiv":{"allOf":[{"$ref":"#/components/schemas/BrennstoffkontoAktiv"},{"type":["object","null"],"description":"Das aktive Brennstoffkonto; null = das Objekt hat keines."}]},"vorzustand":{"allOf":[{"$ref":"#/components/schemas/BrennstoffkontoZustand"},{"type":["object","null"],"description":"Ausgangszustand des aktiven Kontos — wohin ein Aufheben es zurückstellt."}]},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/BrennstoffkontoBefund"},"description":"Leer, solange kein aktives Brennstoffkonto umlagefähig ist oder einen Schlüssel trägt."},"heizkostenKonten":{"type":"array","items":{"$ref":"#/components/schemas/BrennstoffkontoHeizkostenKonto"},"description":"Die Konten des Objekts, deren Kostenart (Schlüssel oder BetrKV-Katalog-Schlüssel) eine Heizkostenart ist."}},"required":["objektId","aktiv","vorzustand","befunde","heizkostenKonten"]},"BrennstoffkontoSetzenRequest":{"type":"object","properties":{"glAccountId":{"type":"string","format":"uuid","description":"Das Konto des Objekts, das Brennstoffkonto werden soll."},"bestaetigt":{"type":"boolean","description":"Pflichtfeld ohne Default (true oder false). true ist nötig, wenn das Konto umlagefähig ist oder einen Umlageschlüssel trägt: das Setzen macht es nicht umlagefähig und entfernt den Schlüssel. Fehlt das Feld, wird abgelehnt (400); es gilt nie still false."}},"required":["glAccountId","bestaetigt"],"additionalProperties":false,"description":"Setzt das Brennstoffkonto des Objekts (die Objekt-Id steht im Pfad). Das Brennstoffkonto verteilt die Heizkosten über die Heizkostenabrechnung und darf nicht zusätzlich als Betriebskosten umgelegt werden. Ein bisheriges Brennstoffkonto geht auf seinen gespeicherten Ausgangszustand zurück."},"BrennstoffkontoAufhebenRequest":{"type":"object","properties":{"bestaetigt":{"type":"boolean","description":"Pflichtfeld ohne Default (true oder false). true ist nötig, wenn der Ausgangszustand das Konto wieder in die Umlage bringt. Fehlt das Feld, wird abgelehnt (400); es gilt nie still false."}},"required":["bestaetigt"],"additionalProperties":false,"description":"Hebt das Brennstoffkonto des Objekts auf (die Objekt-Id steht im Pfad); das Konto geht auf seinen Ausgangszustand zurück."},"BrennstoffkontoGesetztResponse":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"glAccountId":{"type":"string","format":"uuid"},"vorzustand":{"allOf":[{"$ref":"#/components/schemas/BrennstoffkontoZustand"},{"description":"Ausgangszustand des gewählten Kontos — wohin ein späteres Aufheben es zurückstellt."}]},"abgeloestGlAccountId":{"type":["string","null"],"format":"uuid","description":"Das frühere Brennstoffkonto, falls eines abgelöst wurde."},"verlust":{"allOf":[{"$ref":"#/components/schemas/BrennstoffkontoVerlust"},{"description":"Was die Umstellung dem gewählten Konto genommen hat."}]},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/BrennstoffkontoHinweis"}}},"required":["objektId","glAccountId","vorzustand","abgeloestGlAccountId","verlust","hinweise"]},"BrennstoffkontoAufgehobenResponse":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"glAccountId":{"type":"string","format":"uuid"},"zustand":{"allOf":[{"$ref":"#/components/schemas/BrennstoffkontoZustand"},{"description":"Der Zustand, auf den das Konto zurückgegangen ist (gebuchtes Konto: unverändert)."}]},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/BrennstoffkontoHinweis"}}},"required":["objektId","glAccountId","zustand","hinweise"]},"ZaehlerAnlegenRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid","description":"Das Objekt; nach der Anlage fest."},"unitId":{"type":"string","format":"uuid","description":"Die Einheit (Standort); ohne Angabe ein Allgemein-Zähler. Nach der Anlage fest."},"meterType":{"type":"string","description":"Zählerart, z. B. `wasser_kalt`, `wasser_warm`, `waerme`, `strom`."},"meterNo":{"type":"string","description":"Feste Zählernummer. Entweder eine feste Nummer ODER ein Nummernkreis (Präfix/Turnusjahr), nie beides (400). Ohne beides und ohne Turnusjahr bleibt die Nummer leer."},"meterNoPrefix":{"type":"string","description":"Präfix des Nummernkreises (Nummer = Präfix + dreistellig laufend). Entweder eine feste Nummer ODER ein Nummernkreis (Präfix/Turnusjahr), nie beides (400). Ohne beides und ohne Turnusjahr bleibt die Nummer leer."},"turnusjahr":{"type":"integer","description":"Turnusjahr des Vorgabe-Präfixes `KW|WW|HZ|ST-<Turnusjahr>-` (nur ohne Nummer und Präfix)."},"unitOfMeasure":{"type":"string","description":"Maßeinheit, z. B. `m3`, `kwh`."},"sourceSystem":{"type":["string","null"],"description":"Quellsystem eines Imports (z. B. `win-casa`); systemseitige Werte sind verboten."},"sourceRef":{"type":["string","null"],"description":"Referenz im Quellsystem."}},"required":["propertyId","meterType"],"additionalProperties":false},"ZaehlerSammelanlageRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"meterType":{"type":"string"},"unitOfMeasure":{"type":"string"},"meterNoPrefix":{"type":"string"},"turnusjahr":{"type":"integer"},"sourceSystem":{"type":["string","null"],"description":"Quellsystem eines Imports (z. B. `win-casa`); systemseitige Werte sind verboten."},"sourceRef":{"type":["string","null"],"description":"Referenz im Quellsystem."},"einheiten":{"type":"array","items":{"type":"object","properties":{"unitId":{"type":"string","format":"uuid"},"meterNo":{"type":"string"}},"required":["unitId"],"additionalProperties":false},"minItems":1,"maxItems":500,"description":"Höchstens 500 Einheiten, jede nur einmal; je Einheit optional eine eigene Nummer (nie zusammen mit einem Nummernkreis)."}},"required":["propertyId","meterType","einheiten"],"additionalProperties":false},"ZaehlerAendernRequest":{"type":"object","properties":{"meterType":{"type":"string"},"meterNo":{"type":"string"},"unitOfMeasure":{"type":"string"}},"additionalProperties":false,"anyOf":[{"required":["meterType"]},{"required":["meterNo"]},{"required":["unitOfMeasure"]}]},"ZaehlerGespeichertResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"objektId":{"type":"string","format":"uuid"},"einheitId":{"type":["string","null"],"format":"uuid"},"zaehlerart":{"type":"string"},"zaehlernummer":{"type":["string","null"],"description":"Die vergebene Nummer, auch wenn sie aus dem Nummernkreis stammt."},"masseinheit":{"type":["string","null"]},"ersetztZaehlerId":{"type":["string","null"],"format":"uuid"}},"required":["id","objektId","einheitId","zaehlerart","zaehlernummer","masseinheit","ersetztZaehlerId"]},"ZaehlerSammelanlageEinheit":{"type":"object","properties":{"einheitId":{"type":"string","format":"uuid"},"zaehlerId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["angelegt","vorhanden"],"description":"`vorhanden`: die Einheit hatte schon einen aktiven Zähler dieser Art."},"zaehlernummer":{"type":["string","null"]}},"required":["einheitId","zaehlerId","status","zaehlernummer"]},"ZaehlerSammelanlageResponse":{"type":"object","properties":{"objektId":{"type":"string","format":"uuid"},"zaehlerart":{"type":"string"},"angelegt":{"type":"integer"},"vorhanden":{"type":"integer"},"einheiten":{"type":"array","items":{"$ref":"#/components/schemas/ZaehlerSammelanlageEinheit"}}},"required":["objektId","zaehlerart","angelegt","vorhanden","einheiten"]},"ZaehlerArchiviertResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"archiviertAm":{"type":"string","format":"date-time"},"bereitsArchiviert":{"type":"boolean","description":"true ⇒ der Zähler war schon archiviert; nichts wurde geschrieben."}},"required":["id","archiviertAm","bereitsArchiviert"]},"ZaehlerAblesenRequest":{"type":"object","properties":{"reading":{"type":"string","description":"Zählerstand. Dezimal-String mit Punkt und höchstens 3 Nachkommastellen (z. B. `161.700`); ein Komma ist 400."},"readAt":{"type":"string","description":"Ablesezeitpunkt, ISO-8601-Datum oder -Zeitpunkt; ein Kalendertag zählt als 00:00 UTC."},"occasion":{"type":"string","enum":["turnus","wechsel","zwischenablesung"],"description":"Anlass (geschlossen). Die Zwischenablesung am Tag des Mieterwechsels ist Voraussetzung der Verbrauchs-Zuordnung je Vertrag."},"source":{"type":"string","description":"Erhebungsart (`ablesung` · `schaetzung` · `portal`); Standard `ablesung`."},"sourceSystem":{"type":["string","null"],"description":"Quellsystem eines Imports; systemseitige Werte sind verboten."},"sourceRef":{"type":["string","null"],"description":"Referenz im Quellsystem."}},"required":["reading","readAt","occasion"],"additionalProperties":false},"ZaehlerPlausibilitaetMeldung":{"type":"object","properties":{"code":{"type":"string","enum":["VERBRAUCH_NULL","AUSREISSER","ABLESEFENSTER"]},"message":{"type":"string"},"basis":{"type":"string","enum":["vorjahr","letzter_stand"],"description":"Nur AUSREISSER: Grundlage des Urteils."}},"required":["code","message"]},"ZaehlerPlausibilitaet":{"type":"object","properties":{"status":{"type":"string","enum":["ok","warnung"]},"warnungen":{"type":"array","items":{"$ref":"#/components/schemas/ZaehlerPlausibilitaetMeldung"}},"hinweise":{"type":"array","items":{"$ref":"#/components/schemas/ZaehlerPlausibilitaetMeldung"}}},"required":["status","warnungen","hinweise"]},"ZaehlerAbgelesenResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"zaehlerId":{"type":"string","format":"uuid"},"zaehlerstand":{"type":"string","description":"Kanonischer Stand, Skala 3."},"abgelesenAm":{"type":"string","format":"date-time"},"anlass":{"type":"string","enum":["turnus","wechsel","zwischenablesung"]},"verbrauchSeitVorablesung":{"type":["string","null"],"description":"Verbrauch seit dem zeitlichen Vorgänger; `null` bei der Erst-Ablesung."},"plausibilitaet":{"$ref":"#/components/schemas/ZaehlerPlausibilitaet"}},"required":["id","zaehlerId","zaehlerstand","abgelesenAm","anlass","verbrauchSeitVorablesung","plausibilitaet"]},"ZaehlerTauschRequest":{"type":"object","properties":{"readAt":{"type":"string","description":"Zeitpunkt des Tauschs, ISO-8601-Datum oder -Zeitpunkt (Kalendertag = 00:00 UTC)."},"endReading":{"type":"string","description":"Endstand des Altzählers. Dezimal-String mit Punkt und höchstens 3 Nachkommastellen (z. B. `161.700`); ein Komma ist 400."},"startReading":{"type":"string","description":"Anfangsstand des Neuzählers; Standard `0.000`. Dezimal-String mit Punkt und höchstens 3 Nachkommastellen (z. B. `161.700`); ein Komma ist 400."},"newMeterNo":{"type":"string","description":"Zählernummer des Neugeräts."},"meterType":{"type":"string","description":"Art des Neugeräts; Standard die des Altzählers."},"unitOfMeasure":{"type":"string","description":"Maßeinheit des Neugeräts; Standard die des Altzählers."},"sourceSystem":{"type":["string","null"],"description":"Quellsystem eines Imports; systemseitige Werte sind verboten."},"sourceRef":{"type":["string","null"],"description":"Referenz im Quellsystem."}},"required":["readAt","endReading"],"additionalProperties":false},"ZaehlerGetauschtResponse":{"type":"object","properties":{"altZaehlerId":{"type":"string","format":"uuid"},"neuZaehlerId":{"type":"string","format":"uuid"},"endstandAblesungId":{"type":"string","format":"uuid"},"anfangsstandAblesungId":{"type":"string","format":"uuid"},"endstand":{"type":"string"},"anfangsstand":{"type":"string"},"abgelesenAm":{"type":"string","format":"date-time"},"altArchiviertAm":{"type":"string","format":"date-time"}},"required":["altZaehlerId","neuZaehlerId","endstandAblesungId","anfangsstandAblesungId","endstand","anfangsstand","abgelesenAm","altArchiviertAm"]},"AblesungBerichtigenRequest":{"type":"object","properties":{"reading":{"type":"string","description":"Der richtige Zählerstand. Dezimal-String mit Punkt und höchstens 3 Nachkommastellen (z. B. `161.700`); ein Komma ist 400."},"grund":{"type":"string","description":"Warum berichtigt wird (Kommando-Log); fehlt er, fehlt er sichtbar."}},"required":["reading"],"additionalProperties":false},"AblesungBerichtigtResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"zaehlerId":{"type":"string","format":"uuid"},"stand":{"type":"string","description":"Der neue, kanonische Stand (Skala 3)."},"vorherigerStand":{"type":"string","description":"Der Stand vor der Berichtigung (Skala 3)."},"abgelesenAm":{"type":"string","format":"date-time"},"anlass":{"type":"string","enum":["turnus","wechsel","zwischenablesung"]},"verbrauchSeitVorablesung":{"type":["string","null"]},"plausibilitaet":{"$ref":"#/components/schemas/ZaehlerPlausibilitaet"}},"required":["id","zaehlerId","stand","vorherigerStand","abgelesenAm","anlass","verbrauchSeitVorablesung","plausibilitaet"]},"WirtschaftsplanGeld":{"type":"object","properties":{"cents":{"type":"string","description":"Minor-Units-Integer-STRING, vorzeichenbehaftet (z. B. \"-125000\"). Nie eine JSON-number."},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"]},"WirtschaftsplanPosition":{"type":"object","properties":{"kostenart":{"type":"string"},"art":{"type":"string","enum":["kosten","einnahme","ruecklagenzufuehrung"],"description":"Positionsart; das Vorzeichen trägt die Art, der Betrag ist immer > 0."},"betrag":{"$ref":"#/components/schemas/WirtschaftsplanGeld"},"verteilerschluessel":{"type":["string","null"],"description":"Bei `kosten`/`einnahme` Pflicht, bei `ruecklagenzufuehrung` verboten."},"ruecklageId":{"type":["string","null"],"format":"uuid","description":"Bei `ruecklagenzufuehrung` Pflicht, sonst verboten."}},"required":["kostenart","art","betrag"]},"WirtschaftsplanAnlegenRequest":{"type":"object","properties":{"jahr":{"type":"integer","description":"Das WIRTSCHAFTSJAHR des Plans."},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanPosition"},"description":"Mindestens eine Position."},"beginn":{"type":"string","description":"Nur bei einem Objekt mit GO-Vereinbarung (dann Pflicht): erster Tag, `YYYY-MM-DD`."},"ende":{"type":"string","description":"Nur bei einem Objekt mit GO-Vereinbarung (dann Pflicht): letzter Tag, `YYYY-MM-DD`."}},"required":["jahr","positionen"]},"WirtschaftsplanEntwurfRequest":{"type":"object","properties":{"jahr":{"type":"integer"},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanPosition"},"description":"VOLLSTÄNDIGE Positionsliste der neuen Version — kein Teil-Patch."}},"required":["jahr","positionen"]},"WirtschaftsplanVerwerfenRequest":{"type":"object","properties":{"jahr":{"type":"integer"},"version":{"type":"integer","description":"Die zu verwerfende Version; nur ein Entwurf lässt sich verwerfen."}},"required":["jahr","version"]},"WirtschaftsplanVersionResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"version":{"type":"integer"},"status":{"type":"string","enum":["entwurf"]},"positionen":{"type":"integer","description":"Anzahl der gespeicherten Positionen."}},"required":["propertyId","jahr","version","status","positionen"]},"WirtschaftsplanVerwerfenResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"version":{"type":"integer"},"status":{"type":"string","enum":["verworfen"]}},"required":["propertyId","jahr","version","status"]},"WirtschaftsplanVersionZeile":{"type":"object","properties":{"jahr":{"type":"integer"},"version":{"type":"integer"},"status":{"type":"string","enum":["entwurf","beschlossen","verworfen"]},"beginn":{"type":"string","description":"Erster Tag des Plan-Zeitraums, `YYYY-MM-DD`."},"ende":{"type":"string","description":"Letzter Tag des Plan-Zeitraums (inklusiv), `YYYY-MM-DD`."},"goReferenz":{"type":["string","null"]},"positionen":{"type":"integer"},"jahresSoll":{"allOf":[{"$ref":"#/components/schemas/WirtschaftsplanGeld"},{"description":"Kosten − Einnahmen + Rücklagenzuführung."}]},"angelegtAm":{"type":"string","format":"date-time"},"beschlussRef":{"type":["string","null"],"description":"Referenz `beschluss-gegenstand:<uuid>` des tragenden Beschlusses; `null`, solange die Version nicht beschlossen ist."},"beschlussStatus":{"type":["string","null"],"description":"Status, unter dem das Gate freigegeben hat; `null` ohne Bindung."},"fortgeltung":{"type":["boolean","null"],"description":"Wert von `wp_fortgeltung` am Teil-Gegenstand: gilt der Plan für Folgejahre weiter? `null` ohne Bindung."}},"required":["jahr","version","status","beginn","ende","goReferenz","positionen","jahresSoll","angelegtAm","beschlussRef","beschlussStatus","fortgeltung"]},"WirtschaftsplanVersionenResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"jahr":{"type":["integer","null"],"description":"Echo des Filters `jahr`; `null` ohne Filter."},"versionen":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanVersionZeile"}}},"required":["propertyId","jahr","versionen"]},"WirtschaftsplanDiffZeile":{"type":"object","properties":{"kostenart":{"type":"string"},"art":{"type":"string","enum":["kosten","einnahme","ruecklagenzufuehrung"],"description":"Positionsart; das Vorzeichen trägt die Art, der Betrag ist immer > 0."},"vorher":{"allOf":[{"$ref":"#/components/schemas/WirtschaftsplanGeld"},{"type":["object","null"]}]},"nachher":{"allOf":[{"$ref":"#/components/schemas/WirtschaftsplanGeld"},{"type":["object","null"]}]}},"required":["kostenart","art","vorher","nachher"]},"WirtschaftsplanDiff":{"type":"object","properties":{"vonVersion":{"type":"integer"},"nachVersion":{"type":"integer"},"zeilen":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanDiffZeile"}}},"required":["vonVersion","nachVersion","zeilen"]},"WirtschaftsplanEinzelposition":{"type":"object","properties":{"kostenart":{"type":"string"},"art":{"type":"string","enum":["kosten","einnahme","ruecklagenzufuehrung"],"description":"Positionsart; das Vorzeichen trägt die Art, der Betrag ist immer > 0."},"betrag":{"$ref":"#/components/schemas/WirtschaftsplanGeld"}},"required":["kostenart","art","betrag"]},"WirtschaftsplanEinzelplan":{"type":"object","properties":{"unitIds":{"type":"array","items":{"type":"string","format":"uuid"}},"eigentuemerId":{"type":"string"},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanEinzelposition"}},"jahresSoll":{"$ref":"#/components/schemas/WirtschaftsplanGeld"},"monatsHausgeld":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanGeld"},"description":"Ein Betrag je Monat des Wirtschaftsjahres."}},"required":["unitIds","eigentuemerId","positionen","jahresSoll","monatsHausgeld"]},"WirtschaftsplanGesamt":{"type":"object","properties":{"kosten":{"$ref":"#/components/schemas/WirtschaftsplanGeld"},"einnahmen":{"$ref":"#/components/schemas/WirtschaftsplanGeld"},"ruecklagenzufuehrung":{"$ref":"#/components/schemas/WirtschaftsplanGeld"},"jahresSoll":{"$ref":"#/components/schemas/WirtschaftsplanGeld"}},"required":["kosten","einnahmen","ruecklagenzufuehrung","jahresSoll"]},"WirtschaftsplanBefund":{"type":"object","properties":{"regel":{"type":"string"},"fundort":{"type":"string"},"meldung":{"type":"string"}},"required":["regel","fundort","meldung"]},"WirtschaftsplanBerechnung":{"type":"object","properties":{"gesamtplan":{"$ref":"#/components/schemas/WirtschaftsplanGesamt"},"einzelplaene":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanEinzelplan"}},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanBefund"}}},"required":["gesamtplan","einzelplaene","befunde"]},"WirtschaftsplanStandResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"version":{"type":"integer"},"status":{"type":"string","enum":["entwurf","beschlossen","verworfen"]},"beginn":{"type":"string"},"ende":{"type":"string"},"goReferenz":{"type":["string","null"]},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/WirtschaftsplanPosition"}},"diff":{"allOf":[{"$ref":"#/components/schemas/WirtschaftsplanDiff"},{"type":["object","null"],"description":"Nur mit `vergleichMit`: Änderungen von dieser Version zur genannten."}]},"berechnung":{"allOf":[{"$ref":"#/components/schemas/WirtschaftsplanBerechnung"},{"type":["object","null"],"description":"Nur mit `berechnung=true`."}]},"beschlussRef":{"type":["string","null"],"description":"Referenz `beschluss-gegenstand:<uuid>` des tragenden Beschlusses; `null`, solange die Version nicht beschlossen ist."},"beschlussStatus":{"type":["string","null"],"description":"Status, unter dem das Gate freigegeben hat; `null` ohne Bindung."},"fortgeltung":{"type":["boolean","null"],"description":"Wert von `wp_fortgeltung` am Teil-Gegenstand: gilt der Plan für Folgejahre weiter? `null` ohne Bindung."}},"required":["propertyId","jahr","version","status","beginn","ende","goReferenz","positionen","diff","berechnung","beschlussRef","beschlussStatus","fortgeltung"]},"WirtschaftsplanBeschliessenRequest":{"type":"object","properties":{"jahr":{"type":"integer"},"version":{"type":"integer","description":"Die zu beschließende Version; nur die höchste Version des Jahres, nur im Status entwurf."},"beschlussRef":{"type":"string","description":"Referenz `beschluss-gegenstand:<uuid>` aus `casa objekt beschluss list`; der Beschluss muss tragend sein."}},"required":["jahr","version","beschlussRef"]},"WirtschaftsplanBeschliessenResponse":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"version":{"type":"integer"},"status":{"type":"string","enum":["beschlossen"]},"ausgang":{"type":"string","enum":["beschlossen","bereits_beschlossen"]},"beschlussRef":{"type":"string"},"beschlussStatus":{"type":"string"},"abweichungsStufe":{"type":["string","null"],"description":"`null` bei `bereits_beschlossen`: nichts wurde neu geprüft."},"befunde":{"type":["array","null"],"items":{"$ref":"#/components/schemas/WirtschaftsplanBefund"}},"warnungen":{"type":["array","null"],"items":{"$ref":"#/components/schemas/WirtschaftsplanBefund"}},"fortgeltung":{"type":"boolean","description":"Wert von `wp_fortgeltung` am Teil-Gegenstand."}},"required":["propertyId","jahr","version","status","ausgang","beschlussRef","beschlussStatus","abweichungsStufe","befunde","warnungen","fortgeltung"]},"WirtschaftsplanUebernahmeRequest":{"type":"object","properties":{"jahr":{"type":"integer","description":"Das Wirtschaftsjahr, für das fällig gestellt wird (bei Fortgeltung das Folgejahr des Plans)."},"geldkreis":{"type":"string","description":"Bewusst freier Text; der Fachkern urteilt über Geldkreise (hier: `weg_hausgeld`)."}},"required":["jahr","geldkreis"]},"WirtschaftsplanUebernahmeResponse":{"type":"object","properties":{"ausgang":{"type":"string","enum":["ausgefuehrt","bereits_ausgefuehrt"]},"schluessel":{"type":"string","description":"Der Idempotenz-Schlüssel des Laufs, wie der Fachkern ihn gebildet hat."},"geldkreis":{"type":"string"},"kontenkreis":{"type":"string"},"beschlussRef":{"type":"string","description":"Die Rechtsgrundlage, wie die FREIGABE sie gemeldet hat — nie aus der Eingabe."},"beschlussStatus":{"type":"string"},"positionen":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldSollPosition"},"description":"Die GESTELLTEN Positionen, Art `vorschuss`."},"differenzVorschlaege":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldDifferenzVorschlag"},"description":"Die rückwirkenden Differenzen als VORSCHLAG — NICHT gebucht; leer statt fehlend."},"warnungen":{"type":"array","items":{"$ref":"#/components/schemas/HausgeldBefund"}},"quelle":{"type":"string","enum":["eigener_plan","fortgeltung"],"description":"Woher der Plan kam: eigener beschlossener Plan des Jahres oder Fortgeltung eines früheren."},"quelleJahr":{"type":"integer","description":"Das Wirtschaftsjahr des Plans, aus dem die Positionen stammen."}},"required":["ausgang","schluessel","geldkreis","kontenkreis","beschlussRef","beschlussStatus","positionen","differenzVorschlaege","warnungen","quelle","quelleJahr"]},"InstandhaltungAuftragErteilenRequest":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid","description":"optional: ohne Angabe gilt der lebende Auftrag des Vorgangs; kein lebender Auftrag ⇒ 404 `not_found`"}}},"InstandhaltungAuftragErteilenResponse":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid"},"auftragsnummer":{"type":"string"},"erteiltAm":{"type":"string","format":"date"},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungBefund"}}},"required":["auftragId","auftragsnummer","erteiltAm","befunde"]},"InstandhaltungAuftragAusfuehrungRequest":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid","description":"optional: ohne Angabe gilt der lebende Auftrag des Vorgangs; kein lebender Auftrag ⇒ 404 `not_found`"},"ausgefuehrtAm":{"type":"string","format":"date"},"notiz":{"type":"string","description":"1 bis 500 Zeichen"}},"required":["ausgefuehrtAm"]},"InstandhaltungAuftragAusfuehrungResponse":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid"},"ausgefuehrtAm":{"type":"string","format":"date"}},"required":["auftragId","ausgefuehrtAm"]},"InstandhaltungAuftragStornierenRequest":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid","description":"optional: ohne Angabe gilt der lebende Auftrag des Vorgangs; kein lebender Auftrag ⇒ 404 `not_found`"},"grund":{"type":"string","description":"Pflicht: 1 bis 200 Zeichen"}},"required":["grund"]},"InstandhaltungAuftragStornierenResponse":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid"},"vorgangStatus":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]}},"required":["auftragId","vorgangStatus"]},"InstandhaltungRechnungRequest":{"type":"object","properties":{"auftragId":{"type":"string","format":"uuid","description":"optional: ohne Angabe gilt der lebende Auftrag des Vorgangs; kein lebender Auftrag ⇒ 404 `not_found`"},"documentId":{"type":"string","format":"uuid","description":"Pflicht: der Rechnungsbeleg mit Buchungsvorschlag"},"rechnungsdatum":{"type":"string","format":"date"}},"required":["documentId","rechnungsdatum"]},"InstandhaltungRechnungResponse":{"type":"object","properties":{"rechnungId":{"type":"string","format":"uuid"},"betrag":{"$ref":"#/components/schemas/InstandhaltungGeld"},"auftragswert":{"$ref":"#/components/schemas/InstandhaltungGeld"},"abweichung":{"allOf":[{"$ref":"#/components/schemas/InstandhaltungGeld"},{"description":"vorzeichenbehaftet: Summe aller Rechnungen am Auftrag minus Auftragswert"}]},"summeRechnungen":{"$ref":"#/components/schemas/InstandhaltungGeld"},"bauleistung":{"type":"string","enum":["ja","nein","unbekannt"]},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/InstandhaltungBefund"},"description":"Code, Schwere und Klartext; sie sperren die Verknüpfung nicht"}},"required":["rechnungId","betrag","auftragswert","abweichung","summeRechnungen","bauleistung","befunde"]},"InstandhaltungAbschlussRequest":{"type":"object","properties":{"begruendung":{"type":"string","description":"optional: 1 bis 300 Zeichen"}}},"InstandhaltungVorgangStornierenRequest":{"type":"object","properties":{"grund":{"type":"string","description":"Pflicht: 1 bis 200 Zeichen"}},"required":["grund"]},"InstandhaltungAbschlussResponse":{"type":"object","properties":{"vorgangId":{"type":"string","format":"uuid"},"vonStatus":{"type":"string","enum":["gemeldet","in_klaerung","angebote_offen","zur_freigabe","freigegeben","beauftragt","ausgefuehrt","abgerechnet","abgeschlossen","storniert"]},"status":{"type":"string","enum":["abgeschlossen","storniert"]},"ereignisId":{"type":"string","format":"uuid"},"begruendung":{"type":["string","null"],"description":"Begründung bzw. Grund, wie gespeichert; null, wenn keine angegeben wurde"}},"required":["vorgangId","vonStatus","status","ereignisId","begruendung"]},"SchadenfallGeld":{"type":"object","properties":{"cents":{"type":"string","description":"Cent als Integer-STRING, nie eine JSON-Zahl"},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"]},"SchadenfallAnlegenRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid","description":"Pflicht: das Objekt"},"unitId":{"type":"string","format":"uuid"},"versicherungsvertragId":{"type":"string","format":"uuid","description":"optional: Versicherungsvertrag desselben Objekts"},"instandhaltungVorgangId":{"type":"string","format":"uuid","description":"optional: Instandhaltungs-Vorgang desselben Objekts"},"schadensdatum":{"type":"string","format":"date","description":"nicht nach heute"},"schadenart":{"type":"string","description":"Pflicht: 1 bis 60 Zeichen"},"beschreibung":{"type":"string","description":"Pflicht: 10 bis 5000 Zeichen"}},"required":["propertyId","schadensdatum","schadenart","beschreibung"]},"SchadenfallErgebnis":{"type":"object","properties":{"schadenfallId":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"status":{"type":"string","enum":["erfasst","gemeldet","deckung_zugesagt","deckung_abgelehnt","reguliert","abgeschlossen"]},"selbstbehalt":{"allOf":[{"$ref":"#/components/schemas/SchadenfallGeld"},{"type":["object","null"],"description":"null, wenn unbekannt"}]},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/SchadenfallBefund"}}},"required":["schadenfallId","nummer","status","selbstbehalt","befunde"]},"SchadenfallMeldenRequest":{"type":"object","properties":{"gemeldetAm":{"type":"string","format":"date","description":"nicht nach heute, nicht vor dem Schadensdatum"},"aktenzeichen":{"type":"string","description":"optional: 1 bis 60 Zeichen"},"versicherungsvertragId":{"type":"string","format":"uuid","description":"optional: nur, wenn dem Fall noch keine Versicherung zugeordnet ist"}},"required":["gemeldetAm"]},"SchadenfallDeckungRequest":{"type":"object","properties":{"entscheidung":{"type":"string","enum":["zugesagt","abgelehnt"]},"deckungAm":{"type":"string","format":"date","description":"nicht nach heute, nicht vor der Meldung"},"schadenssumme":{"$ref":"#/components/schemas/SchadenfallGeld"},"selbstbehalt":{"$ref":"#/components/schemas/SchadenfallGeld"}},"required":["entscheidung","deckungAm"]},"SchadenfallDeckungResponse":{"type":"object","properties":{"schadenfallId":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"status":{"type":"string","enum":["erfasst","gemeldet","deckung_zugesagt","deckung_abgelehnt","reguliert","abgeschlossen"]},"selbstbehalt":{"allOf":[{"$ref":"#/components/schemas/SchadenfallGeld"},{"type":["object","null"]}]},"befunde":{"type":"array","items":{"$ref":"#/components/schemas/SchadenfallBefund"}},"uebergang":{"type":"boolean","description":"true, wenn der Status gewechselt hat"},"schadenssumme":{"allOf":[{"$ref":"#/components/schemas/SchadenfallGeld"},{"type":["object","null"]}]}},"required":["schadenfallId","nummer","status","selbstbehalt","befunde","uebergang","schadenssumme"]},"SchadenfallErstattungRequest":{"type":"object","properties":{"bankAccountId":{"type":"string","format":"uuid"},"bankTransactionId":{"type":"string","format":"uuid","description":"der Eingang der Erstattung; ein Umsatz gehört höchstens einem Schadenfall"},"asOf":{"type":"string","format":"date"},"bankGlAccountNo":{"type":"string"},"sachkontoNo":{"type":"string"},"buchungstext":{"type":"string","description":"1 bis 140 Zeichen"}},"required":["bankAccountId","bankTransactionId","asOf","bankGlAccountNo","sachkontoNo","buchungstext"]},"SchadenfallErstattungResponse":{"type":"object","properties":{"schadenfallId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["erfasst","gemeldet","deckung_zugesagt","deckung_abgelehnt","reguliert","abgeschlossen"]},"erstattung":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"bankTransactionId":{"type":"string","format":"uuid"},"betrag":{"$ref":"#/components/schemas/SchadenfallGeld"},"eingangAm":{"type":"string","format":"date"},"bookingProposalId":{"type":"string","format":"uuid"}},"required":["id","bankTransactionId","betrag","eingangAm","bookingProposalId"]},"bilanz":{"$ref":"#/components/schemas/SchadenfallBilanz"},"vorschlag":{"type":"object","properties":{"proposalId":{"type":"string","format":"uuid"},"contentHash":{"type":"string"},"sichtHash":{"type":"string"},"ampel":{"type":"string"},"sollKontoNo":{"type":"string"},"habenKontoNo":{"type":"string"},"buchungstext":{"type":"string"}},"required":["proposalId","contentHash","sichtHash","ampel","sollKontoNo","habenKontoNo","buchungstext"]}},"required":["schadenfallId","status","erstattung","bilanz","vorschlag"]},"SchadenfallAbschlussRequest":{"type":"object","properties":{"begruendung":{"type":"string","description":"optional: 1 bis 300 Zeichen"}}},"SchadenfallAbschlussResponse":{"type":"object","properties":{"schadenfallId":{"type":"string","format":"uuid"},"vonStatus":{"type":"string","enum":["erfasst","gemeldet","deckung_zugesagt","deckung_abgelehnt","reguliert","abgeschlossen"]},"status":{"type":"string","enum":["abgeschlossen"]},"begruendung":{"type":["string","null"]},"bilanz":{"$ref":"#/components/schemas/SchadenfallBilanz"},"befund":{"allOf":[{"$ref":"#/components/schemas/SchadenfallBefund"},{"type":["object","null"]}]}},"required":["schadenfallId","vonStatus","status","begruendung","bilanz","befund"]},"FremdvertragGeld":{"type":"object","properties":{"cents":{"type":"string","description":"Cent als Integer-STRING, nie eine JSON-Zahl"},"currency":{"type":"string","enum":["EUR"]}},"required":["cents","currency"]},"FremdvertragAnlegenRequest":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid","description":"Pflicht: das Objekt"},"art":{"type":"string","enum":["versicherung","wartung","dienstleistung","versorgung"],"description":"Pflicht: versicherung | wartung | dienstleistung | versorgung"},"partnerPersonId":{"type":"string","format":"uuid","description":"Pflicht: Person mit gültiger Rolle Kreditor oder Dienstleister"},"bezeichnung":{"type":"string","description":"Pflicht: 1 bis 140 Zeichen"},"vertragsnummer":{"type":"string","description":"optional: 1 bis 80 Zeichen"},"beginn":{"type":"string","format":"date"},"laufzeitEnde":{"type":"string","format":"date"},"kuendigungsfristMonate":{"type":"integer","description":"Pflicht: 0 bis 60"},"verlaengerungStillschweigend":{"type":"boolean","description":"ohne Angabe: Vorgabe der Mandanten-Einstellung, sonst ja"},"verlaengerungMonate":{"type":"integer","description":"ohne Angabe bei stillschweigender Verlängerung: Vorgabe der Einstellung, sonst 12"},"beitrag":{"allOf":[{"$ref":"#/components/schemas/FremdvertragGeld"},{"description":"gehört mit beitragIntervall zusammen"}]},"beitragIntervall":{"type":"string","enum":["monatlich","zweimonatlich","quartalsweise","halbjaehrlich","jaehrlich"]},"selbstbehalt":{"allOf":[{"$ref":"#/components/schemas/FremdvertragGeld"},{"description":"nur bei einem Versicherungsvertrag"}]},"bemerkung":{"type":"string","description":"optional: 1 bis 2000 Zeichen"}},"required":["propertyId","art","partnerPersonId","bezeichnung","beginn","kuendigungsfristMonate"]},"FremdvertragKonditionenErgebnis":{"type":"object","properties":{"version":{"type":"integer"},"gueltigAb":{"type":"string","format":"date"},"verlaengerungStillschweigend":{"type":"boolean"},"verlaengerungMonate":{"type":["integer","null"]}},"required":["version","gueltigAb","verlaengerungStillschweigend","verlaengerungMonate"]},"FremdvertragAnlegenResponse":{"type":"object","properties":{"vertragId":{"type":"string","format":"uuid"},"konditionen":{"$ref":"#/components/schemas/FremdvertragKonditionenErgebnis"}},"required":["vertragId","konditionen"]},"FremdvertragKonditionenRequest":{"type":"object","properties":{"gueltigAb":{"type":"string","format":"date","description":"muss nach dem gueltigAb der letzten Version liegen"},"laufzeitEnde":{"type":["string","null"],"format":"date"},"kuendigungsfristMonate":{"type":"integer","description":"0 bis 60"},"verlaengerungStillschweigend":{"type":"boolean"},"verlaengerungMonate":{"type":["integer","null"],"description":"bei stillschweigender Verlängerung Pflicht, sonst null"},"beitrag":{"allOf":[{"$ref":"#/components/schemas/FremdvertragGeld"},{"type":["object","null"]}]},"beitragIntervall":{"type":["string","null"],"enum":["monatlich","zweimonatlich","quartalsweise","halbjaehrlich","jaehrlich",null]},"selbstbehalt":{"allOf":[{"$ref":"#/components/schemas/FremdvertragGeld"},{"type":["object","null"]}]},"bemerkung":{"type":["string","null"]}},"required":["gueltigAb","laufzeitEnde","kuendigungsfristMonate","verlaengerungStillschweigend","verlaengerungMonate","beitrag","beitragIntervall","selbstbehalt","bemerkung"]},"FremdvertragKonditionenResponse":{"type":"object","properties":{"vertragId":{"type":"string","format":"uuid"},"konditionen":{"$ref":"#/components/schemas/FremdvertragKonditionenErgebnis"}},"required":["vertragId","konditionen"]},"FremdvertragKuendigungRequest":{"type":"object","properties":{"wirksamZum":{"type":"string","format":"date","description":"nicht vor heute"},"grund":{"type":"string","description":"optional: 1 bis 200 Zeichen"}},"required":["wirksamZum"]},"FremdvertragKuendigungResponse":{"type":"object","properties":{"vertragId":{"type":"string","format":"uuid"},"ereignisId":{"type":"string","format":"uuid"},"wirksamZum":{"type":"string","format":"date"},"fruehestesEnde":{"type":["string","null"],"format":"date","description":"nächstes Vertragsende, zu dem die Kündigung nach Frist wirkt; null ohne Laufzeitende"},"spaetesterZugang":{"type":["string","null"],"format":"date","description":"spätester Kündigungszugang zu fruehestesEnde"}},"required":["vertragId","ereignisId","wirksamZum","fruehestesEnde","spaetesterZugang"]},"FremdvertragBeendigungRequest":{"type":"object","properties":{"beendetAm":{"type":"string","format":"date"},"grund":{"type":"string","description":"optional: 1 bis 200 Zeichen"}},"required":["beendetAm"]},"FremdvertragBeendigungResponse":{"type":"object","properties":{"vertragId":{"type":"string","format":"uuid"},"ereignisId":{"type":"string","format":"uuid"},"beendetAm":{"type":"string","format":"date"}},"required":["vertragId","ereignisId","beendetAm"]},"FremdvertragFristEntscheidRequest":{"type":"object","properties":{"bezugEnde":{"type":"string","format":"date","description":"das Vertragsende, auf das sich die Entscheidung bezieht"},"entscheidung":{"type":"string","enum":["verlaengern","kuendigen","neu_ausschreiben"]},"grund":{"type":"string","description":"optional: 1 bis 200 Zeichen"}},"required":["bezugEnde","entscheidung"]},"FremdvertragFristEntscheidResponse":{"type":"object","properties":{"vertragId":{"type":"string","format":"uuid"},"bezugEnde":{"type":"string","format":"date"},"entscheidung":{"type":"string","enum":["verlaengern","kuendigen","neu_ausschreiben"]},"ereignisId":{"type":"string","format":"uuid"},"kuendigungAngelegt":{"type":"boolean","enum":[false]},"hinweis":{"type":"string"}},"required":["vertragId","bezugEnde","entscheidung","ereignisId","kuendigungAngelegt","hinweis"]},"FremdvertragDauerzahlungRequest":{"type":"object","properties":{"dauerzahlungId":{"type":"string","format":"uuid","description":"Pflicht: Dauerzahlung am selben Objekt, noch an keinem anderen Vertrag"}},"required":["dauerzahlungId"]},"FremdvertragDauerzahlungBefundTransport":{"type":"object","properties":{"code":{"type":"string","enum":["beitrag-weicht-von-dauerzahlung-ab"]},"beitragJahr":{"$ref":"#/components/schemas/FremdvertragGeld"},"dauerzahlungJahr":{"$ref":"#/components/schemas/FremdvertragGeld"},"differenz":{"allOf":[{"$ref":"#/components/schemas/FremdvertragGeld"},{"description":"vorzeichenbehaftet: Beitrag minus Dauerzahlung (Jahresbeträge)"}]}},"required":["code","beitragJahr","dauerzahlungJahr","differenz"]},"FremdvertragDauerzahlungResponse":{"type":"object","properties":{"vertragId":{"type":"string","format":"uuid"},"dauerzahlungId":{"type":"string","format":"uuid"},"befund":{"allOf":[{"$ref":"#/components/schemas/FremdvertragDauerzahlungBefundTransport"},{"type":["object","null"],"description":"null, wenn Beitrag und Dauerzahlung zusammenpassen oder ein Wert fehlt; sperrt nie"}]}},"required":["vertragId","dauerzahlungId","befund"]},"FremdvertragDauerzahlungLoesenRequest":{"type":"object","properties":{}},"FremdvertragDauerzahlungLoesenResponse":{"type":"object","properties":{"vertragId":{"type":"string","format":"uuid"},"dauerzahlungId":{"type":"string","format":"uuid"}},"required":["vertragId","dauerzahlungId"]},"FremdvertragEinstellungWerte":{"type":"object","properties":{"vorlaufTage":{"type":"integer"},"verlaengerungStillschweigendVorgabe":{"type":"boolean"},"verlaengerungMonateVorgabe":{"type":"integer"},"schadenMeldefristTage":{"type":"integer"},"schadenhonorarProzentBp":{"type":"integer"},"schadenhonorarAktiv":{"type":"boolean"}},"required":["vorlaufTage","verlaengerungStillschweigendVorgabe","verlaengerungMonateVorgabe","schadenMeldefristTage","schadenhonorarProzentBp","schadenhonorarAktiv"]},"FremdvertragEinstellungSetzenRequest":{"type":"object","properties":{"vorlaufTage":{"type":"integer","description":"1 bis 365"},"verlaengerungStillschweigendVorgabe":{"type":"boolean"},"verlaengerungMonateVorgabe":{"type":"integer","description":"1 bis 60"},"schadenMeldefristTage":{"type":"integer","description":"1 bis 60"},"schadenhonorarProzentBp":{"type":"integer","description":"Basispunkte, 0 bis 10000 (800 = 8,00 %)"},"schadenhonorarAktiv":{"type":"boolean"}},"required":["vorlaufTage","verlaengerungStillschweigendVorgabe","verlaengerungMonateVorgabe","schadenMeldefristTage","schadenhonorarProzentBp","schadenhonorarAktiv"]},"FremdvertragEinstellungSetzenResponse":{"type":"object","properties":{"einstellung":{"$ref":"#/components/schemas/FremdvertragEinstellungWerte"},"vorher":{"$ref":"#/components/schemas/FremdvertragEinstellungWerte"},"geaendert":{"type":"boolean"},"geaendertVon":{"type":"string"},"geaendertAm":{"type":"string","format":"date-time"}},"required":["einstellung","vorher","geaendert","geaendertVon","geaendertAm"]}}},"paths":{"/api/health":{"get":{"summary":"Liveness der Web-App (App-Prozess + DB-Erreichbarkeit).","operationId":"getHealth","responses":{"200":{"description":"healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"503":{"description":"unhealthy — fail-closed"}}}},"/api/version":{"get":{"summary":"Serverseitig eingebrannte Build-ID (Deploy-Skew-Erkennung).","operationId":"getVersion","responses":{"200":{"description":"Build-ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionResponse"}}}}}}},"/api/me":{"get":{"summary":"Aktuelle Session (Tenant + User + Step-up-Status).","operationId":"getMe","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Session (Tenant + User + Step-up)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle); Clients mappen den Status auf code \"unauthenticated\""}}}},"/api/posteingang":{"get":{"summary":"Listet die Freigabe-Inbox (wartende Buchungsvorschläge des aufrufenden Tenants).","operationId":"listPosteingang","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"wartende Vorschläge (PosteingangListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PosteingangListResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/ausnahmen":{"get":{"summary":"Listet die Ausnahme-Inbox (offene Verarbeitungs-/Routing-Ausnahmen des aufrufenden Tenants).","operationId":"listAusnahmen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"offene Ausnahmen (AusnahmenListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AusnahmenListResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/bankzugang":{"get":{"summary":"Listet die Bankzugänge des aufrufenden Tenants samt Status (ohne Anbieter-Zugangsdaten).","operationId":"listBankzugaenge","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Bankzugänge des Tenants (BankzugangListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankzugangListResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/beleg":{"post":{"summary":"Reicht einen Beleg über die echte Ingest-Vordertür ein (Byte-Typ-/Malware-Gate, Blob, Ingest, Dispatch-Enqueue).","operationId":"uploadBeleg","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Der hochzuladende Beleg (Datei-Bytes)."}}}}}},"responses":{"201":{"description":"Ingest-Ergebnis der Vordertür (BelegUploadResponse) — outcome received|duplicate|quarantined.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BelegUploadResponse"}}}},"400":{"description":"kaputter/fehlender multipart-Body oder keine Datei im Feld file (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"413":{"description":"Upload überschreitet die zulässige Maximalgröße — früh am Transport abgewiesen (ApiErrorBody, code payload_too_large)"}}}},"/api/buchung":{"post":{"summary":"Führt einen freigegebenen Buchungsvorschlag aus (execute_booking) — optional rückdatiert.","operationId":"executeBuchung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Buchen ist eine KETTE: Betrag und Konto stehen NICHT im Body, sie stammen aus der freigegebenen Zeile (INV-APPROVAL-01). Das optionale bookingDate rückdatiert die AUSFÜHRUNG; es darf nicht in der Zukunft liegen und muss ein existierender Kalendertag sein. accrual_date bleibt davon unberührt (es kommt aus der freigegebenen Kontierung). Objekt-Zuständigkeitsprüfung und Audit-Trail bleiben am echten Jetzt — eine Rückdatierung ist keine Rechte-Umgehung.","required":["proposalId","proposalVersion","entryKey"],"properties":{"proposalId":{"type":"string","format":"uuid"},"proposalVersion":{"type":"integer","minimum":1},"entryKey":{"type":"string","minLength":1,"description":"Fachlicher Idempotency-Key der Buchung (UNIQUE je Tenant)."},"bookingDate":{"type":"string","format":"date","description":"Optionales Buchungsdatum (Rückdatierung). Weggelassen ⇒ Ausführungstag."}}}}}},"responses":{"201":{"description":"gebucht (journalEntryId, proposalId, proposalVersion, konto, betragCents, betragCurrency)"},"400":{"description":"ungültige Eingabe oder unzulässiges Buchungsdatum (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"unbekannter Vorschlag ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Zustand lässt die Buchung nicht zu: keine/abgelehnte Freigabe, überholt, bereits gebucht (ApiErrorBody, code conflict)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/buchung/eroeffnungsbestand":{"post":{"summary":"Baut Anfangsbestände auf (import_opening_balances) — die Migrationsnaht.","operationId":"importEroeffnungsbestand","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"BELEGLOS, ohne Vorschlag und ohne Freigabe, ausschließlich entry_type = eroeffnung — die Naht ist KEIN Zweitweg für den laufenden Betrieb (das Schema kennt kein entryType und ist strict). Je Rückstand entsteht GENAU EIN Buchungssatz; verdichtet wird nie. Datumskonvention: uebernahmestichtag wird booking_date, originalFaelligkeit wird accrual_date. Idempotent über den deterministischen Schlüssel eroeffnung:<stichtag>:<sourceKey> — eine Wiederholung legt keinen zweiten Bestand an.","required":["propertyId","uebernahmestichtag","rueckstaende"],"properties":{"propertyId":{"type":"string","format":"uuid"},"uebernahmestichtag":{"type":"string","format":"date"},"rueckstaende":{"type":"array","minItems":1,"items":{"type":"object","required":["sourceKey","contractId","debitorKontoNr","ertragKontoNr","nominalCents","currency","originalFaelligkeit","forderungsart","geldkreis"],"properties":{"sourceKey":{"type":"string","minLength":1,"description":"Stabiler Schlüssel des Vorsystems (Herkunft UND Idempotenz-Anker)."},"contractId":{"type":"string","format":"uuid","nullable":true},"unitId":{"type":"string","format":"uuid","nullable":true},"debitorKontoNr":{"type":"string","minLength":1},"ertragKontoNr":{"type":"string","minLength":1},"nominalCents":{"type":"string","pattern":"^-?\\d+$","description":"Signierte Minor-Units als Integer-STRING, nie eine JSON-number."},"currency":{"type":"string","minLength":3,"maxLength":3},"originalFaelligkeit":{"type":"string","format":"date"},"forderungsart":{"type":"string","minLength":1},"geldkreis":{"type":"string","minLength":1},"ustSatzProzent":{"type":"string","pattern":"^\\d+$","nullable":true,"description":"USt-Satz DIESER Buchung in GANZEN Prozent als Integer-STRING (0…99). PFLICHT: fehlt er oder ist er null, wird der Import fail-loud abgewiesen (der Steueranteil wäre unbekannt und der Betrag würde still brutto umgelegt). '0' ist ein AUSGESAGTER Satz (nicht steuerbar) und etwas anderes als „kein Satz\". Der Satz landet auf beiden Zeilen (journal_lines.ust_rate); der Nominalbetrag bleibt brutto, genettet wird erst die Umlagebasis."}}}}}}}}},"responses":{"201":{"description":"aufgebaut (propertyId, uebernahmestichtag, gebucht[], anzahlNeu, anzahlReplay)"},"400":{"description":"ungültige Eingabe, unzulässiger Stichtag oder fachlich abgewiesener Rückstand (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"Konto am Objekt unbekannt ODER fremdes Objekt (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"der Buchungssatz saldiert nicht (ApiErrorBody, code conflict)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable)"}}}},"/api/altbestand/uebernahme":{"post":{"summary":"Übernimmt einen Altbestand (uebernehme_altbestand): offene Posten buchen, Mahn-/Zahlhistorie ablegen, Provenienz binden.","operationId":"uebernehmeAltbestand","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"ALLES ODER NICHTS in EINER Transaktion. Die offenen Posten laufen durch die bestehende Migrationsnaht (je Posten GENAU EINE Eröffnungs-Sollstellung mit Originalfälligkeit in accrual_date; verdichtet wird nie — ein Summenposten wäre nicht mahnbar, verjährungsfalsch und nicht zuordenbar). Die Mahn- und Zahlhistorie wird NIE gebucht und lebt ausschließlich im Altbestand. Mindestens eine Zeile ist Pflicht. Idempotent über UNIQUE (tenant_id, quellSchluessel) je Zeile und über den entryKey der Naht je Buchung — eine Wiederholung derselben Sicherung legt nichts doppelt an, sondern zählt als Replay.","required":["propertyId","uebernahmestichtag","provenienz","offenePosten","historie"],"properties":{"propertyId":{"type":"string","format":"uuid","description":"Eine Übernahme läuft immer für GENAU EIN Objekt (Objekt-Scope)."},"uebernahmestichtag":{"type":"string","format":"date","description":"EINGABE, keine Ableitung: wird booking_date jeder erzeugten Eröffnungs-Sollstellung und hängt über die Provenienz sichtbar an ihr. Es gibt bewusst kein Feld, mit dem er sich automatisch bestimmen ließe."},"provenienz":{"type":"object","description":"Grundgesetz 7 — vollständig Pflicht, ohne Default. Ein Datei-Hash ohne Exportzeitpunkt beantwortet „welche Datei\", nicht „welcher Stand\"; nachträglich ist die Sicherung nicht mehr identifizierbar.","required":["quellsystem","exportiertAm","dateiHash"],"properties":{"quellsystem":{"type":"string","minLength":1,"description":"Das Altsystem, z. B. 'win-casa'."},"exportiertAm":{"type":"string","format":"date-time","description":"Der Zeitpunkt des EXPORTS aus dem Altsystem in UTC (nicht der des Imports)."},"dateiHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"SHA-256 der Sicherungsdatei, 64 Hex, kleingeschrieben."}}},"offenePosten":{"type":"array","description":"Dieselbe Zeilenform wie /api/buchung/eroeffnungsbestand (rueckstaende) — bewusst kein zweiter, driftender Rückstands-Typ. Darf leer sein: ein Bestand ohne offene Forderungen, aber mit Historie, ist ein realer Fall.","items":{"type":"object"}},"historie":{"type":"array","description":"Mahn- und Zahlhistorie — wird NIE gebucht. Darf leer sein.","items":{"type":"object","required":["quellSchluessel","art","contractId","datum","betragCents","currency"],"properties":{"quellSchluessel":{"type":"string","minLength":1,"description":"Stabiler Schlüssel der Quellzeile (Herkunft UND Dubletten-Anker)."},"art":{"type":"string","enum":["mahnung","zahlung"],"description":"'op' ist hier NICHT formulierbar — offene Posten gehen gebucht."},"contractId":{"type":"string","format":"uuid"},"datum":{"type":"string","format":"date","description":"Mahndatum bzw. Zahltag der Quellzeile."},"betragCents":{"type":"string","pattern":"^-?\\d+$","description":"Signierte Minor-Units als Integer-STRING, nie eine JSON-number."},"currency":{"type":"string","minLength":3,"maxLength":3}}}}}}}}},"responses":{"201":{"description":"übernommen (propertyId, uebernahmestichtag, uebernahmeId, eroeffnung|null, anzahlPostenNeu, anzahlPostenReplay)"},"400":{"description":"ungültige Eingabe, doppelter Quellschlüssel im Umschlag, Währungsmischung oder ein fachlich abgewiesener Rückstand (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"Vertrag oder Konto am Objekt unbekannt ODER fremder Mandant (ApiErrorBody, code not_found — ein fremder und ein nie existierender Vertrag liefern DIESELBE Antwort, kein Existenz-Orakel)"},"409":{"description":"der Buchungssatz saldiert nicht oder der Idempotency-Key ist anders gebunden (ApiErrorBody, code conflict)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/altbestand/posten":{"get":{"summary":"Liest die übernommene OP-, Mahn- und Zahlhistorie EINES Mieters (die Auskunft bei Mieterwiderspruch, ADR 0019).","operationId":"listAltbestandPosten","security":[{"bearerAuth":[]}],"parameters":[{"name":"contractId","in":"query","required":true,"description":"PFLICHT. Eine Sicht „alle übernommenen Zeilen des Mandanten\" wäre ein Massenexport von Zahlungsverhalten und Mahnhistorie; die Auskunft ist je Mieter, weil der Anlass je Mieter ist.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Alle Zeilen dieses Mieters, aufsteigend nach (datum, quellSchluessel) — die Ordnung ist Vertrag, eine wechselnde Reihenfolge wäre gegen einen Widerspruch nicht verwendbar. Geliefert werden ALLE Arten, auch die gebuchten: journalEntryId zeigt bei art=op auf die Eröffnungs-Sollstellung und ist bei mahnung/zahlung null. betragCents ist ein signierter Integer-STRING. Ein fremder Vertrag liefert eine LEERE Liste wie ein nie existierter (kein Existenz-Orakel).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AltbestandPostenListResponse"}}}},"400":{"description":"fehlende oder ungültige contractId (ApiErrorBody, code invalid_request — Feldname + Regel, nie der Wert)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/altbestand/provenienz":{"get":{"summary":"Liest die Herkunft EINER Eröffnungs-Sollstellung: Altsystem, Exportzeitpunkt, Datei-Hash, Stichtag, Quellzeile (GG7).","operationId":"getEroeffnungsProvenienz","security":[{"bearerAuth":[]}],"parameters":[{"name":"journalEntryId","in":"query","required":true,"description":"Die Buchung, deren Herkunft erklärt werden soll.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"provenienz mit quellsystem, exportiertAm, dateiHash, uebernahmestichtag, quellSchluessel und contractId — oder null. null ist BEWUSST die Antwort für drei ununterscheidbare Lagen: fremder Mandant, nie existiert, oder eine Buchung, die nicht aus einer Übernahme stammt. Ein 404 für eine davon wäre genau das Existenz-Orakel, das es nicht geben darf.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AltbestandProvenienzResponse"}}}},"400":{"description":"fehlende oder ungültige journalEntryId (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/uebernahme/abrechnungen":{"post":{"summary":"Übernimmt die festgeschriebene Abrechnung EINES früheren Zeitraums eines Objekts als Bestand (uebernehme_abrechnung_bestand).","operationId":"uebernehmeAbrechnungBestand","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Schreibt EINEN billing_runs-Lauf mit status festgeschrieben und Herkunft `uebernahme` (binding_snapshot = die übergebenen Werte, Hash/Siegel daraus) — ohne Rechenweg, Versand, Zustellnachweise und Step-up. Als „offen\" gekennzeichnete Ergebnisse laufen durch die bestehende Migrationsnaht (Nachzahlung: Eröffnungs-Sollstellung mit Originalfälligkeit; Guthaben: Eröffnungs-Gutschrift); „verbucht\" erzeugt keinen offenen Posten. Schutzbedingungen (409): der Zeitraum endet nicht vor dem Übernahmestichtag, oder für Objekt und Zeitraum existiert schon ein Lauf (eigener oder übernommener). Ein zweiter Aufruf mit anderem Idempotency-Key ⇒ 409; mit demselben Key ⇒ Replay ohne zweite Zeile. Keine Personendaten außer der Vertrags-Id; das Personenkonto löst der Server aus der Vertrags-Id auf. Alle Datumsfelder sind echte Kalenderdaten, Zeitraum von ≤ bis.","additionalProperties":false,"required":["propertyId","periodFrom","periodTo","abrechnungsdatum","uebernahmestichtag","vertraege"],"properties":{"pruefen":{"type":"boolean","description":"Reiner Vorschau-Schalter (CLI: --pruefen): true validiert und liefert die Vorschau (200) mit denselben 404/409-Prüfungen, OHNE etwas zu schreiben (kein Lauf, keine Buchung, kein Kommando-Log); fehlt er oder ist false, wird übernommen (201)."},"propertyId":{"type":"string","format":"uuid","description":"Eine Übernahme läuft immer für GENAU EIN Objekt (Objekt-Scope)."},"periodFrom":{"type":"string","format":"date","description":"Beginn des Abrechnungszeitraums (einschließlich)."},"periodTo":{"type":"string","format":"date","description":"Ende des Abrechnungszeitraums (einschließlich); muss VOR dem Übernahmestichtag liegen."},"abrechnungsdatum":{"type":"string","format":"date","description":"Abrechnungsdatum der übernommenen Abrechnung; Fälligkeit eines offenen Guthabens."},"uebernahmestichtag":{"type":"string","format":"date","description":"EINGABE, keine Ableitung: Buchungsdatum der Eröffnungsbuchungen."},"currency":{"type":"string","enum":["EUR"],"description":"Währung, Vorgabe EUR."},"quellsystem":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,31}$","description":"Herkunftsvermerk (Altsystem), nur eine Kennung (enger Slug, z. B. win-casa)."},"gesamtkosten":{"type":"array","description":"Optional: Gesamtkosten je Kostenart des Objekts (dokumentarisch, wird nicht gerechnet).","items":{"type":"object","additionalProperties":false,"required":["kostenart","betragCents"],"properties":{"kostenart":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,63}$","description":"Kostenart als Kennung (Slug)."},"betragCents":{"type":"string","pattern":"^-?\\d+$"}}}},"eroeffnung":{"type":"object","description":"Kontierung der Eröffnungsbuchungen; Pflicht, sobald ein Ergebnis als offen übernommen wird.","additionalProperties":false,"required":["ertragKontoNr","forderungsart","geldkreis","ustSatzProzent"],"properties":{"ertragKontoNr":{"type":"string","pattern":"^\\d{1,12}$","description":"Muss ein Sachkonto des Objekts sein (ein Personenkonto ⇒ 409)."},"forderungsart":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,63}$"},"geldkreis":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,63}$"},"ustSatzProzent":{"type":"string","pattern":"^\\d+$","description":"Ganze Prozent 0…99; ein nicht steuerbarer Rückstand trägt '0'."}}},"vertraege":{"type":"array","minItems":1,"description":"Je Vertrag Vorauszahlung, Anteil und Ergebnis (Ergebnis = Anteil − Vorauszahlung, signiert: > 0 Nachzahlung, < 0 Guthaben).","items":{"type":"object","additionalProperties":false,"required":["contractId","vorauszahlungCents","anteilCents","ergebnisCents","kennzeichen"],"properties":{"contractId":{"type":"string","format":"uuid"},"vorauszahlungCents":{"type":"string","pattern":"^-?\\d+$","description":"Integer-STRING in Cent, nie eine JSON-number."},"anteilCents":{"type":"string","pattern":"^-?\\d+$"},"ergebnisCents":{"type":"string","pattern":"^-?\\d+$"},"kennzeichen":{"type":"string","enum":["verbucht","offen"],"description":"verbucht = die Zahlung liegt vor dem Stichtag, kein offener Posten."},"faelligkeitNachzahlung":{"type":"string","format":"date","description":"Originalfälligkeit; Pflicht bei offener Nachzahlung."}}}}}}}}},"responses":{"200":{"description":"Nur mit pruefen: true — die Vorschau: Summen, geplante Eröffnungsposten und das Siegel; es wurde nichts geschrieben.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UebernahmeAbrechnungVorschauResponse"}}}},"201":{"description":"übernommen (auch die Replay-Antwort bei gleichem Idempotency-Key hat diese Form; Eröffnungsposten mit replay true).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UebernahmeAbrechnungUebernommenResponse"}}}},"400":{"description":"ungültige Eingabe oder ein fachlich abgewiesener Rückstand (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"Objekt, Vertrag oder Konto unbekannt ODER fremder Mandant (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Zeitraum endet nicht vor dem Übernahmestichtag, für Objekt und Zeitraum existiert schon ein Lauf, ein offener Vertrag hat kein Personenkonto, das Ertragskonto ist kein Sachkonto, die Eröffnungsbuchung meldet einen vorhandenen Satz, oder der Idempotency-Key ist anders gebunden (ApiErrorBody, code conflict, Klartext)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}},"get":{"summary":"Listet die Abrechnungsläufe eines Objekts mit Herkunft und Kennzeichen „übernommen\" (neueste zuerst).","operationId":"listUebernahmeAbrechnungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"propertyId","in":"query","required":true,"description":"Das Objekt, dessen Läufe gelistet werden. Ein fremdes oder unbekanntes Objekt liefert eine LEERE Liste (kein Existenz-Orakel).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Läufe des Objekts, neueste zuerst; uebernommen ist true bei Herkunft `uebernahme`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UebernahmeAbrechnungenListResponse"}}}},"400":{"description":"fehlende oder ungültige propertyId (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/objekt":{"get":{"summary":"Listet Objekte (3-Wege-Filter Alle/Aktiv/Archiviert, Default aktiv).","operationId":"listObjekte","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | aktiv | archiviert (Default aktiv). Unbekannter Wert ⇒ 400, nie stiller Fallback.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}}],"responses":{"200":{"description":"Objektliste (ObjektListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjektListResponse"}}}},"400":{"description":"ungültiger status-Filter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt ein Objekt an; der 1:1-Buchungskreis entsteht automatisch (F3).","operationId":"createObjekt","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjektCreateRequest"}}}},"responses":{"201":{"description":"angelegtes Objekt inkl. accountingCircleId (Objekt)"},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/objekt/{id}":{"get":{"summary":"Liest EIN Objekt (auch archiviert) samt Buchungskreis.","operationId":"getObjekt","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Objekt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Objekt"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"patch":{"summary":"Ändert Objekt-Stammfelder (nur nicht-archivierte Objekte).","operationId":"updateObjekt","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjektUpdateRequest"}}}},"responses":{"200":{"description":"geändertes Objekt"},"400":{"description":"leerer/ungültiger Patch ODER Objekt archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/archive":{"post":{"summary":"Archiviert Objekt + 1:1-Buchungskreis (archived_at statt DELETE, K5). Kaskadiert abwärts: alle Gebäude + Einheiten des Objekts werden mitarchiviert (#445).","operationId":"archiveObjekt","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"archiviert (ObjektArchiveResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses (identische Antwort, kein zweites Kommando). Alle Gebäude und Einheiten des Objekts werden in derselben Transaktion mitarchiviert (Kaskade #445, ein Kommando)."},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/steuerpflichtige-erloeskonten":{"post":{"summary":"Zieht am Objekt die steuerpflichtigen Gegenkonten der Sollstellungs-Erlöskonten und das USt-Konto 1776 nach und hält den Stichtag der Sollversteuerung fest (#5992).","operationId":"ensureSteuerpflichtigeErloeskonten","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["gueltigAb"],"properties":{"gueltigAb":{"type":"string","format":"date","description":"Stichtag, der Erste einer Leistungsperiode (Monatserster JJJJ-MM-01, sonst 400); wirkt nur beim ersten Aufruf je Objekt."}}}}}},"responses":{"200":{"description":"nachgezogen: { propertyId, gueltigAb (wirksamer Stichtag oder null), created[], skipped[] } mit { accountNo, name }, unvertraeglich[] mit { accountNo, befund }. Wiederholung ist harmlos: vorhandene Konten bleiben unangetastet, ein Stichtag wandert nie. Ist ein vorhandenes Konto gleicher Nummer nicht exakt das der Werksvorlage (Kontoart, DATEV 8400/1776, USt-Satz), steht es in unvertraeglich und es wird KEIN Stichtag gesetzt."},"400":{"description":"ungültige Eingabe ODER Objekt archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/kontenrahmen-schluessel":{"post":{"summary":"Zieht für die Konten, die ein Musterkontenrahmen VOR #5553 am Objekt angelegt hat, die fehlenden Umlageschlüssel und deren Verknüpfungen nach (#5638).","operationId":"backfillKontenrahmenSchluessel","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"nachgezogen: { propertyId, angelegteSchluessel[] mit { art, allocationKeyId, name }, verknuepfteKonten[] mit { glAccountId, accountNo, art, allocationKeyId } }. Atomar (EIN Kommando) und zustandsidempotent: ein zweiter Aufruf mit frischem Key legt keinen zweiten Schlüssel an und liefert leere Listen, derselbe Header `Idempotency-Key` ist ein Replay des Erst-Ergebnisses; ein vorhandener aktiver, objektweiter Schlüssel derselben Art wird wiederverwendet, Konten mit gepflegtem Schlüssel bleiben unangetastet. Das Einspielen des Rahmens selbst bleibt ein Replay."},"400":{"description":"keine UUID ODER Objekt archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/reactivate":{"post":{"summary":"Nimmt die Archiv-Kaskade eines Objekts zurück (#445): Objekt + 1:1-Buchungskreis werden aktiv, dazu genau die Gebäude/Einheiten/Abrechnungskreise, die DIESELBE Kaskade stillgelegt hat.","operationId":"reactivateObjekt","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"reaktiviert (ObjektReactivateResponse). Vorher EINZELN archivierte Kinder bleiben archiviert. Ein bereits aktives Objekt liefert alreadyActive=true ohne Write. Wiederholungssicher nur über denselben Header `Idempotency-Key`."},"400":{"description":"keine UUID ODER Kaskade zu groß (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"eine zurückgeholte Einheit trüge eine Nummer, die im Objekt inzwischen an eine aktive Einheit vergeben ist (ApiErrorBody, code conflict, #5534) — nichts wurde reaktiviert."}}}},"/api/objekt/{id}/check":{"get":{"summary":"Plausi-Gate: prüft die Gesundheit/Vollständigkeit eines Objekts (Struktur, Flächen-Pflichtwerte §20 NMV, MEA-Rahmen) und liefert Flächensummen je Gebäude/Objekt als AGGREGAT — ein Soll-Abgleich findet nicht statt, das Schema trägt keine Soll-Fläche.","operationId":"checkObjekt","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"asOf","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Stichtag YYYY-MM-DD, gegen den die Attribut-Scheiben gemessen werden (Default: heute UTC)."}],"responses":{"200":{"description":"Plausi-Ergebnis (ObjektCheckResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ObjektCheckResponse"}}}},"400":{"description":"keine UUID ODER ungültiger asOf (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/konto":{"get":{"summary":"Listet Konten (3-Wege-Filter, optional auf EIN Objekt eingegrenzt).","operationId":"listKonten","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | aktiv | archiviert (Default aktiv). Unbekannter Wert ⇒ 400, nie stiller Fallback.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}},{"name":"propertyId","in":"query","required":false,"description":"grenzt auf EIN Objekt ein (Filter, keine Autorisierung — sichtbar ist ohnehin nur der eigene Tenant, RLS).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Kontenliste (KontoListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KontoListResponse"}}}},"400":{"description":"ungültiger status-Filter oder ungültige propertyId (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt EIN Konto im Kontenplan eines Objekts an.","operationId":"createKonto","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KontoCreateRequest"}}}},"responses":{"201":{"description":"angelegtes Konto (Konto)"},"400":{"description":"ungültige Eingabe, unbekannte Kostenkategorie, am Objekt schon vergebene Kontonummer ODER Objekt archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekanntes Objekt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/konto/{id}":{"get":{"summary":"Liest EIN Konto (auch archiviert) samt Kostenkategorie.","operationId":"getKonto","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Konto","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Konto"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"patch":{"summary":"Ändert Konto-Stammfelder (nach Erstbuchung nur noch den Namen).","operationId":"updateKonto","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KontoUpdateRequest"}}}},"responses":{"200":{"description":"geändertes Konto"},"400":{"description":"leerer/ungültiger Patch, Konto archiviert, unbekannte Kostenkategorie, schon vergebene Kontonummer ODER buchungsrelevantes Feld nach Erstbuchung (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/konto/{id}/archive":{"post":{"summary":"Archiviert ein Konto (archived_at statt DELETE, K5).","operationId":"archiveKonto","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"archiviert (KontoArchiveResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses (identische Antwort, kein zweites Kommando)."},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/konto/{id}/umlageschluessel":{"post":{"summary":"Ordnet dem Konto einen Umlageschlüssel zu oder hebt die Zuordnung auf (allocationKeyId null).","operationId":"assignKontoUmlageschluessel","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KontoUmlageschluesselRequest"}}}},"responses":{"200":{"description":"geändertes Konto (Konto)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Konto"}}}},"400":{"description":"keine UUID, Konto archiviert ODER Schlüssel aus fremdem Objekt/archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Konto/Schlüssel unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/kontenrahmen":{"get":{"summary":"Listet die verfügbaren Musterkontenrahmen (Code-Katalog, kein Mandanten-Stammdatum).","operationId":"listKontenrahmen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Vorlagenliste (KontenrahmenListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KontenrahmenListResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/kontenrahmen/{id}/apply":{"post":{"summary":"Spielt einen Musterkontenrahmen auf den Kontenplan EINES Objekts ein (Bulk-Anlage).","operationId":"applyKontenrahmen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Kennung des Musterkontenrahmens","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KontenrahmenApplyRequest"}}}},"responses":{"200":{"description":"eingespielt (KontenrahmenApplyResponse). WIEDERHOLUNG IST HARMLOS: der Idempotency Key ist deterministisch (apply_chart_of_accounts:<propertyId>:<rahmenId>:<version>), ein zweiter Aufruf ist ein Replay des Erst-Ergebnisses — kein zweiter Kontensatz, kein zweites Kommando."},"400":{"description":"ungültige Eingabe ODER Objekt archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannter Rahmen ODER unbekanntes/fremdes Objekt (ApiErrorBody, code not_found)"}}}},"/api/bank":{"get":{"summary":"Listet Bankverbindungen (3-Wege-Filter, optional auf EIN Objekt eingegrenzt).","operationId":"listBankverbindungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | aktiv | archiviert (Default aktiv). Unbekannter Wert ⇒ 400, nie stiller Fallback.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}},{"name":"propertyId","in":"query","required":false,"description":"grenzt auf EIN Objekt ein (Filter, keine Autorisierung — sichtbar ist ohnehin nur der eigene Tenant, RLS).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Bankverbindungsliste (BankListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankListResponse"}}}},"400":{"description":"ungültiger status-Filter oder ungültige propertyId (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt EINE Bankverbindung an einem Objekt an (IBAN-validiert).","operationId":"createBankverbindung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankCreateRequest"}}}},"responses":{"201":{"description":"angelegte Bankverbindung (Bank)"},"400":{"description":"ungültige Eingabe, ungültige IBAN ODER Objekt archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekanntes Objekt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/bank/{id}":{"get":{"summary":"Liest EINE Bankverbindung (auch archiviert).","operationId":"getBankverbindung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Bank","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bank"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"patch":{"summary":"Ändert Bankverbindungs-Stammfelder (IBAN/Kontoart/Gläubiger-ID).","operationId":"updateBankverbindung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankUpdateRequest"}}}},"responses":{"200":{"description":"geänderte Bankverbindung"},"400":{"description":"leerer/ungültiger Patch, ungültige IBAN ODER archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Kontoart oder Bank-Sachkonto des Kautionskontos einer aktiven Kautionsabrede geändert (ApiErrorBody, code conflict)"}}}},"/api/bank/{id}/archive":{"post":{"summary":"Archiviert eine Bankverbindung (archived_at statt DELETE, K5).","operationId":"archiveBankverbindung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"archiviert (BankArchiveResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses (identische Antwort, kein zweites Kommando)."},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Kautionskonto einer aktiven Kautionsabrede — nicht archivierbar (ApiErrorBody, code conflict)"}}}},"/api/bank/{id}/umsatz-import":{"post":{"summary":"Importiert einen Kontoauszug als Datei (camt.053/camt.052/MT940) auf eine Bankverbindung. Die Datei wird serverseitig geparst; verbucht wird das ERKANNTE Format, nicht das deklarierte. Wiederholung ist gefahrlos (Dedup).","operationId":"importBankUmsaetze","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Die Bankverbindung, auf die importiert wird.","schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","required":true,"description":"Leseformat der Datei — wählt NUR den Parser. Verbucht und gemeldet wird das aus der Datei erkannte Format. Unbekannter Wert ⇒ 400, nie stiller Fallback.","schema":{"type":"string","enum":["camt.053","camt.052","mt940"]}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Die Auszugsdatei (Bytes, unverändert). GENAU EIN file-Part je Aufruf — zwei Parts werden abgewiesen (nie still der zweite verworfen)."}}}}}},"responses":{"201":{"description":"Import-Report (BankUmsatzImportResponse) — total = imported + deduplicated + discarded + excluded. Ein vom Import AUSGENOMMENES Konto liefert ebenfalls 201, mit excluded > 0 und exclusion (Begründung), keinen Fehler.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankUmsatzImportResponse"}}}},"400":{"description":"fehlendes/unbekanntes format, kein oder MEHR ALS EIN file-Feld ODER unlesbare Auszugsdatei (ApiErrorBody, code invalid_request) — kein Teil-Import"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannte Bankverbindung ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"die Bankverbindung bezieht ihre Umsätze bereits über einen nicht getrennten Bankzugang — ein Datei-Import würde doppelt buchen (ApiErrorBody, code conflict). Ausweg: Bankzugang trennen."},"413":{"description":"Datei überschreitet die zulässige Maximalgröße (ApiErrorBody, code payload_too_large)"}}}},"/api/person":{"get":{"summary":"Listet Personen (3-Wege-Filter Alle/Aktiv/Archiviert, Default aktiv).","operationId":"listPersonen","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | aktiv | archiviert (Default aktiv). Unbekannter Wert ⇒ 400, nie stiller Fallback.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}}],"responses":{"200":{"description":"Personenliste (PersonListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonListResponse"}}}},"400":{"description":"ungültiger status-Filter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt eine Person im Adressbuch an.","operationId":"createPerson","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonCreateRequest"}}}},"responses":{"201":{"description":"angelegte Person (Person)"},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/person/{id}":{"get":{"summary":"Liest EINE Person (auch archiviert).","operationId":"getPerson","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Person"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"patch":{"summary":"Ändert Personen-Stammfelder (nur nicht-archivierte Personen).","operationId":"updatePerson","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonUpdateRequest"}}}},"responses":{"200":{"description":"geänderte Person"},"400":{"description":"leerer/ungültiger Patch ODER Person archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/person/{id}/archive":{"post":{"summary":"Archiviert eine Person (archived_at statt DELETE, K5). Ihre Rollen bleiben unberührt.","operationId":"archivePerson","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"grund":{"type":"string","minLength":1,"maxLength":500,"pattern":"^[^\\u0000]*[^\\s\\u0000][^\\u0000]*$","description":"Fachlicher Archivgrund ⇒ persons.archive_reason (nicht nur Leerraum, kein NUL-Byte). Fehlt er, wird mit dem festen Platzhalter „Ohne Grundangabe archiviert (bisheriger Adressbuch-Weg)\" archiviert."}}}}}},"responses":{"200":{"description":"archiviert (PersonArchiveResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses (identische Antwort, kein zweites Kommando). Schon archiviert ⇒ alreadyArchived: true, der erste Grund bleibt."},"400":{"description":"keine UUID ODER ungültiger Body (kein JSON-Objekt, unbekanntes Feld, ungültiger grund) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/rolle":{"get":{"summary":"Listet Rollen (3-Wege-Gültigkeitsfilter Alle/Aktiv/Beendet, Default aktiv).","operationId":"listRollen","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | aktiv | beendet (Default aktiv). Gemessen an der GÜLTIGKEIT, nicht an einem archived_at (das hat party_roles nicht). aktiv ∪ beendet ≠ alle: zukünftige Rollen erscheinen nur unter `alle`. Unbekannter Wert ⇒ 400.","schema":{"type":"string","enum":["alle","aktiv","beendet"]}},{"name":"person","in":"query","required":false,"description":"nur Rollen dieser Person (UUID)","schema":{"type":"string","format":"uuid"}},{"name":"asOf","in":"query","required":false,"description":"Stichtag YYYY-MM-DD, gegen den aktiv/beendet gemessen wird (Default: heute, UTC).","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Rollenliste (RolleListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RolleListResponse"}}}},"400":{"description":"ungültiger status-Filter, person-UUID oder Stichtag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Vergibt einer Person eine Rolle an Objekt ODER Einheit (mit Gültigkeit).","operationId":"assignRolle","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RolleAssignRequest"}}}},"responses":{"201":{"description":"vergebene Rolle (Rolle)"},"400":{"description":"ungültige Eingabe, kein/zwei Ziele oder unplausible Gültigkeit (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Person ODER Rollen-Ziel unbekannt, archiviert oder fremder Tenant (ApiErrorBody, code not_found). Die Ziel-Prüfung leistet der Tool-Layer — die Ziel-Spalten tragen KEINE Fremdschlüssel."}}}},"/api/rolle/{id}/end":{"post":{"summary":"Beendet eine Rolle zum Stichtag (obere valid_range-Grenze statt DELETE, K5).","operationId":"endRolle","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RolleEndRequest"}}}},"responses":{"200":{"description":"beendet (RolleEndResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses."},"400":{"description":"ungültiges/unplausibles Enddatum (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/gebaeude":{"get":{"summary":"Listet Gebäude (3-Wege-Filter Alle/Aktiv/Archiviert, Default aktiv; optional je Objekt).","operationId":"listGebaeude","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | aktiv | archiviert (Default aktiv). Unbekannter Wert ⇒ 400, nie stiller Fallback.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}},{"name":"objektId","in":"query","required":false,"description":"Nur Gebäude DIESES Objekts. Einschränkung innerhalb des Tenants, KEINE Autorisierungsgrenze (die macht RLS) — eine fremde ID schneidet auf die leere Menge.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Gebäudeliste (GebaeudeListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GebaeudeListResponse"}}}},"400":{"description":"ungültiger status-Filter oder objektId keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt ein Gebäude an einem aktiven Objekt an.","operationId":"createGebaeude","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GebaeudeCreateRequest"}}}},"responses":{"201":{"description":"angelegtes Gebäude (Gebaeude)"},"400":{"description":"ungültige Eingabe ODER Elternobjekt archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Elternobjekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/gebaeude/{id}":{"get":{"summary":"Liest EIN Gebäude (auch archiviert).","operationId":"getGebaeude","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Gebaeude","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Gebaeude"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"patch":{"summary":"Ändert die Gebäude-Adresse (nur nicht-archivierte Gebäude).","operationId":"updateGebaeude","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GebaeudeUpdateRequest"}}}},"responses":{"200":{"description":"geändertes Gebäude"},"400":{"description":"leerer/ungültiger Patch ODER Gebäude archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/gebaeude/{id}/archive":{"post":{"summary":"Archiviert ein Gebäude (archived_at statt DELETE, K5). Kaskadiert abwärts: alle Einheiten des Gebäudes werden mitarchiviert (#445).","operationId":"archiveGebaeude","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"archiviert (GebaeudeArchiveResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses (identische Antwort, kein zweites Kommando). Alle Einheiten des Gebäudes werden in derselben Transaktion mitarchiviert (Kaskade #445, ein Kommando)."},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/gebaeude/{id}/reactivate":{"post":{"summary":"Nimmt die Archiv-Kaskade eines Gebäudes zurück (#445) — nur der eigene Teilbaum, nie aufwärts.","operationId":"reactivateGebaeude","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"reaktiviert (GebaeudeReactivateResponse)."},"400":{"description":"keine UUID, Kaskade zu groß ODER das ELTERNOBJEKT ist archiviert (ApiErrorBody, code invalid_request) — erst das Objekt reaktivieren."},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"eine zurückgeholte Einheit trüge eine Nummer, die im Objekt inzwischen an eine aktive Einheit vergeben ist (ApiErrorBody, code conflict, #5534) — nichts wurde reaktiviert."}}}},"/api/einheit":{"get":{"summary":"Listet Einheiten (3-Wege-Filter Alle/Aktiv/Archiviert, Default aktiv; optional je Gebäude oder Objekt).","operationId":"listEinheiten","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | aktiv | archiviert (Default aktiv). Wirkt NUR auf units.archived_at — seit #445 kaskadiert archive_building bzw. archive_property abwärts, sodass mit-archivierte Einheiten aus dem aktiv-Default verschwinden.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}},{"name":"gebaeudeId","in":"query","required":false,"description":"Nur Einheiten DIESES Gebäudes. Einschränkung innerhalb des Tenants, keine Autorisierungsgrenze.","schema":{"type":"string","format":"uuid"}},{"name":"objektId","in":"query","required":false,"description":"Nur Einheiten dieses Objekts (über alle seine Gebäude hinweg). Einschränkung innerhalb des Tenants.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Einheitenliste (EinheitListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitListResponse"}}}},"400":{"description":"ungültiger status-Filter oder Eltern-ID keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt eine Einheit an einem aktiven Gebäude an.","operationId":"createEinheit","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitCreateRequest"}}}},"responses":{"201":{"description":"angelegte Einheit (Einheit)"},"400":{"description":"ungültige Eingabe ODER Elterngebäude archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Elterngebäude unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Einheitennummer im Objekt bereits an eine aktive Einheit vergeben (ApiErrorBody, code conflict, #5534)"}}}},"/api/einheit/{id}":{"get":{"summary":"Liest EINE Einheit (auch archiviert) samt Gebäude- und Objekt-Bezug.","operationId":"getEinheit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Einheit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Einheit"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"patch":{"summary":"Ändert unitNo/unitKind/bezeichnung (nur nicht-archivierte Einheiten).","operationId":"updateEinheit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitUpdateRequest"}}}},"responses":{"200":{"description":"geänderte Einheit"},"400":{"description":"leerer/ungültiger Patch ODER Einheit archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"neue Einheitennummer im Objekt bereits an eine aktive Einheit vergeben (ApiErrorBody, code conflict, #5534)"}}}},"/api/einheit/{id}/archive":{"post":{"summary":"Archiviert eine Einheit (archived_at statt DELETE, K5).","operationId":"archiveEinheit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"archiviert (EinheitArchiveResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses (identische Antwort, kein zweites Kommando)."},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/einheit/{id}/reactivate":{"post":{"summary":"Reaktiviert eine Einheit (#445).","operationId":"reactivateEinheit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"reaktiviert (EinheitReactivateResponse)."},"400":{"description":"keine UUID ODER Gebäude/Objekt archiviert (ApiErrorBody, code invalid_request) — erst den Elternteil reaktivieren."},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Einheitennummer im Objekt inzwischen an eine andere aktive Einheit vergeben (ApiErrorBody, code conflict, #5534) — erst die Nummer der aktiven Einheit ändern."}}}},"/api/einheit/{id}/attribut":{"get":{"summary":"Liest die Attribut-Historie einer Einheit (alle Zeitscheiben je Attribut, active zum Stichtag).","operationId":"listEinheitAttribute","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"attributeKey","in":"query","required":false,"description":"nur Scheiben dieses Attribut-Schlüssels (exakte Übereinstimmung)","schema":{"type":"string"}},{"name":"asOf","in":"query","required":false,"description":"Stichtag YYYY-MM-DD, gegen den `active` gemessen wird (Default: heute UTC). Ungültiges Format ⇒ 400.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Attribut-Historie (EinheitAttributListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitAttributListResponse"}}}},"400":{"description":"keine UUID oder ungültiger asOf (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"post":{"summary":"Setzt/ändert eine Attribut-Zeitscheibe „ab Datum\" (SCD-2; Überschneidungen desselben Attributs werden abgelehnt).","operationId":"setEinheitAttribut","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitAttributSetRequest"}}}},"responses":{"200":{"description":"gesetzte Zeitscheibe (EinheitAttributSetResponse)"},"400":{"description":"ungültige Eingabe, leerer/degenerierter Bereich ODER Überschneidung mit einer bestehenden Scheibe desselben Attributs (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit unbekannt, archiviert ODER fremder Tenant (ApiErrorBody, code not_found bzw. invalid_request bei archiviert)"}}}},"/api/einheit/{id}/belegung":{"get":{"summary":"Löst die Belegung einer Einheit zum Stichtag auf („wer wohnt in Einheit X?\"), optional stattdessen die Historie. EINE Zustandsachse mit vier Ausgängen: aktiver Mietvertrag (Mietpartei) · Eigentümer als Selbstnutzer · Drittnutzer-Kontakt · Leerstand. Der Zustand wird ABGELEITET, wo casa den Mietvertrag selbst führt (aktiver Vertrag ⇒ vermietet, Vertragslücke ⇒ Leerstand), und aus der gepflegten Zeitscheibe GELESEN, wo nicht (fremdverwaltete WEG-Einheit). Ein Widerspruch zwischen beiden ist ein BEFUND, keine Sperre.","operationId":"getEinheitBelegung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"description":"Stichtag YYYY-MM-DD, zu dem aufgelöst wird (Default: heute UTC). Ungültiges Format ⇒ 400.","schema":{"type":"string","format":"date"}},{"name":"historie","in":"query","required":false,"description":"`1` ⇒ statt der Auflösung die volle, nicht-archivierte Zeitscheiben-Historie (EinheitBelegungHistorieResponse).","schema":{"type":"string"}}],"responses":{"200":{"description":"aufgelöste Belegung (EinheitBelegungResponse) bzw. Historie (EinheitBelegungHistorieResponse) bei `historie=1`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitBelegungResponse"}}}},"400":{"description":"keine UUID oder ungültiger Stichtag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"post":{"summary":"Setzt/ändert die GEPFLEGTE Belegungs-Zeitscheibe „ab Datum\" (SCD-2; Überschneidungen werden abgelehnt). Pflegt ausschliesslich den Fall, in dem casa den Mietvertrag NICHT führt. Personenzahl 0 bei zustand=leerstand wird abgelehnt: eine leerstehende Einheit zählt bei personenbasierter Umlage fiktiv als 1 Person (BGH VIII ZR 159/05), 0 ist nicht wählbar.","operationId":"setEinheitBelegung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitBelegungSetRequest"}}}},"responses":{"200":{"description":"gesetzte Zeitscheibe (EinheitBelegungSetResponse)"},"400":{"description":"ungültige Eingabe, leerer/degenerierter Bereich, Personenzahl 0 bei Leerstand (BGH-Gate), Drittnutzer ausserhalb von „vermietet\" ODER Überschneidung mit einer bestehenden Scheibe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit oder Drittnutzer-Person unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/einheit/{id}/wechselzeitraum":{"get":{"summary":"Prüft vorab, ob sich ein nachträglich erfasster früherer Bewohner- oder Eigentümerzeitraum (von/bis, beide Tage INKLUSIVE) in den Bestand der Einheit einfügt: ok · ueberlappt (mit Zeilen-Id der betroffenen Zeile; auch wenn das Ende auf den Beginn des bestehenden Zeitraums fällt) · zeitraum-verdreht · beginn-unbekannt, dazu eine etwaige Lücke zum nächsten bestehenden Zeitraum (gemeldet, nicht verboten). Reiner Read, schreibt nichts; erfasst wird über die Belegungs- und Eigentumsendpunkte.","operationId":"pruefeEinheitWechselzeitraum","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"art","in":"query","required":true,"description":"bewohner | eigentuemer","schema":{"type":"string","enum":["bewohner","eigentuemer"]}},{"name":"von","in":"query","required":true,"description":"Erster Tag des Zeitraums (inklusive), JJJJ-MM-TT.","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":true,"description":"Letzter Tag des Zeitraums (inklusive), JJJJ-MM-TT.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Prüfergebnis (WechselzeitraumResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WechselzeitraumResponse"}}}},"400":{"description":"keine UUID, ungültige Art oder ungültiger Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/einheit/{id}/einnahmeart":{"put":{"summary":"Setzt die Einnahmeart einer Einheit (Wohnung, andere Räume, an Angehörige vermietet, nicht steuerpflichtig) und optional das Geschoss — die Merkmale, nach denen die Auswertung `einnahmen-ueberschuss-einnahmeart` die Mieteinnahmen gliedert. `einnahmeart: null` entfernt sie; die Auswertung meldet eine Einheit ohne Einnahmeart dann als Befund, statt einen Wert zu raten.","operationId":"setEinheitEinnahmeart","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitEinnahmeartSetRequest"}}}},"responses":{"200":{"description":"wirksamer Stand nach dem Aufruf (EinheitEinnahmeartResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitEinnahmeartResponse"}}}},"400":{"description":"ungültige Eingabe (unbekannte Einnahmeart, leeres oder zu langes Geschoss) oder Einheit archiviert (ApiErrorBody)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/einheit/{id}/sev-mandat":{"get":{"summary":"Löst die Sondereigentumsverwaltung einer Einheit zum Stichtag auf („beauftragt der Eigentümer uns hier zusätzlich mit der Vermietung, und mit welchen Vertragswerten?\"), optional stattdessen die Historie. Halboffen: ein Mandat ab 01.01.2025 wird zum 01.06.2025 gefunden, zum 31.12.2024 nicht; ein zum 01.07.2025 beendetes am 30.06. noch, am 01.07. nicht mehr. `mandat: null` heisst „am Stichtag keine Sondereigentumsverwaltung\" — nicht „Einheit unbekannt\" (dafür 404).","operationId":"getEinheitSevMandat","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"description":"Stichtag YYYY-MM-DD, zu dem aufgelöst wird (Default: heute UTC). Ungültiges Format ⇒ 400.","schema":{"type":"string","format":"date"}},{"name":"historie","in":"query","required":false,"description":"`1` ⇒ statt der Auflösung alle Zeitabschnitte (SevMandatHistorieResponse).","schema":{"type":"string"}}],"responses":{"200":{"description":"wirksames Mandat (SevMandatResponse) bzw. alle Zeitabschnitte (SevMandatHistorieResponse) bei `historie=1`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMandatResponse"}}}},"400":{"description":"keine UUID oder ungültiger Stichtag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"post":{"summary":"Vereinbart die Sondereigentumsverwaltung für einen Eigentümer und diese Einheit als Zeitabschnitt. NUR in einem Objekt der Verwaltungsart \"pro\" (\"WEG mit Mietverwaltung\"): in einem reinen Mietobjekt gibt es kein Sondereigentum, das zusätzlich beauftragt werden könnte, in einer reinen WEG führt die Verwaltung die Mietseite nicht. Die Person muss im GESAMTEN Mandatszeitraum Eigentümerin der Einheit sein. Es gibt bewusst KEIN Änderungs-Kommando: ein Wechsel von „mit Mietinkasso\" zu „ohne\" ist beenden + neu anlegen (Parität Immoware24).","operationId":"legeEinheitSevMandatAn","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMandatAnlegenRequest"}}}},"responses":{"200":{"description":"angelegte Vereinbarung (SevMandatAnlegenResponse)"},"400":{"description":"ungültige Eingabe, leerer Zeitraum, unstimmige Vertragswerte (Art ohne Wert oder Wert ohne Art), Mietgutschrift ohne Mietinkasso, fehlendes Auszahlungsziel, Objekt nicht \"pro\", Person im Zeitraum nicht Eigentümerin ODER Überschneidung mit einem bestehenden Mandat derselben Wohnung (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit, Person oder Bankverbindung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/sev-mandat/{id}/beenden":{"post":{"summary":"Beendet einen SEV-Zeitabschnitt zu einem Datum. Beendet heisst GEKÜRZT, nicht gelöscht: die Historie bleibt stehen, damit eine bereits abgerechnete SEV-Periode erklärbar bleibt. Kürzen nur — ein Ende nach einem bestehenden Ende und ein Ende am Beginntag werden abgewiesen; dasselbe Ende ein zweites Mal ist ein No-op-Erfolg.","operationId":"beendeSevMandat","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMandatBeendenRequest"}}}},"responses":{"200":{"description":"beendete Vereinbarung (SevMandatBeendenResponse)"},"400":{"description":"ungültiges Datum, Ende am oder vor dem Beginn ODER Ende nach einem bereits gesetzten Ende (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"am oder nach dem Ende liegen noch geltende Angaben des Eigentümers für die Mieterabrechnung — erst aufheben, dann beenden (ApiErrorBody, code conflict)"}}}},"/api/sev-mandat/{id}/anfangsbestand":{"post":{"summary":"Übernimmt den Anfangsbestand des Eigentümer-Verrechnungskontos eines SEV-Mandats aus dem Altbestand — eine Buchung im Geldkreis Sondereigentum (Verrechnungskonto gegen Gegenkonto DESSELBEN Mandats), die in keiner Sicht der offenen Posten erscheint. Der Betrag erscheint als Saldo ab dem Stichtag selbst, der Stichtag zählt inklusiv (GET /api/sev-mandat/{id}/verrechnungskonto). Genau ein aktiver Anfangsbestand je Mandat.","operationId":"erfasseSevAnfangsbestand","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevAnfangsbestandRequest"}}}},"responses":{"200":{"description":"geschriebene Anfangsbestands-Buchung (SevAnfangsbestandResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevAnfangsbestandResponse"}}}},"400":{"description":"ungültige Eingabe, Betrag 0 oder ausserhalb des speicherbaren Bereichs, Stichtag in der Zukunft, Mandat ohne Verrechnungskonto (ohne Mietinkasso) ODER Konto archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"bereits ein aktiver Anfangsbestand erfasst ODER Idempotency-Key an eine andere Eingabe gebunden (ApiErrorBody, code conflict)"}}}},"/api/sev-mandat/{id}/verrechnungskonto":{"get":{"summary":"Saldo des Eigentümer-Verrechnungskontos eines SEV-Mandats zum Stichtag (inklusiv) — das Geld, das dem Eigentümer zusteht. Jeder Eigentümer hat sein eigenes Konto; eine Buchung beim einen ändert den Saldo des anderen nicht.","operationId":"getSevVerrechnungskontoSaldo","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":true,"description":"Stichtag YYYY-MM-DD (inklusiv). Pflicht — kein stilles „heute\". Fehlend oder ungültig ⇒ 400.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Saldo zum Stichtag (SevVerrechnungskontoSaldoResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevVerrechnungskontoSaldoResponse"}}}},"400":{"description":"fehlender oder ungültiger Stichtag ODER Mandat ohne Verrechnungskonto (ohne Mietinkasso) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/sev-mandat/{id}/verguetung":{"get":{"summary":"Vorschlag der Verwaltervergütung eines SEV-Mandats für einen Monat — Fall (vermietet/Leerstand), Bemessungsgrundlage, Netto, USt und Brutto samt vorschlagHash, den ein Mensch mit POST bestätigt. Auf Ist-Basis folgt die Vergütung der Mietgutschrift des Monats.","operationId":"getSevVerguetungVorschlag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"monat","in":"query","required":true,"description":"Monat JJJJ-MM. Pflicht. Fehlend oder ungültig ⇒ 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Vorschlag (SevVerguetungVorschlagResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevVerguetungVorschlagResponse"}}}},"400":{"description":"fehlender oder ungültiger Monat, Monat ausserhalb des Mandatszeitraums ODER Mandat ohne Verrechnungskonto (ohne Mietinkasso) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Reihenfolge-Sperre: Ist-Basis ohne Mietgutschrift des Monats (ApiErrorBody, code conflict)"}}},"post":{"summary":"Bucht die Verwaltervergütung eines SEV-Mandats für einen Monat nach Bestätigung des gesehenen Vorschlags (vorschlagHash): Belastung des Eigentümer-Verrechnungskontos (Art Verwaltervergütung) und Ertrag beim Verwalter, die USt getrennt ausgewiesen. Genau einmal je Mandat und Monat. Bis zum SEV-Monatslauf (#5218) ist diese Route der Einstieg.","operationId":"bucheSevVerguetung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevVerguetungBuchenRequest"}}}},"responses":{"200":{"description":"Ergebnis der Buchung (SevVerguetungBuchungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevVerguetungBuchungResponse"}}}},"400":{"description":"ungültige Eingabe, Monat ausserhalb des Mandatszeitraums, Mandat ohne Verrechnungskonto (ohne Mietinkasso) ODER Konto archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch als Akteur ODER nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Mandat unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Reihenfolge-Sperre (keine Mietgutschrift des Monats), Vorschlag geändert (vorschlagHash), abweichend gebucht, gleichzeitiger Lauf ODER Idempotency-Key an eine andere Eingabe gebunden (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/sev-mietgutschrift":{"post":{"summary":"Legt die monatliche Mietgutschrift der SEV-Mandate des Objekts für eine Periode als Vorschläge vor — Grundlage je Vereinbarung die eingegangene Miete (Buchungsdatum im Monat), die sollgestellte Miete oder ein Festbetrag; eine Periode aus mehreren Monaten ist die Summe der Einzelmonate. Idempotent je Mandat und Monat: ein zweiter Lauf legt nichts vor, eine nachträgliche Zahlung ergibt eine Nachgutschrift über die Differenz. Mandate ohne Mietinkasso werden übersprungen und ausgewiesen.","operationId":"legeSevMietgutschriftenVor","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMietgutschriftLaufRequest"}}}},"responses":{"200":{"description":"Ergebnis des Laufs (SevMietgutschriftLaufResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMietgutschriftLaufResponse"}}}},"400":{"description":"ungültige Eingabe ODER keine lückenlose Monatsfolge (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"nicht zuständig für das Objekt ODER kein Schreibrecht (ApiErrorBody, code forbidden)"},"409":{"description":"Reihenfolge-Sperre: die Miet-Sollstellung eines Monats ist für das Objekt nicht abgeschlossen — die Meldung nennt den fehlenden Schritt ODER Idempotency-Key an eine andere Eingabe gebunden (ApiErrorBody, code conflict)"}}}},"/api/sev-mietgutschrift/{id}/freigabe":{"post":{"summary":"Gibt einen Mietgutschrift-Vorschlag nach Bestätigung seines inhaltsHash frei: je Monat mit Anteil eine Buchung (Art Mietgutschrift) auf dem Verrechnungskonto des Eigentümers. Nur ein Mensch gibt frei.","operationId":"gibSevMietgutschriftFrei","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMietgutschriftFreigabeRequest"}}}},"responses":{"200":{"description":"Die Buchungen (SevMietgutschriftFreigabeResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMietgutschriftFreigabeResponse"}}}},"400":{"description":"ungültige Eingabe ODER Konto archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch als Akteur ODER nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorschlag unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Vorschlag geändert (inhaltsHash) ODER bereits entschieden (ApiErrorBody, code conflict)"}}}},"/api/sev-mietgutschrift/{id}/ablehnung":{"post":{"summary":"Lehnt einen Mietgutschrift-Vorschlag ab: seine Reservierung wird gelöst, ein Folgelauf legt neu vor. Nur ein Mensch lehnt ab.","operationId":"lehneSevMietgutschriftAb","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Die gelösten Monate (SevMietgutschriftAblehnungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMietgutschriftAblehnungResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch als Akteur ODER nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorschlag unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"bereits entschieden (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/sev-auszahlung":{"get":{"summary":"Vorschlag der Auszahlung des Mietüberschusses je SEV-Mandat des Objekts für einen Monat (Stichtag Monatsletzter): Saldo des Verrechnungskontos, Sockel, Auszahlungsbetrag und Empfänger-IBAN — oder das Mandat als übersprungen mit Grund (Rhythmus, offene Posten, kein Überschuss, bereits ausgezahlt, ohne Auszahlungskonto) — samt vorschlagHash, den ein Mensch mit POST bestätigt. Schreibt nichts.","operationId":"getSevAuszahlungVorschlag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"monat","in":"query","required":true,"description":"Monat JJJJ-MM. Pflicht. Fehlend oder ungültig ⇒ 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Vorschlag (SevAuszahlungVorschlagResponse). ACHTUNG PII: `auszahlungen[].empfaengerIban` ist eine IBAN (Kategorie bankdaten) — der Empfänger, den der Mensch vor dem Stellen sehen muss.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevAuszahlungVorschlagResponse"}}}},"400":{"description":"fehlender oder ungültiger Monat (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"post":{"summary":"Stellt die Auszahlungen des Mietüberschusses eines Monats nach Bestätigung des gesehenen Vorschlags (vorschlagHash): je Mandat der Entnahme-Satz auf dem Eigentümer-Verrechnungskonto und EIN Zahlungsauftrag awaiting-approval an das Privatkonto des Eigentümers, abgehend vom angegebenen Objekt-Bankkonto. Ausgeführt wird erst nach der bestehenden Zahlungsfreigabe (Vier-Augen). Idempotent je Mandat und Monat.","operationId":"stelleSevAuszahlungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevAuszahlungStellenRequest"}}}},"responses":{"200":{"description":"Die gestellten Auszahlungen samt Zahlungsaufträgen und die übersprungenen Mandate (SevAuszahlungStellenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevAuszahlungStellenResponse"}}}},"400":{"description":"ungültige Eingabe (u. a. Zusatzfeld wie propertyId oder ein Betrag) ODER das Bankkonto ist kein Konto dieses Objekts (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch als Akteur ODER nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Vorschlag geändert (vorschlagHash), gleichzeitiger Lauf derselben Periode ODER Idempotency-Key an eine andere Eingabe gebunden (ApiErrorBody, code conflict)"}}}},"/api/sev-mandat/{id}/schlussauszahlung":{"get":{"summary":"Vorschlag der Schlussauszahlung eines BEENDETEN SEV-Mandats (Ende erreicht): der GANZE Saldo des Verrechnungskontos — der Sockel wird nicht mehr einbehalten — an das Privatkonto des bisherigen Eigentümers, gesperrt bei offenen Hausgeld-Posten aus dem Mandatszeitraum, samt vorschlagHash, den ein Mensch mit POST bestätigt. Schreibt nichts.","operationId":"getSevSchlussauszahlungVorschlag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Vorschlag (SevSchlussauszahlungVorschlagResponse). ACHTUNG PII: `empfaengerIban` ist eine IBAN (Kategorie bankdaten) — der Empfänger, den der Mensch vor dem Stellen sehen muss.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevSchlussauszahlungVorschlagResponse"}}}},"400":{"description":"das Mandat nennt kein bestätigtes Privatkonto des Eigentümers (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt, fremder Tenant ODER nicht zuständig (ApiErrorBody, code not_found)"},"409":{"description":"das Mandat ist nicht beendet oder sein Ende ist noch nicht erreicht (ApiErrorBody, code conflict)"}}},"post":{"summary":"Stellt die Schlussauszahlung nach Bestätigung des gesehenen Vorschlags (vorschlagHash): der Entnahme-Satz über den ganzen Saldo und EIN Zahlungsauftrag awaiting-approval an das Privatkonto des bisherigen Eigentümers, abgehend vom angegebenen Objekt-Bankkonto. Ausgeführt wird erst nach der bestehenden Zahlungsfreigabe (Vier-Augen).","operationId":"stelleSevSchlussauszahlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevSchlussauszahlungStellenRequest"}}}},"responses":{"200":{"description":"Die gestellte Schlussauszahlung samt Zahlungsauftrag (SevSchlussauszahlungStellenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevSchlussauszahlungStellenResponse"}}}},"400":{"description":"ungültige Eingabe (u. a. ein Betrag oder eine IBAN im Body), das Bankkonto ist kein Konto des Objekts ODER kein Privatkonto (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch als Akteur ODER nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Mandat unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Mandat nicht beendet, Vorschlag geändert (vorschlagHash), gesperrt (offene Posten, kein Überschuss) ODER Idempotency-Key an eine andere Eingabe gebunden (ApiErrorBody, code conflict)"}}}},"/api/sev-mandat/{id}/ertragsumbuchung":{"get":{"summary":"Die Ertragsumbuchungen eines SEV-Mandats in beiden Richtungen (Abgang an den neuen, Zugang vom bisherigen Eigentümer) mit Zeitraum und Beleg.","operationId":"listSevErtragsumbuchungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Die Umbuchungen (SevErtragsumbuchungListResponse). ACHTUNG PII: `beleg.bezeichnung` ist Freitext des Verwalters (Kategorie freitext).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevErtragsumbuchungListResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt, fremder Tenant ODER nicht zuständig (ApiErrorBody, code not_found)"}}},"post":{"summary":"Bucht Mieterträge eines Zeitraums vom Mandat im Pfad (alter Eigentümer) auf das Mandat `nachMandatId` (neuer Eigentümer derselben Wohnung) um — eigene Buchungsart mit Beleg, auf beiden Verrechnungskonten ausgewiesen, beide Seiten in EINER Transaktion. Höchstens die im Zeitraum gutgeschriebene, noch nicht umgebuchte Miete.","operationId":"bucheSevErtragsumbuchung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevErtragsumbuchungBuchenRequest"}}}},"responses":{"200":{"description":"Die gebuchte Umbuchung (SevErtragsumbuchungBuchenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevErtragsumbuchungBuchenResponse"}}}},"400":{"description":"ungültige Eingabe (Zeitraum leer, Betrag, Beleg fehlt, Zusatzfeld) ODER die Mandate betreffen verschiedene Wohnungen (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch als Akteur ODER nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"ein Mandat unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"der Betrag übersteigt die im Zeitraum gutgeschriebene, noch nicht umgebuchte Miete ODER Idempotency-Key an eine andere Eingabe gebunden (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/sev-eigentuemerwechsel":{"get":{"summary":"Befunde „Eigentümer gewechselt, Mandat läuft weiter\" eines Objekts für einen Monat: je SEV-Mandat, dessen Person an mindestens einem Tag, an dem das Mandat wirkt, nicht (mehr) Eigentümerin der Wohnung ist — mit dem ersten solchen Tag und den Eigentümern an diesem Tag. Der Mietgutschrift-Lauf schreibt diesen Monat nicht an den bisherigen Eigentümer gut. Schreibt nichts.","operationId":"getSevEigentuemerwechselBefunde","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"monat","in":"query","required":true,"description":"Monat JJJJ-MM. Pflicht. Fehlend oder ungültig ⇒ 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Die Befunde (SevEigentuemerwechselBefundeResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevEigentuemerwechselBefundeResponse"}}}},"400":{"description":"fehlender oder ungültiger Monat (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"}}}},"/api/objekt/{id}/sev-hausgeld":{"get":{"summary":"Vorschlag der Hausgeldzahlung aus der vereinnahmten Miete für ein Objekt und einen Monat — je SEV-Mandat die offenen Hausgeld-Posten (Rückstände im Mandatszeitraum eingeschlossen, Sonderumlage nur bei Vereinbarung), das Guthaben, die Deckung und jede Unterdeckung als Befund (Einheit, Betrag, Regel), dazu übersprungene Mandate mit Grund, samt vorschlagHash, den ein Mensch mit POST bestätigt. Schreibt nichts.","operationId":"getSevHausgeldVorschlag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"monat","in":"query","required":true,"description":"Monat JJJJ-MM. Pflicht. Fehlend oder ungültig ⇒ 400.","schema":{"type":"string"}}],"responses":{"200":{"description":"Vorschlag (SevHausgeldVorschlagResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevHausgeldVorschlagResponse"}}}},"400":{"description":"fehlender oder ungültiger Monat (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt, fremder Tenant ODER nicht zuständig (ApiErrorBody, code not_found)"}}},"post":{"summary":"Monatslauf eines Objekts nach der Mietgutschrift in zwei Runden über diese eine Route. Runde 1 (Body mit verguetungen: je Mandat mandatId und vorschlagHash des gesehenen Vergütungsvorschlags) prüft alle Vergütungs-Hashes vor der ersten Buchung, bucht die Vergütungen und antwortet mit hausgeldStatus 'nicht_bestaetigt' und dem Hausgeld-Vorschlag, der nach der Vergütung gilt, samt vorschlagHash. Runde 2 (Body mit diesem vorschlagHash) bezahlt das Hausgeld aus der vereinnahmten Miete: Belastung des Verrechnungskontos (Art hausgeld_an_weg) und Ausgleich der Hausgeld-Sollstellung bzw. Ausgabe an den Kreditor (Festbetrag); danach die Zuführung zur Sonderrücklage. Bei Unterdeckung gilt die Regel des Mandats (einziehen / nicht zahlen / aus der Sonderrücklage). Die Mietgutschrift des Monats muss freigegeben sein. Eine Wiederholung mit demselben Idempotency-Key bucht nichts doppelt.","operationId":"zahleSevHausgeld","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevHausgeldZahlenRequest"}}}},"responses":{"200":{"description":"Laufergebnis (SevHausgeldZahlungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevHausgeldZahlungResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch als Akteur ODER nicht zuständig für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt, fremder Tenant ODER ein Mandat in verguetungen gehört nicht zu diesem Objekt (ApiErrorBody, code not_found)"},"409":{"description":"Vorschlag geändert (Vergütungs- oder Hausgeld-vorschlagHash, auch: bereits bezahlt), Mietgutschrift des Monats nicht freigegeben, gleichzeitiger Lauf ODER Idempotency-Key an eine andere Eingabe gebunden (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/sev-garantie-abstimmliste":{"get":{"summary":"Abstimmliste der Garantiemieten eines Objekts über einen Zeitraum: je Wohnung mit Garantie- oder Mindestmiete die garantierte gegen die erzielte Miete, die Differenz, die Gutschrift an den Eigentümer und die Belastung des Garantiegebers, dazu die Summen je Spalte. Gerechnet aus dem Bestand — unabhängig davon, ob die Gutschrift schon vorgelegt oder freigegeben ist. Schreibt nichts.","operationId":"ladeSevGarantieAbstimmliste","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"monate","in":"query","required":true,"description":"Der Zeitraum: lückenlose Monate JJJJ-MM, kommagetrennt in Kalenderfolge (z. B. 2025-03,2025-04), höchstens zwölf. Fehlend, formwidrig oder lückenhaft ⇒ 400.","schema":{"type":"string","example":"2025-03,2025-04"}}],"responses":{"200":{"description":"Die Abstimmliste (SevGarantieAbstimmlisteResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevGarantieAbstimmlisteResponse"}}}},"400":{"description":"fehlender, formwidriger oder lückenhafter Zeitraum ODER Basis kalt ohne getrennt gebuchte Kaltmiete (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt, fremder Tenant ODER nicht zuständig (ApiErrorBody, code not_found)"}}}},"/api/sev-mandat/{id}/eigentuemerabrechnung":{"get":{"summary":"Jahresabrechnung der Sondereigentumsverwaltung für den Eigentümer über einen Zeitraum: Einnahmen, Ausgaben und Auszahlungen je Buchungsart (Klasse nach Art, nie nach Vorzeichen), Mieteinnahmen mit Soll, Ist, Ausfall und Ertrag je m², Kosten der Wohnung und die Entwicklung des Geldbestands mit Probe gegen den Saldo des Verrechnungskontos, dazu der Empfänger mit Anrede und Anschrift. Schreibt nichts.","operationId":"ladeSevEigentuemerabrechnung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":true,"description":"Erster Tag des Zeitraums YYYY-MM-DD (inklusiv, nach Buchungsdatum). Fehlend oder kein Kalendertag ⇒ 400.","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":true,"description":"Letzter Tag des Zeitraums YYYY-MM-DD (inklusiv, nach Buchungsdatum). Fehlend, kein Kalendertag oder vor von ⇒ 400.","schema":{"type":"string","format":"date"}},{"name":"mitAuszahlung","in":"query","required":false,"description":"true (Vorgabe) oder false: false blendet die Positionen des Auszahlungsblocks aus — Summe und Geldbestand zählen die Auszahlungen trotzdem. Ein anderer Wert ⇒ 400.","schema":{"type":"string","enum":["true","false"],"default":"true"}}],"responses":{"200":{"description":"Die Abrechnung (SevEigentuemerabrechnungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevEigentuemerabrechnungResponse"}}}},"400":{"description":"fehlender oder ungültiger Zeitraum, von nach bis, ungültiges mitAuszahlung, unbekannter Query-Parameter ODER Mandat ohne Mietinkasso (kein Verrechnungskonto) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt, fremder Tenant ODER Objekt nicht zuständig — dieselbe Antwort (ApiErrorBody, code not_found)"},"422":{"description":"Empfänger unvollständig: Name, Anrede oder Anschrift des Eigentümers fehlt — kein Ausdruck mit leerem Adressfeld (ApiErrorBody, code invalid_request)"}}}},"/api/sev-mandat/{id}/sonderruecklage":{"get":{"summary":"Saldo der Sonderrücklage eines SEV-Mandats zum Stichtag (inklusiv) samt vereinbartem Höchststand — Geld des Eigentümers, getrennt vom Verrechnungskonto ausgewiesen und nicht Teil der Rücklage der Gemeinschaft. Zuführung (Monatslauf) und Entnahme (Unterdeckung) laufen im Tool-Layer.","operationId":"getSevSonderruecklageSaldo","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":true,"description":"Stichtag YYYY-MM-DD (inklusiv). Pflicht — kein stilles „heute\". Fehlend oder ungültig ⇒ 400.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Saldo zum Stichtag (SevSonderruecklageSaldoResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevSonderruecklageSaldoResponse"}}}},"400":{"description":"fehlender oder ungültiger Stichtag ODER Mandat ohne Mietinkasso (dann gibt es keine Sonderrücklage) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt, fremder Tenant ODER Objekt nicht zuständig (ApiErrorBody, code not_found)"}}}},"/api/sev-mandat/{id}/rechnung":{"get":{"summary":"Die Rechnungen des Sondereigentums eines SEV-Mandats mit Kennzeichen (Kostenart, umlagefähig), Status (bezahlt, nicht_bezahlt, storniert) und Befund einer Unterdeckung.","operationId":"listSevRechnungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Rechnungen des Mandats (SevRechnungListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevRechnungListResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Mandat unbekannt, fremder Tenant ODER Objekt nicht zuständig (ApiErrorBody, code not_found)"}}},"post":{"summary":"Bezahlt eine Rechnung des Sondereigentums aus der Miete des Eigentümers: Belastung des Verrechnungskontos (Art sonstige_ausgabe) mit Kennzeichen Kostenart + umlagefähig. Bei Unterdeckung entscheidet beiUnterdeckung (einziehen, nicht_zahlen, sonderruecklage) mit Befund. Die Rechnung erscheint in keiner Abrechnung der Gemeinschaft.","operationId":"bucheSevRechnung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevRechnungBuchenRequest"}}}},"responses":{"200":{"description":"gebucht, nicht bezahlt (mit Befund) oder unverändert (SevRechnungBuchenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevRechnungBuchenResponse"}}}},"400":{"description":"ungültige Eingabe, unbekannte Kostenart, umlagefähig bei nie umlagefähiger Kostenart, Zahlungsdatum in der Zukunft, Unterdeckung ohne Entscheid ODER Mandat ohne Verrechnungskonto (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Mandat oder Beleg unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"dieselbe Rechnung (Kreditor + Rechnungsnummer) mit anderem Inhalt erfasst ODER Idempotency-Key an eine andere Eingabe gebunden (ApiErrorBody, code conflict)"}}}},"/api/sev-mandat/{id}/mieter-handwert":{"post":{"summary":"Trägt bei SEV OHNE Mietinkasso eine Angabe des Eigentümers für die Mieterabrechnung ein (erfasse_sev_mieter_handwert): eine Vorauszahlung des Mieters oder umlagefähige Kosten der Wohnung, Herkunft „Angabe Eigentümer\". Identität einer Angabe ist ihre handwertId, nie ihr Inhalt: ohne handwertId legt jeder Aufruf eine NEUE Angabe an (erfasst, Fassung 1) — auch zwei gleiche am selben Tag; eine Wiederholung schützt allein der Idempotency-Key. Mit handwertId wird genau diese Angabe des Mandats korrigiert (ersetzt, Fassung + 1; Datum, Betrag, Kostenart, Bezeichnung änderbar, die Art nicht); gleicht sie der geltenden Fassung ⇒ unveraendert. Mit aktion aufheben, handwertId und der gesehenen fassung wird die Angabe append-only aufgehoben (aufgehoben, Fassung + 1): sie fällt aus Liste und Abrechnung; endgültig, keine Korrektur danach. Nur durch einen Menschen.","operationId":"erfasseSevMieterHandwert","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["art","datum","betragCents"],"additionalProperties":false,"properties":{"handwertId":{"type":"string","format":"uuid","description":"nur bei einer Korrektur: die handwertId der zu korrigierenden Angabe dieses Mandats; ohne ⇒ neue Angabe"},"art":{"type":"string","enum":["vorauszahlung","se_kosten"]},"datum":{"type":"string","format":"date","description":"Zahlungs- bzw. Rechnungsdatum, nicht in der Zukunft"},"betragCents":{"type":"string","pattern":"^[1-9][0-9]{0,18}$","description":"Betrag in Cent als Ganzzahl-String, streng positiv"},"kostenart":{"type":"string","description":"Pflicht bei se_kosten (umlagefähiger Katalog-Schlüssel), verboten bei vorauszahlung"},"bezeichnung":{"type":"string","description":"freier Hinweis zur Angabe"}}},{"type":"object","required":["aktion","handwertId","fassung"],"additionalProperties":false,"properties":{"aktion":{"type":"string","enum":["aufheben"]},"handwertId":{"type":"string","format":"uuid","description":"die aufzuhebende Angabe dieses Mandats"},"fassung":{"type":"integer","minimum":1,"description":"die geltende Fassung, die aufgehoben wird (veraltet ⇒ 409)"}}}]}}}},"responses":{"200":{"description":"erfasst, unverändert, ersetzt oder aufgehoben — { ergebnis, handwertId, mandatId, unitId, art, datum, betragCents, kostenart, bezeichnung, fassung, herkunft (angabe_eigentuemer), currency }","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"ungültige Eingabe, Datum in der Zukunft oder außerhalb des Mandats, Mandat mit Mietinkasso ODER Korrektur mit anderer Art (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt ODER kein Mensch (ApiErrorBody, code forbidden)"},"404":{"description":"Mandat unbekannt ODER fremder Tenant ODER handwertId unter diesem Mandat unbekannt — dieselbe Antwort (ApiErrorBody, code not_found)"},"409":{"description":"Idempotency-Key an eine andere Eingabe gebunden, Angabe bereits aufgehoben ODER Aufhebung gegen eine veraltete Fassung (ApiErrorBody, code conflict)"}}}},"/api/einheit/{id}/sev-mieterabrechnung":{"post":{"summary":"Berechnet die Betriebskostenabrechnung des Mieters der SEV-Wohnung aus der Hausgeld-Einzelabrechnung, die der Server aus dem genannten festgeschriebenen WEG-Abschlusslauf lädt (hashgeprüft; nie Beträge, Positionen oder Schlüssel aus dem Body) — umlagefähiger Anteil, Geldkreis miete — plus umlagefähigen Kosten der Wohnung; Vermieter ist der Eigentümer laut unit_ownerships (bei Wechsel ein Abschnitt je Eigentümer). Bei Mietinkasso lädt der Server die Vorauszahlungen aus der Mietbuchhaltung des Vertrags (ein Vorauszahlungsfeld im Body ist ein 400). Dazu derselbe Prüfbericht wie bei Mietobjekten, einschließlich heizkostenv_ohne_verbrauch (Kürzungsrecht nach § 12 HeizkostenV). Schreibt nichts.","operationId":"berechneSevMieterabrechnung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contractId","laufId","kostenarten"],"additionalProperties":false,"properties":{"contractId":{"type":"string","format":"uuid","description":"Mietvertrag auf der Einheit"},"laufId":{"type":"string","format":"uuid","description":"der über festschreibe_weg_abschlusslauf festgeschriebene Abschlusslauf des Objekts; sein Wirtschaftsjahr ist das Abrechnungsjahr. Eine Einzelabrechnung im Body ist ein 400"},"kostenarten":{"type":"array","items":{"type":"object","required":["kostenart","umlagefaehig","betrkvKatalogKey"],"additionalProperties":false,"properties":{"kostenart":{"type":"string"},"umlagefaehig":{"type":"boolean"},"betrkvKatalogKey":{"type":"string","nullable":true}}}}}}}}},"responses":{"200":{"description":"{ abrechnung, pruefbericht } — abrechnung mit abschnitte (vermieter, kosten mit herkunft/herkunftText, vorauszahlungen mit herkunft), Summen und nichtUmlagefaehig; pruefbericht { freigabefaehig, proben, funde }. Cent-Felder sind Ganzzahl-STRINGS.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"ungültige Eingabe (auch eine Einzelabrechnung oder Vorauszahlungen im Body), Wohnung nicht im Abschlusslauf, Kostenart ohne Zuordnung, keine lückenlose Sondereigentumsverwaltung im ganzen Abrechnungsjahr, Umfangswechsel mit ↔ ohne Mietinkasso im Abrechnungsjahr ODER Eigentumslücke (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit, Vertrag oder Abschlusslauf unbekannt, fremder Tenant ODER Objekt nicht zuständig — je dieselbe Antwort (ApiErrorBody, code not_found)"},"409":{"description":"der Abschlusslauf ist storniert, sein Beschluss nicht angenommen/bestandskräftig, er trägt keinen Festschreibungs-Anker ODER sein Stand passt nicht mehr zum Hash — nie Betrag oder Hash in der Antwort (ApiErrorBody, code conflict)"}}}},"/api/einheit/{id}/sev-mieterkosten":{"get":{"summary":"Die SE-Kosten der Wohnung, die für die Mieterabrechnung bereitstehen: genau die umlagefähig gekennzeichneten, bezahlten, nicht stornierten Rechnungen mit Rechnungsdatum im Zeitraum (beide Grenzen inklusiv).","operationId":"listSevMieterKosten","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":true,"description":"Beginn YYYY-MM-DD (inklusiv). Fehlend oder ungültig ⇒ 400.","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":true,"description":"Ende YYYY-MM-DD (inklusiv). Fehlend oder ungültig ⇒ 400.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"umlagefähige SE-Kosten im Zeitraum (SevMieterKostenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMieterKostenResponse"}}}},"400":{"description":"fehlender oder ungültiger Zeitraum (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit unbekannt, fremder Tenant ODER Objekt nicht zuständig (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/beschluss":{"get":{"summary":"Liest die Beschluss-Sammlung eines Objekts (§ 24 Abs. 7 WEG), optional nach Lebenszyklus-Status gefiltert.","operationId":"listObjektBeschluesse","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"description":"kommagetrennte Lebenszyklus-Zustände (angenommen, abgelehnt, angefochten, bestandskraeftig, aufgehoben, nichtig). OHNE Angabe: die VOLLSTÄNDIGE Sammlung — eine stille Vorauswahl gibt es nicht. Ein unbekannter Wert ⇒ 400 (nicht: leere Liste).","schema":{"type":"string"}}],"responses":{"200":{"description":"Beschluss-Sammlung des Objekts (BeschlussListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeschlussListResponse"}}}},"400":{"description":"keine UUID oder unbekannter Status im Filter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"post":{"summary":"Erfasst EINEN Beschluss samt Teil-Gegenständen (auch der WinCASA-Alt-Import läuft hier durch).","operationId":"erfasseObjektBeschluss","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeschlussErfasseRequest"}}}},"responses":{"200":{"description":"erfasster Beschluss samt Teil-Gegenstands-Referenzen (BeschlussErfasseResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeschlussErfasseResponse"}}}},"400":{"description":"ungültige Eingabe, kein Teil-Gegenstand, kein Verkündungszustand als Anfangsstatus ODER laufende Nummer bereits vergeben (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/beschluss/import":{"post":{"summary":"Importiert einen WinCASA-Beschlussbestand (Export der Tabelle VERTHEMEN bzw. VERSAMMLUNG_ERG) in die Sammlung eines Objekts. Multipart-Upload, serverseitig geparst. Teilerfolg ist erlaubt: abgewiesene Zeilen stehen benannt in der Antwort, die übrigen bleiben geschrieben.","operationId":"importiereObjektBeschluesse","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"onr","in":"query","required":true,"description":"Objektnummer des ALTBESTANDS, deren Zeilen übernommen werden. Pflicht und ohne Default: eine Export-Datei kann die Zeilen mehrerer Objekte enthalten, und die laufende Nummer der Sammlung wird je Objekt vergeben (§ 24 Abs. 7 WEG).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"Import-Bericht mit Befunden (BeschlussImportResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeschlussImportResponse"}}}},"400":{"description":"keine UUID, fehlende onr ODER die Datei ist kein Beschluss-Export (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"413":{"description":"Datei zu groß oder Upload zu langsam (ApiErrorBody, code payload_too_large)"}}}},"/api/objekt/{id}/abschluss":{"get":{"summary":"Liest die Abschluss-Läufe eines Objekts. Ein stornierter Lauf verschwindet NICHT aus dem Bestand (GG4/GoBD) — er trägt `storniert: true` und wird vom Nachfolger über `ersetztLaufId` genannt.","operationId":"listObjektAbschlussLaeufe","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"jahr","in":"query","required":false,"description":"Filtert auf EIN Wirtschaftsjahr. Ohne Angabe: alle Jahre — das vermischt nichts, denn jeder Lauf trägt sein Jahr an der Zeile. Ein Jahr ohne Lauf ergibt eine LEERE Liste, keinen Fehler.","schema":{"type":"integer"}}],"responses":{"200":{"description":"die Läufe des Objekts, aktive und stornierte (AbschlussLaufListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbschlussLaufListResponse"}}}},"400":{"description":"keine UUID ODER `jahr` ist keine ganze Zahl (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/abschluss/korrektur":{"post":{"summary":"Führt die Korrektur-Kette einer Kaskaden-Neuberechnung aus: je betroffenem Jahr ein Storno und ein NEUER Lauf mit Referenz auf den stornierten, in EINER Transaktion. Der Idempotenz-Schlüssel kommt vom Aufrufer — zwei Aufrufe am selben Schlüssel ergeben GENAU EINE Kette.","operationId":"fuehreObjektAbschlussKorrekturAus","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbschlussKorrekturRequest"}}}},"responses":{"200":{"description":"die geschriebene Kette; bei `bereits_ausgefuehrt` leer (AbschlussKorrekturResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbschlussKorrekturResponse"}}}},"400":{"description":"ungültige Eingabe ODER eine Gate-Entscheidung nennt ein Jahr, das in dieser Kaskade keinen neuen Lauf bekommt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"das Objekt führt in KEINEM Jahr der Kaskade einen aktiven Lauf — eine Korrektur hätte nichts zu ersetzen (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/buchungsperioden":{"get":{"summary":"Liest Stand und Protokoll der festschreibbaren Buchungsperioden eines Objekts: Schalter (eigener und Mandanten-Vorgabe, aktiv), Wirtschaftsjahr-Beginn, je Festschreibung ob sie gilt oder geöffnet ist (bei Öffnung Grund, wer, wann) und die Journalsätze, die zwischen Öffnung und Neu-Festschreiben mit Datum in der Periode gebucht wurden. Mit format=export kommt dieselbe Antwort als deterministische JSON-Datei (content-disposition attachment, gleiche Daten ergeben gleiche Bytes). Nur Journalsätze: offene Posten und Sollstellungen sind nicht gesperrt.","operationId":"getObjektBuchungsperioden","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["export"]}}],"responses":{"200":{"description":"Stand und Protokoll (BuchungsperiodenResponse); mit format=export als Datei-Download","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuchungsperiodenResponse"}},"application/vnd.casaai.buchungsperioden-export+json":{"schema":{"$ref":"#/components/schemas/BuchungsperiodenResponse"}}}},"400":{"description":"unbekannter Query-Parameter oder format ungleich export (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt, fremder Mandant ODER nicht zuständig (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/buchungsperioden/festschreibung":{"post":{"summary":"Schreibt die nächste Buchungsperiode eines Objekts fest (Wirtschaftsjahr des Objekts, lückenlos) oder schreibt eine geöffnete Periode mit genau ihrem Zeitraum neu fest. Nur ein Mensch; das Objekt kommt aus dem Pfad.","operationId":"festschreibeObjektBuchungsperiode","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuchungsperiodeFestschreibungRequest"}}}},"responses":{"200":{"description":"die geschriebene Festschreibung (BuchungsperiodeFestschreibungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuchungsperiodeFestschreibungResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht — nur ein Mensch (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt, fremder Mandant ODER nicht zuständig (ApiErrorBody, code not_found)"},"409":{"description":"Schalter aus, Lücke, kein Wirtschaftsjahr-Beginn, Wirtschaftsjahr unklar, Periode noch nicht abgelaufen, paralleler Aufruf oder Periode gesperrt; Code in error.code (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/buchungsperioden/oeffnung":{"post":{"summary":"Öffnet eine festgeschriebene Buchungsperiode des Objekts mit Pflichtgrund (auch eine mittlere). Genau eine Öffnungszeile je Festschreibung, unveränderliches Protokoll. Nur ein Mensch; die Festschreibung muss zum Objekt im Pfad gehören.","operationId":"oeffneObjektBuchungsperiode","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuchungsperiodeOeffnungRequest"}}}},"responses":{"200":{"description":"die geschriebene Öffnung (BuchungsperiodeOeffnungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BuchungsperiodeOeffnungResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht — nur ein Mensch (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt oder Festschreibung unbekannt, fremder Mandant ODER nicht zuständig (ApiErrorBody, code not_found)"},"409":{"description":"Periode ist bereits geöffnet; Code in error.code (ApiErrorBody, code conflict)"}}}},"/api/datev/buchungsstapel":{"post":{"summary":"Erzeugt den DATEV-Buchungsstapel (EXTF 700) für ein oder mehrere Objekte und ein Kalenderjahr und legt den Lauf in der Export-Historie ab. Die Antwort trägt die Datei (Windows-1252, Base64) samt sha256 und \"hinweise\" auf nicht festgeschriebene Perioden (Hinweis, kein Abweis). Der Export löst KEINE Festschreibung aus; \"festschreibung\" ist nur das Kennzeichen im Kopfsatz. Ein abweichendes Wirtschaftsjahr geht als zwei Stapel (zwei Aufrufe): exportiert wird der Teil des Kalenderjahres `jahr`, der im Wirtschaftsjahr ab `wirtschaftsjahrBeginn` liegt; berührt das Wirtschaftsjahr das Jahr nicht, ist das ein 400.","operationId":"exportiereDatevBuchungsstapel","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatevBuchungsstapelRequest"}}}},"responses":{"200":{"description":"der Lauf samt Datei (DatevBuchungsstapelResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatevBuchungsstapelResponse"}}}},"400":{"description":"ungültige Eingabe oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt, fremder Mandant ODER nicht zuständig (ApiErrorBody, code not_found)"},"409":{"description":"leerer Umfang, Zeitraum nicht in einem Kalenderjahr (Klartext nennt beide Teilzeiträume), fehlende Kontenzuordnung, Sachkontenlänge, kein eindeutiges Hauptkonto oder Abstimmung gegen das Journal; benannt, nie mit Buchungstext (ApiErrorBody, code conflict)"}}}},"/api/datev/belegpaket":{"post":{"summary":"Erzeugt den DATEV-Buchungsstapel mit Beleglinks UND das zugehörige Belegpaket (ZIP mit document.xml und den unveränderten Original-Belegen) in EINEM Lauf (eine Historien-Zeile). Body wie beim Buchungsstapel. Die Antwort trägt \"stapel\" (Metadaten, laufId, hinweise, datei), \"belegpaket\" (null, wenn keine Buchung einen übertragbaren Beleg hat), \"ohneBeleg\" (Zeilennummer und Grund je Buchung ohne Beleg im Paket; nie Buchungstext oder Name) und \"hinweis\" (Text genau dann, wenn belegpaket null ist). In der Historie liegt nur die Stapel-Datei mit den Beleglinks; das ZIP wird NICHT abgelegt und ist nur in dieser Antwort abrufbar. Ist der Belegspeicher nicht erreichbar, gibt es 503, keinen Teil-Export und keine Historien-Zeile.","operationId":"exportiereDatevBelegpaket","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatevBelegpaketRequest"}}}},"responses":{"200":{"description":"Stapel, Belegpaket und Ohne-Beleg-Liste (DatevBelegpaketResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatevBelegpaketResponse"}}}},"400":{"description":"ungültige Eingabe oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt, fremder Mandant ODER nicht zuständig (ApiErrorBody, code not_found)"},"409":{"description":"leerer Umfang, Zeitraum nicht in einem Kalenderjahr, fehlende Kontenzuordnung, Sachkontenlänge, kein eindeutiges Hauptkonto oder Abstimmung gegen das Journal; benannt, nie mit Buchungstext (ApiErrorBody, code conflict)"},"503":{"description":"Belegspeicher nicht erreichbar; nichts exportiert, keine Historien-Zeile (ApiErrorBody, code unavailable)"}}}},"/api/datev/historie":{"get":{"summary":"Listet die früheren DATEV-Buchungsstapel-Läufe, die für die angemeldete Person sichtbar sind, jüngster zuerst: Lauf-Id, Zeitraum, Objekte, Dateiname, sha256, Zeilenzahl, Summe, Zeitpunkt und erzeugende Person; nie Buchungstexte und keine Datei-Bytes. Ein Lauf über mehrere Objekte steht in der Liste jedes seiner Objekte (nur als Kennzahlen); seine Datei liefert der Download nur, wenn die Person für ALLE Objekte des Laufs zuständig ist. Die Historie hält nur die Stapel-Datei; ein Belegpaket (ZIP) und die DebKred-Datei sind nicht darin. Seitenweise: \"weiter\" der Antwort ist der Cursor für die nächste Seite. Mandant und Zuständigkeit stammen aus der Session.","operationId":"listeDatevHistorie","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":false,"description":"Nur Läufe, die dieses Objekt berühren; wiederholbar (Läufe, die mindestens eines berühren). Ein Objekt außerhalb der eigenen Zuständigkeit liefert nichts.","schema":{"type":"array","items":{"type":"string","format":"uuid"}}},{"name":"limit","in":"query","required":false,"description":"Seitengröße, 1 bis 200 (Vorgabe 200)","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"weiter","in":"query","required":false,"description":"Cursor \"weiter\" der vorigen Seite","schema":{"type":"string"}}],"responses":{"200":{"description":"Eine Seite der Historie (DatevHistorieListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatevHistorieListResponse"}}}},"400":{"description":"ungültiges objekt, limit oder weiter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/datev/historie/{laufId}/datei":{"get":{"summary":"Liefert die abgelegte Stapel-Datei eines früheren Laufs erneut, byte-gleich zum ursprünglichen Export (gleiche sha256), ohne neuen Buchungslauf, ohne Kommando-Log-Eintrag und ohne neue Historien-Zeile. Nur die Stapel-Datei: ein Belegpaket (ZIP) und die DebKred-Datei liegen nicht in der Historie. Unbekannte, fremde oder nicht vollständig zuständige Lauf-Id ⇒ 404. Stimmen die abgelegten Bytes nicht mehr zu ihrem sha256, gibt es 500 und kein Byte.","operationId":"ladeDatevHistorieDatei","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Lauf-Id und Datei (DatevHistorieDateiResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatevHistorieDateiResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Lauf unbekannt, fremder Mandant oder die Person ist nicht für alle Objekte des Laufs zuständig (ApiErrorBody, code not_found)"},"500":{"description":"abgelegte Datei passt nicht mehr zu ihrem sha256; nichts ausgeliefert (ApiErrorBody, code internal)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/datev/debkred":{"post":{"summary":"Erzeugt die DATEV-Stammdatendatei Debitoren/Kreditoren (EXTF, Personenkonten mit Name, Anschrift und bestätigter IBAN) zu einem Buchungsstapel für ein oder mehrere Objekte und ein Kalenderjahr. Die Antwort trägt die Datei (Windows-1252, Base64) samt sha256 und Zahlen. \"umfang\" ist Pflicht (buchungsstapel oder alle-aktiven). Die Datei enthält Namen und Anschriften: sie steht NICHT in der Export-Historie und ist nicht erneut abrufbar (siehe \"hinweise\"); der Beleg im Kommando-Log trägt nur sha256 und Zahlen.","operationId":"exportiereDatevDebKred","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatevDebKredRequest"}}}},"responses":{"200":{"description":"die Datei samt Zahlen (DatevDebKredResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatevDebKredResponse"}}}},"400":{"description":"ungültige Eingabe, fehlender umfang oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt, fremder Mandant ODER nicht zuständig (ApiErrorBody, code not_found)"},"409":{"description":"leerer Umfang, Zeitraum, fehlende Kontenzuordnung, Sachkontenlänge, Personenkonto ohne Geschäftspartner oder bereits verwendeter Idempotency-Key, dessen Datei sich nicht bytegleich herstellen lässt (anderer Body oder geänderte Stammdaten seit dem Erstlauf; bei gleichem Body und unveränderten Stammdaten antwortet der Retry mit 200 und derselben Datei; neuen Key verwenden); benannt, nie mit Name oder Anschrift, ohne Datei (ApiErrorBody, code conflict)"}}}},"/api/einstellungen/festschreibung":{"post":{"summary":"Schaltet die Festschreibung der Buchungsperioden für ein Objekt (propertyId) oder als Mandanten-Vorgabe (propertyId null) ein oder aus. Ausschalten lässt bestehende Festschreibungen unberührt. Nur ein Mensch mit Admin-Recht.","operationId":"setzeFestschreibungSchalter","security":[{"bearerAuth":[]}],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FestschreibungSchalterRequest"}}}},"responses":{"200":{"description":"der jetzt gespeicherte Wert (FestschreibungSchalterResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FestschreibungSchalterResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht — nur ein Mensch (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt, fremder Mandant ODER nicht zuständig (ApiErrorBody, code not_found)"}}}},"/api/abschluss/{id}/freeze":{"get":{"summary":"Fragt, ob an einer Abrechnung noch geschrieben werden darf (Muster F7). Ein bestandskräftiger Lauf plus `vorhaben=neuberechnung` endet mit 409 und nennt den Korrekturweg — ein stilles „nichts passiert\" sähe für den Bediener wie Erfolg aus.","operationId":"getAbschlussFreeze","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"vorhaben","in":"query","required":true,"description":"Was mit der Abrechnung geschehen soll. GESCHLOSSENES Vokabular mit ZWEI Wörtern; ein Inline-Edit ist hier nicht abgelehnt, sondern nicht formulierbar. Ein unbekanntes Wort fällt NIE still auf einen Zweig zurück.","schema":{"type":"string","enum":["storno","neuberechnung"]}},{"name":"snapshotHash","in":"query","required":false,"description":"Der Hash, den der Aufrufer am AKTUELLEN Stand gebildet hat (`bildeAbschlussSnapshotHash`, 64 Hex-Zeichen klein). Nur MIT ihm fährt die Route die zweite Hälfte von F7 und meldet eine Abweichung mit 409; ohne ihn steht `snapshotGeprueft: false` in der Antwort. Die Route bildet ihn NICHT selbst — der Stand entsteht im Rechenwerk (S12-T11), und ein hier nachgebauter Hash wäre die zweite Wahrheit über denselben Stand.","schema":{"type":"string"}}],"responses":{"200":{"description":"die Freeze-Auskunft samt Korrekturweg (AbschlussFreezeResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbschlussFreezeResponse"}}}},"400":{"description":"keine UUID, fehlendes/unbekanntes `vorhaben` ODER ein `snapshotHash` in falscher Form (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Lauf unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"die Abrechnung ist festgeschrieben und das Vorhaben ist `neuberechnung`, ODER der mitgegebene Stand passt nicht mehr zum festgeschriebenen (ApiErrorBody, code conflict)"}}}},"/api/abschluss/{id}/storno":{"post":{"summary":"Storniert EINEN Abschluss-Lauf — der einzige Weg, an einer festgeschriebenen Abrechnung überhaupt etwas zu bewegen. Der Lauf bleibt danach vollständig lesbar (GG4/GoBD).","operationId":"storniereAbschlussLauf","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbschlussStornoRequest"}}}},"responses":{"200":{"description":"der stornierte Lauf samt Stichtag (AbschlussStornoResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbschlussStornoResponse"}}}},"400":{"description":"ungültige Eingabe, fehlender Grund ODER fehlender/unförmiger Stichtag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Lauf unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"der Lauf ist bereits storniert (ApiErrorBody, code conflict). Fail-loud statt No-op: ein zweites Storno überschriebe Grund und Tag des ersten."}}}},"/api/objekt/{id}/hausgeld":{"get":{"summary":"Liest die gestellten Hausgeld-Sollstellungen eines Objekts für EIN Wirtschaftsjahr (§ 28 Abs. 1 WEG). Vorschuss und quittierte Differenz stehen NEBENEINANDER — die Differenz ersetzt den Vorschuss nicht.","operationId":"listObjektHausgeldSoll","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"jahr","in":"query","required":true,"description":"Das WIRTSCHAFTSJAHR — bei einem Rumpfjahr nicht das Kalenderjahr der Fälligkeit. Pflicht und ohne Default: eine Liste über ALLE Jahre vermischte zwei Wirtschaftspläne, und genau diese Achse trennt sie. Ein Jahr ohne Soll ergibt eine LEERE Liste, keinen Fehler.","schema":{"type":"integer"}}],"responses":{"200":{"description":"die gestellten Soll-Zeilen des Objekts im gefragten Wirtschaftsjahr (HausgeldSollListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HausgeldSollListResponse"}}}},"400":{"description":"keine UUID ODER `jahr` fehlt/ist keine ganze Zahl (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/hausgeld/soll":{"post":{"summary":"Stellt das Hausgeld eines Objekts für ein Wirtschaftsjahr fällig — je Einheit und Monat eine Sollstellung. Rückwirkende Differenzen liefert der Lauf als VORSCHLAG und bucht sie NICHT (Owner-Leitplanke 2026-08-20).","operationId":"stelleObjektHausgeldSoll","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HausgeldSollRequest"}}}},"responses":{"200":{"description":"der Lauf samt gestellten Positionen und ungebuchten Differenz-Vorschlägen (HausgeldSollResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HausgeldSollResponse"}}}},"400":{"description":"ungültige Eingabe, unbekannter/fehlender Geldkreis ODER ein Buchungs-Gate der Freigabe hat abgelehnt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"der Geldkreis dieses Laufs ist nicht weg_hausgeld, ODER derselbe Lauf/Monat ist bereits gestellt (ApiErrorBody, code conflict). Ein Miet-Soll läuft über den Sollstellungslauf, nicht hierüber."}}}},"/api/objekt/{id}/hausgeld/differenz":{"post":{"summary":"Quittiert rückwirkende Differenz-Vorschläge eines Soll-Laufs — der GEFÜHRTE Schritt. Schuldner und Plan-Version werden vom VORSCHLAG übernommen und nicht neu abgeleitet.","operationId":"quittiereObjektHausgeldDifferenz","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HausgeldDifferenzRequest"}}}},"responses":{"200":{"description":"die gebuchten Differenz-Positionen (HausgeldDifferenzResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HausgeldDifferenzResponse"}}}},"400":{"description":"ungültige Eingabe, leerer Stapel ODER fehlendes quittiertVon/quittiertAm (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"derselbe Vorschlag ist bereits quittiert (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/hausgeld/zahlung":{"get":{"summary":"Verteilt eine Zahlung auf die Hausgeld- und die Rücklagen-Seite EINER gestellten Sollstellung (S12-T05-Policy, Präzedenz Objekt > Tenant > Default). SCHREIBT NICHTS: die Soll-Zeile ist danach zeichengleich.","operationId":"ordneObjektHausgeldZahlungZu","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"jahr","in":"query","required":true,"description":"Die WIRTSCHAFTSJAHR-Achse des Lauf-Scopes. Ausdrücklich KEIN Filter: die sollstellungId ist innerhalb von (Mandant, Objekt) bereits eindeutig, und beide Achsen sind Prädikat der Abfrage. Die gelieferte Position trägt ihre Herkunft (Monat, Plan-Version, Rechtsgrundlage) selbst.","schema":{"type":"integer"}},{"name":"sollstellungId","in":"query","required":true,"description":"Die Zeile aus `hausgeld_sollstellungen`, gegen die verteilt wird. Die Forderung wird GELESEN, nie vom Aufrufer behauptet.","schema":{"type":"string","format":"uuid"}},{"name":"cents","in":"query","required":true,"description":"Der eingegangene Betrag in ganzen Cents als ZIFFERN-STRING (INV-MONEY-01, nie ein Float). Negativ ist fail-loud.","schema":{"type":"string"}}],"responses":{"200":{"description":"die Aufteilung samt angewandter Regel und der UNVERÄNDERTEN Soll-Position (HausgeldZahlungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HausgeldZahlungResponse"}}}},"400":{"description":"keine UUID, fehlender/ungültiger Betrag ODER eine gesetzte, unbekannte Zuordnungs-Einstellung (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt/Sollstellung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/ruecklagen":{"get":{"summary":"Liest den Katalog der Rücklagen eines Objekts (älteste zuerst) mit Ist-Bestand zum Stichtag und dem Kennzeichen `aufgeloest`. Aufgelöste Rücklagen bleiben im Katalog.","operationId":"listObjektRuecklagen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"description":"Stichtag (INKLUSIV, YYYY-MM-DD) für den Ist-Bestand. Ohne Angabe ist `istBestand` null — der Server liest keine Uhr.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"der Katalog des Objekts (RuecklagenKatalogResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenKatalogResponse"}}}},"400":{"description":"keine UUID ODER `stichtag` ist kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found) — beide Fälle identisch"}}},"post":{"summary":"Legt eine Rücklage des Objekts samt Kontenpaar an (passives Rücklagenkonto, aktives Bestandskonto). Die Erhaltungsrücklage gibt es je Objekt genau einmal (§ 19 Abs. 2 Nr. 4 WEG). Der Idempotenz-Schlüssel kommt vom Aufrufer (Header). Ein Änderungs- oder Löschweg existiert bewusst nicht.","operationId":"legeObjektRuecklageAn","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklageAnlegenRequest"}}}},"responses":{"200":{"description":"die angelegte Rücklage samt Kontenpaar; bei Wiederholung mit demselben Idempotenz-Schlüssel `ausgang` bereits_ausgefuehrt (RuecklageAnlegenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklageAnlegenResponse"}}}},"400":{"description":"keine UUID, ungültige Eingabe (z. B. Zweckbindung fehlt bei `zweckgebunden`) oder Untergruppe/Konto gehört nicht zum Objekt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"das Objekt führt bereits eine Erhaltungsrücklage, ist kein WEG-Objekt oder ein Konto ist schon einer Rücklage zugeordnet (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/ruecklagen/soll-ist":{"get":{"summary":"Liest Soll, Ist und Rückstand der Rücklagen eines Objekts zum Stichtag. Ohne `ruecklageId` alle Rücklagen des Objekts, nach Rücklagen-Id sortiert.","operationId":"listObjektRuecklagenSollIst","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":true,"description":"Stichtag (INKLUSIV, YYYY-MM-DD). Pflicht und ohne Default: der Server liest keine Uhr.","schema":{"type":"string","format":"date"}},{"name":"ruecklageId","in":"query","required":false,"description":"Nur diese Rücklage. Gehört sie nicht zum Objekt (oder ist unbekannt), ist das ein 404 not_found.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Soll/Ist je Rücklage (RuecklagenSollIstResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenSollIstResponse"}}}},"400":{"description":"keine UUID ODER `stichtag` fehlt/ist kein Kalendertag ODER `ruecklageId` ist keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant ODER `ruecklageId` unbekannt/fremd (ApiErrorBody, code not_found) — alle Fälle identisch"}}}},"/api/objekt/{id}/ruecklagen/abstimmung":{"get":{"summary":"Stimmt das aktive Bestandskonto gegen das passive Rücklagenkonto je Rücklage und gesamt zum Stichtag ab (Befunde: fehlende Umbuchung Giro → Festgeld, Konto ohne Gegenstück).","operationId":"getObjektRuecklagenAbstimmung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":true,"description":"Stichtag (INKLUSIV, YYYY-MM-DD). Pflicht und ohne Default: der Server liest keine Uhr.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"die Abstimmung des Objekts (RuecklagenAbstimmungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenAbstimmungResponse"}}}},"400":{"description":"keine UUID ODER `stichtag` fehlt/ist kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"Konto mehreren Rücklagen zugeordnet, Fremdwährung im Konto oder Beschluss ohne lesbaren Status (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/ruecklagen/wiedervorlagen":{"get":{"summary":"Liest die offenen Zwischenfinanzierungen eines Objekts (noch nicht zurückgeführt) mit Fälligkeit, Betrag und Beschluss-Referenz, nach Fälligkeit geordnet. `ueberfaellig` ist eine Auskunft, keine Sperre.","operationId":"listObjektRuecklagenWiedervorlagen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"bis","in":"query","required":true,"description":"Bezugstag (YYYY-MM-DD): überfällig ist, was VOR diesem Tag fällig war. Pflicht und ohne Default: der Server liest keine Uhr.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"die offenen Wiedervorlagen (RuecklagenWiedervorlagenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenWiedervorlagenResponse"}}}},"400":{"description":"keine UUID ODER `bis` fehlt/ist kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found) — beide Fälle identisch"}}}},"/api/objekt/{id}/ruecklagen/soll":{"post":{"summary":"Legt eine Soll-Zuführung einer Rücklage fest und bindet sie an einen Beschluss-Teilgegenstand. Betrag in Cent als Ziffern-String (> 0). Eine aufgelöste Rücklage nimmt kein Soll mehr an.","operationId":"legeObjektRuecklagenSollFest","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenSollRequest"}}}},"responses":{"200":{"description":"die festgelegte Soll-Zuführung; bei Wiederholung mit demselben Idempotenz-Schlüssel `ausgang` bereits_ausgefuehrt (RuecklagenSollResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenSollResponse"}}}},"400":{"description":"keine UUID, ungültige Eingabe oder eine Referenz (Beschluss, Konto) ist am Objekt nicht verwendbar (ApiErrorBody, code invalid_request) — auch: Beschluss-Referenz fehlt oder Betrag nicht positiv"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Rücklage unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"die Rücklage ist aufgelöst (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/ruecklagen/buchung":{"post":{"summary":"Bucht eine Bewegung auf dem passiven Rücklagenkonto: Betrag > 0 ist eine Zuführung, Betrag < 0 eine Entnahme (`betragCents` \"-5000\" = Entnahme von 50,00 €). Eine Entnahme braucht `zweck`, bauliche_veraenderung und modernisierung zusätzlich `umwidmungsBeschlussRef`. Dieselbe Zuführungs-Periode wird nur EINMAL gebucht: die zweite Antwort trägt `ausgang` bereits_gebucht und erzeugt keinen zweiten Journalsatz. Korrektur = Gegenbewegung mit `korrigiertBewegungId`.","operationId":"bucheObjektRuecklagenBewegung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenBuchungRequest"}}}},"responses":{"200":{"description":"die Bewegung, `ausgang` gebucht oder bereits_gebucht (gleiche Periode oder wiederholter Idempotenz-Schlüssel) (RuecklagenBuchungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenBuchungResponse"}}}},"400":{"description":"keine UUID, ungültige Eingabe oder eine Referenz (Beschluss, Konto) ist am Objekt nicht verwendbar (ApiErrorBody, code invalid_request) — auch: Betrag 0, Zweck fehlt oder unbekannt, Feld passt nicht zur Richtung, Buchungsdatum ungültig oder in der Zukunft"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Rücklage unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"Zustandskonflikt (ApiErrorBody, code conflict): die Rücklage ist aufgelöst, die Entnahme übersteigt den Bestand, der Zweck verlangt einen Umwidmungsbeschluss, das Bestandskonto lautet nicht auf die GdWE oder die Korrektur ist unzulässig"}}}},"/api/objekt/{id}/ruecklagen/zins":{"post":{"summary":"Erfasst einen Zinsertrag einer Rücklage: brutto wird in Kapitalertragsteuer (25 %), Solidaritätszuschlag (5,5 % auf die Steuer) und netto aufgeteilt und gebucht. Ein negativer Zins (Verwahrentgelt) hat hier keinen Weg. Derselbe Aufruf (Idempotenz-Schlüssel) ergibt `ausgang` bereits_gebucht ohne zweite Bewegung.","operationId":"erfasseObjektRuecklagenZins","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenZinsRequest"}}}},"responses":{"200":{"description":"der Zinsertrag, `ausgang` gebucht oder bereits_gebucht (RuecklagenZinsResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenZinsResponse"}}}},"400":{"description":"keine UUID, ungültige Eingabe oder eine Referenz (Beschluss, Konto) ist am Objekt nicht verwendbar (ApiErrorBody, code invalid_request) — auch: Bruttozins nicht positiv"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Rücklage unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"Zustandskonflikt (ApiErrorBody, code conflict): die Rücklage ist aufgelöst, am Zins-Konto hängt ein Verteilerschlüssel, die Summenprobe schlägt fehl oder der Replay weicht vom gespeicherten Satz ab"}}}},"/api/objekt/{id}/ruecklagen/zwischenfinanzierung":{"post":{"summary":"Entnimmt der Rücklage kurzfristig Liquidität gegen Beschluss (Zwischenfinanzierung) und legt eine Wiedervorlage an. `beschlussRef` ist Pflicht; die Frist kommt aus der Policy (Objekt vor Mandant vor 3 Monaten) und ist mit `fristMonate` überschreibbar.","operationId":"entnimmObjektRuecklageZwischenfinanzierung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenZwischenfinanzierungRequest"}}}},"responses":{"200":{"description":"die Zwischenfinanzierung mit Fälligkeit; bei Wiederholung mit demselben Idempotenz-Schlüssel `ausgang` bereits_ausgefuehrt (RuecklagenZwischenfinanzierungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenZwischenfinanzierungResponse"}}}},"400":{"description":"keine UUID, ungültige Eingabe oder eine Referenz (Beschluss, Konto) ist am Objekt nicht verwendbar (ApiErrorBody, code invalid_request) — auch: Beschluss-Referenz fehlt oder Frist ungültig"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Rücklage unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"Zustandskonflikt (ApiErrorBody, code conflict): die Rücklage ist aufgelöst, der Bestand oder die Deckung des Beschlusses reicht nicht, oder der Beschluss trägt die Entnahme nicht"}}}},"/api/objekt/{id}/ruecklagen/rueckfuehrung":{"post":{"summary":"Führt eine Zwischenfinanzierung in voller Höhe in die Rücklage zurück. Je Zwischenfinanzierung gibt es genau eine Rückführung.","operationId":"rueckfuehreObjektRuecklageZwischenfinanzierung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenRueckfuehrungRequest"}}}},"responses":{"200":{"description":"die Rückführung; bei Wiederholung mit demselben Idempotenz-Schlüssel `ausgang` bereits_ausgefuehrt (RuecklagenRueckfuehrungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenRueckfuehrungResponse"}}}},"400":{"description":"keine UUID, ungültige Eingabe oder eine Referenz (Beschluss, Konto) ist am Objekt nicht verwendbar (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt, Rücklage oder Zwischenfinanzierung unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — alle Fälle identisch"},"409":{"description":"die Zwischenfinanzierung ist bereits zurückgeführt oder die Rücklage ist aufgelöst (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/ruecklagen/aufloesung":{"post":{"summary":"Löst eine Rücklage auf — nur gegen Aufhebungsbeschluss und nur bei Saldo 0,00 €. Das Konto bleibt, die Rücklage bleibt im Katalog lesbar (`aufgeloest` true); danach wird nichts mehr auf sie gebucht.","operationId":"loeseObjektRuecklageAuf","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenAufloesungRequest"}}}},"responses":{"200":{"description":"die Auflösung; bei Wiederholung mit demselben Idempotenz-Schlüssel `ausgang` bereits_ausgefuehrt (RuecklagenAufloesungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuecklagenAufloesungResponse"}}}},"400":{"description":"keine UUID, ungültige Eingabe oder eine Referenz (Beschluss, Konto) ist am Objekt nicht verwendbar (ApiErrorBody, code invalid_request) — auch: Aufhebungsbeschluss fehlt"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Rücklage unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"Zustandskonflikt (ApiErrorBody, code conflict): der Saldo ist nicht 0,00 € (erst zurückführen oder entnehmen) oder die Rücklage ist bereits aufgelöst"}}}},"/api/objekt/{id}/sonderumlage":{"get":{"summary":"Listet die Sonderumlagen eines Objekts, aufsteigend nach Fälligkeit, mit Zweck, Gesamtbetrag, Zahlweise, Raten-Fälligkeiten, Kennzeichen `gestellt` und der Tatsache `schluesselAbweichung`. Ein Objekt ohne Sonderumlagen ist eine leere Liste.","operationId":"listeObjektSonderumlagen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"die Sonderumlagen des Objekts (SonderumlageListeResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SonderumlageListeResponse"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"}}},"post":{"summary":"Legt eine Sonderumlage mit Beschluss-Teilgegenstand, Zweck, Fälligkeit, Zahlweise (Einmalzahlung oder Ratenplan) und Gesamtbetrag in Cent als Ziffern-String an; das Sonderkonto entsteht mit. Der Idempotenz-Schlüssel kommt vom Aufrufer (Header). Ein Änderungs- oder Löschweg existiert bewusst nicht: eine Korrektur ist ein Zweitbeschluss mit eigener Sonderumlage.","operationId":"legeObjektSonderumlageAn","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SonderumlageAnlegenRequest"}}}},"responses":{"200":{"description":"die angelegte Sonderumlage mit Sonderkonto, Raten und Warnungen; bei Wiederholung mit demselben Idempotenz-Schlüssel `ausgang` bereits_ausgefuehrt (SonderumlageAnlegenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SonderumlageAnlegenResponse"}}}},"400":{"description":"keine UUID oder ungültige Eingabe (ApiErrorBody, code invalid_request) — auch: Beschluss-Referenz fehlt oder gehört zu keinem Beschluss des Objekts, Zweck oder Fälligkeit fehlt, Betrag nicht positiv, Ratenplan widersprüchlich"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"am Beschluss-Teilgegenstand hängt schon eine Sonderumlage, oder der Schlüsselabgleich ist auf blockierend gestellt (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/sonderumlage/soll":{"get":{"summary":"Liest das gestellte Soll EINER Sonderumlage je Einheit und Rate mit Schuldnern (Eigentümer am Fälligkeitstag, Innenverhältnis in Zehntausendsteln). Pflicht: Query `sonderumlageId`. Solange nicht sollgestellt, ist `einheiten` leer.","operationId":"leseObjektSonderumlageSoll","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"sonderumlageId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"das Soll der Sonderumlage (SonderumlageSollResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SonderumlageSollResponse"}}}},"400":{"description":"keine UUID oder `sonderumlageId` fehlt bzw. ist keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Sonderumlage unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — alle Fälle identisch"}}},"post":{"summary":"Stellt eine Sonderumlage Soll: Verteilung nach Miteigentumsanteil auf die Einheiten, Teilung in Raten, Schuldner je Rate ist der Eigentümer am Fälligkeitstag. Append-only: ein zweiter Aufruf stellt nichts neu und antwortet mit `ausgang` bereits_ausgefuehrt (Erfolg). Der Idempotenz-Schlüssel kommt vom Aufrufer (Header).","operationId":"stelleObjektSonderumlageSoll","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SonderumlageSollStellenRequest"}}}},"responses":{"200":{"description":"das gestellte Soll je Einheit; `ausgang` ausgefuehrt, oder bereits_ausgefuehrt, wenn das Soll schon stand (SonderumlageSollStellenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SonderumlageSollStellenResponse"}}}},"400":{"description":"keine UUID oder ungültige Eingabe (ApiErrorBody, code invalid_request) — auch: Beschluss-Referenz des abweichenden Schlüssels gehört zu keinem Beschluss des Objekts"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Sonderumlage unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — alle Fälle identisch"},"409":{"description":"Zustandskonflikt (ApiErrorBody, code conflict): Pflichtinhalt des Beschlusses fehlt (Zweck, Fälligkeit oder Ratenplan), der Miteigentumsanteil fehlt an einer Einheit, eine Einheit hat am Fälligkeitstag keinen Eigentümer (Eigentümerlücke), der Lauf-Typ ist nicht verdrahtet oder der Schlüsselabgleich ist blockierend"}}}},"/api/objekt/{id}/eigentum":{"get":{"summary":"Liest das Eigentum eines Objekts zum Stichtag, gruppiert je Einheit, mit Anteilssumme und Befund `anteilssumme_ungleich_10000`. Pflicht: Query `stichtag` (YYYY-MM-DD, keine Server-Uhr). Optional `einheit` (nur diese Einheit) und `historie` (1/true: auch abgelaufene und künftige Zeilen; `istGegenwart` markiert die am Stichtag wirksamen). Die Zustellanschrift steht nie in der Antwort, nur das Kennzeichen `hatZustellanweisung`.","operationId":"listObjektEigentum","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":true,"schema":{"type":"string","format":"date"}},{"name":"einheit","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"historie","in":"query","required":false,"schema":{"type":"string","enum":["0","1","true","false"]}}],"responses":{"200":{"description":"das Eigentum je Einheit (EigentumListeResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EigentumListeResponse"}}}},"400":{"description":"keine UUID, `stichtag` fehlt oder ist kein Kalendertag, `einheit` keine UUID, `historie` unbekannt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Einheit unbekannt, fremder Mandant ODER Einheit gehört nicht zum Objekt (ApiErrorBody, code not_found) — alle Fälle identisch"}}}},"/api/einheit/{id}/eigentum":{"post":{"summary":"Erfasst eine Eigentumszeile (Person, Anteil in Zehntausendsteln als Integer-String, Beginn, optional Ende, Zustellanschrift, Vollmacht, Umsatzsteuer-Option) an der Einheit. Die Einheit steht im Pfad. Der Idempotenz-Schlüssel kommt vom Aufrufer (Header). Ein Löschweg existiert bewusst nicht: Eigentum wird beendet.","operationId":"erfasseEinheitEigentum","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EigentumErfassenRequest"}}}},"responses":{"200":{"description":"die erfasste Eigentumszeile samt Befunden zur Anteilssumme, ohne Zustellanschrift (EigentumErfassenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EigentumErfassenResponse"}}}},"400":{"description":"keine UUID oder ungültige Eingabe (ApiErrorBody, code invalid_request) — auch: Ende nicht nach Beginn, Anteil kein positiver Integer-String"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit oder Person unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"Zustandskonflikt (ApiErrorBody, code conflict): dieselbe Person hält die Einheit schon im überlappenden Zeitraum (Überlappung), das Objekt trägt kein Eigentum (Miet-Objekt), die Person oder Einheit ist archiviert"}}}},"/api/eigentum/{id}/beenden":{"post":{"summary":"Beendet eine Eigentumszeile; die Pfad-Id ist die `ownershipId`. `endeExklusiv` ist der erste Tag OHNE Eigentum („zum 30.06.\" ⇒ 2025-07-01). Beenden kürzt nur das Fenster; dasselbe Ende ein zweites Mal ist ein Erfolg ohne Änderung (`beendet` false). Der Idempotenz-Schlüssel kommt vom Aufrufer (Header).","operationId":"beendeEigentum","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EigentumBeendenRequest"}}}},"responses":{"200":{"description":"das beendete Eigentum (EigentumBeendenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EigentumBeendenResponse"}}}},"400":{"description":"keine UUID, ungültiges Datum, Ende nicht nach Beginn oder Vollmacht beginnt nicht vor dem Ende (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Eigentumszeile unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"},"409":{"description":"die Zeile endet bereits zu einem ANDEREN Tag (ApiErrorBody, code conflict)"}}}},"/api/einheit/{id}/eigentuemerwechsel":{"get":{"summary":"Listet die Eigentümerwechsel-Vorgänge einer Einheit, aufsteigend nach Grundbuch-Stichtag, mit den beteiligten abgehenden und neuen Eigentumszeilen. Eine Einheit ohne Wechsel ist eine leere Liste.","operationId":"listEinheitEigentuemerwechsel","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"die Wechsel-Vorgänge der Einheit (EigentuemerwechselListeResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EigentuemerwechselListeResponse"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit unbekannt ODER fremder Mandant (ApiErrorBody, code not_found) — beide Fälle identisch"}}},"post":{"summary":"Erfasst einen Eigentümerwechsel als EINEN Vorgang: die abgehenden Eigentumszeilen enden am Grundbuch-Stichtag, die neuen beginnen an ihm; optional mit Verwalterzustimmung. Der Stichtag ist die Eintragung im Grundbuch, Abteilung I — nicht der Notartermin. Laufende SEV-Mandate abgehender Eigentümer werden nicht beendet, sondern in `sevMandateOffen` genannt. Der Idempotenz-Schlüssel kommt vom Aufrufer (Header).","operationId":"erfasseEinheitEigentuemerwechsel","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EigentuemerwechselErfassenRequest"}}}},"responses":{"200":{"description":"der erfasste Wechsel mit beendeten und neuen Zeilen sowie offenen SEV-Mandaten, ohne Zustellanschrift (EigentuemerwechselErfassenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EigentuemerwechselErfassenResponse"}}}},"400":{"description":"keine UUID oder ungültige Eingabe (ApiErrorBody, code invalid_request) — auch: abgehende Zeile doppelt, Anteil kein positiver Integer-String"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit, Person oder abgehende Eigentumszeile unbekannt, fremder Mandant ODER Zeile gehört nicht zur Einheit (ApiErrorBody, code not_found) — alle Fälle identisch"},"409":{"description":"Zustandskonflikt (ApiErrorBody, code conflict): Anteilssumme der neuen Eigentümer weicht von der der abgehenden ab, der Stichtag liegt in einem bereits festgeschriebenen Abrechnungsjahr (Korrektur des Abschlusses), Überlappung, eine abgehende Zeile ist bereits beendet oder schon durch einen Wechsel beendet, das Objekt trägt kein Eigentum"}}}},"/api/objekt/{id}/wirtschaftsplan":{"get":{"summary":"Listet die Versionen der Wirtschaftspläne eines Objekts (optional eines Wirtschaftsjahres). Ein Jahr ohne Plan ergibt eine LEERE Liste, keinen Fehler.","operationId":"listObjektWirtschaftsplanVersionen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"jahr","in":"query","required":false,"description":"Nur dieses WIRTSCHAFTSJAHR.","schema":{"type":"integer"}}],"responses":{"200":{"description":"die Versionen, Jahr und Version aufsteigend (WirtschaftsplanVersionenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanVersionenResponse"}}}},"400":{"description":"keine UUID ODER `jahr` ist keine ganze Zahl (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"post":{"summary":"Legt den Wirtschaftsplan eines Objekts für ein Wirtschaftsjahr als Version 1 an (lege_wirtschaftsplan_an). Geld ist ein Objekt {cents, currency}. Die Objekt-Id kommt ausschliesslich aus dem Pfad.","operationId":"legeObjektWirtschaftsplanAn","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanAnlegenRequest"}}}},"responses":{"200":{"description":"die angelegte Version 1 im Status entwurf (WirtschaftsplanVersionResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanVersionResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld oder unzulässiges Wirtschaftsjahr (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"für Objekt und Jahr gibt es schon einen Plan — Änderungen laufen über den Entwurf als neue Version (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/wirtschaftsplan/stand":{"get":{"summary":"Liest EINE Version eines Wirtschaftsplans. Mit `vergleichMit` liefert die Antwort zusätzlich den Diff von dieser Version zur genannten; mit `berechnung=true` Gesamtplan, Einzelpläne mit Monatsbeträgen und Befunde, serverseitig aus Positionen und Stammdaten gerechnet.","operationId":"getObjektWirtschaftsplanStand","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"jahr","in":"query","required":true,"description":"Das WIRTSCHAFTSJAHR.","schema":{"type":"integer"}},{"name":"version","in":"query","required":true,"description":"Die Version.","schema":{"type":"integer"}},{"name":"vergleichMit","in":"query","required":false,"description":"Eine andere Version desselben Jahres; liefert den Diff.","schema":{"type":"integer"}},{"name":"berechnung","in":"query","required":false,"description":"`true` liefert die Berechnung.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"der Stand (WirtschaftsplanStandResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanStandResponse"}}}},"400":{"description":"keine UUID ODER `jahr`/`version`/`vergleichMit` fehlt oder ist keine ganze Zahl, `berechnung` weder true noch false (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Version unbekannt ODER fremder Tenant — dieselbe Meldung (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/wirtschaftsplan/entwurf":{"post":{"summary":"Bearbeitet den Entwurf: legt eine NEUE Version mit der vollständigen Positionsliste an (bearbeite_wirtschaftsplan_entwurf); die alte Version bleibt unverändert.","operationId":"bearbeiteObjektWirtschaftsplanEntwurf","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanEntwurfRequest"}}}},"responses":{"200":{"description":"die neue Version im Status entwurf (WirtschaftsplanVersionResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanVersionResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld oder unzulässiges Wirtschaftsjahr (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant ODER für das Jahr gibt es noch keinen Plan (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/wirtschaftsplan/verwerfen":{"post":{"summary":"Verwirft eine Version im Status entwurf (verwirf_wirtschaftsplan); ihre Positionen bleiben lesbar. Ein beschlossener oder bereits verworfener Plan bleibt unverändert.","operationId":"verwirfObjektWirtschaftsplan","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanVerwerfenRequest"}}}},"responses":{"200":{"description":"die verworfene Version (WirtschaftsplanVerwerfenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanVerwerfenResponse"}}}},"400":{"description":"ungültige Eingabe oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Version unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"die Version ist kein Entwurf mehr (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/wirtschaftsplan/beschluss":{"post":{"summary":"Beschließt eine Version im Status entwurf (beschliesse_wirtschaftsplan): prüft das Beschluss-Gate, bindet den Plan append-only an den tragenden Teil-Gegenstand und setzt ihn auf beschlossen. Ohne tragenden Beschluss bleibt der Plan Entwurf. Dieselbe Referenz noch einmal ist ein No-op (bereits_beschlossen). Die Objekt-Id kommt ausschliesslich aus dem Pfad.","operationId":"beschliesseObjektWirtschaftsplan","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanBeschliessenRequest"}}}},"responses":{"200":{"description":"der beschlossene Plan mit seiner Bindung (WirtschaftsplanBeschliessenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanBeschliessenResponse"}}}},"400":{"description":"ungültige Eingabe oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Plan unbekannt ODER fremder Tenant ODER Beschluss unbekannt (ApiErrorBody, code not_found)"},"409":{"description":"der Beschluss trägt nicht, der Plan ist kein Entwurf, es gibt eine neuere Version oder er ist schon unter anderer Referenz beschlossen (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/wirtschaftsplan/hausgeld-soll":{"post":{"summary":"Übernimmt den geltenden beschlossenen Wirtschaftsplan ins Hausgeld-Soll und stellt es fällig (uebernehme_wirtschaftsplan_ins_hausgeld_soll). Ohne Zahlen des Aufrufers: Monatsbetrag = Jahresanteil auf zwölf Monate, Rücklage getrennt, rückwirkende Differenzen nur als Vorschlag. Ohne eigenen Plan im Jahr gilt der letzte beschlossene Plan weiter, wenn der Beschluss die Fortgeltung trägt (quelle fortgeltung).","operationId":"uebernehmeObjektWirtschaftsplanInsHausgeldSoll","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanUebernahmeRequest"}}}},"responses":{"200":{"description":"das gestellte Soll plus Herkunft des Plans (WirtschaftsplanUebernahmeResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WirtschaftsplanUebernahmeResponse"}}}},"400":{"description":"ungültige Eingabe oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt oder Plan unbekannt ODER fremder Tenant ODER Beschluss unbekannt (ApiErrorBody, code not_found)"},"409":{"description":"kein geltender Plan (plan-fehlt), Fortgeltung bei abweichendem Wirtschaftsjahr oder ein anderer Geldkreis (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/vermoegensbericht":{"get":{"summary":"Listet die abgelegten Vermögensberichts-Stände eines Objekts (§ 28 Abs. 4 WEG). Ältere Stände verschwinden NICHT (GoBD) — sie tragen ihre `standNr`, der jüngste Stichtag zuerst.","operationId":"listObjektVermoegensberichtStaende","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"description":"Grenzt auf EINEN Stichtag ein (`YYYY-MM-DD`). Ohne Angabe erscheinen alle Stichtage; ein Objekt ohne Stand ergibt eine LEERE Liste, keinen Fehler.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"die abgelegten Stände des Objekts (VermoegensberichtStandListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VermoegensberichtStandListResponse"}}}},"400":{"description":"keine UUID ODER `stichtag` ist kein `YYYY-MM-DD` (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"post":{"summary":"Erzeugt den Vermögensbericht eines Objekts zum Stichtag und legt ihn als NEUEN Stand ab. Der Idempotenz-Schlüssel kommt vom Aufrufer: zwei Aufrufe am selben Schlüssel ergeben GENAU EINEN Stand. Readiness- und Konsistenz-Befunde stehen in der Antwort.","operationId":"legeObjektVermoegensberichtAb","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VermoegensberichtAblageRequest"}}}},"responses":{"200":{"description":"der abgelegte Stand samt Readiness- und Konsistenz-Befunden (VermoegensberichtAblageResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VermoegensberichtAblageResponse"}}}},"400":{"description":"ungültige Eingabe ODER eine Fachablehnung des Rechenkerns — etwa eine Zusatzposition ohne Beleg-Referenz (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"zu diesem Idempotenz-Schlüssel ist der Bericht bereits abgelegt — es entsteht KEIN zweiter Stand (ApiErrorBody, code conflict). Der vorhandene Stand ist über die Liste lesbar."}}}},"/api/vermoegensbericht/{id}":{"get":{"summary":"Liest EINEN abgelegten Stand samt Bericht und Befunden. `onr` ist PFLICHT: der Stand hängt an BEIDEN Achsen, und ein Stand der Nachbargemeinschaft ist über diesen Weg nicht lesbar.","operationId":"getVermoegensberichtStand","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"onr","in":"query","required":true,"description":"Das Objekt, an dem der Stand hängt. Die Objekt-Achse trägt RLS NICHT — eine Verwaltung führt viele WEG-Objekte desselben Mandanten; ohne sie läse eine Objektsicht den Bestandsausweis der Nachbargemeinschaft.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"der Stand samt byte-stabilem Serialisat und seinen Befunden (VermoegensberichtStandResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VermoegensberichtStandResponse"}}}},"400":{"description":"keine UUID ODER `onr` fehlt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Stand unbekannt, fremder Tenant ODER fremdes Objekt (ApiErrorBody, code not_found) — alle drei sehen gleich aus, eine Unterscheidung wäre bereits ein Existenz-Orakel."}}}},"/api/migration/{id}/vergleich":{"get":{"summary":"Der centgenaue Abweichungsbericht je Fachbereich zu EINEM Import-Vorgang: casa.ai rechnet den importierten Bestand nach und stellt ihn gegen die WinCASA-Vergleichswerte des jüngsten Satzes — mit Konto, Person, Differenz und Erklärung je Abweichung und einem Grund je nicht vergleichbarem Fachbereich. Cent-Beträge als Ganzzahl-Text. Schreibt nichts.","operationId":"leseMigrationsvergleich","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Der Bericht (MigrationsvergleichResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrationsvergleichResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mitglied des Mandanten der Sitzung (ApiErrorBody, code forbidden)"},"404":{"description":"Import-Vorgang unbekannt, fremder Tenant ODER keine UUID (ApiErrorBody, code not_found) — alle drei sehen gleich aus, eine Unterscheidung wäre bereits ein Existenz-Orakel."},"409":{"description":"der Vorgang trägt noch keinen Satz WinCASA-Vergleichswerte (ApiErrorBody, code conflict) — erst im Direktimport die Vergleichswerte erzeugen."},"503":{"description":"Berechtigungsprüfung derzeit nicht möglich (ApiErrorBody, code unavailable)"}}}},"/api/beschluss/{id}/status":{"post":{"summary":"Schreibt den Lebenszyklus-Status eines Beschlusses fort (append-only-Verlauf plus Projektion).","operationId":"setzeBeschlussStatus","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeschlussStatusRequest"}}}},"responses":{"200":{"description":"der geschriebene Wechsel (BeschlussStatusResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeschlussStatusResponse"}}}},"400":{"description":"ungültige Eingabe ODER unzulässiger Übergang unter der geltenden Kantenmenge — z. B. bestandskraeftig → angenommen, oder jeder Ausgang aus dem Endzustand nichtig (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Beschluss unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/objekt/{id}/versammlung":{"get":{"summary":"Liest die Versammlungen (und Umlaufbeschlüsse) eines Objekts, jüngstes Versammlungsdatum zuerst.","operationId":"listObjektVersammlungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Versammlungen des Objekts (VersammlungListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungListResponse"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"post":{"summary":"Legt eine Versammlung oder einen Umlaufbeschluss an. Einladungsfrist unter 3 Wochen: Hinweis im Ergebnis und Begründung Pflicht, keine Sperre.","operationId":"legeObjektVersammlungAn","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungAnlegenRequest"}}}},"responses":{"201":{"description":"angelegte Versammlung samt Hinweisen zur Einladungsfrist (VersammlungSchreibResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungSchreibResponse"}}}},"400":{"description":"ungültige Eingabe, Begründung bei unterschrittener Einladungsfrist fehlt (einladungsfrist-begruendung-fehlt) ODER Umlaufbeschluss mit Einladung/Stimmprinzip (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/versammlung/{id}":{"get":{"summary":"Liest EINE Versammlung samt Tagesordnung und Teilnehmern. Die Beschlussfähigkeit wird nicht berechnet, sondern wie gespeichert ausgewiesen.","operationId":"leseVersammlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"die Versammlung samt Tagesordnung und Teilnehmern, Summe der Stimmgewichte und Teilnehmerzahl (VersammlungDetail)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungDetail"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"patch":{"summary":"Ändert eine Versammlung (nicht art, nicht propertyId). Status nur entwurf → durchgefuehrt und entwurf|durchgefuehrt → abgesagt.","operationId":"aendereVersammlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungAendernRequest"}}}},"responses":{"200":{"description":"geänderte Versammlung samt Hinweisen zur Einladungsfrist (VersammlungSchreibResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungSchreibResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld (z. B. art) ODER Begründung bei unterschrittener Einladungsfrist fehlt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Versammlung abgeschlossen (Beschlüsse generiert) ODER Statuswechsel nicht zulässig (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/tops":{"post":{"summary":"Erfasst einen Tagesordnungspunkt (Beschluss, Geschäftsordnung, Notiz). Die laufende TOP-Nummer vergibt der Server als nächste freie je Versammlung; parallele Anlagen erhalten verschiedene Nummern.","operationId":"erfasseVersammlungTop","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTopErfassenRequest"}}}},"responses":{"201":{"description":"erfasster TOP (VersammlungTopSchreibResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTopSchreibResponse"}}}},"400":{"description":"ungültige Eingabe ODER Umlaufbeschluss mit zweitem TOP (umlauf-genau-ein-top) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Versammlung abgeschlossen (versammlung-abgeschlossen) ODER ausdrücklich genannte TOP-Nummer vergeben (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/tops/{topId}":{"patch":{"summary":"Ändert Text und Art eines Tagesordnungspunkts. Die laufende Nummer (Reihenfolge) ist nicht änderbar.","operationId":"aendereVersammlungTop","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"topId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTopAendernRequest"}}}},"responses":{"200":{"description":"geänderter TOP (VersammlungTopSchreibResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTopSchreibResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld (z. B. lfdNr) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung oder TOP unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Versammlung abgeschlossen ODER Art-Änderung widerspräche erfasstem Ergebnis/Beschluss (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/teilnehmer":{"post":{"summary":"Setzt einen Teilnehmer mit Stimmrecht (Upsert je Person; erneutes Setzen überschreibt). Kein Entfernen: wer nicht erschienen ist, wird nicht erfasst. Ob die Person Eigentümer ist, prüft casa.ai nicht (Gäste, Vertreter, Verwalter sind Teilnehmer). Stimmgewicht: koepfe nur 1, mea Zehntausendstel, objekt Anzahl der Einheiten.","operationId":"erfasseVersammlungTeilnehmer","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTeilnehmerErfassenRequest"}}}},"responses":{"200":{"description":"Teilnehmer überschrieben (VersammlungTeilnehmerSchreibResponse, angelegt=false)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTeilnehmerSchreibResponse"}}}},"201":{"description":"Teilnehmer neu erfasst (VersammlungTeilnehmerSchreibResponse, angelegt=true)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTeilnehmerSchreibResponse"}}}},"400":{"description":"ungültige Eingabe, Stimmgewicht passt nicht zum Stimmprinzip ODER Umlaufbeschluss (umlauf-ohne-teilnehmer) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung oder Person unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Versammlung abgeschlossen (versammlung-abgeschlossen) (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/tops/{topId}/ergebnis":{"post":{"summary":"Erfasst das Abstimmungsergebnis EINES Beschluss-TOP: Feststellung angenommen | abgelehnt und Ja/Nein/Enthaltung in Köpfen und in Anteilen (Zehntausendstel). Erneutes Setzen überschreibt, solange die Versammlung nicht abgeschlossen ist. Das System zählt keine Einzelstimmen und leitet die Feststellung nicht aus den Zahlen ab; ein offensichtlicher Widerspruch kommt als Hinweis ergebnis-widerspricht-zahlen, nie als Fehler.","operationId":"erfasseTopErgebnis","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"topId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTopErgebnisRequest"}}}},"responses":{"200":{"description":"gespeichertes Ergebnis, ggf. mit Hinweis (VersammlungTopErgebnisResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungTopErgebnisResponse"}}}},"400":{"description":"ungültige Eingabe (z. B. negative oder nicht ganze Zahl) ODER Geschäftsordnungs-/Notiz-TOP (top-ohne-abstimmung) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung oder TOP unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Versammlung abgeschlossen (versammlung-abgeschlossen) (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/verkuendung":{"post":{"summary":"Verkündet die Versammlung (setzt verkuendet_am EINMAL) und liefert das berechnete Ende der Anfechtungsfrist (ein Monat ab Verkündung, § 45 WEG; Feiertage nicht berücksichtigt). Das Fristende wird nirgends gespeichert. Voraussetzung: Status durchgefuehrt, mindestens ein Beschluss-TOP, jeder Beschluss-TOP hat ein Ergebnis; das Datum liegt nicht vor dem Versammlungsdatum und nicht in der Zukunft.","operationId":"verkuendeVersammlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungVerkuendenRequest"}}}},"responses":{"200":{"description":"verkündet, mit anfechtungsfristEnde (VersammlungVerkuendungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungVerkuendungResponse"}}}},"400":{"description":"ungültige Eingabe, Datum vor dem Versammlungsdatum oder in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"bereits verkündet (bereits-verkuendet), Status nicht durchgefuehrt, kein Beschluss-TOP oder Beschluss-TOPs ohne Ergebnis (Liste der TOP-Nummern), Versammlung abgeschlossen (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/beschluesse":{"post":{"summary":"Übernimmt die verkündeten Beschlüsse der Versammlung in die Beschluss-Sammlung des Objekts, mit laufender Nummer je Objekt (größte Nummer + 1, fortlaufend), genau einmal und alles oder nichts. Voraussetzung: verkündet, mindestens ein Beschluss-TOP, jeder Beschluss-TOP hat ein Ergebnis. Geschäftsordnungs- und Notiz-TOPs werden nicht übernommen und stehen als übersprungen im Ergebnis. Danach ist die Versammlung abgeschlossen und unveränderlich.","operationId":"erzeugeBeschluesseAusVersammlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungBeschluesseGenerierenRequest"}}}},"responses":{"200":{"description":"übernommene Beschlüsse, übersprungene TOPs, Anzahl (VersammlungBeschluesseGenerierenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersammlungBeschluesseGenerierenResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlendes Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"bereits generiert (bereits-generiert), nicht verkündet (nicht-verkuendet), kein Beschluss-TOP (keine-beschluesse) oder Beschluss-TOPs ohne Ergebnis (ergebnis-fehlt, Liste der TOP-Nummern), laufende Nummer vergeben (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/umlauf":{"get":{"summary":"Liest den Stand des Umlaufs: Vorgang, Rücklaufliste mit Namen und Stimmgewichten, Zählung, fristAbgelaufen und feststellbar. Bis zur Feststellung zählt der Server live (mit dem heutigen Tag), danach gilt die eingefrorene Zählung.","operationId":"leseUmlaufStand","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Stand des Umlaufs (UmlaufStandResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufStandResponse"}}}},"400":{"description":"ungültige Versammlungs-Id (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Zugriff auf diesen Mandanten (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt, fremder Tenant, nicht zuständig ODER Umlauf nicht eröffnet — dieselbe Meldung (ApiErrorBody, code not_found)"}}},"post":{"summary":"Eröffnet den Umlauf einer Versammlung der Art umlauf (Status entwurf, genau ein Beschluss-TOP). Allstimmigkeit ist der Default (alle Eigentümer in Textform, § 23 Abs. 3 S. 1 WEG); die abgesenkte Mehrheit (mehrheit_abgegebene) braucht einen vorher gefassten, tragenden Beschluss — das System prüft nicht, ob er sich auf diesen Gegenstand bezieht. Legt je Eigentümer-Person eine Rücklaufzeile an. Die Frist ist keine Ausschlussfrist.","operationId":"eroeffneUmlaufbeschluss","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufEroeffnenRequest"}}}},"responses":{"201":{"description":"Umlauf eröffnet (UmlaufEroeffnetResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufEroeffnetResponse"}}}},"400":{"description":"ungültige Eingabe, mehrheit_abgegebene ohne Beschluss (absenkung-braucht-beschluss), Frist vor der Eröffnung, keine Eigentümer, Stimmgewicht fehlt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlende Zuständigkeit/Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Umlauf bereits eröffnet (umlauf-bereits-eroeffnet) oder Versammlung nicht mehr im Entwurf (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/umlauf/ruecklauf":{"post":{"summary":"Erfasst die Antwort EINER Person (ja, nein, enthaltung) mit Eingangsdatum, Kanal und Textform-Bestätigung. Zustimmung gilt nur in Textform. Eine spätere Antwort überschreibt die frühere, bis der Umlauf festgestellt ist; eine Antwort nach dem Fristende zählt (Hinweis nach-fristablauf).","operationId":"erfasseUmlaufRuecklauf","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufRuecklaufRequest"}}}},"responses":{"200":{"description":"Antwort erfasst, mit Zählstand (UmlaufRuecklaufResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufRuecklaufResponse"}}}},"400":{"description":"ungültige Eingabe, ja ohne Textform (textform-fehlt), Person steht nicht auf der Rücklaufliste (person-nicht-eigentuemer), Eingang vor Eröffnung oder in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlende Zuständigkeit/Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Umlauf bereits festgestellt (umlauf-festgestellt) (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/umlauf/feststellung":{"post":{"summary":"Stellt das Ergebnis des Umlaufs fest (einmalig): friert die Zählung ein, schreibt das Ergebnis in den Beschluss-TOP und setzt die Versammlung auf durchgefuehrt. Ein nicht zustande gekommener Umlauf geht als abgelehnt in die Sammlung. Erst nach der Verkündung entsteht ein Beschluss in der Sammlung.","operationId":"stelleUmlaufErgebnisFest","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufFeststellenRequest"}}}},"responses":{"200":{"description":"festgestellt (UmlaufFeststellungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufFeststellungResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlende Zuständigkeit/Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"noch nicht feststellbar (feststellung-noch-nicht-moeglich) oder bereits festgestellt (umlauf-festgestellt) (ApiErrorBody, code conflict)"}}}},"/api/versammlung/{id}/umlauf/verkuendung":{"post":{"summary":"Verkündet den festgestellten Umlauf (einmalig), hält Mitteilungsdatum und -form fest und liefert das berechnete Ende der Anfechtungsfrist (ein Monat ab Verkündung, § 45 WEG). Auch ein nicht zustande gekommener Umlauf wird verkündet. Danach lassen sich die Beschlüsse generieren (POST /api/versammlung/{id}/beschluesse).","operationId":"verkuendeUmlaufbeschluss","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufVerkuendenRequest"}}}},"responses":{"200":{"description":"verkündet (UmlaufVerkuendungResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlaufVerkuendungResponse"}}}},"400":{"description":"ungültige Eingabe, Datum vor dem Versammlungsdatum oder in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlende Zuständigkeit/Recht (ApiErrorBody, code forbidden)"},"404":{"description":"Versammlung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"noch nicht festgestellt (umlauf-nicht-festgestellt) oder bereits verkündet (bereits-verkuendet) (ApiErrorBody, code conflict)"}}}},"/api/einheitengruppe":{"get":{"summary":"Listet die Abrechnungskreise (3-Wege-Archiv-Filter, optional auf ein Objekt eingegrenzt).","operationId":"listEinheitengruppen","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"aktiv | archiviert | alle (Default aktiv)","schema":{"type":"string"}},{"name":"propertyId","in":"query","required":false,"description":"nur Kreise dieses Objekts","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Kreis-Liste (EinheitengruppeListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitengruppeListResponse"}}}},"400":{"description":"ungültiger Filter/UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt einen Abrechnungskreis an einem aktiven Objekt an.","operationId":"createEinheitengruppe","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitengruppeCreateRequest"}}}},"responses":{"200":{"description":"angelegter Kreis (Einheitengruppe)"},"400":{"description":"ungültige Eingabe ODER Objekt archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/einheitengruppe/{id}":{"get":{"summary":"Liest einen Abrechnungskreis mit seinen Mitgliedschaften (active zum Stichtag).","operationId":"getEinheitengruppe","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"asOf","in":"query","required":false,"description":"Stichtag YYYY-MM-DD, gegen den `active` je Mitgliedschaft gemessen wird (Default heute UTC). Ungültig ⇒ 400.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Kreis-Detail inkl. Mitgliedschaften (EinheitengruppeDetailResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitengruppeDetailResponse"}}}},"400":{"description":"keine UUID oder ungültiger asOf (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Kreis unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"patch":{"summary":"Ändert Stammfelder eines Abrechnungskreises (name/groupKind).","operationId":"updateEinheitengruppe","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitengruppeUpdateRequest"}}}},"responses":{"200":{"description":"geänderter Kreis (Einheitengruppe)"},"400":{"description":"leerer/ungültiger Patch ODER Kreis archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Kreis unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/einheitengruppe/{id}/archive":{"post":{"summary":"Archiviert einen Abrechnungskreis (archived_at statt DELETE).","operationId":"archiveEinheitengruppe","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Archiv-Ergebnis (UmlageArchiveResponse)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Kreis unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/einheitengruppe/{id}/mitglied":{"post":{"summary":"Nimmt eine Einheit „ab Datum\" in den Kreis auf (SCD-2; Überschneidungen derselben Einheit im Kreis werden abgelehnt).","operationId":"addEinheitengruppeMitglied","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitengruppeMitgliedAddRequest"}}}},"responses":{"200":{"description":"aufgenommene Mitgliedschaft (EinheitengruppeMitgliedAddResponse)"},"400":{"description":"ungültige Eingabe, leerer Bereich, Einheit gehört nicht zum Objekt des Kreises, Kreis/Einheit archiviert ODER Überschneidung (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Kreis oder Einheit unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/einheitengruppe/{id}/mitglied/beenden":{"post":{"summary":"Beendet die offene Mitgliedschaft einer Einheit zum Stichtag.","operationId":"endEinheitengruppeMitglied","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinheitengruppeMitgliedEndRequest"}}}},"responses":{"200":{"description":"beendete Mitgliedschaft (EinheitengruppeMitgliedEndResponse)"},"400":{"description":"ungültige Eingabe ODER Ende vor Beginn (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Kreis oder Mitgliedschaft unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/umlageschluessel":{"get":{"summary":"Listet die Umlageschlüssel (3-Wege-Archiv-Filter, optional auf Objekt/Abrechnungskreis eingegrenzt).","operationId":"listUmlageschluessel","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"aktiv | archiviert | alle (Default aktiv)","schema":{"type":"string"}},{"name":"propertyId","in":"query","required":false,"description":"nur Schlüssel dieses Objekts","schema":{"type":"string","format":"uuid"}},{"name":"unitGroupId","in":"query","required":false,"description":"nur auf diesen Kreis gescopte Schlüssel","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Schlüssel-Liste (UmlageschluesselListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlageschluesselListResponse"}}}},"400":{"description":"ungültiger Filter/UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt einen Umlageschlüssel an einem aktiven Objekt an (optional schon gescoped).","operationId":"createUmlageschluessel","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlageschluesselCreateRequest"}}}},"responses":{"200":{"description":"angelegter Schlüssel (Umlageschluessel)"},"400":{"description":"ungültige Eingabe, Objekt archiviert ODER Scope-Kreis fremd-objektlich (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt ODER Scope-Kreis unbekannt/fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/umlageschluessel/{id}":{"get":{"summary":"Liest einen Umlageschlüssel.","operationId":"getUmlageschluessel","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Schlüssel (Umlageschluessel)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Umlageschluessel"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Schlüssel unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"patch":{"summary":"Ändert Stammfelder eines Umlageschlüssels (keyType/name/config). Der Scope wird über /scope gesetzt.","operationId":"updateUmlageschluessel","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlageschluesselUpdateRequest"}}}},"responses":{"200":{"description":"geänderter Schlüssel (Umlageschluessel)"},"400":{"description":"leerer/ungültiger Patch ODER Schlüssel archiviert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Schlüssel unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/umlageschluessel/{id}/scope":{"post":{"summary":"Setzt (unitGroupId) oder löst (null) den Abrechnungskreis-Scope eines Schlüssels. HINWEIS: Der Scope wird gespeichert, aber von der Abrechnung noch NICHT ausgewertet — ein gescopter Schlüssel verteilt heute wie ein objektweiter.","operationId":"scopeUmlageschluessel","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UmlageschluesselScopeRequest"}}}},"responses":{"200":{"description":"neuer Scope (UmlageschluesselScopeResponse)"},"400":{"description":"ungültige Eingabe, Schlüssel archiviert ODER Kreis fremd-objektlich (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Schlüssel ODER Kreis unbekannt/fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/umlageschluessel/{id}/archive":{"post":{"summary":"Archiviert einen Umlageschlüssel (archived_at statt DELETE).","operationId":"archiveUmlageschluessel","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Archiv-Ergebnis (UmlageArchiveResponse)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Schlüssel unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/umlageschluessel/{id}/messdienst-import":{"post":{"summary":"Importiert externe Messdienst-Festbeträge (CSV oder ARGE-D-Satz-Datei, Format serverseitig am Inhalt erkannt) in einen Umlageschlüssel vom Typ „extern\". Append-only: jeder Aufruf legt einen neuen Batch an. Die Antwort echot die GESPEICHERTE Periode zurück — der Abrechnungslauf liest nur Batches mit EXAKT passender Periode.","operationId":"importMessdienstBetraege","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Der zu befüllende Umlageschlüssel; er MUSS den Typ „extern\" haben (sonst 400).","schema":{"type":"string","format":"uuid"}},{"name":"propertyId","in":"query","required":true,"description":"Objekt, für das importiert wird.","schema":{"type":"string","format":"uuid"}},{"name":"periodFrom","in":"query","required":true,"description":"Beginn der Abrechnungsperiode (einschließlich). MUSS exakt der Periode des Abrechnungslaufs entsprechen, sonst bleibt der Import wirkungslos.","schema":{"type":"string","format":"date"}},{"name":"periodTo","in":"query","required":true,"description":"Ende der Abrechnungsperiode (einschließlich) — dieselbe Exaktheitsregel wie periodFrom.","schema":{"type":"string","format":"date"}},{"name":"currency","in":"query","required":true,"description":"Währung ALLER Zeilen dieses Aufrufs (z. B. EUR).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Die Messdienst-CSV (Bytes, unverändert). Semikolon-getrennt, Kopfzeile fix: externalRef;contractId;unitId;betragCents. GENAU EIN file-Part je Aufruf — zwei Parts werden abgewiesen (nie still der zweite verworfen)."}}}}}},"responses":{"201":{"description":"gespeicherter Batch (MessdienstImportResponse). Zeilen ohne Vertrag/Einheit blockieren den Import nicht, sie erscheinen in unmatchedCount.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessdienstImportResponse"}}}},"400":{"description":"fehlende/ungültige Pflicht-Query, kein oder MEHR ALS EIN file-Feld, unlesbare CSV, Schlüssel nicht vom Typ „extern\", archivierter Schlüssel/archiviertes Objekt ODER eine Zeile mit unbekannter Vertrags-/Einheits-Referenz (ApiErrorBody, code invalid_request) — kein Teil-Import"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Umlageschlüssel oder Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"413":{"description":"Datei überschreitet die zulässige Maximalgröße (ApiErrorBody, code payload_too_large)"}}}},"/api/rechte/rolle":{"post":{"summary":"Weist einem User eine Rolle zu (assign_role, RLS-tenant-gebunden).","operationId":"assignRolle","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId","roleKey"],"properties":{"userId":{"type":"string","format":"uuid"},"roleKey":{"type":"string","minLength":1,"maxLength":100}}}}}},"responses":{"201":{"description":"zugewiesen (userId, roleId, roleKey, alreadyAssigned)"},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannte Rolle ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/rechte/objekt":{"post":{"summary":"Setzt eine Objekt-Zuständigkeit (set_object_responsibility), optional an eine Fähigkeit (Rolle) gebunden.","operationId":"setObjektZustaendigkeit","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId","propertyId"],"properties":{"userId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"roleKey":{"type":"string","minLength":1,"maxLength":100,"nullable":true,"description":"Optional (Issue #3273): grenzt die Zuständigkeit auf GENAU diese Fähigkeit/Rolle des Nutzers ein. Weggelassen oder `null` ⇒ Bestandsverhalten — gilt für ALLE Fähigkeiten (`role_id IS NULL`)."}}}}}},"responses":{"201":{"description":"gesetzt (userId, propertyId, assignmentId, roleId, roleKey, alreadyAssigned). `roleId`/`roleKey` sind `null`, wenn ohne `roleKey` (bzw. mit `roleKey: null`) gesetzt — gilt dann für alle Fähigkeiten."},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"unbekanntes Objekt ODER fremder Tenant ODER unbekannte Rolle (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/rechte/objekt/entziehen":{"post":{"summary":"Entzieht eine Objekt-Zuständigkeit (revoke_object_responsibility, wirkt sofort), optional rollenscharf.","operationId":"revokeObjektZustaendigkeit","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId","propertyId"],"properties":{"userId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"roleKey":{"type":"string","minLength":1,"maxLength":100,"nullable":true,"description":"Optional (Issue #3273): entzieht rollenscharf GENAU diese Fähigkeit/Rolle. Weggelassen ⇒ Bestandsverhalten — ALLE Bindungen des Paars enden. `null` ⇒ nur die ungebundene Zeile."}}}}}},"responses":{"200":{"description":"entzogen (userId, propertyId, roleId, roleKey, revoked). `roleId`/`roleKey` sind `null`, wenn ohne `roleKey` entzogen (alle Bindungen) — sonst der adressierte Rollenbezug. Ohne aktive Zuständigkeit sichtbarer No-op (revoked:false)."},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/vertrag":{"get":{"summary":"Listet Verträge (3-Wege-Gültigkeitsfilter Alle/Aktiv/Beendet, Default aktiv).","operationId":"listVertraege","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | aktiv | beendet (Default aktiv). Gemessen an end_date, nicht an archived_at. aktiv ∪ beendet ≠ alle: zukünftige Verträge erscheinen nur unter `alle`. Unbekannter Wert ⇒ 400.","schema":{"type":"string","enum":["alle","aktiv","beendet"]}},{"name":"objektId","in":"query","required":false,"description":"nur Verträge dieses Objekts (UUID)","schema":{"type":"string","format":"uuid"}},{"name":"asOf","in":"query","required":false,"description":"Stichtag YYYY-MM-DD, gegen den aktiv/beendet gemessen wird (Default: heute, UTC).","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Vertragsliste (VertragListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragListResponse"}}}},"400":{"description":"ungültiger status-Filter, objektId-UUID oder Stichtag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt ein Mietverhältnis samt initialer Zahlungs-Zeitscheibe an.","operationId":"createVertrag","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragCreateRequest"}}}},"responses":{"201":{"description":"angelegter Vertrag inkl. Zeitscheiben (Vertrag)"},"400":{"description":"ungültige Eingabe (z. B. Float-Betrag, fehlende depositCurrency) (ApiErrorBody, code invalid_request). Eine Kautionsabrede über mehr als drei Nettokaltmieten der initialen Zeitscheibe (§ 551 Abs. 1 BGB) ⇒ ApiErrorBody, code KAUTION_UEBERSTEIGT_OBERGRENZE; die Meldung nennt Kaution, Nettokaltmiete und Grenze; kein Vertrag entsteht."},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt ODER eine Zahlungs-Komponente unbekannt, archiviert oder fremder Tenant (ApiErrorBody, code not_found). Die Ziel-Prüfung leistet der Tool-Layer."},"409":{"description":"Kautionsabrede ohne bestimmbare Nettokaltmiete ⇒ ApiErrorBody, code KAUTION_OHNE_NETTOKALTMIETE (fail-closed, kein Vertrag entsteht)."}}}},"/api/vertrag/{id}":{"get":{"summary":"Liest EINEN Vertrag samt Konditionen-Zeitscheiben und vereinbarten Zahlungen (auch beendet).","operationId":"getVertrag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Vertrag (mit gefülltem terms-Array)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Vertrag"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/vertrag/{id}/end":{"post":{"summary":"Beendet einen Vertrag zum Stichtag (setzt end_date, schließt offene Zeitscheiben; statt DELETE, K5).","operationId":"endVertrag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragEndRequest"}}}},"responses":{"200":{"description":"beendet (VertragEndResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses."},"400":{"description":"ungültiges/unplausibles Enddatum (am/vor Beginn oder Scheiben-Beginn) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/vertrag/{id}/kuendigung":{"get":{"summary":"Liest die Kündigungslage eines Vertrags: mit zugang + kuendigender den VORSCHLAG des Vertragsendes nach § 573c BGB (ohne Write), dazu die bereits erfasste Kündigung samt Kennzeichnung „abweichend vereinbart\".","operationId":"getVertragKuendigung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"zugang","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Tag des Zugangs (nur zusammen mit kuendigender)"},{"name":"kuendigender","in":"query","required":false,"schema":{"type":"string","enum":["mieter","vermieter"]},"description":"Wer kündigt (nur zusammen mit zugang)"}],"responses":{"200":{"description":"Kündigungslage (vorschlag null ohne Query; kuendigung null ohne erfasste Kündigung)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragKuendigungResponse"}}}},"400":{"description":"ungültige Query (kein existierender Kalendertag, unbekannter Kündigender, nur einer der beiden Parameter) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vertragsende nicht berechenbar: Bundesland des Objekts bzw. (Vermieter) Vertragsbeginn fehlt (ApiErrorBody, code conflict)"}}},"post":{"summary":"Erfasst die Kündigung (terminate_contract) und beendet den Vertrag zum errechneten Ende nach § 573c BGB — oder zum abweichend vereinbarten Ende (vereinbartesEnde), das dann als „abweichend vereinbart\" gekennzeichnet wird. Einmalig: ein bereits beendeter Vertrag antwortet alreadyEnded: true.","operationId":"kuendigeVertrag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragKuendigenRequest"}}}},"responses":{"200":{"description":"gekündigt (VertragKuendigenResponse). Wiederholung mit demselben Idempotency-Key = Replay des Erst-Ergebnisses.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragKuendigenResponse"}}}},"400":{"description":"ungültige Eingabe, contractId im Body, oder vereinbartes Ende am/vor dem Beginn (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt des Vertrags (ApiErrorBody, code forbidden)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Vertragsende nicht berechenbar: Bundesland des Objekts bzw. (Vermieter) Vertragsbeginn fehlt (ApiErrorBody, code conflict)"}}}},"/api/vertrag/{id}/kaution":{"post":{"summary":"Hält die Kautionsabrede eines Vertrags fest (setze_kautionsabrede): Betrag und Währung (Pflicht, wenn der Vertrag noch keine Kaution dokumentiert), Anlageform, Raten nach § 551 Abs. 2 BGB (1…3) und optional die getrennte Anlage. Erst damit wird aus einer dokumentierten Kaution eine sollstellbare Forderung.","operationId":"setzeKautionsabrede","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Die Abrede. Barkaution verlangt kautionRaten; Bürgschaft/Verpfändung verbieten kautionRaten und kautionAnlagekontoId. depositCents/depositCurrency nur gemeinsam; weggelassen ⇒ der am Vertrag dokumentierte Betrag.","required":["kautionAnlageform"],"properties":{"depositCents":{"anyOf":[{"type":"string","pattern":"^[1-9][0-9]*$"},{"type":"integer","minimum":1}],"description":"vereinbarte Kaution in Cents (Integer-STRING > 0; eine ganze Zahl > 0 wird ebenfalls angenommen)"},"depositCurrency":{"type":"string","enum":["EUR"],"description":"Währung der Kaution — Pflicht genau dann, wenn depositCents gesetzt ist"},"kautionAnlageform":{"type":"string","enum":["barkaution","buergschaft","verpfaendung"]},"kautionRaten":{"type":"integer","minimum":1,"maximum":3},"kautionAnlagekontoId":{"type":"string","format":"uuid","description":"Bankverbindung der Kontoart kautionskonto am Objekt des Vertrags"}}}}}},"responses":{"200":{"description":"gesetzt — { contractId, vereinbartCents, currency, kautionAnlageform, kautionRaten, kautionAnlagekontoId }","content":{"application/json":{"schema":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"vereinbartCents":{"type":"string","description":"die nun vereinbarte Kaution (Integer-STRING)"},"currency":{"type":"string"},"kautionAnlageform":{"type":"string","enum":["barkaution","buergschaft","verpfaendung"]},"kautionRaten":{"type":"integer","nullable":true},"kautionAnlagekontoId":{"type":"string","format":"uuid","nullable":true}}}}}},"400":{"description":"ungültige Abrede, z. B. mehr als 3 Raten oder Raten bei Bürgschaft (ApiErrorBody, code invalid_request). Kaution über drei Nettokaltmieten der am Abredetag gültigen Zeitscheibe bei Wohnraum (§ 551 Abs. 1 BGB) ⇒ ApiErrorBody, code KAUTION_UEBERSTEIGT_OBERGRENZE; die Meldung nennt Kaution, Nettokaltmiete und Grenze; nichts geschrieben."},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag oder Kautionskonto unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"kein Kautionsbetrag vereinbart oder bereits Raten/Eingänge gebucht (ApiErrorBody, code conflict). Wohnraum ohne Nettokaltmiete am Abredetag ⇒ ApiErrorBody, code KAUTION_OHNE_NETTOKALTMIETE (fail-closed, nichts geschrieben)."}}}},"/api/vertrag/{id}/indexmiete":{"put":{"summary":"Hält die Indexmiete-Vereinbarung eines Vertrags fest (setze_indexmietvereinbarung): Basisjahr der VPI-Reihe und Ausgangsindex (Berichtsmonat). `vereinbarung: null` nimmt sie zurück.","operationId":"setzeIndexmietvereinbarung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["vereinbarung"],"properties":{"vereinbarung":{"type":"object","nullable":true,"required":["basisjahr","basisindexMonat"],"properties":{"basisjahr":{"type":"integer","minimum":1900,"maximum":9999,"description":"Basisjahr der VPI-Reihe (2020 für 2020=100)"},"basisindexMonat":{"type":"string","pattern":"^[0-9]{4}-(0[1-9]|1[0-2])$","description":"Ausgangsindex: Berichtsmonat YYYY-MM"}}}}}}}},"responses":{"200":{"description":"gesetzt — { contractId, vereinbarung, zuvor }"},"400":{"description":"ungültige Vereinbarung oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"post":{"summary":"Beantragt eine Indexanpassung (beantrage_indexanpassung): neue Miete = bisherige × aktueller Index / Bezugsindex (kaufmännisch gerundet), frühestens zwölf Monate nach der letzten Änderung, wirksam ab dem übernächsten Monat nach Zugang. Eine Erhöhung wird als freigabepflichtiger Vorgang in die Mieterhöhungs-Freigabe gelegt — umgestellt wird erst nach der Freigabe über die Konditionen (kein automatisches Umstellen).","operationId":"beantrageIndexanpassung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["indexMonat","verwaltungsart"],"properties":{"indexMonat":{"type":"string","pattern":"^[0-9]{4}-(0[1-9]|1[0-2])$","description":"Berichtsmonat des aktuellen Index (YYYY-MM)"},"zugangAm":{"type":"string","format":"date","description":"Zugang der Erklärung beim Mieter; optional. Ohne zugangAm ist geplanterWirksamkeitstag Pflicht, mit zugangAm wird er abgelehnt (Wirksamkeit: Beginn des übernächsten Monats)."},"geplanterWirksamkeitstag":{"type":"string","format":"date","description":"Geplanter Wirksamkeitstag (Monatserster); Pflicht genau dann, wenn zugangAm fehlt"},"verwaltungsart":{"type":"string","enum":["eigenverwaltung","fremdverwaltung"]}}}}}},"responses":{"200":{"description":"{ art: vorgelegt | zu-frueh | keine-aenderung, … } — bei `vorgelegt` (Erhöhung wie Senkung, beide freigabepflichtig) mit mieterhoehungId, neueKaltmieteCents, vorhaben (die geplante Zeitscheibe) und inhaltHash; bei `zu-frueh` mit fruehesterTermin und ohne Vorgang."},"400":{"description":"ungültige Anfrage oder nicht rechenbar (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"keine Indexmiete-Vereinbarung, Indexmonat nicht in der Reihe, kein offener Zeitscheiben-Stand oder bereits eine andere Erhöhung zum Wirksamkeitstag (ApiErrorBody, code conflict)"}}}},"/api/vertrag/{id}/mieterhoehung":{"post":{"summary":"Legt ein Mieterhöhungsverlangen nach § 558 BGB an (erstelle_mieterhoehung): Vorgang im Zustand `entwurf` und dokumentiertes Schreiben entstehen, der Vorgang erscheint in der Freigabe. Es entsteht KEINE Zeitscheibe — umgestellt wird erst nach der Freigabe über die Konditionen. Die Vertrags-Id steht nur im Pfad; Mandant und Akteur kommen aus der Sitzung (ein Mandant im Rumpf wird ignoriert).","operationId":"erstelleMieterhoehung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["wirksamAb","zugangAm","neueKaltmieteCents","currency","vergleichsmieteCents","gebiet","laufendeVereinbarung","payments","begruendung","verwaltung"],"properties":{"wirksamAb":{"type":"string","format":"date","description":"Wirksamkeitstag der Erhöhung"},"zugangAm":{"type":"string","format":"date","description":"Zugang des Schreibens — Beginn der Zustimmungsfrist"},"neueKaltmieteCents":{"type":"string","pattern":"^[0-9]+$","description":"verlangte neue Kaltmiete in Cent (Ziffern-String)"},"currency":{"type":"string","example":"EUR"},"vergleichsmieteCents":{"type":"string","pattern":"^[0-9]+$","description":"ortsübliche Vergleichsmiete in Cent (Ziffern-String)"},"gebiet":{"type":"string","enum":["regel","mietpreisbremse"]},"laufendeVereinbarung":{"type":"string","enum":["keine","staffelmiete","indexmiete"]},"payments":{"type":"array","description":"vereinbarte Zahlungen der geplanten neuen Zeitscheibe (Pflicht, auch leer)","items":{"type":"object","required":["componentId","amountCents","currency"],"properties":{"componentId":{"type":"string","format":"uuid"},"amountCents":{"type":"string","pattern":"^[0-9]+$"},"currency":{"type":"string"}}}},"begruendung":{"type":"object","description":"Begründung nach § 558a BGB, Feld `weg`: qualifizierter-mietspiegel | einfacher-mietspiegel (bezeichnung, standJahr, oeffentlichZugaenglich, anlageDokumentId) | mietdatenbank (bezeichnung, standJahr) | vergleichswohnungen (wohnungen[]) | sachverstaendigengutachten (gutachterBezeichnung, gutachtenDatum)"},"verwaltung":{"type":"object","required":["art"],"description":"`art` eigenverwaltung, oder fremdverwaltung mit eigentuemerBezeichnung und vollmachtImOriginal"}}}}}},"responses":{"201":{"description":"angelegt — { mieterhoehungId, schreibenId, contractId, wirksamAb, zustand: \"entwurf\", zustimmungsfristBis, alterBetragCents, neuerBetragCents, … }"},"400":{"description":"ungültige Eingabe oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt bzw. keine Berechtigung (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Kappungsgrenze und/oder Jahressperrfrist verletzt (ApiErrorBody, code MIETERHOEHUNG_UNZULAESSIG) oder zu diesem Wirksamkeitstag besteht schon ein Verlangen (code MIETERHOEHUNG_DOPPELT); Indexmiete-/Staffelmiete-Kollision. Nichts geschrieben."},"422":{"description":"Wucherschwelle überschritten (code MIETERHOEHUNG_WUCHER), Begründung trägt das Verlangen nicht (code MIETERHOEHUNG_SCHREIBEN_UNGUELTIG), Wirksamkeitstag vor Ende der Zustimmungsfrist (code MIETERHOEHUNG_VOR_ZUSTIMMUNGSFRIST) oder in der Vergangenheit (code MIETERHOEHUNG_RUECKWIRKEND). Nichts geschrieben."}}}},"/api/mieterhoehung/{id}/entscheidung":{"post":{"summary":"Entscheidet EINE Mieterhöhungs-Fassung (entscheide_mieterhoehung): freigeben (`approved`) oder ablehnen (`rejected`, mit Grund-Code). Bindung und Inhalts-Hash bestimmt der Server frisch aus der Datenbank; der Rumpf trägt keinen Hash. Verlangt eine frische Anmeldung (Step-up). Ein Agent darf nicht entscheiden.","operationId":"entscheideMieterhoehung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mieterhoehungId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["decision"],"properties":{"decision":{"type":"string","enum":["approved","rejected"]},"reasonCode":{"type":"string","enum":["falscher-betrag","falscher-kreditor","falsche-kontierung","kein-beleg","doppelt","nicht-plausibel","sonstiges"],"description":"Pflicht bei `rejected`, verboten bei `approved`"}}}}}},"responses":{"200":{"description":"entschieden — { approvalId, mieterhoehungId, decision, bindung, contentHash }"},"400":{"description":"ungültige Eingabe, z. B. Ablehnung ohne Grund (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Entscheider ist ein Agent bzw. ohne Berechtigung, oder Step-up nötig (ApiErrorBody, code forbidden)"},"404":{"description":"Fassung unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Fassung verfallen oder schon entschieden (ApiErrorBody, code conflict)"}}}},"/api/mieterhoehung/{id}/feststellung":{"post":{"summary":"Stellt die Reaktion des Mieters auf ein Erhöhungsverlangen fest (stelle_mieterhoehung_fest): ausdrückliche Zustimmung (Zustand `wirksam`), Widerspruch oder Sonderkündigung (Zustand `abgelehnt`). Setzt einen wirksamen Zustellnachweis voraus; die Feststellung ist append-only und fällt genau einmal. Nur ein Mensch darf sie festhalten, der Erfasser ist der Akteur.","operationId":"stelleMieterhoehungFest","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mieterhoehungId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["art","festgestelltAm"],"additionalProperties":false,"properties":{"art":{"type":"string","enum":["zustimmung-ausdruecklich","widerspruch","sonderkuendigung"]},"festgestelltAm":{"type":"string","format":"date","description":"Kalendertag der Reaktion (YYYY-MM-DD)"}}}}}},"responses":{"200":{"description":"festgestellt — { mieterhoehungId, feststellungId, zustand, wirksam }"},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Akteur ist ein Agent bzw. ohne Berechtigung (ApiErrorBody, code forbidden) — nichts geschrieben"},"404":{"description":"Mieterhöhung unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"nicht zugestellt (kein Zustellnachweis) oder bereits festgestellt (ApiErrorBody, code conflict) — nichts geschrieben"}}}},"/api/mieterhoehung/{id}/zahlung":{"post":{"summary":"Erfasst eine beobachtete Zahlung zum Erhöhungsverlangen (erfasse_mieterhoehungszahlung). Betrag, Währung und Datum liest der Server aus dem Buchungssatz, der eine Zahlung auf dem Mieter-Personenkonto dieses Vertrags sein muss. `unterVorbehalt` ist Pflicht ohne Default: das Merkmal „vorbehaltlos\" bestätigt ein Mensch, es wird nie aus dem Bank-Matching abgeleitet. Mit der dritten vorbehaltlosen Zahlung in drei Perioden entsteht genau eine konkludente Feststellung (Zustand `wirksam`); eine Zahlung unter Vorbehalt zählt nicht.","operationId":"erfasseMieterhoehungszahlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mieterhoehungId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["zahlungEntryId","periode","unterVorbehalt"],"additionalProperties":false,"properties":{"zahlungEntryId":{"type":"string","format":"uuid","description":"journal_entries.id des Zahlungs-Buchungssatzes"},"periode":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$","description":"Sollperiode (YYYY-MM)"},"unterVorbehalt":{"type":"boolean","description":"Pflicht, kein Default: true = unter Vorbehalt geleistet (zählt nicht)"}}}}}},"responses":{"200":{"description":"erfasst — { mieterhoehungId, zahlungEntryId, neuErfasst, zaehlendePerioden, feststellungId, betragCents, currency, gezahltAm }"},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Akteur ist ein Agent bzw. ohne Berechtigung (ApiErrorBody, code forbidden) — nichts geschrieben"},"404":{"description":"Mieterhöhung oder Buchungssatz (keine Zahlung dieses Vertrags) unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"nicht zugestellt (kein Zustellnachweis) (ApiErrorBody, code conflict) — nichts geschrieben"}}}},"/api/mieterhoehung/{id}/ruecknahme":{"post":{"summary":"Nimmt eine wirksame Mieterhöhung zurück (nimm_mieterhoehung_zurueck): Pflichtbegründung, Zustand `zurueckgenommen`. Die Antwort trägt `alterBetragCents`, den Betrag, der wieder gilt — aus dem Vorgang gelesen.","operationId":"nimmMieterhoehungZurueck","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mieterhoehungId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["zurueckgenommenAm","begruendung"],"additionalProperties":false,"properties":{"zurueckgenommenAm":{"type":"string","format":"date","description":"Kalendertag der Rücknahme (YYYY-MM-DD)"},"begruendung":{"type":"string","minLength":1,"maxLength":1000}}}}}},"responses":{"200":{"description":"zurückgenommen — { mieterhoehungId, ruecknahmeId, zustand, alterBetragCents, currency }"},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Akteur ist ein Agent bzw. ohne Berechtigung (ApiErrorBody, code forbidden) — nichts geschrieben"},"404":{"description":"Mieterhöhung unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Mieterhöhung ist nicht wirksam (ApiErrorBody, code conflict) — nichts geschrieben"}}}},"/api/mieterhoehung/{id}/indexerklaerung":{"get":{"summary":"Erzeugt die Erklärung einer Indexanpassung nach § 557b Abs. 3 BGB als Text im Standardwortlaut (erzeuge_indexanpassungserklaerung): alter und neuer Index, alte und neue Miete, Rechenweg und Wirksamkeitsmonat (Beginn des übernächsten Monats nach dem Zugang). Indexwerte und geplanter Betrag kommen aus dem gespeicherten Index-Vorgang und werden gegen die Kette nachgerechnet; weicht das Ergebnis ab, gibt es keinen Text. Nur lesend — der Text wird erzeugt, nicht versendet.","operationId":"getMieterhoehungIndexerklaerung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mieterhoehungId eines Index-Vorgangs"}],"responses":{"200":{"description":"{ text, vorlageVersion, dokumentHash, zugangErfasst } — dokumentHash ist SHA-256 (hex) über den Text; zugangErfasst false = kein Zugangstag erfasst, der Wirksamkeitsmonat ist die Vorschau aus dem geplanten Wirksamkeitstag.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexanpassungErklaerungResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"kein Index-Vorgang, sondern z. B. ein § 558-Verlangen (ApiErrorBody, code MIETERHOEHUNG_KEIN_INDEXVORGANG), oder die Nachrechnung weicht vom gespeicherten Vorgang ab (code conflict) — kein Text."}}}},"/api/mieterhoehung/{id}/versand":{"post":{"summary":"Versendet das freigegebene Mieterhöhungsschreiben nach § 558a BGB (versende_mieterhoehungsschreiben) über das Außenwirkungs-Gate: Zustellnachweis mit Dokument-Hash, Zustand `versendet` (nie `wirksam`). `mail` geht über den Versandkanal des Mandanten, `druck` protokolliert nur die Übergabe. Akteurs-Kette und Step-up bestimmt der Server aus Sitzung und Freigabe — nie aus dem Rumpf. Verlangt eine frische Anmeldung (Step-up) und eine Freigabe durch eine andere Person. Ein Agent darf nicht versenden.","operationId":"versendeMieterhoehungsschreiben","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mieterhoehungId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["versandweg"],"properties":{"versandweg":{"type":"string","enum":["mail","druck"]},"selbstfreigabeBestaetigt":{"type":"boolean","description":"ausdrückliche Bestätigung bei Ein-Personen-Mandanten (Selbstfreigabe)"}}}}}},"responses":{"200":{"description":"Versuch protokolliert — { mieterhoehungId, versandweg, ausgang: \"zugestellt\" | \"fehlgeschlagen\", zustellnachweisId, providerRef, fehlerCode }; bei \"fehlgeschlagen\" bleibt der Zustand unverändert"},"400":{"description":"ungültige Eingabe oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Gate hat abgewiesen: keine Freigabe, Selbstfreigabe, kein frischer Step-up, kein Ausführungsrecht oder Versender ist ein Agent (ApiErrorBody, code MIETERHOEHUNG_VERSAND_GESPERRT). Nichts versendet."},"404":{"description":"Vorgang unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Schreiben ist schon zugegangen (ApiErrorBody, code MIETERHOEHUNG_BEREITS_VERSENDET) oder die Anmeldung trägt schon eine andere Ausführung (code MIETERHOEHUNG_VERSAND_GESPERRT). Kein zweiter Versand."}}}},"/api/vertrag/{id}/zahlung":{"post":{"summary":"Konditionswechsel: vereinbarte Zahlungen als Zeitscheibe ändern (schließt die offene Scheibe auf `ab`, öffnet lückenlos eine neue).","operationId":"changeVertragZahlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragZahlungChangeRequest"}}}},"responses":{"200":{"description":"gewechselt (VertragZahlungChangeResponse). Wiederholter Aufruf mit gleichem Idempotency-Key = Replay des Erst-Ergebnisses."},"400":{"description":"rückwirkendes/ungültiges ab oder Float auf Geld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"kein offener Zeitscheiben-Stand oder nebenläufiger Wechsel (ApiErrorBody, code conflict)"}}}},"/api/vertrag/{id}/personen":{"get":{"summary":"Liest die Kopfzahl-Historie eines Vertrags (alle Zeitscheiben, active zum Stichtag).","operationId":"listVertragPersonen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"asOf","in":"query","required":false,"description":"Stichtag YYYY-MM-DD, gegen den `active` gemessen wird (Default: heute UTC). Ungültiges Format ⇒ 400.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Kopfzahl-Historie (VertragPersonenListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragPersonenListResponse"}}}},"400":{"description":"keine UUID oder ungültiger asOf (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vertrag unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}},"post":{"summary":"Setzt/ändert eine Kopfzahl-Zeitscheibe „ab Datum\" (SCD-2; Überschneidungen desselben Vertrags werden abgelehnt).","operationId":"setVertragPersonen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragPersonenSetRequest"}}}},"responses":{"200":{"description":"gesetzte Zeitscheibe (VertragPersonenSetResponse)"},"400":{"description":"ungültige Eingabe (negative/gebrochene Kopfzahl, validFrom nach validTo) ODER Überschneidung mit einer bestehenden Scheibe desselben Vertrags (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vertrag unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/vertrag/{id}/personen/{sliceId}/remove":{"post":{"summary":"Entfernt eine Kopfzahl-Zeitscheibe außer der ersten (stillgelegt, K5); die Vorgängerin deckt die Lücke wieder bzw. ist wieder laufend. Kein Body. Wiederholung = Replay.","operationId":"removeVertragPersonen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"sliceId","in":"path","required":true,"description":"Id der Scheibe (aus GET /api/vertrag/{id}/personen)","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"entfernt (VertragPersonenRemoveResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VertragPersonenRemoveResponse"}}}},"400":{"description":"id oder sliceId keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vertrag oder Scheibe unbekannt, fremder Tenant, an einem anderen Vertrag oder schon entfernt (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"die erste Scheibe des Vertrags bleibt (P82) — ändern statt entfernen (ApiErrorBody, code conflict)"}}}},"/api/mieterwechsel":{"post":{"summary":"Mieterwechsel auf einer Einheit: Altvertrag beenden, Neuvertrag anlegen, Zeitscheiben fortschreiben (eine Transaktion).","operationId":"executeMieterwechsel","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MieterwechselRequest"}}}},"responses":{"201":{"description":"Wechsel ausgeführt (MieterwechselResponse). Wiederholter Aufruf mit gleichem Idempotency-Key = Replay des Erst-Ergebnisses.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MieterwechselResponse"}}}},"400":{"description":"überlappende Belegung, unbestätigter Leerstand, unplausibles Enddatum, objektfremder Altvertrag oder Float auf Geld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Einheit, Altvertrag oder Zahlungs-Komponente unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"},"409":{"description":"Altvertrag bereits beendet oder Einheit anderweitig belegt (ApiErrorBody, code conflict)"}}}},"/api/mandat":{"get":{"summary":"Listet SEPA-Mandate (Status-Filter alle|pending|active|revoked|expired, Default alle).","operationId":"listMandate","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"description":"alle | pending | active | revoked | expired (Default alle). Unbekannter Wert ⇒ 400.","schema":{"type":"string","enum":["alle","pending","active","revoked","expired"]}},{"name":"vertragId","in":"query","required":false,"description":"nur Mandate dieses Vertrags (UUID)","schema":{"type":"string","format":"uuid"}},{"name":"personId","in":"query","required":false,"description":"nur Mandate dieser Person (UUID)","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Mandatsliste (MandatListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MandatListResponse"}}}},"400":{"description":"ungültiger status-Filter oder UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt ein SEPA-Mandat zu einem Vertrag an (Status pending).","operationId":"createMandat","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MandatCreateRequest"}}}},"responses":{"201":{"description":"angelegtes Mandat (Mandat)"},"400":{"description":"ungültige Eingabe ODER doppelte mandateRef im Tenant (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vertrag ODER Person unbekannt, archiviert oder fremder Tenant (ApiErrorBody, code not_found). Die Ziel-Prüfung leistet der Tool-Layer."}}}},"/api/mandat/{id}":{"get":{"summary":"Liest EIN SEPA-Mandat samt Vertrags-/Personen-Bezug (auch widerrufen/abgelaufen).","operationId":"getMandat","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Mandat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Mandat"}}}},"400":{"description":"keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/mandat/{id}/status":{"post":{"summary":"Führt den Mandatsstatus (validierter Übergang nach active/revoked/expired).","operationId":"setMandatStatus","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MandatStatusRequest"}}}},"responses":{"200":{"description":"Status geführt (MandatStatusResponse). Wiederholter Aufruf = Idempotenz-Replay des Erst-Ergebnisses."},"400":{"description":"ungültiges Ziel oder unerlaubter Übergang (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannt ODER fremder Tenant (ApiErrorBody, code not_found)"}}}},"/api/option":{"get":{"summary":"Listet Options-Zeilen (optionaler Filter scopeType/scopeId/key).","operationId":"listOptions","security":[{"bearerAuth":[]}],"parameters":[{"name":"scopeType","in":"query","required":false,"description":"tenant | objekt | einheit | vertrag","schema":{"type":"string","enum":["tenant","objekt","einheit","vertrag"]}},{"name":"scopeId","in":"query","required":false,"description":"Ziel-UUID der Ebene","schema":{"type":"string","format":"uuid"}},{"name":"key","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Options-Liste (OptionListResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptionListResponse"}}}},"400":{"description":"ungültiger Filter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Setzt/überschreibt eine gescopte Option (Upsert je scope+key).","operationId":"setOption","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptionSetRequest"}}}},"responses":{"200":{"description":"gesetzte Option (OptionSetResponse); created unterscheidet neu vs. überschrieben"},"400":{"description":"ungültige Eingabe (unbekannter scope_type, fehlende scope_id, fehlender value …) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/option/effective":{"get":{"summary":"Löst den effektiven Wert eines Schlüssels über die Kandidaten-Scopes auf (spezifischster gewinnt).","operationId":"resolveOption","security":[{"bearerAuth":[]}],"parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string"}},{"name":"objektId","in":"query","required":false,"description":"Objekt-Ebene in die Auflösung einbeziehen","schema":{"type":"string","format":"uuid"}},{"name":"einheitId","in":"query","required":false,"description":"Einheiten-Ebene einbeziehen","schema":{"type":"string","format":"uuid"}},{"name":"vertragId","in":"query","required":false,"description":"Vertrags-Ebene einbeziehen","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"effektiver Wert (OptionResolveResponse); found:false ⇒ nirgends gesetzt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptionResolveResponse"}}}},"400":{"description":"fehlender key ODER ungültige Scope-Referenz (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/cli/login/start":{"post":{"summary":"Schritt 1 des CLI-Browser-Logins: startet eine Anmelderunde und liefert die im Browser zu öffnende Anmelde-URL.","operationId":"startCliLogin","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CliLoginStartRequest"}}}},"responses":{"200":{"description":"Anmelderunde angelegt — `verificationUrl` im Browser öffnen, `loginId` für den Tausch aufbewahren.","content":{"application/json":{"schema":{"type":"object","required":["loginId","verificationUrl"],"properties":{"loginId":{"type":"string","description":"Kennung der Runde; zusammen mit dem Rückruf-Code nötig, um den Token zu holen."},"verificationUrl":{"type":"string","description":"Adresse der Freigabe-Seite; liegt auf derselben Origin wie diese Anfrage."}}}}}},"400":{"description":"state fehlt/unbrauchbar, redirectUri ist keine Loopback-Adresse ODER frisch ist kein Boolean (ApiErrorBody, code invalid_request)"},"429":{"description":"zu viele gleichzeitig offene Anmeldevorgänge (ApiErrorBody, code invalid_request)"}}}},"/api/cli/login/exchange":{"post":{"summary":"Schritt 3 des CLI-Browser-Logins: tauscht den einmaligen Rückruf-Code gegen den Session-Token (nur im Antwort-Body, nie in einer URL).","operationId":"exchangeCliLoginCode","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["loginId","code"],"properties":{"loginId":{"type":"string","description":"Die `loginId` aus Schritt 1."},"code":{"type":"string","description":"Der einmalige Code aus dem Loopback-Rückruf."}}}}}},"responses":{"200":{"description":"Session-Token (Bearer) — ausschließlich hier im Body, nie in einer URL (Query-Strings landen in Access-Logs, Proxy-Logs und der Browser-History). Gehört in eine sichere Ablage, nie in eine Ausgabe.","content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","description":"Better-Auth-Session-Token für `Authorization: Bearer <token>`."}}}}}},"400":{"description":"Anmeldevorgang unbekannt, abgelaufen, noch nicht bestätigt oder bereits eingelöst (ApiErrorBody, code invalid_request)"}}}},"/api/abrechnung":{"post":{"summary":"Startet einen Betriebskosten-Abrechnungslauf (start_billing_run) — Readiness fail-closed, Eingabe INV-TIME-01-gebunden.","operationId":"startAbrechnung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Der Umgriff des Laufs. `unitGroupId` schränkt optional auf EINEN Abrechnungskreis ein. Der Start bindet BEIDE Geld-Seiten reproduzierbar (binding_content_hash) — die Umlage-Eingabe und, seit #1812, die VZ-Stammdaten der Gegenrechnung als eigenen vz-Zweig. Dieselbe Eingabe ergibt deterministisch dasselbe Ergebnis, und eine spätere Stammdatenänderung verschiebt die Zahlen dieses Laufs nicht.","required":["propertyId","periodFrom","periodTo"],"properties":{"propertyId":{"type":"string","format":"uuid"},"unitGroupId":{"type":"string","format":"uuid","nullable":true,"description":"Optionaler Abrechnungskreis-Umgriff."},"periodFrom":{"type":"string","format":"date","description":"Beginn des Abrechnungszeitraums (einschließlich)."},"periodTo":{"type":"string","format":"date","description":"Ende des Abrechnungszeitraums (einschließlich)."},"sourceSystem":{"type":"string","nullable":true,"description":"Herkunftssystem (Migration/Import)."},"sourceRef":{"type":"string","nullable":true,"description":"Herkunftsreferenz (Migration/Import)."}}}}}},"responses":{"201":{"description":"Lauf gestartet — die Antwort trägt den bindingContentHash (INV-TIME-01), das Bindungs-Siegel BEIDER Geld-Seiten: Umlage-Eingabe UND VZ-Stammdaten der Gegenrechnung (seit #1812).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbrechnungStartResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"unbekanntes ODER fremdes Objekt (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"blockierende Readiness-Befunde oder bereits ein offener Lauf (ApiErrorBody, code conflict)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/abrechnung/{id}":{"get":{"summary":"Liest die Ergebniszahlen eines Abrechnungslaufs maschinenlesbar — Geld ausschließlich als Integer-STRING, cent-genau.","operationId":"getAbrechnungErgebnis","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Ergebniszahlen des Laufs. GELD REIST AUSSCHLIESSLICH ALS INTEGER-STRING ({ cents: \"<Integer>\", currency: \"EUR\" }), ustRatePercent ebenso — nie als JSON-number: Beträge jenseits 2^53 überleben so exakt. `null` bleibt `null` (Wohnraum hat KEINEN USt-Satz, das ist etwas anderes als 0 %). Ist der Lauf nicht rechenbar, ist `umlage` EXPLIZIT `null` mit Klartext in `umlageFehler` und den `readinessFindings` — NIE ein leeres `lines`-Array (das wäre von „alles verteilt, Summe 0\" nicht unterscheidbar). `rechenbar` ist abgeleitet (umlage !== null && gegenrechnung !== null). `lines`, `totalUmlagefaehig` und `totalVerteiltNetto` reisen zusammen, damit INV-BK-01 am gelieferten Dokument nachprüfbar bleibt. WIEDERHOLBARKEIT: run, umlage, gegenrechnung und readinessFindings stammen aus dem gebundenen Snapshot und sind bei zweimaligem Lesen byte-gleich — seit #1812 auch die VZ-Seite, die als eigener vz-Zweig im Snapshot liegt und in den bindingContentHash eingeht. EINZIGE Ausnahme: ein vor #1812 gebundener ALT-Lauf hat keinen vz-Zweig; seine VZ-Stammdaten werden weiterhin bei jedem Lesen live gelesen, ohne dass sich bindingContentHash ändert.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbrechnungErgebnisResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannter Lauf, fremder Tenant ODER keine UUID (ApiErrorBody, code not_found — kein Existenz-Orakel, insbesondere kein 403)"}}}},"/api/abrechnung/{id}/s35a-bescheinigungen":{"get":{"summary":"Erzeugt die §35a-Bescheinigungen ALLER Wohnraum-Mieter eines FESTGESCHRIEBENEN Abrechnungslaufs (Serienlauf je Objekt) — Geld ausschließlich als Integer-STRING.","operationId":"getAbrechnungS35aBescheinigungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["json","pdf"]},"description":"Ohne Angabe (oder `json`) die JSON-Serie; `pdf` liefert EIN Dokument (application/pdf) mit je Bescheinigung einer Seite."}],"responses":{"200":{"description":"Die Serie: je Wohnraum-Vertrag mit Anteil > 0 eine Bescheinigung (Nutzungszeitraum, Einheiten, je §35a-Kategorie der Arbeits-/Lohnkostenanteil; bei Bewohnerwechsel zeitanteilig, Mehrfachbuchungen summiert). Je Vertrag dieselbe Summe wie im §35a-Ausweis der NK-Abrechnung. Gewerbemieter und Eigentümer-Leerstand erhalten keine Bescheinigung; ein Betrag ohne mieterscharfen Anteil steht mit Grund in nichtBescheinigt. INVARIANTE: summeBescheinigungen + summeNichtBescheinigt = summeS35aKosten, cent-genau, Restcent deterministisch. Mit ?format=pdf stattdessen application/pdf (Content-Disposition attachment), byte-deterministisch.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/S35aBescheinigungenResponse"}},"application/pdf":{"schema":{"type":"string","format":"binary","description":"Nur mit ?format=pdf: EIN PDF, je Bescheinigung eine Seite (Content-Disposition attachment)."}}}},"400":{"description":"unbekanntes Format oder unbekannter Query-Parameter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannter Lauf, fremder Tenant ODER keine UUID (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Lauf nicht festgeschrieben, Bestandslauf ohne beim Binden gesiegelte §35a-Klassifikation bzw. ohne gesiegelte Anzeigefelder (nie Live-Fallback), oder seine §35a-Belege sind nicht bescheinigungsfähig (Kategorie fehlt, Buchungsdatum außerhalb des Zeitraums) — ApiErrorBody, code conflict, ohne Zahl"}}}},"/api/abrechnung/{id}/berechnet":{"post":{"summary":"Setzt den Lauf auf `berechnet` (mark_billing_run_berechnet) — nur bei freigabefähigem Prüfbericht. KEIN Body.","operationId":"markAbrechnungBerechnet","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Übergang vollzogen (id, status).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbrechnungBerechnetResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"unbekannter Lauf, fremder Tenant ODER keine UUID (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Prüfbericht nicht freigabefähig — der Lauf bleibt Entwurf (ApiErrorBody, code conflict)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/auswertung/ust-liste":{"get":{"summary":"Umsatzsteuer, Vorsteuer und Zahllast eines Objekts über einen Zeitraum — je Steuersatz, auf Wunsch je Konto.","operationId":"getAuswertungUstListe","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Objekt (Buchungskreis)."},{"name":"von","in":"query","required":true,"schema":{"type":"string","format":"date"},"description":"Erster Tag des Zeitraums (einschliesslich)."},{"name":"bis","in":"query","required":true,"schema":{"type":"string","format":"date"},"description":"Letzter Tag des Zeitraums (einschliesslich)."},{"name":"rhythmus","in":"query","required":false,"schema":{"type":"string","enum":["monat","quartal","jahr"]},"description":"Rhythmus der ausgewiesenen Perioden (Default quartal)."},{"name":"je-konto","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]},"description":"true ⇒ die Antwort trägt zusätzlich das Detail je Konto und Satz (`zeilen`); sonst ist `zeilen` null. Kebab-Schreibweise, weil die CLI-Flagge `--je-konto` unverändert durchgereicht wird."}],"responses":{"200":{"description":"Umsatzsteuer-Liste des Objekts (UstListeResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UstListeResponse"}}}},"400":{"description":"Objekt-Referenz, Zeitraum oder Rhythmus unbrauchbar (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/offene-posten":{"get":{"summary":"Liest die offenen Posten des Mandanten samt der drei getrennten Summen (Rückstand · Guthaben · Saldo).","operationId":"listOffenePosten","security":[{"bearerAuth":[]}],"parameters":[{"name":"propertyId","in":"query","required":false,"description":"Auf EIN Objekt eingrenzen (Filter, keine Autorisierung).","schema":{"type":"string","format":"uuid"}},{"name":"contractId","in":"query","required":false,"description":"Auf EINEN Debitor eingrenzen.","schema":{"type":"string","format":"uuid"}},{"name":"geldkreis","in":"query","required":false,"schema":{"type":"string","enum":["miete","weg_hausgeld","sev"]}},{"name":"menge","in":"query","required":false,"description":"`offen` (Default) = die Arbeitsliste (offen/teilweise); `alle` zusätzlich die erledigten Posten.","schema":{"type":"string","enum":["offen","alle"]}},{"name":"richtung","in":"query","required":false,"description":"Weggelassen ⇒ ALLE Richtungen. Kein Default auf `forderung` — sonst verschwänden Guthaben aus der Standardsicht.","schema":{"type":"string","enum":["forderung","guthaben","verbindlichkeit"]}},{"name":"dueFrom","in":"query","required":false,"description":"Untere Grenze der Fälligkeits-Achse (einschließlich).","schema":{"type":"string","format":"date"}},{"name":"dueTo","in":"query","required":false,"description":"Obere Grenze der Fälligkeits-Achse (einschließlich).","schema":{"type":"string","format":"date"}},{"name":"stichtag","in":"query","required":false,"description":"Stichtag der Verzugstage; weggelassen ⇒ heute.","schema":{"type":"string","format":"date"}},{"name":"archiveScope","in":"query","required":false,"description":"3-Wege-Filter auf die Archiv-Kette; Default `aktiv`. Der Read filtert, er verschweigt nichts — `alle` liefert auch archivierte Objekte.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}},{"name":"asOf","in":"query","required":false,"description":"Stichtag der Archiv-Achse. OHNE asOf misst der Read auf `archived_at` (Betriebs-Default), MIT asOf auf dem Verwaltungszeitraum.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Posten + Summen aus DERSELBEN Projektion (ADR 0011, INV-OP-01). Alle Cent-Felder sind vorzeichenbehaftete Integer-STRINGS, nie JSON-numbers. Rückstand, Guthaben und Saldo stehen GETRENNT: „Rückstand gesamt\" ist rueckstandCents — dort verschwindet kein Mahnfall hinter einem fremden Guthaben.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OffenePostenListResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request — Feldname + Regel, nie der Wert)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/auswertung/saldenliste":{"get":{"summary":"Summen- und Saldenliste der Sachkonten EINES Objekts für einen Zeitraum: je Konto Anfangsbestand, Soll- und Haben-Umsatz und Endsaldo, gegliedert nach Kontenklassen.","operationId":"getSaldenliste","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Objekt (Buchungskreis). PFLICHT: `account_no` ist nur JE OBJEKT eindeutig — ohne Eingrenzung vermischte die Liste gleichnamige Konten verschiedener Objekte.","schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":true,"description":"Beginn des Zeitraums (einschließlich). Alles davor ist der Anfangsbestand.","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":true,"description":"Ende des Zeitraums (einschließlich). Sätze danach zählen nirgends mit.","schema":{"type":"string","format":"date"}},{"name":"nurBewegt","in":"query","required":false,"description":"`true` ⇒ nur Konten mit mindestens einer Buchung IM Zeitraum. Konten mit Vortrag, aber ohne Bewegung, entfallen dann ebenfalls (gefilterteKonten nennt ihre Zahl).","schema":{"type":"string","enum":["true","false"]}},{"name":"format","in":"query","required":false,"description":"`json` (Vorgabe) oder `csv`. Bei `csv` ist die Antwort `text/csv` (UTF-8 mit BOM, Semikolon, Dezimalkomma, CRLF) — nicht der JSON-Umschlag.","schema":{"type":"string","enum":["json","csv"]}}],"responses":{"200":{"description":"Die Liste. Alle Cent-Felder sind vorzeichenbehaftete Integer-STRINGS, nie JSON-numbers — eine Jahressumme überschreitet 2^53. Bei format=csv ist der Body die fertige CSV-Datei (Content-Disposition attachment).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaldenlisteResponse"}},"text/csv":{"schema":{"type":"string","description":"CSV mit Kopfzeile, je Kontenklasse eine Zwischensummen-Zeile und am Ende die Gesamtsumme."}}}},"400":{"description":"ungültige Query — fehlendes/verdrehtes Datum, fehlende oder unbrauchbare Objekt-Referenz (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/auswertungen":{"get":{"summary":"Der Katalog der Auswertungen: welche Berichte es gibt, welche Zeitachsen sie kennen und welche Spalten sie liefern.","operationId":"getAuswertungsKatalog","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Der Katalog. Die Reihenfolge ist die Lesefolge der Buchhaltung, nicht die Einfüge-Reihenfolge.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuswertungKatalogResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/auswertungen/{auswertung}":{"get":{"summary":"EINE Auswertung des Katalogs für ein Objekt und einen Zeitraum, als JSON oder CSV — mit Quellenangabe (Mandant, Objekt, Zeitraum, Datenstand).","operationId":"getAuswertung","security":[{"bearerAuth":[]}],"parameters":[{"name":"auswertung","in":"path","required":true,"description":"Katalog-Name des Berichts (`GET /api/auswertungen` nennt die verfügbaren).","schema":{"type":"string"}},{"name":"objekt","in":"query","required":true,"description":"Objekt (Buchungskreis). PFLICHT: Kontonummern sind nur JE OBJEKT eindeutig, und die Quellenangabe muss sagen, für welches Objekt die Zahl gilt.","schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":true,"description":"Beginn des Zeitraums (einschließlich). PFLICHT — ein Export ohne Untergrenze ist später nicht vergleichbar.","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":true,"description":"Ende des Zeitraums (einschließlich). PFLICHT — sonst änderte derselbe Ausdruck morgen sein Ergebnis.","schema":{"type":"string","format":"date"}},{"name":"stichtag","in":"query","required":false,"description":"Nur bei Auswertungen mit Zeitbezug `zeitraum-und-stichtag` (offene Posten: Stichtag der Verzugstage). Vorgabe: der Abruftag.","schema":{"type":"string","format":"date"}},{"name":"format","in":"query","required":false,"description":"`json` (Vorgabe) oder `csv`. Bei `csv` ist die Antwort `text/csv` (UTF-8 mit BOM, Semikolon, Dezimalkomma, CRLF) mit der Quellenangabe als Kopfzeilen.","schema":{"type":"string","enum":["json","csv"]}},{"name":"nurBewegt","in":"query","required":false,"description":"Nur `saldenliste`: `true` ⇒ nur Konten mit mindestens einer Buchung IM Zeitraum.","schema":{"type":"string","enum":["true","false"]}},{"name":"konto","in":"query","required":false,"description":"Nur `buchungsliste`: Kontonummer am Objekt — der Satz zählt, wenn EINE seiner Zeilen darauf liegt.","schema":{"type":"string"}},{"name":"beleg","in":"query","required":false,"description":"Nur `buchungsliste`: `mit` ⇒ die Beleg-Kette löst auf, `ohne` ⇒ sie löst nicht auf.","schema":{"type":"string","enum":["mit","ohne"]}},{"name":"menge","in":"query","required":false,"description":"Nur `offene-posten`: `offen` (Vorgabe) = Arbeitsliste, `alle` zusätzlich die erledigten Posten.","schema":{"type":"string","enum":["offen","alle"]}},{"name":"einheit","in":"query","required":false,"description":"Nur `hausgeld-steuerzuarbeit`: Einheit (alternativ `eigentuemer`).","schema":{"type":"string","format":"uuid"}},{"name":"eigentuemer","in":"query","required":false,"description":"Nur `hausgeld-steuerzuarbeit`: Eigentümer (alternativ `einheit`).","schema":{"type":"string","format":"uuid"}},{"name":"abschlusslauf","in":"query","required":false,"description":"Nur `hausgeld-steuerzuarbeit`: festgeschriebener Abschluss-Lauf. Ohne `einheit` ist die Antwort leer; fremder oder unbekannter Lauf ⇒ 404 (not_found), nicht festgeschriebener (unbestätigter, ohne Anker) oder stornierter Lauf ⇒ 409 (conflict); ohne Angabe gilt der aktive Lauf des Jahres (keiner ⇒ leer).","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Die Auswertung. Jede Zelle ist ein String oder null; `spalten[i].typ` sagt, wie sie zu lesen ist (`betrag` ⇒ Integer-Cents). Bei format=csv ist der Body die fertige CSV-Datei (Content-Disposition attachment), deren Kopfzeilen dieselbe Quellenangabe tragen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuswertungResponse"}},"text/csv":{"schema":{"type":"string","description":"CSV mit `# `-Quellenkopf, Leerzeile, Spalten-Kopfzeile und den Datenzeilen."}}}},"400":{"description":"ungültige Parameter — fehlendes Objekt oder Datum, verdrehter Zeitraum, oder ein Filter, den DIESE Auswertung nicht führt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"der Katalog führt diese Auswertung nicht (ApiErrorBody, code not_found)"}}}},"/api/auswertung/finanzstatus":{"get":{"summary":"Finanzstatus EINES Objekts: Entwicklung der Geldkonten im Zeitraum (Anfangsbestand, Zugänge, Abgänge, Endbestand, laufender Saldo je Buchung nach Wertstellung) und Vermögensübersicht zum Stichtag.","operationId":"getFinanzstatus","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Objekt (Buchungskreis). PFLICHT: `account_no` ist nur JE OBJEKT eindeutig — ohne Eingrenzung vermischte der Status gleichnamige Konten verschiedener Objekte.","schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"description":"Stichtag der Vermögensübersicht (EINSCHLIESSLICH). Entweder `stichtag` ODER `von`+`bis` — beides zusammen oder keins von beidem ist ein 400.","schema":{"type":"string","format":"date"}},{"name":"von","in":"query","required":false,"description":"Beginn des Zeitraums (einschließlich). Alles davor ist der Anfangsbestand der Geldkonten.","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":false,"description":"Ende des Zeitraums (einschließlich) und zugleich der Stichtag der mitgelieferten Vermögensübersicht.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Der Finanzstatus. Alle Cent-Felder sind vorzeichenbehaftete Integer-STRINGS, nie JSON-numbers — ein Jahresumsatz überschreitet 2^53. `entwicklung` ist im Stichtags-Modus `null`. `stimmt` und `bilanzgleichgewicht` werden AUSGEWIESEN, nicht erzwungen: eine Schieflage soll sichtbar sein.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinanzstatusResponse"}}}},"400":{"description":"ungültige Query — fehlende/unbrauchbare Objekt-Referenz, kein oder doppelter Modus, verdrehter Zeitraum (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/honorar/vorschau":{"get":{"summary":"Verwalterhonorar EINES Objekts für EINEN Monat als Vorschau: Positionsaufstellung je Einheit/Basis/Zuschlag, Netto, Umsatzsteuer und Brutto — ohne Buchung.","operationId":"getHonorarVorschau","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Objekt, dessen Verwaltungsvertrag abgerechnet wird. Die Honorarvereinbarung hängt je Objekt, es gibt keinen mandantenweiten Default.","schema":{"type":"string","format":"uuid"}},{"name":"monat","in":"query","required":true,"description":"Abrechnungsmonat `JJJJ-MM`. Das Honorar ist eine monatliche Größe; ein Teilmonat ist nicht vereinbart und wird benannt abgelehnt (409 conflict), statt eine Tageskonvention zu erfinden.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$"}}],"responses":{"200":{"description":"Die Aufstellung. Alle Cent-Felder und der USt-Satz sind Integer-STRINGS, nie JSON-numbers.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HonorarVorschauResponse"}}}},"400":{"description":"ungültige Query oder unbrauchbar gespeicherte Vereinbarung (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"für dieses Objekt ist keine Honorarvereinbarung hinterlegt (oder das Objekt gehört einem anderen Mandanten — unter RLS ununterscheidbar, kein Existenz-Orakel). Hinterlegt wird sie als OBJEKT-Option unter dem Schlüssel `verwalterhonorar.vereinbarungen` über `POST /api/option`; ihr Wert ist die LISTE der Zeitscheiben."},"409":{"description":"nicht berechenbar: keine Zeitscheibe für den Monat (Lücke oder Wechsel mitten im Monat), Eigenbestand ohne Honorar, Monat nicht vollständig im Verwaltungszeitraum oder vereinbarter Zuschlag ohne Ereignisquelle (ApiErrorBody, code conflict)"}}}},"/api/honorar/rentabilitaet":{"get":{"summary":"Rentabilität EINES Objekts über einen Zeitraum ganzer Monate: Ertrag, Aufwand, Deckungsbeitrag, Marge, Kapazitätsanteil und Urteil samt den geltenden Kalkulationssätzen. Ohne erfasste Zeit lautet das Urteil nicht-beurteilbar, nie wirtschaftlich.","operationId":"getRentabilitaet","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Das Objekt.","schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":true,"description":"Erster Monat `JJJJ-MM` (inklusiv).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$"}},{"name":"bis","in":"query","required":true,"description":"Letzter Monat `JJJJ-MM` (inklusiv), höchstens 24 Monate ab von.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$"}}],"responses":{"200":{"description":"Alle Cent-Felder und Basispunkte sind Integer-STRINGS; margeBasispunkte ist null ohne Ertrag. Keine Mitarbeiternamen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RentabilitaetResponse"}}}},"400":{"description":"ungültige Query, Zeitraum ungültig oder länger als 24 Monate (zeitraum-zu-lang), oder unbrauchbare Kalkulations-Option mit Regel-Text (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt oder mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/zaehler":{"get":{"summary":"Zähler des Mandanten (optional je Objekt, Einheit, Zählerart) — mit Einheitsnummer, Art, Maßeinheit und Archivstand.","operationId":"listZaehler","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":false,"description":"Nur Zähler dieses Objekts.","schema":{"type":"string","format":"uuid"}},{"name":"einheit","in":"query","required":false,"description":"Nur Zähler dieser Einheit.","schema":{"type":"string","format":"uuid"}},{"name":"zaehlerart","in":"query","required":false,"description":"Nur Zähler dieser Art (z. B. `kaltwasser`).","schema":{"type":"string"}},{"name":"archiveScope","in":"query","required":false,"description":"Archivstand der Zähler: `aktiv` (Default), `archiviert` oder `alle`.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}}],"responses":{"200":{"description":"Die Zähler.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerListeResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt einen Zähler an (create_meter). Ohne Nummer: Nummernkreis `KW|WW|HZ|ST-<Turnusjahr>-NNN` als Vorgabe; die Antwort nennt die vergebene Nummer. Objekt und Standort sind danach fest. Derselbe Idempotency-Key legt nur einen Zähler an.","operationId":"legeZaehlerAn","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerAnlegenRequest"}}}},"responses":{"201":{"description":"Der angelegte Zähler.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerGespeichertResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld, Nummer und Präfix zugleich oder Einheit eines anderen Objekts (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent, keine Zuständigkeit für das Objekt oder Testzeitraum abgelaufen (ApiErrorBody, code forbidden)"},"404":{"description":"unbekanntes ODER fremdes Objekt bzw. unbekannter oder fremder Zähler — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Objekt oder Einheit ist archiviert (ApiErrorBody, code conflict)"}}}},"/api/zaehler/{id}/ablesungen":{"get":{"summary":"Ablesungs-Historie EINES Zählers, aufsteigend nach Ablesezeitpunkt; Stände als Dezimal-Strings (Skala 3).","operationId":"listZaehlerAblesungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":false,"description":"Erster Kalendertag `JJJJ-MM-TT` (inklusiv).","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":false,"description":"Letzter Kalendertag `JJJJ-MM-TT` (inklusiv).","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Die Ablesungen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerAblesungenResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannter ODER fremder Zähler — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"post":{"summary":"Erfasst eine Ablesung (record_meter_reading). Plausibilitäts-Warnungen (Ausreißer, Verbrauch null) und Hinweise (Ablesefenster) stehen in `plausibilitaet`; sie sind KEIN Fehler, der Stand ist dann gespeichert. Die Zwischenablesung am Tag des Mieterwechsels ist Voraussetzung der Verbrauchs-Zuordnung je Vertrag. Derselbe Idempotency-Key erfasst nur eine Ablesung.","operationId":"erfasseZaehlerAblesung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerAblesenRequest"}}}},"responses":{"201":{"description":"Die gespeicherte Ablesung mit Plausibilitäts-Ergebnis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerAbgelesenResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld (auch die Zähler-Id im Body) oder Stand mit Komma statt Punkt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent, keine Zuständigkeit für das Objekt oder Testzeitraum abgelaufen (ApiErrorBody, code forbidden)"},"404":{"description":"unbekannter ODER fremder Zähler bzw. unbekannte oder fremde Ablesung — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Zähler archiviert, Stand unter dem Vorstand (negativer Verbrauch) oder Zeitpunkt schon belegt (ApiErrorBody, code conflict, Klartext der Maske)"}}}},"/api/zaehler/{id}/tausch":{"post":{"summary":"Tauscht einen Zähler als EINE Fachhandlung (replace_meter): Endstand des Altzählers, Neuzähler (`replaces_meter_id`), Anfangsstand (Standard 0.000), Altzähler archiviert. Die Antwort nennt die Id des neuen Zählers.","operationId":"tauscheZaehler","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerTauschRequest"}}}},"responses":{"201":{"description":"Alt- und Neuzähler mit beiden Ständen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerGetauschtResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld (auch die Zähler-Id im Body) oder Stand mit Komma statt Punkt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent, keine Zuständigkeit für das Objekt oder Testzeitraum abgelaufen (ApiErrorBody, code forbidden)"},"404":{"description":"unbekannter ODER fremder Zähler bzw. unbekannte oder fremde Ablesung — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Zähler archiviert, Endstand unter dem Vorstand oder Zeitpunkt belegt (ApiErrorBody, code conflict, Klartext der Maske)"}}}},"/api/ablesung/{id}":{"patch":{"summary":"Berichtigt den Stand EINER Ablesung (correct_meter_reading); Zeitpunkt und Anlass bleiben. Antwort mit `stand`, `vorherigerStand` und neu gerechneter `plausibilitaet`. Eine Ablesung, auf der eine festgeschriebene Abrechnung beruht, ist gesperrt (409).","operationId":"berichtigeAblesung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AblesungBerichtigenRequest"}}}},"responses":{"200":{"description":"Die berichtigte Ablesung mit altem und neuem Stand.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AblesungBerichtigtResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld (auch die Zähler-Id im Body) oder Stand mit Komma statt Punkt (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent, keine Zuständigkeit für das Objekt oder Testzeitraum abgelaufen (ApiErrorBody, code forbidden)"},"404":{"description":"unbekannter ODER fremder Zähler bzw. unbekannte oder fremde Ablesung — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"festgeschriebene Abrechnung beruht auf der Ablesung (ABRECHNUNG_FESTGESCHRIEBEN), Zähler archiviert oder negativer Verbrauch (ApiErrorBody, code conflict, Klartext)"}}}},"/api/zaehler/sammelanlage":{"post":{"summary":"Legt denselben Zählertyp für mehrere Einheiten EINES Objekts an (create_meters_for_units, höchstens 500 Einheiten). Je Einheit `angelegt` oder `vorhanden`; eine Wiederholung legt nur Fehlendes an.","operationId":"legeZaehlerSammelanlage","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerSammelanlageRequest"}}}},"responses":{"200":{"description":"Je Einheit angelegt oder vorhanden.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerSammelanlageResponse"}}}},"400":{"description":"ungültige Eingabe, unbekanntes Feld, doppelte Einheit, Nummer und Nummernkreis zugleich oder Einheit eines anderen Objekts (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent, keine Zuständigkeit für das Objekt oder Testzeitraum abgelaufen (ApiErrorBody, code forbidden)"},"404":{"description":"unbekanntes ODER fremdes Objekt bzw. unbekannter oder fremder Zähler — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Objekt oder Einheit ist archiviert (ApiErrorBody, code conflict)"}}}},"/api/zaehler/{id}":{"patch":{"summary":"Ändert Zählerart, Zählernummer oder Maßeinheit (update_meter); mindestens ein Feld. Objekt und Standort sind nach der Anlage fest (400).","operationId":"aendereZaehler","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerAendernRequest"}}}},"responses":{"200":{"description":"Der geänderte Zähler.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerGespeichertResponse"}}}},"400":{"description":"leerer Patch, unbekanntes Feld (auch propertyId/unitId) oder ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent, keine Zuständigkeit für das Objekt oder Testzeitraum abgelaufen (ApiErrorBody, code forbidden)"},"404":{"description":"unbekanntes ODER fremdes Objekt bzw. unbekannter oder fremder Zähler — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"der Zähler ist archiviert (ApiErrorBody, code conflict)"}}}},"/api/zaehler/{id}/archiv":{"post":{"summary":"Legt einen Zähler still (archive_meter). Ein zweites Archivieren ist 200 mit `bereitsArchiviert: true`. Ein Zähler mit Ablesungen lässt sich erst nach dem Stand zum jüngsten Periodenende stilllegen (409 OFFENE_ABLESUNG).","operationId":"archiviereZaehler","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ id, archiviertAm, bereitsArchiviert }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerArchiviertResponse"}}}},"400":{"description":"ungültige Zähler-Id oder ein Feld im Body — der Body ist leer (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent, keine Zuständigkeit für das Objekt oder Testzeitraum abgelaufen (ApiErrorBody, code forbidden)"},"404":{"description":"unbekanntes ODER fremdes Objekt bzw. unbekannter oder fremder Zähler — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"offene Ablesung: der Stand zum jüngsten Periodenende fehlt (ApiErrorBody, code conflict, Klartext der Maske)"}}}},"/api/zaehler/verbrauch":{"get":{"summary":"Verbrauch je Zähler und je (Einheit, Zählerart) für einen Zeitraum. Anfangsstand = letzter Stand bis zum Periodenbeginn (auch aus dem Vorjahr). Fehlt eine Grenze, steht `vollstaendig: false` mit `fehlend` — nie interpoliert.","operationId":"getZaehlerVerbrauch","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Objekt, dessen Zähler abgeleitet werden.","schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":true,"description":"Erster Kalendertag `JJJJ-MM-TT` (inklusiv).","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":true,"description":"Letzter Kalendertag `JJJJ-MM-TT` (inklusiv).","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Der Verbrauch; Stände und Verbrauch sind Dezimal-Strings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerVerbrauchResponse"}}}},"400":{"description":"ungültige Query oder Zeitraum (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekanntes ODER fremdes Objekt — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/zaehler/{id}/zwischenstand":{"get":{"summary":"Zwischenstand-VORSCHLAG eines Zählers für einen Stichtag (Mieterwechsel): linear nach Kalendertagen zwischen dem letzten Stand davor und dem ersten danach, mit Begründung. Wird NICHT gebucht und ist nie ein Wert des Abrechnungslaufs; übernehmen heißt, die Ablesung selbst zu erfassen (Anlass zwischenablesung, Erhebungsart schaetzung). Nur lesend.","operationId":"getZaehlerZwischenstand","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":true,"description":"Stichtag `JJJJ-MM-TT`.","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Der Vorschlag oder der Grund, warum es keinen gibt (`code`); Stände sind Dezimal-Strings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerZwischenstandResponse"}}}},"400":{"description":"fehlender oder unlesbarer Stichtag bzw. unbekannter Parameter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannter ODER fremder Zähler — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/zaehler/pflicht":{"get":{"summary":"Erfassungspflicht nach HeizkostenV für Objekt und Zählerart (ab 3 Wohneinheiten, mit Ausnahme-Option `zaehler.erfassungspflicht_ausnahme`). Ein HINWEIS, keine Sperre; nur lesend.","operationId":"getZaehlerPflicht","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Das zu prüfende Objekt.","schema":{"type":"string","format":"uuid"}},{"name":"zaehlerart","in":"query","required":true,"description":"Zählerart, z. B. waerme, wasser_warm, wasser_kalt, strom.","schema":{"type":"string"}}],"responses":{"200":{"description":"Die Pflicht (`ja` · `nein` · `ausnahme` · `nicht-heizkostenv`) mit Hinweisen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZaehlerPflichtResponse"}}}},"400":{"description":"fehlende oder ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekanntes ODER fremdes Objekt — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"unbrauchbare Ausnahme-Option `zaehler.erfassungspflicht_ausnahme` am Objekt (ApiErrorBody) — mit Klartext abgelehnt statt geraten"}}}},"/api/objekt/{id}/brennstoffkonto":{"get":{"summary":"Liest das Brennstoffkonto eines Objekts: das aktive Konto mit Zustand und Zeitpunkt der Wahl, den gemerkten Ausgangszustand (`vorzustand`), den Befund (`brennstoffkonto-verteilt-doppelt`, wenn das Brennstoffkonto trotzdem umlagefähig ist oder einen Schlüssel trägt) und die Konten des Objekts mit Heizkosten-Kostenart als Auswahlhilfe. Nur lesend.","operationId":"getBrennstoffkonto","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Brennstoffkonto, Befund und Auswahlhilfe (BrennstoffkontoResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrennstoffkontoResponse"}}}},"400":{"description":"ungültige Objekt-Id (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekanntes ODER fremdes Objekt — dieselbe Meldung (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"post":{"summary":"Setzt das Brennstoffkonto des Objekts. Das Brennstoffkonto verteilt die Heizkosten über die Heizkostenabrechnung und darf nicht zusätzlich als Betriebskosten umgelegt werden; das Setzen macht das Konto nicht umlagefähig und entfernt den Umlageschlüssel (`bestaetigt: true` ist Pflicht, wenn es das verliert). Das frühere Brennstoffkonto geht auf seinen gespeicherten Ausgangszustand zurück. Ein Konto mit Buchungen wird nicht umgestellt. Der Idempotency-Key kommt vom Aufrufer.","operationId":"setzeBrennstoffkonto","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrennstoffkontoSetzenRequest"}}}},"responses":{"201":{"description":"Brennstoffkonto gesetzt (BrennstoffkontoGesetztResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrennstoffkontoGesetztResponse"}}}},"400":{"description":"ungültige Eingabe oder fehlende Bestätigung (umstellung-braucht-bestaetigung, die Meldung nennt, was verloren geht) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlende Zuständigkeit/Recht (ApiErrorBody, code forbidden)"},"404":{"description":"unbekanntes Objekt, unbekanntes, archiviertes oder objektfremdes Konto — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"bereits-brennstoffkonto oder konto-gebucht — Konto mit Buchungen wird nicht umgestellt (ApiErrorBody, code conflict)"}}}},"/api/objekt/{id}/brennstoffkonto/aufheben":{"post":{"summary":"Hebt das Brennstoffkonto des Objekts auf: die Markierung endet, das Konto geht auf seinen gespeicherten Ausgangszustand zurück (`bestaetigt: true` ist Pflicht, wenn es dadurch wieder umlagefähig wird oder einen Schlüssel erhält). Ein inzwischen gebuchtes Konto bleibt wie es ist. Der Idempotency-Key kommt vom Aufrufer.","operationId":"hebeBrennstoffkontoAuf","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrennstoffkontoAufhebenRequest"}}}},"responses":{"200":{"description":"Brennstoffkonto aufgehoben (BrennstoffkontoAufgehobenResponse)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrennstoffkontoAufgehobenResponse"}}}},"400":{"description":"ungültige Eingabe oder fehlende Bestätigung (umstellung-braucht-bestaetigung) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder fehlende Zuständigkeit/Recht (ApiErrorBody, code forbidden)"},"404":{"description":"unbekanntes Objekt oder das Objekt hat kein Brennstoffkonto (ApiErrorBody, code not_found)"}}}},"/api/honorar/lauf/vorschlag":{"post":{"summary":"Vorschlag des Honorarlaufs EINES Objekts für EINE Periode (Monat oder Quartal, passend zum Rhythmus, #5583): die Rechnung aus der Honorarvorschau, das für die Periode schon Gebuchte, die Differenz, ob eine Entnahme entstünde, und der Inhalts-Hash — ohne zu schreiben.","operationId":"honorarlaufVorschlag","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["propertyId","monat"],"additionalProperties":false,"properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","pattern":"^\\d{4}-(?:\\d{2}|Q[1-4])$","description":"Abrechnungsperiode: Monat `JJJJ-MM` oder Quartal `JJJJ-Qn` (n = 1…4), passend zum Rhythmus der Buchungskonfiguration (#5583)"}}}}}},"responses":{"200":{"description":"der Vorschlag — { propertyId, monat, nettoCents, umsatzsteuerCents, bruttoCents, currency, positionen, sonderleistungen, sonderleistungenNettoCents, sonderleistungenUmsatzsteuerCents, monatsrechnungen, gebuchtCents, differenzCents (vorzeichenbehaftet), entnahme, buchungsteile, vorschlagHash }. Cent-Felder sind Integer-STRINGS. Beim Quartal (#5583) ist die Rechnung die Summe der drei `monatsrechnungen`, die der `vorschlagHash` mitdeckt. Jede erfasste, nicht stornierte Sonderleistung des Monats ist eine EIGENE Position mit eigener USt (#5189). `buchungsteile` zeigt die Sätze, die das Stellen bucht — Gutschrift und Rechnung getrennt, nie saldiert (ein gleich teurer Tausch hat Differenz 0, bucht aber beide).","content":{"application/json":{"schema":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string"},"nettoCents":{"type":"string"},"umsatzsteuerCents":{"type":"string"},"bruttoCents":{"type":"string"},"currency":{"type":"string"},"positionen":{"type":"array","items":{"type":"object","additionalProperties":true}},"sonderleistungen":{"type":"array","items":{"$ref":"#/components/schemas/HonorarSonderleistungPosition"},"description":"Die nicht stornierten Sonderleistungen des Monats (#5189), je Erfassung eine Position mit eigener USt, nach Leistungsdatum."},"sonderleistungenNettoCents":{"type":"string","description":"Σ Netto der Sonderleistungen"},"sonderleistungenUmsatzsteuerCents":{"type":"string","description":"Σ USt der Sonderleistungen (je Position gerundet)"},"monatsrechnungen":{"type":"array","description":"Die Monatsrechnungen der Periode (#5583) in Monatsfolge — beim Quartal die drei Summanden der Rechnung oben, je Monat derselbe Rechenweg wie die Honorarvorschau; der `vorschlagHash` deckt sie mit (gleiche Summe, andere Verteilung ⇒ anderer Hash). Beim Monat genau ein Eintrag, gleich der Rechnung oben.","items":{"type":"object","properties":{"monat":{"type":"string","description":"Abrechnungsmonat `JJJJ-MM`"},"nettoCents":{"type":"string"},"umsatzsteuerCents":{"type":"string"},"bruttoCents":{"type":"string"},"currency":{"type":"string"},"positionen":{"type":"array","items":{"type":"object","additionalProperties":true}},"sonderleistungen":{"type":"array","items":{"$ref":"#/components/schemas/HonorarSonderleistungPosition"}},"sonderleistungenNettoCents":{"type":"string","description":"Σ Netto der Sonderleistungen des Monats"},"sonderleistungenUmsatzsteuerCents":{"type":"string","description":"Σ USt der Sonderleistungen des Monats"}}}},"gebuchtCents":{"type":"string","description":"Σ der wirksamen (nicht stornierten) Honorarbuchungen der Periode"},"differenzCents":{"type":"string","description":"Brutto − Gebuchtes (Saldo, vorzeichenbehaftet); sagt NICHT, ob ein Start bucht — auch bei 0 bucht ein Gleichpreistausch Gutschrift und Neuberechnung; maßgeblich sind allein `buchungsteile`"},"entnahme":{"type":"boolean","description":"ob beim Stellen ein Entnahmeauftrag in die Zahlungsfreigabe ginge"},"buchungsteile":{"type":"object","description":"Die Sätze, die das Stellen bucht (#5189) — je Teil ≠ 0 ein eigener Satz mit eigener Rechnungsnummer, nie gegeneinander aufgerechnet.","properties":{"gutschriftCents":{"type":"string","description":"Betrag (≥ 0) des Gutschrift-Satzes; \"0\" heisst: keine Gutschrift"},"rechnungCents":{"type":"string","description":"Betrag (≥ 0) des Rechnungs-Satzes; \"0\" heisst: keine Rechnung"},"neueSonderleistungen":{"type":"array","items":{"$ref":"#/components/schemas/HonorarSonderleistungPosition"},"description":"Sonderleistungen, die der Rechnungs-Satz neu abrechnet"},"gutgeschriebeneSonderleistungen":{"type":"array","items":{"$ref":"#/components/schemas/HonorarSonderleistungPosition"},"description":"stornierte, schon abgerechnete Sonderleistungen, die der Gutschrift-Satz gutschreibt"}}},"vorschlagHash":{"type":"string","description":"Hex-SHA-256 des Inhalts — mit ihm wird gestellt"}}}}}},"400":{"description":"ungültige Eingabe oder unbrauchbar gespeicherte Vereinbarung (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"keine Honorarvereinbarung hinterlegt ODER Objekt mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"nicht stellbar: keine gültige Buchungskonfiguration (Objekt-Option `verwalterhonorar.buchung`), keine Zeitscheibe für den Monat, Eigenbestand oder Monat ausserhalb des Verwaltungszeitraums (ApiErrorBody, code conflict)"}}}},"/api/honorar/lauf":{"post":{"summary":"Stellt das Verwalterhonorar EINES Objekts für EINE Periode — Monat oder Quartal, passend zum Rhythmus (#5583) — (stelle_verwalterhonorar): Soll Aufwand „Verwaltervergütung\" an Haben Kreditor Verwalter, Rechnungsnummer aus dem Nummernkreis des Verwalters (HON-nnnnnn). NUR mit dem Inhalts-Hash aus POST /api/honorar/lauf/vorschlag. Genau einmal je Periode — ein zweiter Start ist `unveraendert`, eine geänderte Vereinbarung eine Differenzbuchung. Bei vereinbarter Entnahme ein Zahlungsauftrag `awaiting-approval` in der bestehenden Zahlungsfreigabe (gib_zahlungsauftrag_frei, Vier-Augen) — nie direkt ausgeführt.","operationId":"stelleVerwalterhonorar","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["propertyId","monat","vorschlagHash","requestedExecutionDate"],"additionalProperties":false,"properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","pattern":"^\\d{4}-(?:\\d{2}|Q[1-4])$","description":"Abrechnungsperiode: Monat `JJJJ-MM` oder Quartal `JJJJ-Qn` (n = 1…4), passend zum Rhythmus der Buchungskonfiguration (#5583)"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/honorar/lauf/vorschlag — Bestätigung, keine Datenquelle"},"requestedExecutionDate":{"type":"string","format":"date","description":"Ausführungstag eines Entnahmeauftrags — explizit, nie implizit „heute\""}}}}}},"responses":{"200":{"description":"gestellt — { laufId, propertyId, monat, ergebnis (gebucht · differenz_gebucht · unveraendert), buchung, paymentOrderId, paymentOrderContentHash }","content":{"application/json":{"schema":{"type":"object","properties":{"laufId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string"},"ergebnis":{"type":"string","enum":["gebucht","differenz_gebucht","unveraendert"]},"buchung":{"type":"object","nullable":true,"properties":{"entryId":{"type":"string","format":"uuid"},"rechnungsnummer":{"type":"string"},"betragCents":{"type":"string","description":"vorzeichenbehaftet; negativ bei einer gesenkten Vereinbarung"}}},"paymentOrderId":{"type":"string","format":"uuid","nullable":true},"paymentOrderContentHash":{"type":"string","nullable":true}}}}}},"400":{"description":"ungültige Eingabe — u. a. ein unbekanntes Feld (Betrag und Konten kommen nie aus der Eingabe) (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht, keine Zuständigkeit für das Objekt oder kein menschlicher Akteur (ApiErrorBody, code forbidden)"},"404":{"description":"keine Honorarvereinbarung hinterlegt ODER Objekt mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Inhalt seit dem Vorschlag geändert, keine gültige Buchungskonfiguration, keine eindeutige bestätigte Bankverbindung des Verwalters für die Entnahme oder ein gleichzeitiger Lauf derselben Periode — es wird nichts gebucht (ApiErrorBody, code conflict)"}}}},"/api/honorar/lauf/storno":{"post":{"summary":"Storniert den Honorarlauf EINES Objekts für EINE Periode — Monat oder Quartal (#5583) — (storniere_verwalterhonorar): je wirksamer Honorarbuchung ein Storno-Satz über den bestehenden Storno-Weg (storno_entry, Periode des Originals) und Abbruch noch nicht eingereichter Entnahmeaufträge. Danach ist die Periode neu stellbar.","operationId":"storniereVerwalterhonorar","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["propertyId","monat","reason"],"additionalProperties":false,"properties":{"propertyId":{"type":"string","format":"uuid"},"monat":{"type":"string","pattern":"^\\d{4}-(?:\\d{2}|Q[1-4])$","description":"Abrechnungsperiode: Monat `JJJJ-MM` oder Quartal `JJJJ-Qn` (n = 1…4), in der Form des zu stornierenden Satzes — auch nach einem Rhythmuswechsel bleibt die alte Periodenform stornierbar; der Storno prüft den Rhythmus nicht (#5583)"},"reason":{"type":"string","minLength":1,"description":"Begründung des Stornos (Pflicht wie beim bestehenden Storno-Weg)"}}}}}},"responses":{"200":{"description":"storniert — { laufId, stornoEntryIds, cancelledPaymentOrderIds }","content":{"application/json":{"schema":{"type":"object","properties":{"laufId":{"type":"string","format":"uuid"},"stornoEntryIds":{"type":"array","items":{"type":"string","format":"uuid"}},"cancelledPaymentOrderIds":{"type":"array","items":{"type":"string","format":"uuid"}}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht, keine Zuständigkeit für das Objekt oder kein menschlicher Akteur (ApiErrorBody, code forbidden)"},"409":{"description":"für den Monat ist kein Honorar gebucht (auch: Objekt mandantenfremd — kein Existenz-Orakel) oder die Entnahme ist bereits eingereicht — es wird nichts storniert (ApiErrorBody, code conflict)"}}}},"/api/kaution":{"get":{"summary":"Liest die Kautionsliste des Mandanten zum Stichtag: vereinbart · erhalten · offen · getrennte Anlage (§ 551 BGB).","operationId":"listKautionsliste","security":[{"bearerAuth":[]}],"parameters":[{"name":"propertyId","in":"query","required":false,"description":"Auf EIN Objekt eingrenzen (Filter, keine Autorisierung).","schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"description":"Stichtag der Eingänge UND des Vertragsfilters; weggelassen ⇒ heute (Render-Uhr der Anfrage, nie die Browser-Uhr).","schema":{"type":"string","format":"date"}},{"name":"archiveScope","in":"query","required":false,"description":"3-Wege-Filter auf die Archiv-Kette des Vertrags-Reads; Default `aktiv`.","schema":{"type":"string","enum":["alle","aktiv","archiviert"]}},{"name":"abrechnungsstand","in":"query","required":false,"description":"Filter auf den Abrechnungsstand (#6897): `abgerechnet` (nicht stornierte Abrechnung vorhanden), `nicht-abgerechnet` (keine; auch Bürgschaft/Verpfändung), `abrechnungsreif` (Vertrag beendet UND nicht abgerechnet; nie eine Sicherheit ohne Geldfluss). Zeilen und Summen entstehen aus der gefilterten Menge; ohne Angabe alle Zeilen.","schema":{"type":"string","enum":["abgerechnet","nicht-abgerechnet","abrechnungsreif"]}}],"responses":{"200":{"description":"Zeilen + Summen aus DERSELBEN Zeilenmenge. Je Zeile trägt `abrechnung` den Abrechnungsstand (`null` ⇒ nicht abgerechnet).  Cent-Felder sind vorzeichenbehaftete Integer-STRINGS. `offenCents` ist POSITIV bei Rückstand; ein dokumentarisch übernommener Bestand steht auf `eingang-unbekannt` und trägt `mahnbarerRestCents: \"0\"` — er wird durch die Umstellung nicht gemahnt. `summen` summiert nur EUR-Zeilen; andere Währungen stehen je Währung getrennt in `summenFremdwaehrung`. ACHTUNG: `mietpartei` ist personenbezogen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KautionslisteResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request — Feldname + Regel, nie der Wert)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/kaution/eingang":{"post":{"summary":"Verbucht einen Bankumsatz des am Vertrag hinterlegten Kautionskontos als Eingang der Kaution (verbuche_kautionseingang): Bank an Kautions-Personenkonto des Mieters, mit Buchungsanspruch und Tilgung der offenen Raten — ohne Zuordnung zum Mietkonto. Nur bei Barkaution.","operationId":"verbucheKautionseingang","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bankTransactionId","contractId","vorschlagHash"],"properties":{"bankTransactionId":{"type":"string","format":"uuid","description":"Umsatz auf einer Bankverbindung der Kontoart kautionskonto"},"contractId":{"type":"string","format":"uuid"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash des über POST /api/kaution/freigabe freigegebenen Vorschlags — ohne gültige Freigabe wird nichts gebucht (409)"}}}}}},"responses":{"200":{"description":"verbucht (Wiederholung ⇒ `replay: true`, nichts doppelt). Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"type":"object","properties":{"bankTransactionId":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"zahlungEntryId":{"type":"string","format":"uuid"},"entryNo":{"type":"string"},"betragCents":{"type":"string"},"currency":{"type":"string"},"gegenkonto":{"type":"string","enum":["forderung"],"description":"immer das Kautions-Personenkonto des Vertrags"},"replay":{"type":"boolean"}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag oder Bankumsatz unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"keine gültige Freigabe des Vorschlags (fehlt, abgelehnt oder Inhalt seither geändert), kein Kautionskonto oder nicht das am Vertrag hinterlegte, keine Abrede, Bürgschaft/Verpfändung (kein Zahlungsstrom), kein Eingang oder Umsatz bereits anders verbucht (ApiErrorBody, code conflict)"}}}},"/api/kaution/sollstellung":{"post":{"summary":"Stellt die bis zum Stichtag fälligen Kautionsraten eines Vertrags soll (stelle_kaution_soll): SOLL Kautions-Personenkonto des Mieters / HABEN Kaution, je Rate ein Satz — getrennt vom Mietkonto, idempotent je Rate. Nur bei Barkaution.","operationId":"stelleKautionSoll","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contractId","vorschlagHash"],"properties":{"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"Raten mit Fälligkeit ≤ Stichtag; weggelassen ⇒ heute. Nie in der Zukunft (400)."},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash des über POST /api/kaution/freigabe freigegebenen Vorschlags (gleicher Stichtag) — ohne gültige Freigabe wird nichts gebucht (409)"}}}}}},"responses":{"200":{"description":"Der vollständige Ratenplan mit Status je Rate (`sollgestellt` · `bereits-sollgestellt` · `nicht-faellig`); Cent-Felder sind Integer-STRINGS. Wiederholen bucht nichts doppelt (`neuSollgestellt: 0`).","content":{"application/json":{"schema":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"anlageform":{"type":"string","enum":["barkaution","buergschaft","verpfaendung"]},"vereinbartCents":{"type":"string"},"currency":{"type":"string"},"raten":{"type":"array","items":{"type":"object","properties":{"nummer":{"type":"integer"},"faelligAm":{"type":"string","format":"date"},"betragCents":{"type":"string"},"status":{"type":"string","enum":["sollgestellt","bereits-sollgestellt","nicht-faellig"]},"entryId":{"type":"string","format":"uuid","nullable":true},"entryNo":{"type":"string","nullable":true}}}},"neuSollgestellt":{"type":"integer"}}}}}},"400":{"description":"ungültige Eingabe oder Stichtag in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"keine gültige Freigabe des Vorschlags (fehlt, abgelehnt oder Inhalt seither geändert), keine Kautionsabrede (übernommener Bestand — „vereinbart, Eingang unbekannt\", wird nicht sollgestellt), Bürgschaft/Verpfändung (kein Zahlungsstrom), kein Mieter für das Kautions-Personenkonto, kein Mietbeginn oder Kontonummer am Objekt belegt (ApiErrorBody, code conflict)"}}}},"/api/kaution/vorschlag":{"post":{"summary":"Berechnet den VORSCHLAG eines Kautions-Geldpfads (Ratensollstellung oder Kautionseingang) samt Inhalts-Hash — mit derselben Rechnung wie die Ausführung, ohne zu schreiben.","operationId":"kautionsvorschlag","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["art","contractId"],"properties":{"art":{"type":"string","enum":["sollstellung","eingang"]},"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"nur bei sollstellung: Raten mit Fälligkeit ≤ Stichtag; weggelassen ⇒ heute"},"bankTransactionId":{"type":"string","format":"uuid","description":"nur und Pflicht bei eingang: Umsatz auf dem hinterlegten Kautionskonto"}}}}}},"responses":{"200":{"description":"der Vorschlag — { art, vorschlagHash, status (offen · freigegeben · abgelehnt), inhalt }. Cent-Felder im Inhalt sind Integer-STRINGS.","content":{"application/json":{"schema":{"type":"object","properties":{"art":{"type":"string","enum":["sollstellung","eingang"]},"vorschlagHash":{"type":"string","description":"Hex-SHA-256 des Inhalts — mit ihm wird freigegeben und ausgeführt"},"status":{"type":"string","enum":["offen","freigegeben","abgelehnt"]},"inhalt":{"type":"object","additionalProperties":true,"description":"der vollständige Buchungsinhalt, wie er freigegeben würde"}}}}}},"400":{"description":"ungültige Eingabe oder Stichtag in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vertrag oder Bankumsatz unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"der Geldpfad ist für diesen Vertrag/Umsatz nicht möglich (keine Abrede, kein Zahlungsstrom, falsche Anlage …) (ApiErrorBody, code conflict)"}}}},"/api/kaution/freigabe":{"post":{"summary":"Gibt einen Kautions-Vorschlag frei (gib_kaution_frei): bindet die Freigabe an genau den vorgelegten Inhalts-Hash. Erst danach buchen POST /api/kaution/sollstellung bzw. POST /api/kaution/eingang.","operationId":"gibKautionFrei","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["art","contractId","vorschlagHash"],"properties":{"art":{"type":"string","enum":["sollstellung","eingang"]},"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"nur bei sollstellung: Raten mit Fälligkeit ≤ Stichtag; weggelassen ⇒ heute"},"bankTransactionId":{"type":"string","format":"uuid","description":"nur und Pflicht bei eingang: Umsatz auf dem hinterlegten Kautionskonto"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/kaution/vorschlag"}}}}}},"responses":{"200":{"description":"freigegeben — { approvalId, art, contractId, vorschlagHash }","content":{"application/json":{"schema":{"type":"object","properties":{"approvalId":{"type":"string","format":"uuid"},"art":{"type":"string","enum":["sollstellung","eingang"]},"contractId":{"type":"string","format":"uuid"},"vorschlagHash":{"type":"string"}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreib-/Freigaberecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag oder Bankumsatz unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"der Inhalt weicht vom vorgelegten Hash ab (neu vorschlagen), über diesen Vorschlag ist bereits entschieden oder der Geldpfad ist nicht möglich (ApiErrorBody, code conflict)"}}}},"/api/bauabzug/anmeldung":{"get":{"summary":"Liest die einbehaltene Bauabzugsteuer je Monat EINES Kalenderjahres — Grundlage der Anmeldung (§ 48a EStG): Summe, Zahl der Einbehalte und Fälligkeit am 10. des Folgemonats. Gezählt wird nur tatsächlich Einbehaltenes: ein Einbehalt zählt, solange seine Buchung (Kreditor an Verbindlichkeit Finanzamt, entsteht mit der Freigabe des Zahlungsauftrags) wirksam, also nicht storniert ist; ein noch nicht freigegebener Auftrag zählt nicht.","operationId":"listBauabzugAnmeldung","security":[{"bearerAuth":[]}],"parameters":[{"name":"jahr","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{4}$"},"description":"Kalenderjahr JJJJ"}],"responses":{"200":{"description":"{ jahr, monate[] } aufsteigend nach Monat; Monate ohne Einbehalt erscheinen nicht. Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BauabzugAnmeldungResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/bauabzug/pruefungen":{"get":{"summary":"Liest die Bauabzugs-Entscheidungen je Bauleistungs-Position der Zahlungsaufträge: Grund, Rechnungsbetrag, Auszahlung, Einbehalt, Fälligkeit und den Befund der Freistellungsbescheinigung — eine fehlende oder abgelaufene wird mit Status, Nummer und Gültigkeit benannt.","operationId":"listBauabzugPruefungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"paymentOrderId","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"nur die Positionen dieses Zahlungsauftrags"}],"responses":{"200":{"description":"{ pruefungen[] } nach Zahlungstag und Posten geordnet; ein fremder/unbekannter Auftrag ergibt eine leere Liste. Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BauabzugPruefungenResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/bauabzug/freistellungsbescheinigung":{"get":{"summary":"Liest die hinterlegten Freistellungsbescheinigungen (§ 48b EStG) EINES Kreditors: Nummer, gültig bis, Umfang, Auftragsbezug und ausstellendes Finanzamt, absteigend nach Gültigkeit.","operationId":"listFreistellungsbescheinigungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"kreditorPersonId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ kreditorPersonId, bescheinigungen[] } — ein fremder/unbekannter Kreditor ergibt eine leere Liste (kein Existenz-Orakel).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreistellungsbescheinigungenResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Hinterlegt eine Freistellungsbescheinigung am Kreditor (hinterlege_freistellungsbescheinigung). Ohne gültige Bescheinigung behält der Zahlungsauftrag für eine Bauleistung über der Bagatellgrenze 15 % für das Finanzamt ein.","operationId":"hinterlegeFreistellungsbescheinigung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["kreditorPersonId","nummer","gueltigBis","umfang","finanzamt"],"properties":{"kreditorPersonId":{"type":"string","format":"uuid"},"nummer":{"type":"string","maxLength":64,"description":"Nummer der Bescheinigung (nicht leer)"},"gueltigBis":{"type":"string","format":"date","description":"letzter Gültigkeitstag (einschliesslich)"},"umfang":{"type":"string","enum":["allgemein","auftragsbezogen"]},"auftragsbezug":{"type":"string","maxLength":200,"nullable":true,"description":"genau bei Umfang auftragsbezogen anzugeben"},"finanzamt":{"type":"string","maxLength":200,"description":"ausstellendes Finanzamt"}}}}}},"responses":{"200":{"description":"hinterlegt — { freistellungsbescheinigungId, kreditorPersonId, nummer, gueltigBis, umfang }","content":{"application/json":{"schema":{"type":"object","properties":{"freistellungsbescheinigungId":{"type":"string","format":"uuid"},"kreditorPersonId":{"type":"string","format":"uuid"},"nummer":{"type":"string"},"gueltigBis":{"type":"string","format":"date"},"umfang":{"type":"string","enum":["allgemein","auftragsbezogen"]}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht (ApiErrorBody, code forbidden)"},"404":{"description":"Kreditor unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"dieselbe Nummer ist am Kreditor bereits hinterlegt (ApiErrorBody, code conflict)"}}}},"/api/bauabzug/kostenart":{"post":{"summary":"Kennzeichnet eine Kostenart als Bauleistung (§ 48 Abs. 1 Satz 3 EStG) oder nimmt das Kennzeichen zurück (setze_kostenart_bauleistung). Eingangsrechnungen auf Aufwandskonten dieser Kostenart lösen am Zahlungsauftrag die Bauabzugs-Prüfung aus.","operationId":"setzeKostenartBauleistung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["costCategoryId","istBauleistung"],"properties":{"costCategoryId":{"type":"string","format":"uuid"},"istBauleistung":{"type":"boolean"}}}}}},"responses":{"200":{"description":"gesetzt — { costCategoryId, istBauleistung }","content":{"application/json":{"schema":{"type":"object","properties":{"costCategoryId":{"type":"string","format":"uuid"},"istBauleistung":{"type":"boolean"}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht (ApiErrorBody, code forbidden)"},"404":{"description":"Kostenart unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/bauabzug/objekt-einstellung":{"post":{"summary":"Setzt die Lage des Auftraggebers am Objekt, die § 48 EStG unterscheidet (setze_bauabzug_objekt_einstellung): ausschließlich steuerfreie Vermietungsumsätze nach § 4 Nr. 12 UStG heben die Bagatellgrenze auf 15.000 € (§ 48 Abs. 2 Nr. 1 EStG); ein Vermieter von höchstens zwei Wohnungen ist vom Abzug ausgenommen (§ 48 Abs. 1 Satz 2 EStG, Grund vermieter-hoechstens-zwei-wohnungen). Ohne Einstellung gilt 5.000 € und keine Ausnahme.","operationId":"setzeBauabzugObjektEinstellung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["propertyId","ausschliesslichSteuerfreieVermietung","hoechstensZweiWohnungen"],"properties":{"propertyId":{"type":"string","format":"uuid"},"ausschliesslichSteuerfreieVermietung":{"type":"boolean"},"hoechstensZweiWohnungen":{"type":"boolean"}}}}}},"responses":{"200":{"description":"gesetzt — { propertyId, ausschliesslichSteuerfreieVermietung, hoechstensZweiWohnungen }","content":{"application/json":{"schema":{"type":"object","properties":{"propertyId":{"type":"string","format":"uuid"},"ausschliesslichSteuerfreieVermietung":{"type":"boolean"},"hoechstensZweiWohnungen":{"type":"boolean"}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/bauabzug/volle-zahlung":{"post":{"summary":"Erlaubt, einen offenen Posten (Bauleistung) trotz fehlender Freistellungsbescheinigung VOLL zu zahlen (erlaube_volle_zahlung_bauleistung) — nur mit dokumentierter Begründung und nur mit dem Recht bauabzug.volle-zahlung. Je Posten gilt die erste Erlaubnis.","operationId":"erlaubeVolleZahlungBauleistung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["openItemId","begruendung"],"properties":{"openItemId":{"type":"string","description":"der offene Posten (Eingangsrechnung)"},"begruendung":{"type":"string","maxLength":1000,"description":"dokumentierte Begründung (nicht leer)"}}}}}},"responses":{"200":{"description":"erlaubt — { openItemId, begruendung, erlaubtVon }","content":{"application/json":{"schema":{"type":"object","properties":{"openItemId":{"type":"string"},"begruendung":{"type":"string"},"erlaubtVon":{"type":"string"}}}}}},"400":{"description":"ungültige Eingabe, z. B. leere Begründung (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"das Recht bauabzug.volle-zahlung fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Posten unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"für diesen Posten ist die volle Zahlung bereits erlaubt (ApiErrorBody, code conflict)"}}}},"/api/kaution/rueckbehalt-fristen":{"get":{"summary":"Liest Fristende und Überfälligkeit je gehaltenem Rückbehalt: für jede nicht stornierte Kautionsabrechnung im Rückbehalt-Status gehalten oder teilfreigegeben Vertrag, Abrechnungsdatum, Rückbehalt, Rest, fristEnde (beim Buchen gespeicherter Termin (Wiedervorlage am): Abrechnungsdatum + Frist des Mandanten zum Buchungszeitpunkt; eine spätere Änderung der Frist wirkt nur auf neue Abrechnungen), ueberfaellig und die Tage der Überschreitung. Nur lesend — keine automatische Aktion, keine Mail.","operationId":"getKautionRueckbehaltFristen","security":[{"bearerAuth":[]}],"parameters":[{"name":"stichtag","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"nurUeberfaellig","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"{ stichtag, fristMonate, zeilen[] } — nur Rückbehalte der Objekte mit Zuständigkeit; Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KautionRueckbehaltFristenResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/instandhaltung":{"get":{"summary":"Liest die Instandhaltungs-Vorgänge des Mandanten, begrenzt auf die Objekte mit Zuständigkeit des Aufrufers: Nummer, Titel, Typ, Dringlichkeit, Status, Objekt, Einheit, Auftragswert (Cent als Integer-STRING), Auftragsnummer und die Zahl offener Befunde. Filter propertyId, status, dringlichkeit, typ, nurOffen (ohne abgeschlossen und storniert), limit (Vorgabe 50, höchstens 200) und offset. Nur lesend.","operationId":"getInstandhaltungListe","security":[{"bearerAuth":[]}],"parameters":[{"name":"propertyId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"dringlichkeit","in":"query","required":false,"schema":{"type":"string"}},{"name":"typ","in":"query","required":false,"schema":{"type":"string"}},{"name":"nurOffen","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"{ stichtag, limit, offset, zeilen[] } — leer ohne Vorgänge; Geld ist ein Integer-STRING in Cent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungListeResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder unbekannter Statuswert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Erfasst eine Meldung: Pflicht propertyId, typSchluessel (aktiver Vorgangstyp), titel, beschreibung, dringlichkeit; optional unitId, melderPersonId, beginnAm, haeufigkeit, baulichVeraendernd. Der Vorgang entsteht im Status gemeldet mit Nummer. Der Idempotenz-Schlüssel kommt vom Aufrufer (Header).","operationId":"meldeInstandhaltung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungMeldenRequest"}}}},"responses":{"200":{"description":"Der Vorgang mit Nummer, Status, nächsten Schritten und Befunden.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungMeldungResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt, Einheit oder Melder unbekannt oder mandantenfremd (ApiErrorBody, code not_found)"}}}},"/api/instandhaltung/{id}":{"get":{"summary":"Liest EINEN Instandhaltungs-Vorgang mit Verlauf, Angeboten, Aufträgen, Freigabestand des lebenden Auftrags, Rechnungen mit Zahlungsstand (nicht-gebucht | nicht-ermittelbar | offen | ausgeglichen), Befunden und nächsten Schritten. Optional stichtag (Vorgabe: Berliner Tag der Server-Uhr). Nur lesend.","operationId":"getInstandhaltungVorgang","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Der Vorgang mit allen Bestandteilen; Geld ist ein Integer-STRING in Cent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungVorgangResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/instandhaltung/katalog":{"get":{"summary":"Liest den aufgelösten Vorgangstypen-Katalog des Mandanten (Vorgabe plus Abweichungen); standardmäßig nur aktive Typen, mit auchInaktive=true alle. Nur lesend.","operationId":"getInstandhaltungKatalog","security":[{"bearerAuth":[]}],"parameters":[{"name":"auchInaktive","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"{ typen[] } — schluessel, bezeichnung, ohneAngebotErlaubt, aktiv, vorgabe.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungKatalogResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"put":{"summary":"Legt einen Vorgangstyp im Katalog des Mandanten an oder ändert ihn: schluessel, bezeichnung, ohneAngebotErlaubt, aktiv. Nur ein Mensch mit Recht (sonst 403).","operationId":"setzeInstandhaltungVorgangstyp","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungKatalogSetzenRequest"}}}},"responses":{"200":{"description":"Der gesetzte Vorgangstyp.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungKatalogSetzenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"}}}},"/api/instandhaltung/einstellung":{"get":{"summary":"Liest die Instandhaltung-Einstellung des Mandanten: Zweitfreigabe-Schwelle, Vergleichsangebote-Schwelle (Cent als Integer-STRING), Mindestangebote und die Herkunft (vorgabe | mandant). Nur lesend.","operationId":"getInstandhaltungEinstellung","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Die Einstellung; ohne gespeicherte Zeile gilt die Vorgabe des Kerns (herkunft vorgabe).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungEinstellungResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"put":{"summary":"Setzt die Instandhaltung-Einstellung des Mandanten: zweitfreigabeAbCents (Cent als Integer-String, null = nie), vergleichsangeboteAbCents, mindestangebote. Nur ein Mensch mit Recht (sonst 403).","operationId":"setzeInstandhaltungEinstellung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungEinstellungSetzenRequest"}}}},"responses":{"200":{"description":"Die gesetzte Einstellung samt vorherigem Stand; Geld als Integer-String in Cent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungEinstellungSetzenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"}}}},"/api/instandhaltung/aufgaben":{"get":{"summary":"Liest die offene Instandhaltung-Arbeit als abgeleitete Aufgaben (sofort-unbearbeitet, angebot-ausstehend, freigabe-wartet, rechnung-fehlt) der Objekte mit Zuständigkeit des Aufrufers. Optional stichtag (Vorgabe: Berliner Tag der Server-Uhr) und propertyId. Nur lesend.","operationId":"getInstandhaltungAufgaben","security":[{"bearerAuth":[]}],"parameters":[{"name":"stichtag","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"propertyId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ stichtag, zeilen[] } — leer ohne offene Arbeit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAufgabenResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/instandhaltung/{id}/qualifizieren":{"post":{"summary":"Qualifiziert einen Vorgang: Typ, Dringlichkeit, baulich verändernd, Gestattungsbeschluss, Beginn und Häufigkeit, oder ausdrücklich beginnUnbekannt. Die Vorgangs-Id steht im Pfad, nie im Body. Aus gemeldet wird in_klaerung.","operationId":"qualifiziereInstandhaltungVorgang","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungQualifizierenRequest"}}}},"responses":{"200":{"description":"Der Vorgang mit Status, nächsten Schritten und Befunden.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungQualifizierenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vorgang steht jenseits von in_klaerung (code conflict)"}}}},"/api/instandhaltung/{id}/dienstleister":{"post":{"summary":"Weist dem Vorgang einen Dienstleister zu; es entsteht ein Angebot im Status angefragt. Die Vorgangs-Id steht im Pfad.","operationId":"weiseInstandhaltungDienstleisterZu","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungDienstleisterRequest"}}}},"responses":{"200":{"description":"Vorgangsstatus und das angefragte Angebot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungDienstleisterResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vorgang gesperrt oder Dienstleister schon zugeordnet (code conflict)"}}}},"/api/instandhaltung/{id}/angebot":{"post":{"summary":"Erfasst das Angebot eines zugeordneten Dienstleisters: dienstleisterPersonId, betrag als Objekt {cents, currency}, optional gueltigBis, realisierungAb, dokumentId. Die Vorgangs-Id steht im Pfad.","operationId":"erfasseInstandhaltungAngebot","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAngebotRequest"}}}},"responses":{"200":{"description":"Das Angebot; Geld als {cents, currency}.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAngebotResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vorgang gesperrt oder Angebot nicht mehr änderbar (code conflict)"}}}},"/api/instandhaltung/{id}/angebot/waehlen":{"post":{"summary":"Wählt ein vorliegendes Angebot des Vorgangs. Die Vorgangs-Id steht im Pfad.","operationId":"waehleInstandhaltungAngebot","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAngebotWaehlenRequest"}}}},"responses":{"200":{"description":"Das gewählte Angebot, Zahl der Angebote und ein möglicher Befund.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAngebotWaehlenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Angebot nicht wählbar oder Vorgang gesperrt (code conflict)"}}}},"/api/instandhaltung/{id}/angebot/verwerfen":{"post":{"summary":"Verwirft ein Angebot des Vorgangs mit Grund. Die Vorgangs-Id steht im Pfad.","operationId":"verwerfeInstandhaltungAngebot","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAngebotVerwerfenRequest"}}}},"responses":{"200":{"description":"Das verworfene Angebot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAngebotResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Angebot nicht änderbar, in Auftrag oder Vorgang gesperrt (code conflict)"}}}},"/api/instandhaltung/{id}/freigabe":{"post":{"summary":"Beantragt die Kostenfreigabe des Vorgangs (Auftrag im Status zur_freigabe): optional angebotId, kostenobergrenze als Objekt {cents, currency}, dienstleisterPersonId, costCategoryId. Zu einem Vorgang mit lebendem Auftrag ist ein zweiter Antrag ein Konflikt. Die Vorgangs-Id steht im Pfad.","operationId":"beantrageInstandhaltungKostenfreigabe","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungFreigabeBeantragenRequest"}}}},"responses":{"200":{"description":"Auftrag-Id, Version, Betrag {cents, currency}, nötige Stufen und Befunde.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungFreigabeBeantragenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vorgang gesperrt oder es läuft schon ein Auftrag (code conflict)"}}}},"/api/instandhaltung/{id}/freigabe/entscheid":{"post":{"summary":"Entscheidet eine Stufe (verwalter, zweit) der Kostenfreigabe des Vorgangs: approved oder rejected mit rejectReason. Eine zweite Stufe ist nur bei aktivem Vier-Augen-Schalter und erreichter Schwelle nötig. Der Antragsteller kann bei aktivem Vier-Augen nicht selbst freigeben (403). Die Vorgangs-Id steht im Pfad.","operationId":"entscheideInstandhaltungKostenfreigabe","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungFreigabeEntscheidenRequest"}}}},"responses":{"200":{"description":"Entscheidung, Auftrags- und Vorgangsstatus, offene Stufen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungFreigabeEntscheidenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Selbstfreigabe verboten oder Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Stufe schon entschieden oder Auftrag hat sich geändert (code conflict)"}}}},"/api/fremdvertrag":{"get":{"summary":"Liest die Verträge mit Dritten des Mandanten (Versicherung, Wartung, Dienstleistung, Versorgung), begrenzt auf die Objekte mit Zuständigkeit des Aufrufers: Art, Bezeichnung, Partner, Beginn, Konditionen zum Stichtag (Beträge als Integer-STRING in Cent), Fristenstand, Zahl der Schadenfälle. Filter propertyId, art, status (aktiv | beendet | alle, Vorgabe aktiv), limit (Vorgabe 50, höchstens 200) und offset. Nur lesend.","operationId":"getFremdvertragListe","security":[{"bearerAuth":[]}],"parameters":[{"name":"propertyId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"art","in":"query","required":false,"schema":{"type":"string","enum":["versicherung","wartung","dienstleistung","versorgung"]}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["aktiv","beendet","alle"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"{ stichtag, zeilen[], gesamt, limit, offset } — leer ohne Verträge; Geld ist ein Integer-STRING in Cent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragListeResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder unbekannter Filterwert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt einen Vertrag mit Dritten samt ersten Konditionen an: propertyId, art, partnerPersonId (Rolle Kreditor oder Dienstleister), bezeichnung, beginn, kuendigungsfristMonate; optional laufzeitEnde, vertragsnummer, Verlängerung (ohne Angabe: Vorgabe der Einstellung, sonst ja, 12 Monate), beitrag mit beitragIntervall, selbstbehalt (nur Versicherung) und bemerkung. Geld ist ein Objekt {cents, currency}.","operationId":"legeFremdvertragAn","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragAnlegenRequest"}}}},"responses":{"200":{"description":"Vertrags-Id und die ersten Konditionen (Version 1).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragAnlegenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/fremdvertrag/{id}":{"get":{"summary":"Liest EINEN Vertrag mit Dritten: Konditionen zum Stichtag, Konditionen-Historie, Ereignisse, Fristenstand (spaetesterZugang, aufgabeAb), Dauerzahlungs-Abgleich und Schadenfälle. Optional stichtag (Vorgabe: Berliner Tag der Server-Uhr). Nur lesend.","operationId":"getFremdvertrag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Der Vertrag mit allen Bestandteilen; Geld ist ein Integer-STRING in Cent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vertrag unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/fremdvertrag/fristen":{"get":{"summary":"Liest den Fristenwächter der Verträge mit Dritten: je Vertrag kategorie (kuendigungsfrist | frist-verpasst | ohne-laufzeit), spaetesterZugang, aufgabeAb, tageBisFrist, Ampel und offen. Filter stichtag (Vorgabe: Berliner Tag der Server-Uhr), propertyId, art, nurOffen (Vorgabe true) und mitUeberwachungsluecken (Verträge ohne Laufzeitende). Nur lesend, begrenzt auf die Objekte mit Zuständigkeit des Aufrufers.","operationId":"getFremdvertragFristen","security":[{"bearerAuth":[]}],"parameters":[{"name":"stichtag","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"propertyId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"art","in":"query","required":false,"schema":{"type":"string","enum":["versicherung","wartung","dienstleistung","versorgung"]}},{"name":"nurOffen","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}},{"name":"mitUeberwachungsluecken","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"{ stichtag, zeilen[] } — leer ohne Fristen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragFristenResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter, kein Kalendertag oder unbekannte Art (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/fremdvertrag/einstellung":{"get":{"summary":"Liest die Einstellung der Verträge mit Dritten des Mandanten: Vorlauf-Tage, Vorgaben für die Verlängerung, Meldefrist für Schadenfälle, Schadenhonorar (Basispunkte und Text) und Herkunft (vorgabe | mandant). Ohne gespeicherte Einstellung gilt die Vorgabe. Nur lesend.","operationId":"getFremdvertragEinstellung","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Die Einstellung des Mandanten oder die Vorgabe.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragEinstellungResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"put":{"summary":"Setzt die Einstellung der Verträge mit Dritten des Mandanten (alle sechs Werte, kein Teil-Patch): vorlaufTage, Vorgaben für die Verlängerung, schadenMeldefristTage, Schadenhonorar in Basispunkten und ob es aktiv ist. Nur ein Mensch mit dem Recht, Rollen und Rechte zu verwalten.","operationId":"setzeFremdvertragEinstellung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragEinstellungSetzenRequest"}}}},"responses":{"200":{"description":"Gesetzte Werte, Stand davor und geaendert-Kennzeichen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragEinstellungSetzenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"}}}},"/api/schadenfall":{"get":{"summary":"Liest die Schadenfälle des Mandanten, begrenzt auf die Objekte mit Zuständigkeit des Aufrufers, neueste Schäden zuerst: Nummer, Status, Schadensdatum, Schadenart, Objekt, Schadenssumme (Cent als Integer-STRING) und Zahl der Befunde. Filter propertyId, status (kommagetrennt), versicherungsvertragId, instandhaltungVorgangId, nurOffen (ohne abgeschlossen), limit (Vorgabe 50, höchstens 200) und offset. Nur lesend.","operationId":"getSchadenfallListe","security":[{"bearerAuth":[]}],"parameters":[{"name":"propertyId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"versicherungsvertragId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"instandhaltungVorgangId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"nurOffen","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0}}],"responses":{"200":{"description":"{ stichtag, zeilen[], gesamt, limit, offset } — leer ohne Schadenfälle; Geld ist ein Integer-STRING in Cent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallListeResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder unbekannter Statuswert (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Erfasst einen Schadenfall (Status erfasst): propertyId, schadensdatum (nicht nach heute), schadenart, beschreibung; optional unitId, versicherungsvertragId und instandhaltungVorgangId (beide desselben Objekts).","operationId":"legeSchadenfallAn","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallAnlegenRequest"}}}},"responses":{"200":{"description":"Schadenfall-Id, Nummer, Status, Selbstbehalt und Befunde.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallErgebnis"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt, Einheit, Vertrag oder Vorgang unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/schadenfall/{id}":{"get":{"summary":"Liest EINEN Schadenfall: Kopf, Versicherungsvertrag, Instandhaltungs-Vorgang, Befunde, Bilanz (Schadenssumme, Selbstbehalt, erwartete und tatsächliche Erstattung, Differenz), Erstattungen mit Buchungsstand (gebucht | vorgeschlagen) und den Honorar-Vorschlag, der nicht automatisch abgerechnet wird. Optional stichtag (Vorgabe: Berliner Tag der Server-Uhr). Nur lesend.","operationId":"getSchadenfall","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"stichtag","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Der Schadenfall mit allen Bestandteilen; Geld ist ein Integer-STRING in Cent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Schadenfall unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/mieterhoehung/staffelliste":{"get":{"summary":"Liest die Staffelmieterhöhungsliste (UC-LIST-016): je Vertrag mit mindestens einem Kaltmieten-Wechsel die zum Stichtag geltende (aktuelle) und die unmittelbar vorherige Kaltmiete mit Gültigkeitsbeginn und Differenz, die nächste künftige Stufe und die Herkunft des Wechsels (anlage = im Anlage-Kommando des Vertrags entstanden, sonst konditionswechsel). Aktuell heißt: gilt zum Stichtag — nicht die zuletzt erfasste. von/bis grenzen auf Verträge ein, deren aktuelle Stufe in diesem Zeitraum gültig wurde. Nur lesend.","operationId":"getStaffelmieteListe","security":[{"bearerAuth":[]}],"parameters":[{"name":"stichtag","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"von","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"objekt","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ stichtag, zeilen[] } — nur Verträge der Objekte mit Zuständigkeit; Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffelmieteListeResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter, kein Kalendertag oder von nach bis (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/mieterhoehung/faellig":{"get":{"summary":"Liest, wer für eine Mieterhöhung fällig ist: je laufendem Wohnraumvertrag der zuständigen Objekte den frühesten § 558-Termin (Jahressperrfrist; gesperrt mit Grund bei Index- oder Staffelvereinbarung), bei Indexmiete den § 557b-Termin mit dem jüngsten VPI-Monat und der neuen Miete als Vorschau (vpi-fehlt oder basisjahr-abweichend statt eines geschätzten oder umgerechneten Werts) und das Ende der Zustimmungsfrist eines versendeten Vorgangs. Nur lesend — kein Vorgang, keine Mail; Gewerbeverträge erscheinen nicht.","operationId":"getMieterhoehungFaellig","security":[{"bearerAuth":[]}],"parameters":[{"name":"stichtag","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"{ stichtag, zeilen[] } — nur Verträge der Objekte mit Zuständigkeit; Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MieterhoehungFaelligResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/mahnlauf":{"get":{"summary":"Liest die Übersicht des Registers „Mahnlauf\": die offenen Vorgänge (fällig oder in Arbeit) der Objekte mit Zuständigkeit, den Vorgang, den das Register öffnet (Query `lauf` ist der Deep-Link), die früheren (ausgeführten) Vorgänge und — ohne offenen Vorgang — die Zahl der zu mahnenden Debitoren. Ein Vorgang gehört dem, der ihn bearbeitet; ein fremd bearbeiteter Vorgang ist nur anzusehen. Nur lesend — nichts davon mahnt.","operationId":"getMahnlaufUebersicht","security":[{"bearerAuth":[]}],"parameters":[{"name":"lauf","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"Deep-Link: Vorgang, der bevorzugt geöffnet wird"}],"responses":{"200":{"description":"{ offene[], gewaehlt, fruehere[], zuMahnendeDebitoren } — Cent-Felder sind Integer-STRINGS; Namen nur, soweit die Lesung sie führt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufUebersichtResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter oder keine UUID (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Startet einen Mahnlauf-Vorgang (starte_mahnlauf_vorgang) oder öffnet den eigenen, schon vorbereiteten: der Vorbereitungs-Schlüssel entsteht serverseitig aus Mandant, Nutzer, Stichtag und der Zahl ausgeführter Vorgänge, nie aus dem Body. Ein zweiter Aufruf desselben Nutzers zum selben Stichtag liefert denselben Vorgang (`neu: false`, 200) und legt keinen zweiten an. Ein Vorgang gehört dem, der ihn bearbeitet. Mahnt nicht — Ausführen, Freigabe und Versand sind ein eigener Schritt. Der Idempotency-Key kommt vom Aufrufer.","operationId":"starteMahnlaufVorgang","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["stichtag"],"additionalProperties":false,"properties":{"stichtag":{"type":"string","format":"date","description":"Stichtag des Mahnlaufs (JJJJ-MM-TT)"},"automatisch":{"type":"boolean","default":false,"description":"true ⇔ automatisch vorbereitet (Vorgabe false)"}}}}}},"responses":{"200":{"description":"der eigene vorbereitete Vorgang wurde geöffnet (`neu: false`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufStartResponse"}}}},"201":{"description":"ein neuer Vorgang wurde angelegt (`neu: true`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufStartResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. kein Kalendertag oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Schreibrecht, Zuständigkeit oder Mandantenzugehörigkeit fehlt, Testzeitraum abgelaufen, Paket nicht enthalten, oder der Aufrufer ist ein Agent (ApiErrorBody, code forbidden)"},"409":{"description":"der Schlüssel trägt einen ausgeführten oder von jemand anderem bearbeiteten Vorgang (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}":{"get":{"summary":"Liest EINEN Vorgang: Kopf (Stichtag, Status, Schritt, Summen, wer ihn bearbeitet), Umfang (Objekte und Einheiten der Zuständigkeit), die Positionen der Ableitung mit Beträgen und — bei einem ausgeführten Vorgang — das Ergebnis. Unbekannter, mandantenfremder oder nicht sichtbarer Vorgang: dieselbe 404. Nur lesend.","operationId":"getMahnlaufVorgang","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"}],"responses":{"200":{"description":"der Vorgang — Cent-Felder sind Integer-STRINGS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufVorgangResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Vorgang unbekannt ODER mandantenfremd ODER nicht sichtbar — dieselbe Meldung (ApiErrorBody, code not_found)"}}},"patch":{"summary":"Bereitet einen Vorgang vor — mit GENAU EINEM der Schlüssel `stichtag` (setze_mahnlauf_stichtag), `umfang` (setze_mahnlauf_umfang: objektIds und abgewaehlteEinheitIds) oder `schritt` (setze_mahnlauf_schritt, 0 bis 3). Zwei Schlüssel oder keiner ⇒ 400. Ein Vorgang gehört dem, der ihn bearbeitet (fremd in Arbeit ⇒ 409); ein ausgeführter Vorgang ist nicht mehr änderbar (409). Mahnt nicht. Der Idempotency-Key kommt vom Aufrufer.","operationId":"bereiteMahnlaufVorgangVor","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"maxProperties":1,"properties":{"stichtag":{"type":"string","format":"date"},"umfang":{"type":"object","required":["objektIds","abgewaehlteEinheitIds"],"additionalProperties":false,"properties":{"objektIds":{"type":"array","items":{"type":"string","format":"uuid"}},"abgewaehlteEinheitIds":{"type":"array","items":{"type":"string","format":"uuid"}}}},"schritt":{"type":"integer","minimum":0,"maximum":3}}}}}},"responses":{"200":{"description":"gesetzt — der Vorgang nach dem Aufruf (`geaendert: false`, wenn der Wert schon so stand)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufVorbereitetResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. zwei Schlüssel oder keiner, Schritt außerhalb 0…3 (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Schreibrecht, Zuständigkeit oder Mandantenzugehörigkeit fehlt, Testzeitraum abgelaufen, Paket nicht enthalten, oder der Aufrufer ist ein Agent (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"Vorgang fremd in Arbeit, bereits ausgeführt, gleichzeitig geändert oder ein Objekt läuft in einem anderen Vorgang (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}/ausschluss":{"post":{"summary":"Nimmt eine Position mit Pflichtgrund aus dem Mahnlauf (schliesse_mahnposition_aus): `positionsSchluessel` aus der Lesung, `grund` höchstens 200 Zeichen. Erneutes Ausschließen lässt eine Zeile stehen (der jüngere Grund gilt). Ein Vorgang gehört dem, der ihn bearbeitet; ein ausgeführter Vorgang ist nicht mehr änderbar. Mahnt nicht.","operationId":"schliesseMahnpositionAus","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["positionsSchluessel","grund"],"additionalProperties":false,"properties":{"positionsSchluessel":{"type":"string"},"grund":{"type":"string","maxLength":200}}}}}},"responses":{"200":{"description":"ausgeschlossen — der Grund wird nicht zurückgegeben","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufAusschlussResponse"}}}},"400":{"description":"Grund fehlt oder zu lang, Position nicht ausschließbar, ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Schreibrecht, Zuständigkeit oder Mandantenzugehörigkeit fehlt, oder der Aufrufer ist ein Agent (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"Vorgang fremd in Arbeit oder bereits ausgeführt (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}/ausschluss/aufheben":{"post":{"summary":"Holt eine ausgeschlossene Position in den Mahnlauf zurück (hole_mahnposition_zurueck). Gab es keinen Ausschluss, ist das ein Erfolg ohne Wirkung (`zurueckgeholt: false`). Ein Vorgang gehört dem, der ihn bearbeitet; ein ausgeführter Vorgang ist nicht mehr änderbar. Mahnt nicht.","operationId":"holeMahnpositionZurueck","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["positionsSchluessel"],"additionalProperties":false,"properties":{"positionsSchluessel":{"type":"string"}}}}}},"responses":{"200":{"description":"zurückgeholt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufAusschlussAufhebenResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Schreibrecht, Zuständigkeit oder Mandantenzugehörigkeit fehlt, oder der Aufrufer ist ein Agent (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"Vorgang fremd in Arbeit oder bereits ausgeführt (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}/ausfuehren":{"post":{"summary":"Führt einen vorbereiteten Mahnlauf-Vorgang aus (fuehre_mahnlauf_vorgang_aus, Außenwirkung): erzeugt je Schreiben einen Eintrag und gibt die unauffälligen Schreiben frei. Verlangt eine frische Anmeldung, das Ausführungsrecht und einen Menschen; Mandant und Akteur kommen aus der Sitzung, der Step-up-Nachweis nie aus dem Body. Ein zweiter Aufruf liefert das Erst-Ergebnis (`erstAusfuehrung: false`). Der Versand ist ein eigener Schritt.","operationId":"fuehreMahnlaufVorgangAus","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"ausgeführt (oder das Erst-Ergebnis eines schon ausgeführten Vorgangs)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufAusfuehrenResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. ein Body mit `stepUp` oder einem anderen Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"frische Anmeldung fehlt, ist abgelaufen oder schon verbraucht (ApiErrorBody, code step_up_required — `casa auth login --frisch`), oder das Ausführungsrecht fehlt/ist entzogen, die Selbstfreigabe wird abgelehnt, oder der Aufrufer ist ein Agent (code forbidden). Nichts geschrieben, nichts versendet."},"404":{"description":"Vorgang unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"Vorgang fremd in Arbeit oder gleichzeitig geändert, nichts zu mahnen (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}/versand":{"post":{"summary":"Versendet die Schreiben eines AUSGEFÜHRTEN Vorgangs (versende_mahnschreiben, Außenwirkung, eigene frische Anmeldung): `versandweg` mail oder druck, optional `mahnschreibenIds` für „Versand fortsetzen\" (nur diese Schreiben). Nur wenn der Vorgang ausgeführt ist und mindestens ein Schreiben `download_bereit` ist, sonst 409 OHNE Verbrauch der Anmeldung; ein zweiter Versand desselben Schreibens ist ausgeschlossen. Die Antwort nennt die Zähler und je Schreiben den Ausgang.","operationId":"versendeMahnlauf","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["versandweg"],"additionalProperties":false,"properties":{"versandweg":{"type":"string","enum":["mail","druck"]},"mahnschreibenIds":{"type":"array","minItems":1,"items":{"type":"string","format":"uuid"},"description":"nur diese Schreiben versenden (Versand fortsetzen)"}}}}}},"responses":{"200":{"description":"der Versand lief — Zähler und Ergebnis je Schreiben (einzelne Schreiben können fehlgeschlagen sein)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufVersandResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. unbekannter Versandweg oder ein Body mit `stepUp` (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"frische Anmeldung fehlt, ist abgelaufen oder schon verbraucht (ApiErrorBody, code step_up_required — `casa auth login --frisch`), oder das Ausführungsrecht fehlt/ist entzogen, die Selbstfreigabe wird abgelehnt, oder der Aufrufer ist ein Agent (code forbidden). Nichts geschrieben, nichts versendet."},"404":{"description":"Vorgang oder eines der Schreiben unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"Vorgang nicht ausgeführt oder nichts mehr zu versenden (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}/schreiben/{mahnschreibenId}/freigabe":{"post":{"summary":"Entscheidet über EIN Schreiben einzeln (entscheide_mahnschreiben): `entscheidung` freigeben oder zurueckweisen, beim Zurückweisen mit `grundCode` (optional `grundNotiz`). Nach freigeben folgt der Versand genau dieses Schreibens (Außenwirkung, frische Anmeldung, Ausführungsrecht); der Versandweg ist mail. Ein Agent darf nicht; eine rote Ampel ist nicht freigebbar.","operationId":"entscheideMahnschreiben","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"},{"name":"mahnschreibenId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mahnschreibenId (aus dem Ergebnis des Vorgangs)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entscheidung"],"additionalProperties":false,"properties":{"entscheidung":{"type":"string","enum":["freigeben","zurueckweisen"]},"grundCode":{"type":"string","enum":["falscher-betrag","falscher-kreditor","falsche-kontierung","kein-beleg","doppelt","nicht-plausibel","sonstiges"],"description":"Pflicht bei zurueckweisen, verboten bei freigeben"},"grundNotiz":{"type":"string","maxLength":500,"description":"optionaler Freitext, nur mit grundCode"}}}}}},"responses":{"200":{"description":"entschieden (bei freigeben samt Versand-Ergebnis)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufSchreibenFreigabeResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. zurueckweisen ohne Grundcode oder freigeben mit Grund (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"frische Anmeldung fehlt, ist abgelaufen oder schon verbraucht (ApiErrorBody, code step_up_required — `casa auth login --frisch`), oder das Ausführungsrecht fehlt/ist entzogen, die Selbstfreigabe wird abgelehnt, oder der Aufrufer ist ein Agent (code forbidden). Nichts geschrieben, nichts versendet."},"404":{"description":"Vorgang oder Schreiben unbekannt, mandantenfremd oder nicht im Vorgang — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"schon entschieden, Ampel rot oder Inhalt zwischenzeitlich geändert (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}/schreiben/{mahnschreibenId}/zustellung":{"post":{"summary":"Dokumentiert die von Hand erfolgte Zustellung EINES Schreibens (dokumentiere_mahnzustellung, Außenwirkung): `zugestelltAm`, `kanal` (brief, einschreiben, persoenliche_uebergabe) und die ausdrückliche Bestätigung `tatsacheBestaetigt: true`. Genau ein Nachweis je Schreiben; ein zweiter ist ein Konflikt.","operationId":"dokumentiereMahnzustellung","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"},{"name":"mahnschreibenId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mahnschreibenId (aus dem Ergebnis des Vorgangs)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["zugestelltAm","kanal","tatsacheBestaetigt"],"additionalProperties":false,"properties":{"zugestelltAm":{"type":"string","format":"date","nullable":true},"kanal":{"type":"string","enum":["brief","einschreiben","persoenliche_uebergabe"],"nullable":true},"tatsacheBestaetigt":{"type":"boolean"}}}}}},"responses":{"200":{"description":"dokumentiert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufZustellungResponse"}}}},"400":{"description":"Angaben fehlen, Bestätigung false, Datum in der Zukunft oder nach dem Stichtag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"frische Anmeldung fehlt, ist abgelaufen oder schon verbraucht (ApiErrorBody, code step_up_required — `casa auth login --frisch`), oder das Ausführungsrecht fehlt/ist entzogen, die Selbstfreigabe wird abgelehnt, oder der Aufrufer ist ein Agent (code forbidden). Nichts geschrieben, nichts versendet."},"404":{"description":"Vorgang oder Schreiben unbekannt, mandantenfremd oder nicht im Vorgang — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"bereits dokumentiert oder versendet, Vorgang nicht ausgeführt (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}/schreiben/{mahnschreibenId}/erneut":{"post":{"summary":"Sendet EIN fehlgeschlagenes Schreiben erneut (sende_mahnschreiben_erneut, Außenwirkung, frische Anmeldung): nur für den Status `fehlgeschlagen`, sonst 409. Ein zweiter Versand desselben Schreibens ist ausgeschlossen.","operationId":"sendeMahnschreibenErneut","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"},{"name":"mahnschreibenId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mahnschreibenId (aus dem Ergebnis des Vorgangs)"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{}}}}},"responses":{"200":{"description":"erneut gesendet (`ausgang` versandt oder wieder fehlgeschlagen)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufErneutResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. ein Body mit `stepUp` (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"frische Anmeldung fehlt, ist abgelaufen oder schon verbraucht (ApiErrorBody, code step_up_required — `casa auth login --frisch`), oder das Ausführungsrecht fehlt/ist entzogen, die Selbstfreigabe wird abgelehnt, oder der Aufrufer ist ein Agent (code forbidden). Nichts geschrieben, nichts versendet."},"404":{"description":"Vorgang oder Schreiben unbekannt, mandantenfremd oder nicht im Vorgang — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"Schreiben nicht fehlgeschlagen, bereits versendet oder zugestellt, Vorgang nicht ausgeführt (ApiErrorBody, code conflict)"}}}},"/api/mahnlauf/{laufId}/schreiben/{mahnschreibenId}/datei":{"get":{"summary":"Lädt die Datei EINES Mahnschreibens als JSON (`datei`: dateiname, sha256, groesseBytes, inhaltBase64) und vermerkt den Download (vermerke_mahnschreiben_download) VOR der Antwort. Die binäre PDF-Route `…/pdf` bleibt daneben bestehen und liefert dieselben Bytes. Keine Außenwirkung, kein Step-up.","operationId":"getMahnschreibenDatei","security":[{"bearerAuth":[]}],"parameters":[{"name":"laufId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"vorgangId"},{"name":"mahnschreibenId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"mahnschreibenId (aus dem Ergebnis des Vorgangs)"}],"responses":{"200":{"description":"die Datei samt Prüfsumme","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MahnlaufSchreibenDateiResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Schreibrecht (daten.schreiben) fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang oder Schreiben unbekannt, mandantenfremd oder nicht im Vorgang — dieselbe Meldung (ApiErrorBody, code not_found)"}}}},"/api/inkasso":{"get":{"summary":"Listet die Inkasso-Übergaben des Mandanten, neueste zuerst; Query `objekt` (UUID) und `status` (entwurf | uebergeben | zurueckgenommen | abgeschlossen). Nur lesend. Die Übergabe ist ein Datensatz: sie sendet nichts an Dritte und erzeugt kein Partnerformat.","operationId":"listeInkassoUebergaben","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":false,"schema":{"type":"string","format":"uuid"},"description":"nur Übergaben dieses Objekts"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["entwurf","uebergeben","zurueckgenommen","abgeschlossen"]},"description":"nur Übergaben mit diesem Status"}],"responses":{"200":{"description":"{ uebergaben[] } — Cent-Felder sind Integer-STRINGS; Empfänger, Begründung, Grund und Notiz sind Freitext.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InkassoUebergabeListeResponse"}}}},"400":{"description":"ungültige Query, z. B. unbekannter Parameter, keine UUID oder unbekannter Status (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Legt eine Inkasso-Übergabe als ENTWURF an (lege_inkasso_uebergabe_an): je Posten offener Rest, Fälligkeit, Mahnstufe, Mahngebühren und Verzugszinsen bis zum Stichtag; die Forderungsaufstellung wird gebildet, gehasht und eingefroren. Voraussetzung ist Mahnstufe 3 oder anwalt; darunter nur mit `begruendungMahnstufe`. Die Übergabe ist ein Datensatz: sie sendet nichts an Dritte und erzeugt kein Partnerformat. Derselbe Posten kann nicht in zwei aktiven Übergaben stehen (409). Der Idempotency-Key kommt vom Aufrufer.","operationId":"legeInkassoUebergabeAn","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["propertyId","personId","weg","stichtag","offenePostenIds"],"additionalProperties":false,"properties":{"propertyId":{"type":"string","format":"uuid","description":"Objekt"},"personId":{"type":"string","format":"uuid","description":"der Schuldner"},"contractId":{"type":"string","format":"uuid"},"weg":{"type":"string","enum":["inkasso","gerichtliches-mahnverfahren","klage"]},"empfaenger":{"type":"string","description":"Inkassounternehmen oder Kanzlei (Freitext)"},"stichtag":{"type":"string","format":"date","description":"Stichtag der Forderungsaufstellung (JJJJ-MM-TT)"},"offenePostenIds":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"begruendungMahnstufe":{"type":"string","description":"Pflicht für jeden Posten unter Mahnstufe 3 (Freitext)"}}}}}},"responses":{"201":{"description":"die angelegte Übergabe (Status entwurf) samt ausgeschriebener Forderungsaufstellung und Postenliste","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InkassoUebergabeDetailResponse"}}}},"400":{"description":"ungültige Eingabe, `begruendung-mahnstufe-fehlt`, `posten-gehoert-nicht-zur-uebergabe` (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Zuständigkeit, Schreibrecht oder Mandantenzugehörigkeit fehlt, Testzeitraum abgelaufen, Paket nicht enthalten, oder der Aufrufer ist ein Agent (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt oder Schuldner unbekannt ODER mandantenfremd (ApiErrorBody, code not_found)"},"409":{"description":"`posten-bereits-uebergeben` oder `posten-nicht-mehr-offen` (ApiErrorBody, code conflict)"}}}},"/api/inkasso/{id}":{"get":{"summary":"Liest EINE Inkasso-Übergabe samt eingefrorener Forderungsaufstellung (ausgeschrieben, Cent als Integer-Strings) und Postenliste. Unbekannt und mandantenfremd antworten gleich. Nur lesend.","operationId":"getInkassoUebergabe","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"uebergabeId"}],"responses":{"200":{"description":"die Übergabe","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InkassoUebergabeDetailResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Übergabe unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"}}}},"/api/inkasso/{id}/uebergabe":{"post":{"summary":"Übergibt den Entwurf (uebergebe_inkasso): setzt den Mahnstatus jedes Postens auf „Beim Rechtsanwalt\" (anwalt), in derselben Transaktion. Body `{ uebergebenAm }`. Sendet nichts an Dritte. Eine zweite Übergabe ⇒ 409. Der Idempotency-Key kommt vom Aufrufer.","operationId":"uebergebeInkasso","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"uebergabeId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["uebergebenAm"],"additionalProperties":false,"properties":{"uebergebenAm":{"type":"string","format":"date","description":"Tag der Übergabe (JJJJ-MM-TT)"}}}}}},"responses":{"200":{"description":"übergeben","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InkassoUebergabeUebergebenResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Zuständigkeit, Schreibrecht oder Mandantenzugehörigkeit fehlt, Testzeitraum abgelaufen, Paket nicht enthalten, oder der Aufrufer ist ein Agent (ApiErrorBody, code forbidden)"},"404":{"description":"Übergabe unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"nicht mehr im Entwurf, oder ein Posten ist nicht mehr offen bzw. gesperrt (ApiErrorBody, code conflict)"}}}},"/api/inkasso/{id}/zuruecknahme":{"post":{"summary":"Nimmt die Übergabe mit Pflichtgrund zurück (nimm_inkasso_uebergabe_zurueck): die Posten werden frei; der Mahnstatus wird NICHT zurückgestuft. Body `{ grund }` (höchstens 500 Zeichen). Ohne Grund ⇒ 400. Der Idempotency-Key kommt vom Aufrufer.","operationId":"nimmInkassoUebergabeZurueck","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"uebergabeId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["grund"],"additionalProperties":false,"properties":{"grund":{"type":"string","minLength":1,"maxLength":500,"description":"Grund der Rücknahme (Freitext)"}}}}}},"responses":{"200":{"description":"zurückgenommen","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InkassoUebergabeZuruecknahmeResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. fehlender Grund (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Zuständigkeit, Schreibrecht oder Mandantenzugehörigkeit fehlt, Testzeitraum abgelaufen, Paket nicht enthalten, oder der Aufrufer ist ein Agent (ApiErrorBody, code forbidden)"},"404":{"description":"Übergabe unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"unzulässiger Statusübergang, z. B. schon zurückgenommen oder abgeschlossen (ApiErrorBody, code conflict)"}}}},"/api/inkasso/{id}/abschluss":{"post":{"summary":"Schließt die übergebene Inkasso-Übergabe ab (schliesse_inkasso_uebergabe_ab): Body `{ art, notiz? }` mit art bezahlt | vergleich | uneinbringlich | sonstiges. Die Posten werden frei. Der Idempotency-Key kommt vom Aufrufer.","operationId":"schliesseInkassoUebergabeAb","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"uebergabeId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["art"],"additionalProperties":false,"properties":{"art":{"type":"string","enum":["bezahlt","vergleich","uneinbringlich","sonstiges"]},"notiz":{"type":"string","description":"Notiz zum Abschluss (Freitext)"}}}}}},"responses":{"200":{"description":"abgeschlossen","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InkassoUebergabeAbschlussResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. unbekannte Abschlussart (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Zuständigkeit, Schreibrecht oder Mandantenzugehörigkeit fehlt, Testzeitraum abgelaufen, Paket nicht enthalten, oder der Aufrufer ist ein Agent (ApiErrorBody, code forbidden)"},"404":{"description":"Übergabe unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"},"409":{"description":"unzulässiger Statusübergang, z. B. noch im Entwurf oder schon abgeschlossen (ApiErrorBody, code conflict)"}}}},"/api/inkasso/{id}/forderungsaufstellung":{"get":{"summary":"Lädt die eingefrorene Forderungsaufstellung als CSV-Datei in einer JSON-Antwort (`datei`: dateiname, sha256, groesseBytes, inhaltBase64; dazu `aufstellungHash`). Semikolon-getrennt, UTF-8 mit BOM, Dezimalkomma; zweimal geladen ⇒ byte-gleich. Der Dateiname trägt keine Personenangaben. Reiner Lesezugriff — nichts wird geschrieben; `Cache-Control: no-store`.","operationId":"getInkassoForderungsaufstellung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"uebergabeId"}],"responses":{"200":{"description":"die Datei samt Prüfsumme","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InkassoAufstellungDateiResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Übergabe unbekannt ODER mandantenfremd — dieselbe Meldung (ApiErrorBody, code not_found)"}}}},"/api/kaution/einstellung":{"get":{"summary":"Liest die Kaution-Einstellung des Mandanten: die Frist des Rückbehalts in Monaten (Vorgabe 6; beginnt mit dem Abrechnungsdatum der Kautionsabrechnung) und `istVorgabe` (true, solange der Mandant nichts eingestellt hat).","operationId":"getKautionEinstellung","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"{ rueckbehaltFristMonate, istVorgabe }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KautionEinstellungResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"put":{"summary":"Setzt die Frist des Rückbehalts des Mandanten (setze_kaution_rueckbehalt_frist): ganze Zahl 1…36 Monate. Nur ein Mensch mit Admin-Recht (rollenrechte.verwalten). Gilt nur für neue Abrechnungen — das Wiedervorlage-Datum wird beim Buchen an der Abrechnung festgeschrieben, bestehende bleiben unverändert. Idempotent: derselbe Wert nochmal ändert nichts.","operationId":"setzeKautionRueckbehaltFrist","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["monate"],"additionalProperties":false,"properties":{"monate":{"type":"integer","minimum":1,"maximum":36,"description":"Frist des Rückbehalts in Monaten"}}}}}},"responses":{"200":{"description":"{ rueckbehaltFristMonate, istVorgabe: false } — die jetzt geltende Frist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KautionEinstellungResponse"}}}},"400":{"description":"monate keine ganze Zahl 1…36 oder unbekanntes Feld (ApiErrorBody, code invalid_request) — nichts geschrieben"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch oder ohne Admin-Recht (ApiErrorBody, code forbidden)"}}}},"/api/kaution/zinsen":{"get":{"summary":"Liest die gebuchten Zinsgutschriften EINER Kaution (aufsteigend nach Zeitraum; stornierte erscheinen nicht).","operationId":"listKautionszinsen","security":[{"bearerAuth":[]}],"parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ contractId, gutschriften[] } — Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KautionszinsenResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/kaution/zinsen/stand":{"get":{"summary":"Liest den Zinsstand je Kautions-Anlagekonto: bis wann das Konto verzinst ist (letzter gebuchter Zinszeitraum, null ohne Zinslauf), die Zahl der Barkautionen und die noch unbeanspruchten Haben-Umsätze. Nur lesend; ob ein Umsatz ein Zins ist, entscheidet die Antwort nicht.","operationId":"getKautionZinsstand","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"{ konten[] } — nur Anlagekonten der Objekte mit Zuständigkeit; Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KautionZinsstandResponse"}}}},"400":{"description":"unbekannter Query-Parameter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/kaution/zinsen/saetze":{"get":{"summary":"Liest die Satzhistorie „gültig ab\" EINES Kautionskontos, aufsteigend nach gueltigAb. Der Satz an einem Tag ist der Eintrag mit dem größten gueltigAb <= Tag; vor dem ersten Eintrag gilt kein Satz. Ein fremdes, unbekanntes oder nicht zuständiges Konto liefert eine leere Liste (kein Existenz-Orakel).","operationId":"listKautionZinssaetze","security":[{"bearerAuth":[]}],"parameters":[{"name":"bankAccountId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ bankAccountId, saetze[] } — Satzhistorie aufsteigend nach gueltigAb","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KautionZinssaetzeResponse"}}}},"400":{"description":"bankAccountId fehlt oder keine UUID, unbekannter Query-Parameter (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}},"post":{"summary":"Schreibt EINEN Eintrag der Satzhistorie eines Kautionskontos (setze_kautionskonto_festzins): Upsert auf (Konto, gueltigAb) — gleicher gueltigAb überschreibt den Satz, ein wiederholter gleicher Aufruf ändert nichts; basispunkte null löscht den Eintrag dieses Tages. Ein gueltigAb in einem gebuchten Zinszeitraum des Kontos wird abgewiesen (Anlegen, Überschreiben und Löschen). Reine Stammdatenänderung ohne Buchung und ohne Freigabe. Nur ein Mensch.","operationId":"setzeKautionZinssatz","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bankAccountId","gueltigAb","basispunkte"],"additionalProperties":false,"properties":{"bankAccountId":{"type":"string","format":"uuid","description":"Bankverbindung der Kontoart kautionskonto"},"gueltigAb":{"type":"string","format":"date","description":"erster Tag, an dem der Satz gilt (inklusiv)"},"basispunkte":{"type":["integer","null"],"minimum":0,"maximum":2000,"description":"Satz in Basispunkten (150 = 1,50 %); null löscht den Eintrag dieses Tages"}}}}}},"responses":{"200":{"description":"{ bankAccountId, gueltigAb, basispunkte } — der jetzt gespeicherte Satz dieses Tages (null = Eintrag gelöscht)","content":{"application/json":{"schema":{"type":"object","required":["bankAccountId","gueltigAb","basispunkte"],"properties":{"bankAccountId":{"type":"string","format":"uuid"},"gueltigAb":{"type":"string","format":"date"},"basispunkte":{"type":["integer","null"]}}}}}},"400":{"description":"Schemafehler, z. B. Satz außerhalb 0…2000 oder gueltigAb kein Kalendertag (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch (ein Agent pflegt den Satz nicht)"},"404":{"description":"Konto unbekannt, archiviert, eines fremden Mandanten oder außerhalb der Zuständigkeit; Löschen eines Eintrags, den es für den Tag nicht gibt"},"409":{"description":"das Konto ist kein Kautionskonto, oder gueltigAb liegt in einem gebuchten Zinszeitraum des Kontos"}}}},"/api/kaution/zinsen/festzins":{"put":{"summary":"Pflegt den Zinssatz EINES Kautionskontos „gültig ab heute\" (setze_kautionskonto_festzins mit gueltigAb = heute, Verwaltungstag): legt einen Eintrag der Satzhistorie an oder überschreibt den von heute; basispunkte null löscht den Eintrag von heute. Für andere Tage: POST /api/kaution/zinsen/saetze. Reine Stammdatenänderung ohne Buchung und ohne Freigabe. Nur ein Mensch; ein Konto einer anderen Art oder ein heute in einem gebuchten Zinszeitraum ⇒ 409.","operationId":"setzeKautionskontoFestzins","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bankAccountId","basispunkte"],"additionalProperties":false,"properties":{"bankAccountId":{"type":"string","format":"uuid","description":"Bankverbindung der Kontoart kautionskonto"},"basispunkte":{"type":["integer","null"],"minimum":0,"maximum":2000,"description":"Satz in Basispunkten (150 = 1,50 %); null löscht den Eintrag von heute"}}}}}},"responses":{"200":{"description":"{ bankAccountId, basispunkte } — der jetzt gespeicherte Satz von heute (null = Eintrag gelöscht)","content":{"application/json":{"schema":{"type":"object","required":["bankAccountId","basispunkte"],"properties":{"bankAccountId":{"type":"string","format":"uuid"},"basispunkte":{"type":["integer","null"]}}}}}},"400":{"description":"Schemafehler, z. B. Satz außerhalb 0…2000 (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Mensch (ein Agent pflegt den Satz nicht)"},"404":{"description":"Konto unbekannt, archiviert, eines fremden Mandanten oder außerhalb der Zuständigkeit; Löschen, wenn es für heute keinen Eintrag gibt"},"409":{"description":"das Konto ist kein Kautionskonto, oder heute liegt in einem gebuchten Zinszeitraum des Kontos"}}}},"/api/kaution/zinsen/vorschlag":{"post":{"summary":"Berechnet den VORSCHLAG des Jahreszinslaufs eines Kautionskontos (nächstes offenes Kalenderjahr): je Kaution mit Guthaben im Jahr Stand zum 01.01., Zinstage, Satz bzw. Sätze und Zins (taggenau, Zinseszins über den Stand zum 01.01.), dazu die Summe — samt Inhalts-Hash, ohne zu schreiben. Eine Kaution, deren Abrechnungstag im Jahr liegt, ist nicht enthalten.","operationId":"kautionszinsvorschlag","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"description":"Zwei Formen, unterschieden über `art` (Vorgabe `jahreslauf`, bestehende Aufrufer ohne `art` bleiben gültig): `jahreslauf` = der Zinslauf eines Kautionskontos, `gutschrift` = die Zuordnung einer Bankgutschrift (Haben-Umsatz auf einem Kautionskonto) zu einem Zinsjahr mit offenem Saldo auf 1481. Ohne `jahr` listet `gutschrift` die offenen Jahre.","oneOf":[{"type":"object","title":"Jahreslauf","required":["bankAccountId","jahr"],"properties":{"art":{"type":"string","enum":["jahreslauf"],"description":"optional — Vorgabe jahreslauf"},"bankAccountId":{"type":"string","format":"uuid","description":"das Kautionskonto (Bankverbindung der Kontoart kautionskonto)"},"jahr":{"type":"integer","minimum":1000,"maximum":9999,"description":"das Kalenderjahr — erlaubt ist nur „naechstesOffenesJahr“ des Kontos (GET /api/kaution/zinsen/stand), dessen 31.12. nicht in der Zukunft liegt"}}},{"type":"object","title":"Gutschrift","required":["art","bankTransactionId"],"properties":{"art":{"type":"string","enum":["gutschrift"]},"bankTransactionId":{"type":"string","format":"uuid","description":"der Haben-Umsatz (Zinsgutschrift der Bank) auf einem Kautionskonto"},"jahr":{"type":"integer","minimum":1000,"maximum":9999,"description":"ein Jahr mit offenem Saldo auf 1481 für dieses Kautionskonto; ohne Angabe listet die Antwort die offenen Jahre"}}}]}}}},"responses":{"200":{"description":"der Vorschlag — Hash, Freigabe-Status (offen · freigegeben · abgelehnt), Zins je Kaution, Summe und der vollständige Inhalt. Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"vorschlagHash":{"type":"string","description":"Hex-SHA-256 des Inhalts — mit ihm wird freigegeben und gebucht"},"status":{"type":"string","enum":["offen","freigegeben","abgelehnt"]},"bankAccountId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"summeCents":{"type":"string","description":"Σ der Zinsen aller Kautionen (Integer-STRING)"},"currency":{"type":"string"},"anteile":{"type":"array","items":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"standJahresbeginnCents":{"type":"string","description":"Kautionsstand zum 01.01. inkl. gebuchter Zinsen der Vorjahre (Integer-STRING)"},"zinstage":{"type":"integer","description":"Zahl der Tage des Jahres mit Kapital"},"saetze":{"type":"array","description":"der Satz bzw. die Sätze, die im Zinsjahr für diese Kaution gelten","items":{"type":"object","properties":{"gueltigAb":{"type":"string","format":"date"},"basispunkte":{"type":"integer","description":"150 = 1,50 %"}}}},"zinsCents":{"type":"string","description":"Zins des Jahres für diese Kaution, kaufmännisch auf den Cent gerundet (Integer-STRING)"}}}},"inhalt":{"type":"object","additionalProperties":true,"description":"der vollständige Buchungsinhalt, wie er freigegeben würde"}}},{"type":"object","title":"GutschriftVorschlag","description":"art=gutschrift: ohne `jahr` nur `offeneJahre` (Jahre mit offenem Saldo auf 1481); mit `jahr` zusätzlich Hash, Status, Differenz (`ausgeglichen` · `mehrbetrag` · `minderbetrag`) und die Anteile je Kaution. Cent-Felder sind Integer-STRINGS.","properties":{"art":{"type":"string","enum":["gutschrift"]},"jahr":{"type":["integer","null"]},"vorschlagHash":{"type":"string"},"status":{"type":"string","enum":["offen","freigegeben","abgelehnt"]},"bankTransactionId":{"type":"string","format":"uuid"},"bankAccountId":{"type":"string","format":"uuid"},"currency":{"type":"string"},"gutschriftCents":{"type":"string","description":"die Zinsgutschrift der Bank (Integer-STRING)"},"saldoCents":{"type":"string","description":"offener Saldo des Jahres auf 1481 (Integer-STRING)"},"differenz":{"type":"string","enum":["ausgeglichen","mehrbetrag","minderbetrag"]},"differenzCents":{"type":"string","description":"Betrag der Differenz (Integer-STRING, ≥ 0)"},"offeneJahre":{"type":"array","items":{"type":"object","properties":{"jahr":{"type":"integer"},"saldoCents":{"type":"string","description":"offener Saldo (Integer-STRING)"}}}},"anteile":{"type":"array","items":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"gewicht":{"type":"string","description":"Guthaben × Tage (Integer-STRING)"},"mehrbetragCents":{"type":"string","description":"Mehrbetrag-Anteil dieser Kaution (Integer-STRING)"},"behandlung":{"type":"string","enum":["personenkonto","zahlungsauftrag","vermieter","kein-anteil"],"description":"personenkonto = dem Mieter gutgeschrieben · zahlungsauftrag = schon ausgezahlte Kaution, Anteil ab 1,00 € geht zusätzlich als Zahlungsauftrag zur Freigabe an den gespeicherten Empfänger · vermieter = Anteil unter 1,00 € einer ausgezahlten Kaution, trägt der Vermieter auf 58600"},"empfaenger":{"type":["object","null"],"properties":{"bankverbindungId":{"type":"string","format":"uuid"},"name":{"type":"string"}}}}}}}}]}}}},"400":{"description":"ungültige Eingabe oder 31.12. des Jahres liegt in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Kautionskonto unbekannt, mandantenfremd ODER nicht zuständig (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"das Jahr ist nicht das nächste offene des Kontos, an einem Tag mit Kapital gilt kein Zinssatz, das Jahr ist mit anderem Inhalt gebucht oder eine Kaution hat im Jahr einen Abgang ohne Abrechnung; art gutschrift: der Umsatz ist kein Haben-Umsatz auf einem Kautionskonto, ist schon gebucht (Bankumsatz-Anspruch) oder das Jahr hat keinen offenen Saldo auf 1481 (ApiErrorBody, code conflict)"}}}},"/api/kaution/zinsen/freigabe":{"post":{"summary":"Gibt ein Zinsjahr frei (gib_kautionszinsen_frei): bindet die Freigabe an genau den vorgelegten Inhalts-Hash. Erst danach bucht POST /api/kaution/zinsen/buchung.","operationId":"gibKautionszinsenFrei","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"description":"Zwei Formen, unterschieden über `art` (Vorgabe `jahreslauf`, bestehende Aufrufer ohne `art` bleiben gültig): `jahreslauf` = das Zinsjahr eines Kautionskontos, `gutschrift` = die Zuordnung einer Bankgutschrift (Umsatz und Jahr) freigeben.","oneOf":[{"type":"object","title":"Jahreslauf","required":["bankAccountId","jahr","vorschlagHash"],"properties":{"art":{"type":"string","enum":["jahreslauf"],"description":"optional — Vorgabe jahreslauf"},"bankAccountId":{"type":"string","format":"uuid","description":"das Kautionskonto (Bankverbindung der Kontoart kautionskonto)"},"jahr":{"type":"integer","minimum":1000,"maximum":9999,"description":"das Kalenderjahr — erlaubt ist nur „naechstesOffenesJahr“ des Kontos (GET /api/kaution/zinsen/stand), dessen 31.12. nicht in der Zukunft liegt"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/kaution/zinsen/vorschlag"}}},{"type":"object","title":"Gutschrift","required":["art","bankTransactionId","jahr","vorschlagHash"],"properties":{"art":{"type":"string","enum":["gutschrift"]},"bankTransactionId":{"type":"string","format":"uuid","description":"der Haben-Umsatz (Zinsgutschrift der Bank) auf einem Kautionskonto"},"jahr":{"type":"integer","minimum":1000,"maximum":9999,"description":"das Jahr mit offenem Saldo auf 1481, dem die Gutschrift zugeordnet wird"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/kaution/zinsen/vorschlag mit art gutschrift"}}}]}}}},"responses":{"200":{"description":"freigegeben — { approvalId, bankAccountId, jahr, vorschlagHash }","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"approvalId":{"type":"string","format":"uuid"},"bankAccountId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"vorschlagHash":{"type":"string"}}},{"type":"object","title":"GutschriftFreigabe","description":"art=gutschrift: { art, approvalId, bankTransactionId, jahr, vorschlagHash }","properties":{"art":{"type":"string","enum":["gutschrift"]},"approvalId":{"type":"string","format":"uuid"},"bankTransactionId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"vorschlagHash":{"type":"string"}}}]}}}},"400":{"description":"ungültige Eingabe oder 31.12. des Jahres liegt in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreib-/Freigaberecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Kautionskonto unbekannt, mandantenfremd ODER nicht zuständig (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"der Inhalt weicht vom vorgelegten Hash ab (neu vorschlagen), über dieses Zinsjahr ist bereits entschieden oder der Zinslauf ist nicht möglich (ApiErrorBody, code conflict)"}}}},"/api/kaution/zinsen/buchung":{"post":{"summary":"Bucht das freigegebene Zinsjahr (buche_kautionszinsen): je Kaution mit Zins ein Satz zum 31.12. SOLL 1481 Zinsforderung Kautionskonto / HABEN Kautions-Personenkonto des Mieters (§ 551 Abs. 3 BGB), ohne Bankumsatz-Anspruch — idempotent je Konto, Jahr und Kaution.","operationId":"bucheKautionszinsen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"description":"Zwei Formen, unterschieden über `art` (Vorgabe `jahreslauf`, bestehende Aufrufer ohne `art` bleiben gültig): `jahreslauf` = das Zinsjahr eines Kautionskontos, `gutschrift` = die Zuordnung einer Bankgutschrift (Umsatz und Jahr) buchen.","oneOf":[{"type":"object","title":"Jahreslauf","required":["bankAccountId","jahr","vorschlagHash"],"properties":{"art":{"type":"string","enum":["jahreslauf"],"description":"optional — Vorgabe jahreslauf"},"bankAccountId":{"type":"string","format":"uuid","description":"das Kautionskonto (Bankverbindung der Kontoart kautionskonto)"},"jahr":{"type":"integer","minimum":1000,"maximum":9999,"description":"das Kalenderjahr — erlaubt ist nur „naechstesOffenesJahr“ des Kontos (GET /api/kaution/zinsen/stand), dessen 31.12. nicht in der Zukunft liegt"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/kaution/zinsen/vorschlag"}}},{"type":"object","title":"Gutschrift","required":["art","bankTransactionId","jahr","vorschlagHash"],"properties":{"art":{"type":"string","enum":["gutschrift"]},"bankTransactionId":{"type":"string","format":"uuid","description":"der Haben-Umsatz (Zinsgutschrift der Bank) auf einem Kautionskonto"},"jahr":{"type":"integer","minimum":1000,"maximum":9999,"description":"das Jahr mit offenem Saldo auf 1481, dem die Gutschrift zugeordnet wird"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/kaution/zinsen/vorschlag mit art gutschrift"}}}]}}}},"responses":{"200":{"description":"gebucht — Zins je Kaution mit Status (`gebucht` · `bereits-gebucht` · `kein-anteil`). Wiederholen bucht nichts doppelt (`neuGebucht: 0`). Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"bankAccountId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"summeCents":{"type":"string"},"currency":{"type":"string"},"anteile":{"type":"array","items":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"standJahresbeginnCents":{"type":"string","description":"Kautionsstand zum 01.01. inkl. gebuchter Zinsen der Vorjahre (Integer-STRING)"},"zinstage":{"type":"integer","description":"Zahl der Tage des Jahres mit Kapital"},"saetze":{"type":"array","description":"der Satz bzw. die Sätze, die im Zinsjahr für diese Kaution gelten","items":{"type":"object","properties":{"gueltigAb":{"type":"string","format":"date"},"basispunkte":{"type":"integer","description":"150 = 1,50 %"}}}},"zinsCents":{"type":"string","description":"Zins des Jahres für diese Kaution, kaufmännisch auf den Cent gerundet (Integer-STRING)"},"status":{"type":"string","enum":["gebucht","bereits-gebucht","kein-anteil"]},"entryIds":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"neuGebucht":{"type":"integer"}}},{"type":"object","title":"GutschriftBuchung","description":"art=gutschrift: EIN Buchungssatz (`entryId`) Bank an 1481 mit Mehrbetrag bzw. Minderbetrag; je Anteil `behandlung` und — bei einer schon ausgezahlten Kaution ab 1,00 € — der Zahlungsauftrag (`paymentOrderId`, awaiting-approval). Cent-Felder sind Integer-STRINGS.","properties":{"art":{"type":"string","enum":["gutschrift"]},"bankTransactionId":{"type":"string","format":"uuid"},"bankAccountId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"currency":{"type":"string"},"gutschriftCents":{"type":"string"},"saldoCents":{"type":"string"},"differenz":{"type":"string","enum":["ausgeglichen","mehrbetrag","minderbetrag"]},"differenzCents":{"type":"string"},"entryId":{"type":"string","format":"uuid"},"neuGebucht":{"type":"integer"},"anteile":{"type":"array","items":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"gewicht":{"type":"string"},"mehrbetragCents":{"type":"string"},"behandlung":{"type":"string","enum":["personenkonto","zahlungsauftrag","vermieter","kein-anteil"]},"paymentOrderId":{"type":["string","null"],"format":"uuid"}}}}}}]}}}},"400":{"description":"ungültige Eingabe oder 31.12. des Jahres liegt in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Kautionskonto unbekannt, mandantenfremd ODER nicht zuständig (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"keine gültige Freigabe (fehlt, abgelehnt oder Inhalt seither geändert), das Jahr ist nicht das nächste offene des Kontos oder mit anderem Inhalt gebucht, oder an einem Tag mit Kapital gilt kein Zinssatz (ApiErrorBody, code conflict)"}}}},"/api/kaution/zinsen/storno":{"post":{"summary":"Storno des ZULETZT gebuchten Zinsjahres eines Kautionskontos in drei Stufen (stufe vorschlag | freigabe | ausfuehren; Tools gib_kautionszinsjahr_storno_frei und storniere_kautionszinsjahr, Artefakt-Art kautionszinsjahr-storno): je Kaution die Gegenbuchung des Jahreszinssatzes über den Weg von storno_entry. Danach ist das Jahr wieder das nächste offene Zinsjahr und bucht unter der nächsten Generation (g<n+1>) neu; ein zweiter Storno bucht nichts. Nur solange dem Jahr keine Bankgutschrift zugeordnet und keine Kaution abgerechnet ist.","operationId":"storniereKautionszinsjahr","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["stufe","bankAccountId","jahr","grund"],"additionalProperties":false,"properties":{"stufe":{"type":"string","enum":["vorschlag","freigabe","ausfuehren"],"description":"welche der drei Stufen gefahren wird"},"bankAccountId":{"type":"string","format":"uuid","description":"das Kautionskonto"},"jahr":{"type":"integer","description":"das zu stornierende Kalenderjahr — muss das zuletzt gebuchte des Kontos sein"},"grund":{"type":"string","minLength":1,"maxLength":500,"description":"Storno-Grund (Pflicht, nicht leer; Freitext eines Menschen)"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Pflicht bei freigabe und ausfuehren: Hash aus stufe vorschlag"}}}}}},"responses":{"200":{"description":"vorschlag: { vorschlagHash, status, bankAccountId, jahr, generation, bereitsStorniert, summeCents, currency, anteile[{ contractId, zinsCents }] }; freigabe: { approvalId, bankAccountId, jahr, vorschlagHash }; ausfuehren: { bankAccountId, jahr, generation, storniertAm, neuStorniert, nullzinsjahr, stornierteSaetze }. Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"type":"object","properties":{"stufe":{"type":"string","enum":["vorschlag","freigabe","ausfuehren"]},"vorschlagHash":{"type":"string"},"status":{"type":"string","enum":["offen","freigegeben","abgelehnt"]},"approvalId":{"type":"string","format":"uuid"},"bankAccountId":{"type":"string","format":"uuid"},"jahr":{"type":"integer"},"generation":{"type":"integer"},"bereitsStorniert":{"type":"boolean"},"summeCents":{"type":"string"},"currency":{"type":"string"},"anteile":{"type":"array","items":{"type":"object","properties":{"contractId":{"type":"string","format":"uuid"},"zinsCents":{"type":"string"}}}},"storniertAm":{"type":"string","format":"date-time"},"neuStorniert":{"type":"integer","description":"Zahl der in diesem Aufruf gegengebuchten Sätze; 0 = nichts gegengebucht (das Jahr war schon storniert oder ohne Zins gebucht, s. nullzinsjahr)"},"nullzinsjahr":{"type":"boolean","description":"true = das Jahr war ohne Zins gebucht (Nullzins-Marke): keine Gegenbuchung, das Jahr ist trotzdem wieder offen"},"stornierteSaetze":{"type":"array","items":{"type":"string","format":"uuid"}}}}}}},"400":{"description":"ungültige Eingabe, auch fehlender oder zu langer Grund und unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Kautionskonto unbekannt, mandantenfremd ODER nicht zuständig (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"nicht das zuletzt gebuchte Jahr, dem Jahr ist eine Bankgutschrift zugeordnet, eine Kaution des Jahres ist abgerechnet, keine gültige Freigabe (fehlt, abgelehnt oder Inhalt seither geändert) — es wird nichts geschrieben (ApiErrorBody, code conflict)"}}}},"/api/kaution/abrechnung":{"get":{"summary":"Liest den gespeicherten Abrechnungsstand EINES Vertrags (nicht stornierte Kautionsabrechnung) mit Rückbehalt-Status keiner | gehalten | teilfreigegeben | freigegeben, dem noch gehaltenen Rest und den Teilfreigaben.","operationId":"getKautionsabrechnungStand","security":[{"bearerAuth":[]}],"parameters":[{"name":"contractId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Der gespeicherte Stand; Cent-Felder sind Integer-STRINGS. `rueckbehaltBegruendung` ist Freitext eines Menschen (personenbezogen).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KautionsabrechnungStandResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel); keine geltende Abrechnung ⇒ ApiErrorBody, code KAUTION_KEINE_ABRECHNUNG."}}},"post":{"summary":"Rechnet die Kaution eines beendeten Vertrags ab (rechne_kaution_ab): Kaution + Zinsen − ausgewählte fällige Forderungen dieses Vertrags (Verrechnung über die bestehende OP-Verrechnung) − Rückbehalt mit Grundart (BK-Nachzahlung gedeckelt, Sonstiges mit Begründung). Bucht NUR mit hashgebundener Freigabe des Inhalts (vorschlagHash aus POST /api/kaution/abrechnung/vorschlag, freigegeben über POST /api/kaution/abrechnung/freigabe). Die Auszahlung geht als Zahlungsauftrag in die bestehende Freigabe (gib_zahlungsauftrag_frei, Vier-Augen) — nie direkt. Genau einmal je Vertrag.","operationId":"rechneKautionAb","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contractId","stichtag","offenePostenIds","requestedExecutionDate","vorschlagHash"],"additionalProperties":false,"properties":{"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date","description":"Abrechnungsstichtag; der Vertrag muss zu ihm beendet sein, Achse für „fällig\""},"offenePostenIds":{"type":"array","maxItems":200,"items":{"type":"string","format":"uuid"},"description":"die zu verrechnenden offenen Posten — nur am Stichtag fällige Forderungen DIESES Vertrags, sonst 409"},"empfaengerBankverbindungId":{"type":"string","format":"uuid","description":"gewählter Empfänger der Auszahlung (#7135): eine bestätigte Bankverbindung eines Mieters des Vertrags (aus `waehlbareEmpfaenger` des Vorschlags); fehlt sie, wird bei genau einer wählbaren Verbindung vorbelegt, bei mehreren ist der Empfänger offen (409 bei Freigabe/Ausführung). Eine nicht (mehr) bestätigte oder fremde Verbindung ⇒ 409."},"rueckbehalte":{"type":"array","maxItems":20,"description":"Rückbehalt als Zeilen mit Grundart (#7134): `bk-nachzahlung` höchstens einmal, gedeckelt auf die letzte bekannte BK-Nachzahlung (ohne Aufschlag), bei letztem Guthaben oder ohne bekannte Nachzahlung nicht wählbar (409); `sonstiges` beliebig oft, frei bis zum Guthaben, Begründung Pflicht (409 ohne). Die Summe darf das verbleibende Guthaben nicht übersteigen (409).","items":{"type":"object","required":["grundart","betragCents"],"additionalProperties":false,"properties":{"grundart":{"type":"string","enum":["bk-nachzahlung","sonstiges"]},"betragCents":{"anyOf":[{"type":"string","pattern":"^[1-9][0-9]{0,17}$"},{"type":"integer","minimum":1,"maximum":9007199254740991}],"description":"Rückbehalt dieser Zeile in Cent (Integer-STRING > 0; eine sichere ganze Zahl wird ebenfalls angenommen)"},"begruendung":{"type":"string","maxLength":500,"description":"Pflicht bei `sonstiges`; bei `bk-nachzahlung` optional (sonst „BK-Nachzahlung <Jahr>“)"}}}},"requestedExecutionDate":{"type":"string","format":"date","description":"gewünschter Ausführungstag des Auszahlungsauftrags"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash des FREIGEGEBENEN Vorschlags aus POST /api/kaution/abrechnung/vorschlag (art abrechnung), freigegeben über POST /api/kaution/abrechnung/freigabe"}}}}}},"responses":{"200":{"description":"Die Abrechnung: Bestand, Zinsen, Guthaben, Verrechnung je Posten, Rückbehalt und Deckel, Auszahlung, Restforderung, Art; dazu `paymentOrderId`/`paymentOrderContentHash` des Auftrags `awaiting-approval` (null bei Auszahlung 0). Cent-Felder sind Integer-STRINGS.","content":{"application/json":{"schema":{"type":"object","properties":{"kautionsabrechnungId":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"kautionsbestandCents":{"type":"string"},"zinsenCents":{"type":"string"},"guthabenCents":{"type":"string"},"verrechnetCents":{"type":"string"},"verrechnung":{"type":"array","items":{"type":"object","properties":{"postenId":{"type":"string","format":"uuid"},"zugeteiltCents":{"type":"string"},"restbetragNachherCents":{"type":"string"}}}},"rueckbehaltCents":{"type":"string","description":"Σ der Rückbehalt-Zeilen"},"rueckbehaltDeckelCents":{"type":"string","description":"Deckel der BK-Zeile; \"0\" ohne BK-Zeile"},"rueckbehalte":{"type":"array","description":"die zugelassenen Rückbehalt-Zeilen (#7134), ohne Begründung","items":{"type":"object","properties":{"grundart":{"type":"string","enum":["bk-nachzahlung","sonstiges"]},"betragCents":{"type":"string"},"deckelCents":{"type":"string","nullable":true}}}},"letzteBkNachzahlungCents":{"type":"string","nullable":true},"bkDeckelCents":{"type":"string","description":"Deckel einer BK-Zeile = letzte BK-Nachzahlung ohne Aufschlag; \"0\" ohne"},"bkWaehlbar":{"type":"boolean","description":"ist „BK-Nachzahlung“ als Grundart wählbar (letzte Nachzahlung > 0)"},"bkNichtWaehlbarGrund":{"type":"string","nullable":true,"enum":["keine-bk-nachzahlung","letztes-guthaben"]},"auszahlungCents":{"type":"string"},"restforderungCents":{"type":"string"},"art":{"type":"string","enum":["auszahlung","restforderung","ausgeglichen"]},"currency":{"type":"string"},"paymentOrderId":{"type":"string","format":"uuid","nullable":true},"paymentOrderContentHash":{"type":"string","nullable":true}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vertrag nicht beendet oder bereits abgerechnet, Posten nicht verrechenbar, Rückbehalt: Sonstiges ohne Begründung, zweite BK-Zeile, BK nicht wählbar (letztes Guthaben bzw. keine bekannte Nachzahlung), BK über dem Deckel oder Summe über dem Guthaben, keine Kautionsanlage oder keine bestätigte Bankverbindung des Mieters, Empfänger offen (mehrere wählbar, keine Wahl) oder gewählte Bankverbindung nicht (mehr) bestätigt bzw. nicht die eines Mieters des Vertrags, keine Freigabe des Inhalts oder Inhalt seit der Freigabe geändert — es wird nichts gebucht (ApiErrorBody, code conflict)"}}}},"/api/kaution/rueckbehalt-freigabe":{"post":{"summary":"Gibt den Rückbehalt einer Kautionsabrechnung als eigenen Schritt frei (gib_kautionsrueckbehalt_frei): optional gegen dann fällige Forderungen dieses Vertrags verrechnet, der Rest als Zahlungsauftrag in die bestehende Freigabe. Mit betragCents nur einen TEILBETRAG (#6900): Status teilfreigegeben mit Rest, der letzte Schritt (Rest 0) freigegeben; ohne betragCents der ganze Rest. Jeder Schritt bucht NUR mit hashgebundener Freigabe seines Inhalts (art rueckbehalt).","operationId":"gibKautionsrueckbehaltFrei","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["contractId","stichtag","offenePostenIds","requestedExecutionDate","vorschlagHash"],"additionalProperties":false,"properties":{"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"offenePostenIds":{"type":"array","maxItems":200,"items":{"type":"string","format":"uuid"}},"requestedExecutionDate":{"type":"string","format":"date"},"betragCents":{"type":"string","pattern":"^-?[0-9]{1,18}$","description":"Teilbetrag des Rückbehalts in Cent (Ziffern-STRING, #6900); zulässig 0 < betragCents ≤ Rest, sonst 409. Fehlt er, wird der ganze Rest freigegeben (Inhalt wie vorher)."},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash des FREIGEGEBENEN Vorschlags aus POST /api/kaution/abrechnung/vorschlag (art rueckbehalt), freigegeben über POST /api/kaution/abrechnung/freigabe"}}}}}},"responses":{"200":{"description":"Rückbehalt, verrechneter Teil, Auszahlung, Restforderung (Integer-STRINGS) und der Auftrag `awaiting-approval` (null bei Auszahlung 0).","content":{"application/json":{"schema":{"type":"object","properties":{"kautionsabrechnungId":{"type":"string","format":"uuid"},"rueckbehaltCents":{"type":"string"},"verrechnetCents":{"type":"string"},"auszahlungCents":{"type":"string"},"restforderungCents":{"type":"string"},"paymentOrderId":{"type":"string","format":"uuid","nullable":true},"paymentOrderContentHash":{"type":"string","nullable":true},"rueckbehaltStatus":{"type":"string","enum":["teilfreigegeben","freigegeben"],"description":"Status NACH diesem Schritt (#6900)"},"rueckbehaltRestCents":{"type":"string","description":"danach noch gehaltener Rest; \"0\" bei freigegeben"}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"kein gehaltener Rückbehalt, bereits freigegeben, Teilbetrag 0/negativ/über dem Rest, Posten nicht verrechenbar, Auszahlungsseite unvollständig, keine Freigabe des Inhalts oder Inhalt seit der Freigabe geändert — es wird nichts gebucht (ApiErrorBody, code conflict)"}}}},"/api/kaution/abrechnung/vorschlag":{"post":{"summary":"Berechnet den VORSCHLAG einer Kautionsabrechnung (art abrechnung), einer Rückbehalt-Freigabe (art rueckbehalt) bzw. eines Stornos (art storno) samt Inhalts-Hash — mit derselben Rechnung wie die Ausführung, ohne zu schreiben.","operationId":"kautionsabrechnungsvorschlag","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"KautionsabrechnungBezug","description":"art=abrechnung — die Abrechnung selbst (rechne_kaution_ab).","required":["art","contractId","stichtag","offenePostenIds","requestedExecutionDate"],"additionalProperties":false,"properties":{"art":{"type":"string","enum":["abrechnung"]},"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"offenePostenIds":{"type":"array","maxItems":200,"items":{"type":"string","format":"uuid"}},"requestedExecutionDate":{"type":"string","format":"date"},"empfaengerBankverbindungId":{"type":"string","format":"uuid","description":"gewählter Empfänger der Auszahlung (#7135): eine bestätigte Bankverbindung eines Mieters des Vertrags (aus `waehlbareEmpfaenger` des Vorschlags); fehlt sie, wird bei genau einer wählbaren Verbindung vorbelegt, bei mehreren ist der Empfänger offen (409 bei Freigabe/Ausführung). Eine nicht (mehr) bestätigte oder fremde Verbindung ⇒ 409."},"rueckbehalte":{"type":"array","maxItems":20,"description":"beantragter Rückbehalt als Zeilen mit Grundart (#7134): `bk-nachzahlung` höchstens einmal, gedeckelt auf die letzte bekannte BK-Nachzahlung (ohne Aufschlag), bei letztem Guthaben oder ohne bekannte Nachzahlung nicht wählbar (409); `sonstiges` beliebig oft, frei bis zum Guthaben, Begründung Pflicht (409 ohne). Die Summe darf das verbleibende Guthaben nicht übersteigen (409).","items":{"type":"object","required":["grundart","betragCents"],"additionalProperties":false,"properties":{"grundart":{"type":"string","enum":["bk-nachzahlung","sonstiges"]},"betragCents":{"anyOf":[{"type":"string","pattern":"^[1-9][0-9]{0,17}$"},{"type":"integer","minimum":1,"maximum":9007199254740991}]},"begruendung":{"type":"string","maxLength":500,"description":"Pflicht bei `sonstiges`; bei `bk-nachzahlung` optional (sonst „BK-Nachzahlung <Jahr>“)."}}}}}},{"type":"object","title":"KautionsrueckbehaltBezug","description":"art=rueckbehalt — die spätere Freigabe des Rückbehalts (gib_kautionsrueckbehalt_frei); keine Zinsen, kein Rückbehalt-Antrag.","required":["art","contractId","stichtag","offenePostenIds","requestedExecutionDate"],"additionalProperties":false,"properties":{"art":{"type":"string","enum":["rueckbehalt"]},"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"offenePostenIds":{"type":"array","maxItems":200,"items":{"type":"string","format":"uuid"}},"requestedExecutionDate":{"type":"string","format":"date"},"betragCents":{"type":"string","pattern":"^-?[0-9]{1,18}$","description":"Teilbetrag des Rückbehalts in Cent (Ziffern-STRING, #6900); zulässig 0 < betragCents ≤ Rest, sonst 409. Fehlt er, wird der ganze Rest freigegeben (Inhalt wie vorher)."}}},{"type":"object","title":"KautionsabrechnungStornoBezug","description":"art=storno — der Storno einer ausgeführten Abrechnung (storniere_kautionsabrechnung, #6645).","required":["art","kautionsabrechnungId","grund"],"additionalProperties":false,"properties":{"art":{"type":"string","enum":["storno"]},"kautionsabrechnungId":{"type":"string","format":"uuid","description":"die zu stornierende Abrechnung"},"grund":{"type":"string","minLength":1,"maxLength":500,"description":"Storno-Grund (Pflicht, nicht leer)"}}}],"discriminator":{"propertyName":"art"}}}}},"responses":{"200":{"description":"der Vorschlag — { art, contractId, vorschlagHash, status (offen · freigegeben · abgelehnt), inhalt }. Cent-Felder im Inhalt sind Integer-STRINGS.","content":{"application/json":{"schema":{"type":"object","properties":{"art":{"type":"string","enum":["abrechnung","rueckbehalt","storno"]},"contractId":{"type":"string","format":"uuid"},"vorschlagHash":{"type":"string","description":"Hex-SHA-256 des Inhalts — mit ihm wird freigegeben und ausgeführt"},"status":{"type":"string","enum":["offen","freigegeben","abgelehnt"]},"zustand":{"type":"string","enum":["bereit","empfaenger-offen"],"description":"`empfaenger-offen` (#7135): mehrere wählbare Bankverbindungen, keine Wahl — freigeben und ausführen lässt sich der Vorschlag erst mit `empfaengerBankverbindungId` (sonst 409)"},"waehlbareEmpfaenger":{"type":"array","description":"alle bestätigten, am Ausführungstag gültigen Bankverbindungen aller Mieter des Vertrags (#7135, PERSONENBEZOGEN: Name, IBAN); nur bei art abrechnung gefüllt, nicht Teil des Hashs","items":{"type":"object","required":["bankverbindungId","personId","name","iban","bic"],"properties":{"bankverbindungId":{"type":"string","format":"uuid"},"personId":{"type":"string","format":"uuid"},"name":{"type":"string"},"iban":{"type":"string"},"bic":{"type":"string","nullable":true}}}},"inhalt":{"type":"object","additionalProperties":true,"description":"der vollständige Inhalt (Beträge, Zinsen als `zinsenCents`, Rückbehalt-Zeilen mit Grundart und Begründung, Posten, Anlage, Empfänger), wie er freigegeben würde; bei art abrechnung dazu `bkDeckelCents`, `bkWaehlbar` und `bkNichtWaehlbarGrund` (ist „BK-Nachzahlung“ als Grundart wählbar, bis zu welchem Betrag)"}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag bzw. (art storno) Abrechnung unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"die Abrechnung bzw. Rückbehalt-Freigabe ist so nicht möglich (dieselben Gründe wie bei der Ausführung) (ApiErrorBody, code conflict)"}}}},"/api/kaution/abrechnung/freigabe":{"post":{"summary":"Gibt einen Vorschlag der Kautionsabrechnung, Rückbehalt-Freigabe bzw. des Stornos frei (gib_kautionsabrechnung_frei): bindet die Freigabe an genau den vorgelegten Inhalts-Hash, bucht selbst nichts. Erst danach buchen POST /api/kaution/abrechnung, POST /api/kaution/rueckbehalt-freigabe bzw. POST /api/kaution/abrechnung/storno.","operationId":"gibKautionsabrechnungFrei","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"KautionsabrechnungBezug","description":"art=abrechnung — die Abrechnung selbst (rechne_kaution_ab).","required":["art","contractId","stichtag","offenePostenIds","requestedExecutionDate","vorschlagHash"],"additionalProperties":false,"properties":{"art":{"type":"string","enum":["abrechnung"]},"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"offenePostenIds":{"type":"array","maxItems":200,"items":{"type":"string","format":"uuid"}},"requestedExecutionDate":{"type":"string","format":"date"},"empfaengerBankverbindungId":{"type":"string","format":"uuid","description":"gewählter Empfänger der Auszahlung (#7135): eine bestätigte Bankverbindung eines Mieters des Vertrags (aus `waehlbareEmpfaenger` des Vorschlags); fehlt sie, wird bei genau einer wählbaren Verbindung vorbelegt, bei mehreren ist der Empfänger offen (409 bei Freigabe/Ausführung). Eine nicht (mehr) bestätigte oder fremde Verbindung ⇒ 409."},"rueckbehalte":{"type":"array","maxItems":20,"description":"beantragter Rückbehalt als Zeilen mit Grundart (#7134): `bk-nachzahlung` höchstens einmal, gedeckelt auf die letzte bekannte BK-Nachzahlung (ohne Aufschlag), bei letztem Guthaben oder ohne bekannte Nachzahlung nicht wählbar (409); `sonstiges` beliebig oft, frei bis zum Guthaben, Begründung Pflicht (409 ohne). Die Summe darf das verbleibende Guthaben nicht übersteigen (409).","items":{"type":"object","required":["grundart","betragCents"],"additionalProperties":false,"properties":{"grundart":{"type":"string","enum":["bk-nachzahlung","sonstiges"]},"betragCents":{"anyOf":[{"type":"string","pattern":"^[1-9][0-9]{0,17}$"},{"type":"integer","minimum":1,"maximum":9007199254740991}]},"begruendung":{"type":"string","maxLength":500,"description":"Pflicht bei `sonstiges`; bei `bk-nachzahlung` optional (sonst „BK-Nachzahlung <Jahr>“)."}}}},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/kaution/abrechnung/vorschlag"}}},{"type":"object","title":"KautionsrueckbehaltBezug","description":"art=rueckbehalt — die spätere Freigabe des Rückbehalts (gib_kautionsrueckbehalt_frei); keine Zinsen, kein Rückbehalt-Antrag.","required":["art","contractId","stichtag","offenePostenIds","requestedExecutionDate","vorschlagHash"],"additionalProperties":false,"properties":{"art":{"type":"string","enum":["rueckbehalt"]},"contractId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"offenePostenIds":{"type":"array","maxItems":200,"items":{"type":"string","format":"uuid"}},"requestedExecutionDate":{"type":"string","format":"date"},"betragCents":{"type":"string","pattern":"^-?[0-9]{1,18}$","description":"Teilbetrag des Rückbehalts in Cent (Ziffern-STRING, #6900); zulässig 0 < betragCents ≤ Rest, sonst 409. Fehlt er, wird der ganze Rest freigegeben (Inhalt wie vorher)."},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/kaution/abrechnung/vorschlag"}}},{"type":"object","title":"KautionsabrechnungStornoBezug","description":"art=storno — der Storno einer ausgeführten Abrechnung (storniere_kautionsabrechnung, #6645).","required":["art","kautionsabrechnungId","grund","vorschlagHash"],"additionalProperties":false,"properties":{"art":{"type":"string","enum":["storno"]},"kautionsabrechnungId":{"type":"string","format":"uuid","description":"die zu stornierende Abrechnung"},"grund":{"type":"string","minLength":1,"maxLength":500,"description":"Storno-Grund (Pflicht, nicht leer)"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash aus POST /api/kaution/abrechnung/vorschlag"}}}],"discriminator":{"propertyName":"art"}}}}},"responses":{"200":{"description":"freigegeben — { approvalId, art, contractId, vorschlagHash }","content":{"application/json":{"schema":{"type":"object","properties":{"approvalId":{"type":"string","format":"uuid"},"art":{"type":"string","enum":["abrechnung","rueckbehalt","storno"]},"contractId":{"type":"string","format":"uuid"},"vorschlagHash":{"type":"string"}}}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreib-/Freigaberecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag bzw. (art storno) Abrechnung unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"der Inhalt weicht vom vorgelegten Hash ab (neu vorschlagen), über diesen Vorschlag ist bereits entschieden oder der Schritt ist nicht möglich (ApiErrorBody, code conflict)"}}}},"/api/kaution/abrechnung/storno":{"post":{"summary":"Storniert eine ausgeführte Kautionsabrechnung (storniere_kautionsabrechnung): NUR mit hashgebundener Freigabe (vorschlagHash aus POST /api/kaution/abrechnung/vorschlag, art storno, freigegeben über POST /api/kaution/abrechnung/freigabe). Danach ist POST /api/kaution/abrechnung für denselben Vertrag wieder möglich.","operationId":"storniereKautionsabrechnung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["kautionsabrechnungId","grund","vorschlagHash"],"additionalProperties":false,"properties":{"kautionsabrechnungId":{"type":"string","format":"uuid","description":"die zu stornierende Abrechnung"},"grund":{"type":"string","minLength":1,"maxLength":500,"description":"Storno-Grund (Pflicht, nicht leer)"},"vorschlagHash":{"type":"string","pattern":"^[0-9a-f]{64}$","description":"Hash des FREIGEGEBENEN Storno-Vorschlags (art storno)"}}}}}},"responses":{"200":{"description":"storniert — { kautionsabrechnungId, contractId, storniertAm, stornierteZahlungsauftraege, stornierteVerrechnungen }","content":{"application/json":{"schema":{"type":"object","properties":{"kautionsabrechnungId":{"type":"string","format":"uuid"},"contractId":{"type":"string","format":"uuid"},"storniertAm":{"type":"string","format":"date-time"},"stornierteZahlungsauftraege":{"type":"array","items":{"type":"string","format":"uuid"}},"stornierteVerrechnungen":{"type":"array","items":{"type":"string","format":"uuid"}}}}}}},"400":{"description":"ungültige Eingabe, auch unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"kein Schreibrecht oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Abrechnung unbekannt ODER mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"keine Freigabe des Inhalts, fremder Hash, bereits storniert oder Auszahlungsauftrag schon eingereicht (mit Auftrag und Status) — es wird nichts geschrieben (ApiErrorBody, code conflict)"}}}},"/api/honorar/sonderleistungen":{"post":{"summary":"Erfasst EINE Sonderleistung (erfasse_sonderleistung) mit dem Preis-Schnappschuss aus dem Katalog des Objekts. Derselbe Idempotency-Key legt sie nur einmal an.","operationId":"erfasseSonderleistung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["propertyId","schluessel","leistungsdatum","menge"],"properties":{"propertyId":{"type":"string","format":"uuid"},"schluessel":{"type":"string","minLength":1,"maxLength":100,"description":"Schlüssel der Leistung im Katalog des Objekts (exakter Abgleich)."},"leistungsdatum":{"type":"string","format":"date","description":"Tag der Leistung — bestimmt den Honorarmonat."},"menge":{"type":"string","description":"Dezimal-STRING mit Punkt: bei Festpreis und je Einheit ganzzahlig ≥ 1, je Stunde > 0 mit höchstens zwei Nachkommastellen (\"1.25\")."},"unitId":{"type":"string","format":"uuid","nullable":true,"description":"Bezug auf eine Einheit DES Objekts; fehlt er, ist die Leistung objektweit."},"notiz":{"type":"string","maxLength":2000,"nullable":true}}}}}},"responses":{"200":{"description":"{ sonderleistungId, bezeichnung, menge, nettoCents, umsatzsteuersatzProzent, umsatzsteuerCents, bruttoCents, currency } — Cent-Felder und Satz als Integer-STRINGS."},"400":{"description":"ungültige Eingabe, unbekanntes Feld, Leistung nicht im Katalog, Menge passt nicht zur Preisart, Einheit nicht im Objekt oder unbrauchbarer Katalog (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"am Objekt ist kein Sonderleistungs-Katalog hinterlegt ODER das Objekt ist mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/honorar/sonderleistungen/serie":{"post":{"summary":"Serienerfassung (erfasse_sonderleistungsserie): EINE Leistung mit Preis je Einheit für jede Einheit, die am Leistungsdatum zum Objekt gehört — in einem Schritt (z. B. § 35a-Bescheinigung). Dieselbe Serie (Objekt, Leistung, Leistungsdatum) entsteht nur einmal; eine Wiederholung meldet bereitsErfasst: true.","operationId":"erfasseSonderleistungsserie","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["propertyId","schluessel","leistungsdatum"],"properties":{"propertyId":{"type":"string","format":"uuid"},"schluessel":{"type":"string","minLength":1,"maxLength":100,"description":"Leistung der Preisart je_einheit im Katalog des Objekts."},"leistungsdatum":{"type":"string","format":"date"},"notiz":{"type":"string","maxLength":2000,"nullable":true}}}}}},"responses":{"200":{"description":"{ serieId, anzahl, sonderleistungIds, nettoCents, currency, bereitsErfasst }"},"400":{"description":"ungültige Eingabe, Leistung nicht im Katalog, Leistung nicht je Einheit, Objekt ohne Einheiten am Leistungsdatum (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"kein Sonderleistungs-Katalog am Objekt ODER Objekt mandantenfremd (ApiErrorBody, code not_found)"}}}},"/api/honorar/sonderleistungen/storno":{"post":{"summary":"Storniert eine erfasste Sonderleistung (storniere_sonderleistung). Sie bleibt auffindbar, zählt aber in keiner Honorarrechnung mehr.","operationId":"storniereSonderleistung","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["propertyId","sonderleistungId","grund"],"properties":{"propertyId":{"type":"string","format":"uuid"},"sonderleistungId":{"type":"string","format":"uuid"},"grund":{"type":"string","minLength":1,"maxLength":500}}}}}},"responses":{"200":{"description":"{ sonderleistungId, storniert: true }"},"400":{"description":"ungültige Eingabe oder unbekanntes Feld (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"keine Sonderleistung mit dieser Id an diesem Objekt ODER mandantenfremd (ApiErrorBody, code not_found)"},"409":{"description":"die Sonderleistung ist bereits storniert (ApiErrorBody, code conflict)"}}}},"/api/honorar/sonderleistungen/vorlage":{"post":{"summary":"Kopiert den Vorlage-Katalog des Mandanten (Mandanten-Option `verwalterhonorar.sonderleistungen`) als EIGENEN Sonderleistungs-Katalog an ein Objekt (uebernimm_sonderleistungsvorlage). Eine Kopie, kein Verweis; ein vorhandener Katalog wird nie überschrieben.","operationId":"uebernimmSonderleistungsvorlage","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["propertyId"],"properties":{"propertyId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"{ anzahl } — Zahl der übernommenen Katalogeinträge"},"400":{"description":"ungültige Eingabe oder unbrauchbare Vorlage (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt unbekannt oder mandantenfremd (ApiErrorBody, code not_found)"},"409":{"description":"kein Vorlage-Katalog hinterlegt ODER das Objekt hat schon einen Katalog (ApiErrorBody, code conflict)"}}}},"/api/honorar/anpassungen":{"get":{"summary":"Geschichte der Honorar-Anpassungen EINES Objekts, neueste zuerst — ohne den Akteur, der sie vorgenommen hat.","operationId":"listHonorarAnpassungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Das Objekt.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ anpassungen: [ { id, propertyId, wirksamAb, grundlage, beschlussId, zustimmungAm, begruendung, scheibeAlt, scheibeNeu, createdAt } ] }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HonorarAnpassungenResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt oder mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"post":{"summary":"Passt die Honorarvereinbarung eines Objekts an (passe_honorarvereinbarung_an): neue Zeitscheibe ab einem Monatsersten, die laufende endet am Vortag. WEG nur mit tragendem Beschluss, keine Rückwirkung auf gestellte Monate. Derselbe Idempotency-Key legt die Anpassung nur einmal an.","operationId":"passeHonorarvereinbarungAn","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasseHonorarvereinbarungAnRequest"}}}},"responses":{"201":{"description":"{ anpassungId, neueScheibe, geschlosseneScheibe, vergleich, hinweise } — Cent-Felder und Sätze als Integer-STRINGS.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HonorarAnpassungResponse"}}}},"400":{"description":"ungültige Eingabe oder verletzte Regel des Fachkerns, z. B. weg-braucht-beschluss oder vereinbarung-ungueltig (ApiErrorBody, code invalid_request; die Meldung beginnt mit dem Regel-Code)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt oder Beschluss unbekannt oder mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"zu diesem Datum gibt es schon eine Anpassung (anpassung-existiert) ODER die Anpassung wirkt auf einen gestellten Monat zurück (ApiErrorBody, code conflict)"}}}},"/api/zeit":{"get":{"summary":"Die EIGENEN Zeiteinträge im Zeitraum (nach Leistungsdatum), neueste zuerst, einschließlich stornierter. Ohne von/bis: der laufende Kalendermonat (Europe/Berlin).","operationId":"listZeit","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":false,"description":"Nur Einträge dieses Objekts.","schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":false,"description":"Erster Kalendertag `JJJJ-MM-TT` (inklusiv).","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":false,"description":"Letzter Kalendertag `JJJJ-MM-TT` (inklusiv).","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"{ eintraege }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZeiteintraegeResponse"}}}},"400":{"description":"ungültige Query oder von liegt nach bis (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objektfilter: Objekt unbekannt oder mandantenfremd (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}},"post":{"summary":"Trägt Zeit nachträglich ein (erfasse_zeit, Quelle manuell). Objektbezug ist Pflicht. Derselbe Idempotency-Key legt den Eintrag nur einmal an.","operationId":"erfasseZeit","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErfasseZeitRequest"}}}},"responses":{"201":{"description":"{ zeitId, dauerMinuten, leistungsdatum, hinweise }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZeitErfasstResponse"}}}},"400":{"description":"ungültige Eingabe, z. B. 0 Minuten oder Datum in der Zukunft (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt oder Bezug unbekannt oder mandantenfremd (ApiErrorBody, code not_found)"},"409":{"description":"Objekt ist archiviert (ApiErrorBody, code conflict)"}}}},"/api/zeit/start":{"post":{"summary":"Startet einen Timer (starte_zeit). Mehrere Timer dürfen gleichzeitig laufen; läuft einer an einem anderen Objekt, kommt der Hinweis timer-an-anderem-objekt.","operationId":"starteZeit","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StarteZeitRequest"}}}},"responses":{"201":{"description":"{ zeitId, beginn, leistungsdatum, hinweise }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZeitGestartetResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Objekt oder Bezug unbekannt oder mandantenfremd (ApiErrorBody, code not_found)"},"409":{"description":"Objekt ist archiviert (ApiErrorBody, code conflict)"}}}},"/api/zeit/laufend":{"get":{"summary":"Die laufenden Timer des Angemeldeten (nicht gestoppt, nicht storniert), ältester zuerst.","operationId":"listZeitLaufend","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"{ timer }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZeitLaufendResponse"}}}},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"}}}},"/api/zeit/{id}":{"patch":{"summary":"Korrigiert einen EIGENEN, beendeten Eintrag (korrigiere_zeit). Ein laufender Timer ist nicht korrigierbar.","operationId":"korrigiereZeit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KorrigiereZeitRequest"}}}},"responses":{"200":{"description":"{ zeitId, dauerMinuten, leistungsdatum, hinweise }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZeitErfasstResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Eintrag unbekannt, mandantenfremd oder von einem anderen Mitarbeiter (ApiErrorBody, code not_found)"},"409":{"description":"der Timer läuft noch, der Eintrag ist storniert oder kein Timer (ApiErrorBody, code conflict)"}}}},"/api/zeit/{id}/stopp":{"post":{"summary":"Stoppt einen EIGENEN laufenden Timer (stoppe_zeit); die Dauer wird aus Beginn und Ende gerechnet.","operationId":"stoppeZeit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"{ zeitId, ende, dauerMinuten, hinweise }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZeitGestopptResponse"}}}},"400":{"description":"ungültige Id (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Eintrag unbekannt, mandantenfremd oder von einem anderen Mitarbeiter (ApiErrorBody, code not_found)"},"409":{"description":"der Timer ist bereits gestoppt, storniert oder kein Timer (ApiErrorBody, code conflict)"}}}},"/api/zeit/{id}/storno":{"post":{"summary":"Storniert einen EIGENEN Eintrag (storniere_zeit); er bleibt auffindbar, zählt aber nirgends mehr. Grund ist Pflicht.","operationId":"storniereZeit","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorniereZeitRequest"}}}},"responses":{"200":{"description":"{ zeitId, storniert: true }","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ZeitStorniertResponse"}}}},"400":{"description":"Grund fehlt oder ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Agent oder keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden)"},"404":{"description":"Eintrag unbekannt, mandantenfremd oder von einem anderen Mitarbeiter (ApiErrorBody, code not_found)"},"409":{"description":"der Eintrag ist bereits storniert (ApiErrorBody, code conflict)"}}}},"/api/bankabgleich/vorlegen":{"post":{"summary":"Legt EINEN Bankumsatz als Buchungsvorschlag vor (create_bank_transaction_booking_proposal) — vorbereitend, reversibel, ohne Freigabe.","operationId":"legeBankumsatzVor","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Die KONTIERUNG, mehr nicht. Ampel, Betrag und Verteilung kommen aus dem autorisierenden Read — ein Aufrufer, der sie mitschicken dürfte, könnte das ALL-GREEN-Gate der Sammel-Freigabe aushebeln. Die Anomalie-Schwelle (deviationThresholdPercent) ist bewusst NICHT erreichbar.","required":["bankAccountId","bankTransactionId","asOf"],"properties":{"bankAccountId":{"type":"string","format":"uuid","description":"Die Bankverbindung, auf der der Umsatz liegt."},"bankTransactionId":{"type":"string","format":"uuid","description":"Der vorzulegende Bankumsatz."},"asOf":{"type":"string","format":"date","description":"Bewertungs-Stichtag — dieselbe Achse wie die Anzeige."},"bankGlAccountNo":{"type":"string","description":"Sachkonto der BANK-Seite (Soll) — OPTIONAL seit #1519: es wird aus bankAccountId abgeleitet (gl_accounts.kontotyp = bank am Objekt der Bankverbindung). Ein trotzdem mitgeschickter Wert wird gegen das abgeleitete GEGENGEPRÜFT und bei Abweichung abgewiesen, nicht übernommen. Keine oder mehrere Zuordnungen am Objekt ⇒ fail-closed mit Stammdaten-Klärungsweg; es wird nie das erste Konto gewählt."},"receivableGlAccountNo":{"type":"string","description":"Sachkonto der FORDERUNGS-Seite; weggelassen ⇒ aus dem Beleg der Sollstellung."},"contractId":{"type":"string","format":"uuid","description":"Debitor (Vollkontierung); weggelassen ⇒ aus dem eindeutigen OP-Kandidaten."},"manualAllocationContractId":{"type":"string","format":"uuid","description":"Der vom Menschen GEWÄHLTE Vertrag, aus dem die VERTEILUNG abgeleitet wird (#1761) — der Ausgang für den Sonderfall ohne-gegen-op. NICHT dasselbe wie contractId (das ist der Debitor): hier fehlt nicht die Gegenpartei, sondern das Tilgungsziel. Greift NUR bei leerer Kandidatenliste (sonst 409 — keine Umgehung der Klärung); hat der Vertrag keinen offenen Posten, wird ausdrücklich abgewiesen statt ins Leere gebucht. Ein widersprechendes contractId ⇒ 409. Jede so entstandene Zuordnung trägt die Provenienz „vom Menschen bestimmt\"."}}}}}},"responses":{"201":{"description":"Vorschlags-Version angelegt. `ampel` stammt aus der BEWERTUNG und entscheidet, ob einzeln oder gesammelt freigegeben werden darf.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankabgleichVorlageResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"Umsatz/Sachkonto/Bankverbindung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel; eine archivierte Bankverbindung ist von einer nie existierenden nicht zu unterscheiden)"},"409":{"description":"Debitor nicht eindeutig, kein Tilgungsziel — ODER die Stammdaten geben das Bank-Sachkonto nicht her: keine bzw. mehrere Zuordnungen am Objekt der Bankverbindung, oder ein mitgeschicktes bankGlAccountNo weicht vom abgeleiteten ab (ApiErrorBody, code conflict). Diese Ablehnungen sind DETERMINISTISCH — ein Retry hilft nie; die Meldung nennt den Klärungsweg (Kontenplan pflegen bzw. den Wert weglassen)."},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/bankabgleich/verbuchen":{"post":{"summary":"Legt vor, gibt frei und bucht (execute_bank_transaction_booking) — `modus` wählt das Freigabe-Gate: einzeln (gelb erlaubt) oder sammel (all-green).","operationId":"verbucheBankumsatz","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"description":"Zwei Formen, unterschieden über `modus` — das ist kein Komfort, sondern der fachliche Unterschied zwischen zwei Freigabe-Gates. `einzeln` fährt approve_proposal (GELB einzeln erlaubt, ROT blockiert) und verlangt `kontierung`; `sammel` fährt batch_approve_proposals (ALL-GREEN, ein nicht-grünes Element lässt den ganzen Aufruf scheitern, bevor etwas gebucht wird) und verlangt `kontierungen` (1..200). Den Modus aus der Anzahl zu erraten wäre gefährlich: ein Skript mit nur einem Umsatz bekäme still das schwächere Gate.","oneOf":[{"type":"object","title":"EinzelVerbuchung","description":"modus=einzeln — EIN Umsatz über approve_proposal (die gelbe Karte darf hier durch, weil sie einzeln angesehen wird).","required":["modus","bankAccountId","asOf","kontierung"],"properties":{"modus":{"type":"string","enum":["einzeln"]},"bankAccountId":{"type":"string","format":"uuid"},"asOf":{"type":"string","format":"date"},"kontierung":{"type":"object","description":"Felder wie bei /api/bankabgleich/vorlegen, ohne bankAccountId und asOf.","required":["bankTransactionId"],"properties":{"bankTransactionId":{"type":"string","format":"uuid"},"bankGlAccountNo":{"type":"string"},"receivableGlAccountNo":{"type":"string"},"contractId":{"type":"string","format":"uuid"}}}}},{"type":"object","title":"SammelVerbuchung","description":"modus=sammel — MEHRERE Umsätze über EIN ALL-GREEN-Gate (ein nicht-grünes Element lässt den ganzen Aufruf scheitern).","required":["modus","bankAccountId","asOf","kontierungen"],"properties":{"modus":{"type":"string","enum":["sammel"]},"bankAccountId":{"type":"string","format":"uuid"},"asOf":{"type":"string","format":"date"},"kontierungen":{"type":"array","description":"1..200 Kontierungen — die Obergrenze ist die Anzeige-Obergrenze der Vorlage (keine Freigabe über Ungesehenes).","minItems":1,"maxItems":200,"items":{"type":"object","required":["bankTransactionId"],"properties":{"bankTransactionId":{"type":"string","format":"uuid"},"bankGlAccountNo":{"type":"string"},"receivableGlAccountNo":{"type":"string"},"contractId":{"type":"string","format":"uuid"}}}}}}],"discriminator":{"propertyName":"modus"}}}}},"responses":{"201":{"description":"Gebucht. Je Umsatz entsteht GENAU EIN wirksamer Buchungsanspruch (INV-BANK-01); Zahlungssatz, Verrechnung und Anspruch liegen in EINER Transaktion. Im Sammelweg wird ERST vollständig freigegeben und DANN gebucht — scheitert eine einzelne Buchung, bleiben die übrigen gebucht und der betroffene Umsatz steht in der Reconciliation weiterhin `offen` (kein stiller Verlust, aber auch keine vorgetäuschte Gesamt-Atomarität).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankabgleichVerbuchungResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"fehlende Step-up-Frische oder keine Zuständigkeit (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"Umsatz/Vorschlag/Sachkonto/Bankverbindung unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel; eine archivierte Bankverbindung ist von einer nie existierenden nicht zu unterscheiden)"},"409":{"description":"bereits entschieden, Ampel blockiert, Sammel-Freigabe nicht durchgehend grün, Vorschlag nicht mehr freigegeben — ODER die Stammdaten geben das Bank-Sachkonto nicht her: keine bzw. mehrere Zuordnungen am Objekt der Bankverbindung, oder ein mitgeschicktes bankGlAccountNo weicht vom abgeleiteten ab (ApiErrorBody, code conflict). Diese Ablehnungen sind DETERMINISTISCH — ein Retry hilft nie; die Meldung nennt den Klärungsweg (Kontenplan pflegen bzw. den Wert weglassen)."},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/sollstellung":{"post":{"summary":"Startet einen Sollstellungslauf (start_sollstellungslauf) — Ergebnis sind VORSCHLÄGE, gebucht wird erst nach der Freigabe.","operationId":"starteSollstellungslauf","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Objekt + Stichtag. Offene Readiness-Befunde blockieren den Start (409); sie lassen sich übergehen, aber NUR mit Begründung — sie wandert ins Kommando-Log. Es gibt bewusst keinen force-Schalter ohne Text.","required":["propertyId","stichtag"],"properties":{"propertyId":{"type":"string","format":"uuid"},"stichtag":{"type":"string","format":"date"},"uebergehen":{"type":"object","description":"Das AUDITIERTE Übergehen offener Readiness-Befunde.","required":["begruendung"],"properties":{"begruendung":{"type":"string","minLength":1}}}}}}}},"responses":{"201":{"description":"Lauf gestartet — die Antwort zählt die erzeugten Vorschläge (neu/storno/ersatz) und die übersprungenen Debitoren.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SollstellungslaufStartResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"keine Zuständigkeit für das Objekt (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"unbekanntes ODER fremdes Objekt (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"offene Readiness-Befunde ohne Begründung oder bereits ein offener Lauf (ApiErrorBody, code conflict)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/sollstellung/freigabe":{"post":{"summary":"Gibt die Vorschläge eines Sollstellungslaufs in EINEM Zug frei (batch_approve_proposals) — ALL-GREEN, keine Teil-Freigabe.","operationId":"gibSollstellungFrei","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Die freizugebenden Vorschläge. Das Gate sitzt im Werkzeug: Step-up, Maker-Checker, Ampel-Regel und Hash-Bindung — es gibt bewusst KEIN sollstellungs-eigenes Freigabe-Tool. Ein einziger nicht-grüner Vorschlag lässt den ganzen Aufruf scheitern, bevor etwas freigegeben ist.","required":["proposalIds"],"properties":{"proposalIds":{"type":"array","minItems":1,"items":{"type":"string","format":"uuid"}}}}}}},"responses":{"201":{"description":"Freigegeben. Je Element reist der contentHash mit — der Beleg, an den die Freigabe bindet (INV-APPROVAL-01).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SollstellungFreigabeResponse"}}}},"400":{"description":"ungültige Eingabe (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"fehlende Step-up-Frische oder keine Zuständigkeit (ApiErrorBody, code forbidden — fail-closed)"},"404":{"description":"unbekannter ODER fremder Vorschlag (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"bereits entschieden oder nicht durchgehend grün (ApiErrorBody, code conflict)"},"503":{"description":"Zuständigkeitsprüfung nicht durchführbar (ApiErrorBody, code unavailable — nie durchwinken)"}}}},"/api/sollstellung/{id}/vorschlaege":{"get":{"summary":"Liest die Vorschläge EINES Sollstellungslaufs — die `proposalIds`, die POST /api/sollstellung/freigabe erwartet.","operationId":"listSollstellungVorschlaege","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Der Sollstellungslauf.","schema":{"type":"string","format":"uuid"}},{"name":"art","in":"query","required":false,"description":"Auf EINE Vorschlagsart eingrenzen. Weggelassen ⇒ ALLE. Wer freigibt, will in der Regel alle: die kanonische Ordnung STORNO VOR ERSATZ ist die, in der INV-SOLL-01 zu keinem Zeitpunkt zwei wirksame Forderungen sieht — sie zu zerreissen ist eine bewusste Entscheidung des Aufrufers.","schema":{"type":"string","enum":["neu","storno","ersatz"]}},{"name":"nurOffene","in":"query","required":false,"description":"`true` ⇒ nur Vorschläge OHNE bindende Entscheidung — die Menge, die eine Freigabe noch annimmt.","schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Kopf, Vorschläge und Readiness-Befunde des Laufs. `betragCents` ist ein vorzeichenbehafteter Integer-STRING, nie eine JSON-number. Die `ampel` ist GELESEN (der Lauf hat sie gesetzt), nicht hier gerechnet. `bindetAktuellenStand` unterscheidet „noch nicht entschieden\" von „Freigabe durch eine Korrektur ungültig geworden\" — zwei Zustände, die in einem einzelnen Boolean verschmelzen würden. Die `befunde` stehen NEBEN den Vorschlägen: „für diesen Vertrag ist nichts entstanden\" darf nicht als „Lauf leer\" ankommen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SollstellungVorschlaegeResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request — Feldname + Regel, nie der Wert)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannter Lauf, fremder Tenant ODER keine UUID (ApiErrorBody, code not_found — kein Existenz-Orakel, insbesondere kein 403)"}}}},"/api/bank/{id}/umsaetze":{"get":{"summary":"Liest die IMPORTIERTEN Umsätze einer Bankverbindung — die `bankTransactionId`, die POST /api/bankabgleich/* erwartet.","operationId":"listBankUmsaetze","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Die Bankverbindung.","schema":{"type":"string","format":"uuid"}},{"name":"menge","in":"query","required":false,"description":"`alle` (Default) · `offen` (kein wirksamer Buchungsanspruch) · `gebucht`. Der Default ist bewusst `alle`: diese Route ist die Auskunft über den IMPORT, nicht die Arbeitsliste — ein bereits gebuchter Umsatz darf nicht spurlos verschwinden.","schema":{"type":"string","enum":["alle","offen","gebucht"]}},{"name":"providerId","in":"query","required":false,"description":"Auf GENAU EINE Bank-Referenz eingrenzen (bei camt `AcctSvcrRef`) — der Weg, einen Umsatz aus dem eigenen Auszug wiederzufinden.","schema":{"type":"string"}},{"name":"correlationId","in":"query","required":false,"description":"Auf EINEN Import-Lauf eingrenzen.","schema":{"type":"string"}},{"name":"buchungVon","in":"query","required":false,"description":"Untere Grenze des Buchungsdatums (einschließlich).","schema":{"type":"string","format":"date"}},{"name":"buchungBis","in":"query","required":false,"description":"Obere Grenze des Buchungsdatums (einschließlich).","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","required":false,"description":"1…200; Default 50. `abgeschnitten` sagt, ob mehr da war.","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Die Umsätze der Verbindung, jüngstes Buchungsdatum zuerst. `betragCents` ist ein vorzeichenbehafteter Integer-STRING (> 0 Eingang, < 0 Ausgang), nie eine JSON-number. `gebucht` kommt aus DEMSELBEN Anspruchs-Prädikat wie Arbeitsliste und Reconciliation (INV-BANK-01) — es gibt keine zweite Formulierung. ACHTUNG PII: verwendungszweck, gegenkontoIban und gegenkontoInhaber sind personenbezogen (freitext/bankdaten/name) und reisen absichtlich mit, weil ohne sie kein Mensch einen Umsatz zuordnen kann; der rohe Provider-Datensatz (`raw`) reist NICHT mit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BankUmsatzListResponse"}}}},"400":{"description":"ungültige Query (ApiErrorBody, code invalid_request — Feldname + Regel, nie der Wert)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"unbekannte Bankverbindung, fremder Tenant ODER keine UUID (ApiErrorBody, code not_found — kein Existenz-Orakel, insbesondere kein 403)"}}}},"/api/auswertung/einnahmen-ueberschuss":{"get":{"summary":"Einnahmen-Überschuss-Aufstellung EINES Objekts für EIN Kalenderjahr (Zufluss/Abfluss, § 11 EStG): Einnahmen und Werbungskosten je Gruppe, Brutto/USt/Netto, Überschuss — für das Objekt oder den Anteil eines Eigentümers; Kautionen, durchlaufende Posten, Rücklagen und Eigentümer-Einlagen/-Entnahmen zählen nicht.","operationId":"getEinnahmenUeberschuss","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Objekt (Buchungskreis).","schema":{"type":"string","format":"uuid"}},{"name":"jahr","in":"query","required":true,"description":"Kalenderjahr (JJJJ).","schema":{"type":"string","pattern":"^\\d{4}$"}},{"name":"eigentuemer","in":"query","required":false,"description":"Eigentümer (`persons.id`); fehlt ⇒ Objekt gesamt. Der Anteil folgt dem Eigentumsanteil am Tag jeder Position, Rest-Cent nach größtem Rest.","schema":{"type":"string","format":"uuid"}},{"name":"format","in":"query","required":false,"description":"`json` (Vorgabe) oder `csv` (UTF-8 mit BOM, Semikolon, Dezimalkomma, CRLF, Quellenkopf) — zur Weitergabe an Eigentümer oder Steuerberater.","schema":{"type":"string","enum":["json","csv"]}}],"responses":{"200":{"description":"Die Aufstellung als Katalog-Tabelle (`betrag`-Zellen sind Integer-Cent-Strings) oder bei format=csv die fertige CSV-Datei.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuswertungResponse"}},"text/csv":{"schema":{"type":"string","description":"CSV mit `# `-Quellenkopf, Leerzeile, Spalten-Kopfzeile und den Datenzeilen."}}}},"400":{"description":"ungültige Query — fehlendes/ungültiges Objekt oder Jahr, unbekannter Parameter oder Format (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt oder fremd, oder die Person hat im Jahr keinen Anteil (ApiErrorBody, code not_found)"},"422":{"description":"Stammdaten nicht auswertbar — Einheit ohne Eigentümer, uneinheitliche Anteile, nicht einordenbares Gegenkonto (ApiErrorBody, code invalid_request)"}}}},"/api/auswertung/einnahmen-ausgaben":{"get":{"summary":"Liest das Einnahmen-/Ausgaben-Journal eines Objekts für einen Zeitraum: je Geldbewegung eine Zeile mit Gegenkonto, Beleg und Netto/USt/Brutto, dazu die Summen je Gegenkonto. Eine Umbuchung zwischen zwei Geldkonten ist weder Einnahme noch Ausgabe — sie steht in `umbuchungen`.","operationId":"liesEinnahmenAusgabenJournal","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Das Objekt (UUID) — Pflicht, s. Kommentar in der Spec-Quelle.","schema":{"type":"string","format":"uuid"}},{"name":"von","in":"query","required":true,"description":"Erster Tag des Zeitraums (einschließlich).","schema":{"type":"string","format":"date"}},{"name":"bis","in":"query","required":true,"description":"Letzter Tag des Zeitraums (einschließlich).","schema":{"type":"string","format":"date"}},{"name":"je-konto","in":"query","required":false,"description":"Auf GENAU EIN Gegenkonto eingrenzen (`gl_accounts.account_no` am Objekt) — die Kontosicht (WinCASA `JOURNAL_EINAUS_K`). Die Summen gelten dann für dieses Konto; ein Konto ohne Bewegung ergibt eine LEERE Liste, keinen Fehler.","schema":{"type":"string"}}],"responses":{"200":{"description":"Die Aufstellung des Zeitraums (EinnahmenAusgabenResponse). Geld reist als Integer-STRING in Cent, nie als JSON-number. `ustHerkunft` sagt je Zeile, ob der USt-Betrag GEBUCHT oder aus dem Satz ABGELEITET ist (GG7). ACHTUNG PII: `gegenkonto`/`geldkonten` sind Kontonummern und können Personenkonten benennen (`gl_accounts.account_no`, Kategorie kontakt).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EinnahmenAusgabenResponse"}}}},"400":{"description":"fehlendes/ungültiges Objekt, fehlender oder verdrehter Zeitraum (ApiErrorBody, code invalid_request — Feldname + Regel, nie der Wert)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/sondereigentumsverwaltung/stand":{"get":{"summary":"Liest den Monatsstand der Sondereigentumsverwaltung eines Objekts: je SEV-Wohnung die erledigten und offenen Schritte, den Saldo des Eigentümers, Sockel und Sonderrücklage, die Unterdeckungen mit Betrag und den nächsten fälligen Schritt. Werte ohne Quelle stehen auf „nicht verfügbar\", nie auf null.","operationId":"liesSevMonatsstand","security":[{"bearerAuth":[]}],"parameters":[{"name":"objekt","in":"query","required":true,"description":"Das Objekt (UUID) — Pflicht: der Monatsstand ist je Objekt, nicht mandantenweit.","schema":{"type":"string","format":"uuid"}},{"name":"monat","in":"query","required":true,"description":"Der Monat als `JJJJ-MM` (Monat 01 bis 12). Ohne Monat gäbe es keinen Stand, sondern eine Momentaufnahme, die morgen anders lautet.","schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}}],"responses":{"200":{"description":"Der Monatsstand (SevMonatsstandResponse). Beträge reisen als Integer-STRING in Cent, nie als JSON-number — und als `null`, sobald ihr `stand` nicht `bekannt` ist. ACHTUNG PII: `wohnungen[].eigentuemer` ist ein Personenname (Kategorie name); das ist die Auskunft, die bestellt wurde (Abnahme 4: Eigentümer mit Namen).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SevMonatsstandResponse"}}}},"400":{"description":"fehlendes/ungültiges Objekt oder ungültiger Monat (ApiErrorBody, code invalid_request — Feldname + Regel, nie der Wert)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"404":{"description":"Objekt unbekannt ODER fremder Tenant (ApiErrorBody, code not_found — kein Existenz-Orakel)"}}}},"/api/instandhaltung/{id}/auftrag":{"post":{"summary":"Erteilt den Auftrag des Vorgangs, nachdem die Kostenfreigabe vollständig ist: optional auftragId (ohne Angabe der lebende Auftrag des Vorgangs). Ein Auftrag ohne gültige Freigabe wird nie erteilt (409). Gestattungs- und Freistellungsbefunde sind Warnungen, die Erteilung läuft trotzdem. Die Vorgangs-Id steht im Pfad.","operationId":"erteileInstandhaltungAuftrag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAuftragErteilenRequest"}}}},"responses":{"200":{"description":"Auftrags-Id, Auftragsnummer, Erteilungstag und Befunde.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAuftragErteilenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang oder Auftrag unbekannt, mandantenfremd oder außerhalb der Objektsicht, oder kein lebender Auftrag (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Auftrag nicht freigegeben oder die Freigabe ist nicht mehr gültig (ApiErrorBody, code conflict)"}}}},"/api/instandhaltung/{id}/auftrag/ausfuehrung":{"post":{"summary":"Meldet die Ausführung des erteilten Auftrags: ausgefuehrtAm (nicht nach heute, nicht vor der Erteilung), optional notiz und auftragId (ohne Angabe der lebende Auftrag). Die Vorgangs-Id steht im Pfad.","operationId":"meldeInstandhaltungAusfuehrung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAuftragAusfuehrungRequest"}}}},"responses":{"200":{"description":"Auftrags-Id und Ausführungstag.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAuftragAusfuehrungResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang oder Auftrag unbekannt, mandantenfremd oder außerhalb der Objektsicht, oder kein lebender Auftrag (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Auftrag nicht erteilt (ApiErrorBody, code conflict)"}}}},"/api/instandhaltung/{id}/auftrag/stornieren":{"post":{"summary":"Storniert den Auftrag des Vorgangs mit Grund (Pflicht); optional auftragId. Nach der Freigabe fällt der Vorgang zurück in angebote_offen, eine neue Freigabe ist nötig. Ein ausgeführter Auftrag oder ein Auftrag mit Rechnung lässt sich nicht mehr stornieren (409). Die Vorgangs-Id steht im Pfad.","operationId":"storniereInstandhaltungAuftrag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAuftragStornierenRequest"}}}},"responses":{"200":{"description":"Auftrags-Id und neuer Vorgangsstatus.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAuftragStornierenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang oder Auftrag unbekannt, mandantenfremd oder außerhalb der Objektsicht, oder kein lebender Auftrag (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Auftrag ausgeführt, Rechnung verknüpft oder schon storniert (ApiErrorBody, code conflict)"}}}},"/api/instandhaltung/{id}/rechnung":{"post":{"summary":"Verknüpft einen Rechnungsbeleg mit dem ausgeführten Auftrag: documentId, rechnungsdatum, optional auftragId. Befunde (freistellung-fehlt, rechnung-ueber-auftrag, gestattungsbeschluss-fehlt) sperren nicht: die Verknüpfung gelingt und nennt sie. Die harte Sperre der Zahlung ohne Freistellungsbescheinigung liegt im Zahlungsauftrag. Die Vorgangs-Id steht im Pfad.","operationId":"verknuepfeInstandhaltungRechnung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungRechnungRequest"}}}},"responses":{"200":{"description":"Rechnungs-Id, Betrag, Auftragswert, Abweichung, Summe, Bauleistung und Befunde mit Code, Schwere und Text.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungRechnungResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang oder Auftrag unbekannt, mandantenfremd oder außerhalb der Objektsicht, oder kein lebender Auftrag (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Beleg schon verknüpft oder Auftrag nicht ausgeführt (ApiErrorBody, code conflict)"}}}},"/api/instandhaltung/{id}/abschluss":{"post":{"summary":"Schließt den Vorgang ab; optional begruendung. Die Vorgangs-Id steht im Pfad.","operationId":"schliesseInstandhaltungVorgang","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAbschlussRequest"}}}},"responses":{"200":{"description":"Vorgangs-Id, vorheriger und neuer Status, Ereignis-Id und Begründung.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAbschlussResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang oder Auftrag unbekannt, mandantenfremd oder außerhalb der Objektsicht, oder kein lebender Auftrag (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Zu dem Vorgang läuft noch ein Auftrag (ApiErrorBody, code conflict)"}}}},"/api/instandhaltung/{id}/stornieren":{"post":{"summary":"Storniert den Vorgang mit Grund (Pflicht). Läuft noch ein Auftrag, ist erst der Auftrag zu stornieren (409). Die Vorgangs-Id steht im Pfad.","operationId":"storniereInstandhaltungVorgang","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungVorgangStornierenRequest"}}}},"responses":{"200":{"description":"Vorgangs-Id, vorheriger und neuer Status, Ereignis-Id und Grund.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstandhaltungAbschlussResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vorgang oder Auftrag unbekannt, mandantenfremd oder außerhalb der Objektsicht, oder kein lebender Auftrag (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Zu dem Vorgang läuft noch ein Auftrag (ApiErrorBody, code conflict)"}}}},"/api/schadenfall/{id}/meldung":{"post":{"summary":"Hält die Meldung an den Versicherer fest: gemeldetAm, optional aktenzeichen und versicherungsvertragId. Eine verstrichene Meldefrist ist ein Befund (meldefrist-verstrichen); die Meldung wird trotzdem festgehalten. Die Schadenfall-Id steht im Pfad.","operationId":"meldeSchadenfallVersicherer","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallMeldenRequest"}}}},"responses":{"200":{"description":"Schadenfall-Id, Nummer, Status gemeldet, Selbstbehalt und Befunde.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallErgebnis"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Schadenfall unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Schadenfall steht in einem Status, in dem die Meldung nicht möglich ist (ApiErrorBody, code conflict)"}}}},"/api/schadenfall/{id}/deckung":{"post":{"summary":"Erfasst die Deckungsentscheidung des Versicherers: entscheidung (zugesagt | abgelehnt), deckungAm, optional schadenssumme und selbstbehalt als Geld-Objekt {cents, currency}. Die Schadenfall-Id steht im Pfad.","operationId":"erfasseSchadenfallDeckung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallDeckungRequest"}}}},"responses":{"200":{"description":"Schadenfall-Id, Nummer, Status, Selbstbehalt, Schadenssumme und Befunde.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallDeckungResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Schadenfall unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Der Status des Schadenfalls erlaubt die Entscheidung nicht (ApiErrorBody, code conflict)"}}}},"/api/schadenfall/{id}/erstattung":{"post":{"summary":"Ordnet einen Bankumsatz als Erstattung zu. Die Buchung entsteht als Vorschlag und wird erst nach der Freigabe gebucht. Der Fall muss auf Deckung zugesagt oder reguliert stehen; ein Umsatz gehört höchstens einem Schadenfall. Die Schadenfall-Id steht im Pfad.","operationId":"erfasseSchadenfallErstattung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallErstattungRequest"}}}},"responses":{"200":{"description":"Erstattung, Bilanz und der Buchungsvorschlag (nicht gebucht).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallErstattungResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Schadenfall unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Bankumsatz schon einem Schadenfall zugeordnet oder der Fall steht nicht auf Deckung zugesagt oder reguliert (ApiErrorBody, code conflict)"}}}},"/api/schadenfall/{id}/abschluss":{"post":{"summary":"Schließt den Schadenfall ab (optional begruendung); ohne Versicherungsbezug ist eine Begründung Pflicht. Die Schadenfall-Id steht im Pfad.","operationId":"schliesseSchadenfall","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallAbschlussRequest"}}}},"responses":{"200":{"description":"Schadenfall-Id, vorheriger Status, Begründung, Bilanz und Befund.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchadenfallAbschlussResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Schadenfall unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Der Status des Schadenfalls erlaubt den Abschluss nicht (ApiErrorBody, code conflict)"}}}},"/api/fremdvertrag/{id}/konditionen":{"post":{"summary":"Legt eine neue Konditions-Version des Vertrags an (kein Teil-Patch: jeder Schlüssel ist Pflicht, leer ist null). gueltigAb muss nach dem gueltigAb der letzten Version liegen. Die Vertrags-Id steht im Pfad.","operationId":"aendereFremdvertragKonditionen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragKonditionenRequest"}}}},"responses":{"200":{"description":"Vertrags-Id und die neue Konditions-Version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragKonditionenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vertrag beendet oder gueltigAb nicht nach der letzten Version (ApiErrorBody, code conflict)"}}}},"/api/fremdvertrag/{id}/kuendigung":{"post":{"summary":"Hält die Kündigung des Vertrags fest (wirksamZum nicht vor heute, optional grund). Die Antwort nennt das früheste Vertragsende und den spätesten Zugang als Auskunft; sie sperrt nicht. Die Vertrags-Id steht im Pfad.","operationId":"kuendigeFremdvertrag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragKuendigungRequest"}}}},"responses":{"200":{"description":"Ereignis-Id, Wirksamkeit, frühestes Ende und spätester Zugang.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragKuendigungResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vertrag schon beendet (ApiErrorBody, code conflict)"}}}},"/api/fremdvertrag/{id}/beendigung":{"post":{"summary":"Beendet den Vertrag zum Tag beendetAm (nicht vor dem Beginn, optional grund). Die Vertrags-Id steht im Pfad.","operationId":"beendeFremdvertrag","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragBeendigungRequest"}}}},"responses":{"200":{"description":"Ereignis-Id und Beendigungstag.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragBeendigungResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vertrag schon beendet (ApiErrorBody, code conflict)"}}}},"/api/fremdvertrag/{id}/frist-entscheid":{"post":{"summary":"Hält die Entscheidung zu einem Vertragsende fest: bezugEnde, entscheidung (verlaengern | kuendigen | neu_ausschreiben), optional grund. Es wird nie eine Kündigung angelegt. Danach verschwindet die Zeile aus dem Fristenwächter. Die Vertrags-Id steht im Pfad.","operationId":"entscheideFremdvertragFrist","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragFristEntscheidRequest"}}}},"responses":{"200":{"description":"Ereignis-Id, Entscheidung und Hinweis.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragFristEntscheidResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Zu diesem Vertragsende ist schon entschieden oder der Vertrag ist beendet (ApiErrorBody, code conflict)"}}}},"/api/fremdvertrag/{id}/dauerzahlung":{"post":{"summary":"Verknüpft den Vertrag mit einer Dauerzahlung desselben Objekts. Weichen Beitrag und Dauerzahlung ab, nennt die Antwort den Befund; er sperrt nicht. Die Vertrags-Id steht im Pfad.","operationId":"verknuepfeFremdvertragDauerzahlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragDauerzahlungRequest"}}}},"responses":{"200":{"description":"Vertrags-Id, Dauerzahlungs-Id und optional der Abweichungs-Befund.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragDauerzahlungResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag oder Dauerzahlung unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Vertrag schon verknüpft oder Dauerzahlung schon vergeben (ApiErrorBody, code conflict)"}}}},"/api/fremdvertrag/{id}/dauerzahlung/loesen":{"post":{"summary":"Löst die Verknüpfung des Vertrags mit seiner Dauerzahlung (Body {}). Die Dauerzahlung selbst bleibt unberührt. Die Vertrags-Id steht im Pfad.","operationId":"loeseFremdvertragDauerzahlung","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragDauerzahlungLoesenRequest"}}}},"responses":{"200":{"description":"Vertrags-Id und die bis eben verknüpfte Dauerzahlung.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FremdvertragDauerzahlungLoesenResponse"}}}},"400":{"description":"ungültige Nutzlast (ApiErrorBody, code invalid_request)"},"401":{"description":"nicht authentifiziert — leerer Body (kein Oracle)"},"403":{"description":"Recht fehlt (ApiErrorBody, code forbidden)"},"404":{"description":"Vertrag unbekannt, mandantenfremd oder außerhalb der Objektsicht (ApiErrorBody, code not_found — kein Existenz-Orakel)"},"409":{"description":"Der Vertrag ist mit keiner Dauerzahlung verknüpft (ApiErrorBody, code conflict)"}}}}}}