{
  "openapi": "3.0.3",
  "info": {
    "title": "Verbrauchsportal API",
    "version": "1.0.1",
    "description": "REST API for the Verbrauchsportal. All endpoints require Token authentication (IsAuthenticated + IsApiUser)."
  },
  "servers": [
    {
      "url": "http://localhost:8000",
      "description": "Local development server"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
    "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "hex"
    }
    },
    "schemas": {
      "RealEstate": {
        "type": "object",
        "required": ["REID", "Street", "HouseNumber", "PostalCode", "City"],
        "properties": {
          "REID":        { "type": "integer", "example": 1 },
          "Street":      { "type": "string",  "example": "Musterstraße" },
          "HouseNumber": { "type": "string",  "example": "12a" },
          "PostalCode":  { "type": "string",  "example": "10115" },
          "City":        { "type": "string",  "example": "Berlin" }
        }
      },
      "RealEstateUnit": {
        "type": "object",
        "required": ["REUID", "REID", "REUDesc", "REUCID"],
        "properties": {
          "REUID":   { "type": "integer", "example": 101 },
          "REID":    { "type": "integer", "example": 1 },
          "REUDesc": { "type": "string",  "example": "Wohnung OG links" },
          "REUCID":  { "type": "integer", "example": 1 }
        }
      },
      "User": {
        "type": "object",
        "required": ["PersonenID", "email"],
        "properties": {
          "PersonenID":           { "type": "integer", "example": 42 },
          "lastname":             { "type": "string",  "example": "Mustermann" },
          "firstname":            { "type": "string",  "example": "Max" },
          "companyname":          { "type": "string",  "example": "Muster GmbH" },
          "email":                { "type": "string",  "format": "email", "example": "max@example.com" },
          "password":             { "type": "string",  "writeOnly": true, "example": "secret123" },
          "VISysEMailPreference": { "type": "integer", "example": 1 },
          "SalutationID":         { "type": "integer", "example": 1 },
          "SaAnschrift":          { "type": "string",  "example": "Max Mustermann, Musterstraße 12" },
          "SaAnrede":             { "type": "string",  "example": "Sehr geehrter Herr Mustermann" },
          "SaBriefkopf":          { "type": "string",  "example": "Muster GmbH" }
        }
      },
      "ApiUser": {
        "type": "object",
        "properties": {
          "ApiUserID":            { "type": "integer", "example": 1 },
          "ApiUserName":          { "type": "string",  "example": "api_import" },
          "companyname":          { "type": "string",  "example": "Hausverwaltung GmbH" },
          "ApiUserEMail":         { "type": "string",  "format": "email", "example": "api@example.com" },
          "VISysEMailPreference": { "type": "integer", "example": 1 }
        }
      },
      "ReuMietV": {
        "type": "object",
        "required": ["MietVID", "REUID", "MieterID", "ContractValidFrom"],
        "properties": {
          "MietVID":            { "type": "integer", "example": 201 },
          "REUID":              { "type": "integer", "example": 101 },
          "MieterID":           { "type": "integer", "example": 42 },
          "ContractValidFrom":  { "type": "string",  "format": "date", "example": "2024-01-01" },
          "ContractValidUntil": { "type": "string",  "format": "date", "example": "2024-12-31", "nullable": true }
        }
      },
      "MietVWithDetails": {
        "type": "object",
        "description": "Raw SQL result – includes joined REU and RealEstate fields",
        "properties": {
          "MietVID":            { "type": "integer", "example": 201 },
          "REUID":              { "type": "integer", "example": 101 },
          "MieterID":           { "type": "integer", "example": 42 },
          "ContractValidFrom":  { "type": "string",  "format": "date", "example": "2024-01-01" },
          "ContractValidUntil": { "type": "string",  "format": "date", "example": "2024-12-31" },
          "REID":               { "type": "integer", "example": 1 },
          "REUDesc":            { "type": "string",  "example": "Wohnung OG links" },
          "Street":             { "type": "string",  "example": "Musterstraße" },
          "HouseNumber":        { "type": "string",  "example": "12a" },
          "PostalCode":         { "type": "string",  "example": "10115" },
          "City":               { "type": "string",  "example": "Berlin" }
        }
      },
      "VISysRefVerbrauchRahmen": {
        "type": "object",
        "required": ["VISysRefVerbrID", "REID", "Jahr", "VISysVerbrauchsArtID"],
        "properties": {
          "VISysRefVerbrID":      { "type": "integer", "example": 301 },
          "REID":                 { "type": "integer", "example": 1 },
          "Jahr":                 { "type": "integer", "example": 2023 },
          "VISysVerbrauchsArtID": { "type": "integer", "example": 1 }
        }
      },
      "VISysRefVerbrauchsDS": {
        "type": "object",
        "required": ["RefVerBrDatID", "RefVerBrSD", "RefVerBrED", "RefVerBrWert", "RefVerBrID"],
        "properties": {
          "RefVerBrDatID":    { "type": "integer", "example": 401 },
          "RefVerBrSD":       { "type": "string",  "format": "date", "example": "2023-01-01" },
          "RefVerBrED":       { "type": "string",  "format": "date", "example": "2023-12-31" },
          "RefVerBrWert":     { "type": "number",  "format": "float", "example": 12500.5 },
          "RefVerBrID":       { "type": "integer", "example": 301 },
          "RefVerBrWertNormA":{ "type": "number",  "format": "float", "example": 11800.0, "nullable": true }
        }
      },
      "VISysVerbrauchRahmen": {
        "type": "object",
        "required": ["VISysVerbrauchsID", "MietVID", "Jahr", "VISysVerbrauchsArtID"],
        "properties": {
          "VISysVerbrauchsID":    { "type": "integer", "example": 501 },
          "MietVID":              { "type": "integer", "example": 201 },
          "REUDesc":              { "type": "string",  "example": "Wohnung OG links", "nullable": true },
          "Jahr":                 { "type": "integer", "example": 2023 },
          "VISysVerbrauchsArtID": { "type": "integer", "example": 1 }
        }
      },
      "VISysVerbrauchsDS": {
        "type": "object",
        "required": ["VerBrDatID", "VerBrSD", "VerBrED", "VerBrWert", "VerBrID"],
        "properties": {
          "VerBrDatID":    { "type": "integer", "example": 601 },
          "VerBrSD":       { "type": "string",  "format": "date", "example": "2023-01-01" },
          "VerBrED":       { "type": "string",  "format": "date", "example": "2023-03-31" },
          "VerBrWert":     { "type": "number",  "format": "float", "example": 3100.25 },
          "VerBrID":       { "type": "integer", "example": 501 },
          "VerBrWertNormA":{ "type": "number",  "format": "float", "example": 2950.0, "nullable": true }
        }
      },
      "TokenResponse": {
        "type": "object",
        "properties": {
          "token": { "type": "string", "example": "9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b" }
        }
      },
      "DeleteResponse": {
        "type": "object",
        "properties": {
          "deleted": {
            "type": "array",
            "example": [15, { "app_real_estate.RealEstate": 5 }]
          }
        }
      }
    }
  },
  "paths": {
    "/api/res": {
      "get": {
        "summary": "List all real estates",
        "tags": ["RealEstate"],
        "responses": {
          "200": {
            "description": "List of real estates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/RealEstate" }
                },
                "example": [
                  { "REID": 1, "Street": "Musterstraße", "HouseNumber": "12a", "PostalCode": "10115", "City": "Berlin" },
                  { "REID": 2, "Street": "Hauptstraße",  "HouseNumber": "5",   "PostalCode": "80331", "City": "München" }
                ]
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create or update a real estate",
        "tags": ["RealEstate"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/RealEstate" },
              "example": {
                "REID": 1,
                "Street": "Musterstraße",
                "HouseNumber": "12a",
                "PostalCode": "10115",
                "City": "Berlin"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created or updated real estate",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RealEstate" }
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      },
      "delete": {
        "summary": "Delete ALL data cascade (CAUTION: irreversible)",
        "tags": ["RealEstate"],
        "responses": {
          "200": {
            "description": "Number of deleted objects",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/DeleteResponse" }
              }
            }
          }
        }
      }
    },
    "/api/reus": {
      "get": {
        "summary": "List all real estate units",
        "tags": ["RealEstateUnit"],
        "responses": {
          "200": {
            "description": "List of units",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/RealEstateUnit" }
                },
                "example": [
                  { "REUID": 101, "REID": 1, "REUDesc": "Wohnung OG links", "REUCID": 1 }
                ]
              }
            }
          }
        }
      },
      "put": {
        "summary": "Bulk create or update real estate units",
        "tags": ["RealEstateUnit"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  { "$ref": "#/components/schemas/RealEstateUnit" },
                  { "type": "array", "items": { "$ref": "#/components/schemas/RealEstateUnit" } }
                ]
              },
              "example": [
                { "REUID": 101, "REID": 1, "REUDesc": "Wohnung OG links", "REUCID": 1 },
                { "REUID": 102, "REID": 1, "REUDesc": "Wohnung EG rechts", "REUCID": 1 }
              ]
            }
          }
        },
        "responses": {
          "201": {
            "description": "Number of upserted records",
            "content": {
              "application/json": {
                "schema": { "type": "integer" },
                "example": 2
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      }
    },
    "/api/users": {
      "get": {
        "summary": "List all users",
        "tags": ["User"],
        "responses": {
          "200": {
            "description": "List of users",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/User" }
                },
                "example": [
                  {
                    "PersonenID": 42,
                    "lastname": "Mustermann",
                    "firstname": "Max",
                    "companyname": null,
                    "email": "max@example.com",
                    "VISysEMailPreference": 1,
                    "SalutationID": 1,
                    "SaAnschrift": null,
                    "SaAnrede": null,
                    "SaBriefkopf": null
                  }
                ]
              }
            }
          }
        }
      },
      "put": {
        "summary": "Create or update a user",
        "description": "If `password` is omitted, a random password is generated.",
        "tags": ["User"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/User" },
              "example": {
                "PersonenID": 42,
                "lastname": "Mustermann",
                "firstname": "Max",
                "email": "max@example.com",
                "VISysEMailPreference": 1,
                "SalutationID": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created or updated user",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/User" }
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      }
    },
    "/api/mietvs/{reid}": {
      "get": {
        "summary": "Get all tenancies for a real estate",
        "tags": ["MietV"],
        "parameters": [
          {
            "name": "reid",
            "in": "path",
            "required": true,
            "schema": { "type": "integer" },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "List of tenancies with property details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/MietVWithDetails" }
                },
                "example": [
                  {
                    "MietVID": 201,
                    "REUID": 101,
                    "MieterID": 42,
                    "ContractValidFrom": "2024-01-01",
                    "ContractValidUntil": null,
                    "REID": 1,
                    "REUDesc": "Wohnung OG links",
                    "Street": "Musterstraße",
                    "HouseNumber": "12a",
                    "PostalCode": "10115",
                    "City": "Berlin"
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/api/mietvs": {
      "put": {
        "summary": "Create or update a tenancy",
        "tags": ["MietV"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ReuMietV" },
              "example": {
                "MietVID": 201,
                "REUID": 101,
                "MieterID": 42,
                "ContractValidFrom": "2024-01-01",
                "ContractValidUntil": null
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created or updated tenancy",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ReuMietV" }
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      }
    },
    "/api/refverbrrahmen": {
      "put": {
        "summary": "Create or update a reference consumption frame",
        "tags": ["RefVerRahmen"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/VISysRefVerbrauchRahmen" },
              "example": {
                "VISysRefVerbrID": 301,
                "REID": 1,
                "Jahr": 2023,
                "VISysVerbrauchsArtID": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Created or updated reference frame",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/VISysRefVerbrauchRahmen" }
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      }
    },
    "/api/refverbrdaten": {
      "put": {
        "summary": "Bulk create or update reference consumption data points",
        "tags": ["RefVerDaten"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  { "$ref": "#/components/schemas/VISysRefVerbrauchsDS" },
                  { "type": "array", "items": { "$ref": "#/components/schemas/VISysRefVerbrauchsDS" } }
                ]
              },
              "example": [
                {
                  "RefVerBrDatID": 401,
                  "RefVerBrSD": "2023-01-01",
                  "RefVerBrED": "2023-12-31",
                  "RefVerBrWert": 12500.5,
                  "RefVerBrID": 301,
                  "RefVerBrWertNormA": 11800.0
                }
              ]
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success message with count",
            "content": {
              "application/json": {
                "schema": { "type": "string" },
                "example": "1 Datensätze wurden neu eingetragen / aktualisiert (oder waren schon vorhanden)"
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      }
    },
    "/api/verbrrahmen": {
      "put": {
        "summary": "Bulk create or update consumption frames",
        "tags": ["VerRahmen"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  { "$ref": "#/components/schemas/VISysVerbrauchRahmen" },
                  { "type": "array", "items": { "$ref": "#/components/schemas/VISysVerbrauchRahmen" } }
                ]
              },
              "example": [
                {
                  "VISysVerbrauchsID": 501,
                  "MietVID": 201,
                  "REUDesc": "Wohnung OG links",
                  "Jahr": 2023,
                  "VISysVerbrauchsArtID": 1
                }
              ]
            }
          }
        },
        "responses": {
          "201": {
            "description": "Number of upserted records",
            "content": {
              "application/json": {
                "schema": { "type": "integer" },
                "example": 1
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      }
    },
    "/api/verbrdaten": {
      "post": {
        "summary": "Bulk create consumption data points (no update)",
        "tags": ["VerDaten"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  { "$ref": "#/components/schemas/VISysVerbrauchsDS" },
                  { "type": "array", "items": { "$ref": "#/components/schemas/VISysVerbrauchsDS" } }
                ]
              },
              "example": [
                {
                  "VerBrDatID": 601,
                  "VerBrSD": "2023-01-01",
                  "VerBrED": "2023-03-31",
                  "VerBrWert": 3100.25,
                  "VerBrID": 501,
                  "VerBrWertNormA": 2950.0
                }
              ]
            }
          }
        },
        "responses": {
          "201": {
            "description": "Number of created records",
            "content": {
              "application/json": {
                "schema": { "type": "integer" },
                "example": 1
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      },
      "put": {
        "summary": "Bulk create or update consumption data points",
        "tags": ["VerDaten"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  { "$ref": "#/components/schemas/VISysVerbrauchsDS" },
                  { "type": "array", "items": { "$ref": "#/components/schemas/VISysVerbrauchsDS" } }
                ]
              },
              "example": [
                {
                  "VerBrDatID": 601,
                  "VerBrSD": "2023-01-01",
                  "VerBrED": "2023-03-31",
                  "VerBrWert": 3100.25,
                  "VerBrID": 501,
                  "VerBrWertNormA": 2950.0
                }
              ]
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success message",
            "content": {
              "application/json": {
                "schema": { "type": "string" },
                "example": "Daten wurden neu eingetragen / aktualisiert"
              }
            }
          },
          "400": { "description": "Validation error" }
        }
      }
    },
    "/api/me": {
      "get": {
        "summary": "Get current API user info",
        "tags": ["Me"],
        "responses": {
          "200": {
            "description": "Current authenticated API user",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiUser" },
                "example": {
                  "ApiUserID": 1,
                  "ApiUserName": "api_import",
                  "companyname": "Hausverwaltung GmbH",
                  "ApiUserEMail": "api@example.com",
                  "VISysEMailPreference": 1
                }
              }
            }
          }
        }
      }
    },
    "/api/me/tokencreate": {
      "post": {
        "summary": "Regenerate auth token for current user",
        "description": "Deletes the existing token and issues a new one.",
        "tags": ["Me"],
        "responses": {
          "200": {
            "description": "New auth token",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/TokenResponse" },
                "example": {
                  "token": "9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b"
                }
              }
            }
          }
        }
      }
    }
  }
}
