{
  "openapi": "3.0.3",
  "info": {
    "title": "Nebenkostenrechner API",
    "description": "REST API fuer die programmatische Berechnung von Betriebskostenabrechnungen nach BetrKV. API-Zugang erfordert den Business-Plan.",
    "version": "1.0.0",
    "contact": {
      "name": "Nebenkostenrechner Support",
      "url": "https://www.mein-nebenkostenrechner.de/kontakt",
      "email": "info@mein-nebenkostenrechner.de"
    },
    "license": {
      "name": "Proprietaer"
    }
  },
  "servers": [
    {
      "url": "https://www.mein-nebenkostenrechner.de/api/v1",
      "description": "Produktion"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "paths": {
    "/calculate": {
      "post": {
        "summary": "Nebenkostenabrechnung berechnen",
        "description": "Berechnet eine vollstaendige Betriebskostenabrechnung mit Aufteilung pro Mieter.",
        "operationId": "calculate",
        "tags": ["Berechnung"],
        "security": [{ "ApiKeyAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/AbrechnungInput" },
              "example": {
                "objekt": {
                  "adresse": "Musterstrasse 1",
                  "plz": "10115",
                  "ort": "Berlin",
                  "gesamtflaeche": 200,
                  "wohneinheiten": 4,
                  "gesamtPersonen": 8,
                  "abrechnungszeitraumVon": "2025-01-01",
                  "abrechnungszeitraumBis": "2025-12-31"
                },
                "mieter": [
                  {
                    "id": "m1",
                    "name": "Mustermann",
                    "flaeche": 65,
                    "personenanzahl": 2,
                    "einzugsdatum": "2020-01-01",
                    "vorauszahlungen": 2400
                  }
                ],
                "positionen": [
                  {
                    "kostenartId": "grundsteuer",
                    "betrag": 800,
                    "verteilerschluessel": "wohnflaeche"
                  },
                  {
                    "kostenartId": "wasserversorgung",
                    "betrag": 1200,
                    "verteilerschluessel": "personenanzahl"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Berechnung erfolgreich",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean" },
                    "ergebnis": { "$ref": "#/components/schemas/Ergebnis" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/validate": {
      "post": {
        "summary": "Eingabedaten validieren",
        "description": "Prueft Objekt-, Mieter- und Kostendaten auf Vollstaendigkeit, Plausibilitaet und BetrKV-Konformitaet.",
        "operationId": "validate",
        "tags": ["Validierung"],
        "security": [{ "ApiKeyAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/AbrechnungInput" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Validierung abgeschlossen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valid": { "type": "boolean", "description": "true wenn keine Fehler" },
                    "errors": { "type": "array", "items": { "type": "string" }, "description": "Kritische Fehler" },
                    "warnings": { "type": "array", "items": { "type": "string" }, "description": "Warnungen (Plausibilitaet)" },
                    "infos": { "type": "array", "items": { "type": "string" }, "description": "Informationen" }
                  }
                },
                "example": {
                  "valid": true,
                  "errors": [],
                  "warnings": ["Heizkosten: 2,50 EUR/m2/Jahr deutlich ueber dem ueblichen Bereich."],
                  "infos": ["1 Mieter, 2 Kostenpositionen", "Heizkosten enthalten - HeizKV 30/70-Aufteilung wird angewendet."]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/pdf": {
      "post": {
        "summary": "PDF-Abrechnung generieren",
        "description": "Generiert eine rechtskonforme Betriebskostenabrechnung als PDF-Datei. Erfordert 'write'-Berechtigung.",
        "operationId": "generatePdf",
        "tags": ["PDF"],
        "security": [{ "ApiKeyAuth": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  { "$ref": "#/components/schemas/AbrechnungInput" },
                  {
                    "type": "object",
                    "properties": {
                      "anschreiben": {
                        "type": "object",
                        "properties": {
                          "modus": { "type": "string", "enum": ["standard", "eigen"], "description": "'standard' = automatisch generiert, 'eigen' = eigener Text" },
                          "text": { "type": "string", "description": "Eigener Anschreiben-Text (nur bei modus='eigen')" }
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "PDF erfolgreich generiert",
            "content": {
              "application/pdf": {
                "schema": { "type": "string", "format": "binary" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/ValidationError" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/cost-types": {
      "get": {
        "summary": "Kostenarten abrufen",
        "description": "Gibt alle 17 Kostenarten nach BetrKV zurueck mit Standardverteilerschluesseln und typischen Bereichen.",
        "operationId": "getCostTypes",
        "tags": ["Stammdaten"],
        "security": [],
        "responses": {
          "200": {
            "description": "Liste aller Kostenarten",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": { "type": "integer" },
                    "kostenarten": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/Kostenart" }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/distribution-keys": {
      "get": {
        "summary": "Verteilerschluessel abrufen",
        "description": "Gibt alle verfuegbaren Verteilerschluessel zurueck.",
        "operationId": "getDistributionKeys",
        "tags": ["Stammdaten"],
        "security": [],
        "responses": {
          "200": {
            "description": "Liste aller Verteilerschluessel",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": { "type": "integer" },
                    "verteilerschluessel": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string" },
                          "label": { "type": "string" },
                          "description": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API-Key im Format nk_XXXX... (erstellen unter /api-keys, erfordert Business-Plan)"
      }
    },
    "schemas": {
      "AbrechnungInput": {
        "type": "object",
        "required": ["objekt", "mieter", "positionen"],
        "properties": {
          "objekt": { "$ref": "#/components/schemas/Objekt" },
          "mieter": { "type": "array", "items": { "$ref": "#/components/schemas/Mieter" }, "minItems": 1 },
          "positionen": { "type": "array", "items": { "$ref": "#/components/schemas/Kostenposition" }, "minItems": 1 }
        }
      },
      "Objekt": {
        "type": "object",
        "required": ["adresse", "plz", "ort", "gesamtflaeche", "wohneinheiten", "abrechnungszeitraumVon", "abrechnungszeitraumBis"],
        "properties": {
          "adresse": { "type": "string", "description": "Strasse und Hausnummer" },
          "plz": { "type": "string", "pattern": "^[0-9]{5}$", "description": "5-stellige PLZ" },
          "ort": { "type": "string" },
          "gesamtflaeche": { "type": "number", "minimum": 1, "description": "Gesamtwohnflaeche in m2" },
          "wohneinheiten": { "type": "integer", "minimum": 1 },
          "gesamtPersonen": { "type": "integer", "minimum": 1, "description": "Gesamtpersonenzahl (fuer Verteilerschluessel 'personenanzahl')" },
          "abrechnungszeitraumVon": { "type": "string", "format": "date", "description": "ISO-Datum, z.B. 2025-01-01" },
          "abrechnungszeitraumBis": { "type": "string", "format": "date", "description": "ISO-Datum, z.B. 2025-12-31" }
        }
      },
      "Mieter": {
        "type": "object",
        "required": ["id", "name", "flaeche", "einzugsdatum"],
        "properties": {
          "id": { "type": "string", "description": "Eindeutige Mieter-ID" },
          "name": { "type": "string" },
          "flaeche": { "type": "number", "minimum": 1, "description": "Wohnflaeche in m2" },
          "personenanzahl": { "type": "integer", "minimum": 1 },
          "einzugsdatum": { "type": "string", "format": "date" },
          "auszugsdatum": { "type": "string", "format": "date", "description": "Optional, fuer anteilige Berechnung" },
          "vorauszahlungen": { "type": "number", "description": "Geleistete Vorauszahlungen in EUR" },
          "verbrauch": {
            "type": "object",
            "description": "Verbrauchswerte fuer verbrauchsabhaengige Verteilung",
            "additionalProperties": { "type": "number" }
          }
        }
      },
      "Kostenposition": {
        "type": "object",
        "required": ["kostenartId", "betrag", "verteilerschluessel"],
        "properties": {
          "kostenartId": { "type": "string", "description": "ID der Kostenart (z.B. 'grundsteuer', 'wasserversorgung')" },
          "betrag": { "type": "number", "minimum": 0.01, "description": "Gesamtbetrag in EUR" },
          "verteilerschluessel": { "type": "string", "enum": ["wohnflaeche", "personenanzahl", "verbrauch", "wohneinheiten"] }
        }
      },
      "Kostenart": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "nr": { "type": "integer" },
          "name": { "type": "string" },
          "description": { "type": "string" },
          "defaultVerteilerschluessel": { "type": "string" },
          "allowedVerteilerschluessel": { "type": "array", "items": { "type": "string" } },
          "isHeizkosten": { "type": "boolean" },
          "typicalRange": {
            "type": "object",
            "nullable": true,
            "properties": {
              "min": { "type": "number" },
              "max": { "type": "number" },
              "unit": { "type": "string" }
            }
          }
        }
      },
      "Ergebnis": {
        "type": "object",
        "description": "Berechnungsergebnis mit Aufteilung pro Mieter",
        "properties": {
          "mieterErgebnisse": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "mieterId": { "type": "string" },
                "mieterName": { "type": "string" },
                "anteilGesamt": { "type": "number", "description": "Gesamtanteil in EUR" },
                "vorauszahlungen": { "type": "number" },
                "nachzahlung": { "type": "number", "description": "Positiv = Nachzahlung, negativ = Guthaben" },
                "positionen": { "type": "array", "items": { "type": "object" } }
              }
            }
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Fehlender oder ungueltiger API-Key",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": { "type": "string" },
                "message": { "type": "string" }
              }
            },
            "example": { "error": "API-Key erforderlich", "message": "Bitte senden Sie einen API-Key im X-API-Key Header." }
          }
        }
      },
      "Forbidden": {
        "description": "API-Zugang erfordert Business-Plan",
        "content": {
          "application/json": {
            "example": { "error": "API-Zugang erfordert Business-Plan", "message": "Ihr aktueller Plan beinhaltet keinen API-Zugang.", "upgrade_url": "/preise" }
          }
        }
      },
      "ValidationError": {
        "description": "Ungueltige Eingabedaten",
        "content": {
          "application/json": {
            "example": { "error": "Validierungsfehler", "details": ["objekt.adresse ist erforderlich", "mieter muss ein Array sein"] }
          }
        }
      },
      "RateLimited": {
        "description": "Rate-Limit ueberschritten (1.000/Tag oder 60/Minute)",
        "content": {
          "application/json": {
            "example": { "error": "Rate-Limit ueberschritten", "message": "Tageslimit von 1000 Anfragen erreicht." }
          }
        }
      },
      "ServerError": {
        "description": "Interner Serverfehler",
        "content": {
          "application/json": {
            "example": { "error": "Berechnungsfehler", "message": "Interner Fehler bei der Berechnung." }
          }
        }
      }
    }
  },
  "tags": [
    { "name": "Berechnung", "description": "Betriebskostenabrechnung berechnen" },
    { "name": "Validierung", "description": "Eingabedaten pruefen" },
    { "name": "PDF", "description": "PDF-Dokument generieren" },
    { "name": "Stammdaten", "description": "Kostenarten und Verteilerschluessel (oeffentlich)" }
  ]
}
