{"openapi":"3.1.0","info":{"title":"PPWR Compliance Suite — REST-API","version":"1.0.0","description":"Schnittstelle zur Erfassung, Nachweisverwaltung und Konformitätsprüfung von Verpackungen nach Verordnung (EU) 2025/40 über Verpackungen und Verpackungsabfälle (PPWR).\n\nRegelsatz-Version: **2026.08-1**\n\nAuthentifizierung: `POST /api/v1/auth/login` liefert ein Bearer-Token (JWT), das in allen weiteren Aufrufen im Header `Authorization: Bearer <token>` mitzugeben ist.\n\nRollen: `viewer`/`auditor` (lesen), `editor` (schreiben), `compliance_manager` (Konformitätserklärung zeichnen, Freigaben), `admin` (alles).","contact":{"name":"PPWR Compliance Suite"}},"servers":[{"url":"https://ppwr-software.eu","description":"Diese Instanz"}],"tags":[{"name":"Auth","description":"Anmeldung und Sitzung"},{"name":"Organisation","description":"Unternehmensstammdaten und Registrierungen (Art. 15, 44)"},{"name":"Stammdaten","description":"Lieferanten, Produkte, Wiederverwendungssysteme"},{"name":"Verpackungen","description":"Kernobjekt mit allen Angaben zu Art. 5–12, 24, 25"},{"name":"Dokumente","description":"Upload, Scan, OCR, Nachweisarchiv"},{"name":"Compliance","description":"Regelprüfung, Findings, Roadmap"},{"name":"Konformitätserklärung","description":"Anhang VIII, PDF, Versionierung"},{"name":"Reporting","description":"EPR-Mengenmeldung (Art. 45/56), Exporte, Dashboard"},{"name":"Katalog","description":"Werkstoffcodes, Kategorien, Fristen, Regelsatz"},{"name":"Fristen","description":"Aufgaben- und Fristenmanagement"},{"name":"Verwaltung","description":"Nutzer, Rollen, Audit-Log"},{"name":"Öffentlich","description":"Auskunft hinter dem Datenträger (ohne Anmeldung)"}],"paths":{"/health":{"get":{"tags":["Auth"],"summary":"Liveness-Prüfung","security":[],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Anmelden","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object","properties":{"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"user":{"$ref":"#/components/schemas/User"}}}}}},"401":{"description":"Anmeldedaten falsch","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/refresh":{"post":{"tags":["Auth"],"summary":"Token erneuern","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["refreshToken"],"properties":{"refreshToken":{"type":"string"}}}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/auth/me":{"get":{"tags":["Auth"],"summary":"Angemeldeten Nutzer lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}}}}},"/api/v1/auth/change-password":{"post":{"tags":["Auth"],"summary":"Passwort ändern","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["currentPassword","newPassword"],"properties":{"currentPassword":{"type":"string"},"newPassword":{"type":"string","minLength":12}}}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}}}}},"/api/v1/auth/logout":{"post":{"tags":["Auth"],"summary":"Abmelden","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}}}}},"/api/v1/organisation":{"get":{"tags":["Organisation"],"summary":"Unternehmensstammdaten lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organisation"}}}}}},"put":{"tags":["Organisation"],"summary":"Unternehmensstammdaten anlegen oder ändern","description":"Firmenname, vollständige Postanschrift und ein elektronisches Kommunikationsmittel sind nach Art. 15(6) zwingend und Voraussetzung für die Konformitätserklärung.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organisation"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organisation"}}}}}}},"/api/v1/registrations":{"get":{"tags":["Organisation"],"summary":"Registrierung (Art. 44) auflisten","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Organisation"],"summary":"Registrierung (Art. 44) anlegen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Registration"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Registration"}}}},"422":{"description":"Validierungsfehler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/registrations/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Datensatz-ID"}],"get":{"tags":["Organisation"],"summary":"Registrierung (Art. 44) lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Registration"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Organisation"],"summary":"Registrierung (Art. 44) ändern","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Registration"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Registration"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Organisation"],"summary":"Registrierung (Art. 44) löschen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}},"409":{"description":"Noch verknüpft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/registrations-coverage":{"get":{"tags":["Organisation"],"summary":"Abdeckungsanalyse Registrierungen je Zielmarkt","description":"Zeigt, für welche Zielmärkte von Verpackungen keine aktive Registrierung vorliegt (Art. 44 Abs. 4: ohne Registrierung kein Inverkehrbringen).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/suppliers":{"get":{"tags":["Stammdaten"],"summary":"Lieferant auflisten","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Stammdaten"],"summary":"Lieferant anlegen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Supplier"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Supplier"}}}},"422":{"description":"Validierungsfehler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/suppliers/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Datensatz-ID"}],"get":{"tags":["Stammdaten"],"summary":"Lieferant lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Supplier"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Stammdaten"],"summary":"Lieferant ändern","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Supplier"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Supplier"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Stammdaten"],"summary":"Lieferant löschen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}},"409":{"description":"Noch verknüpft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/supplier-declarations":{"get":{"tags":["Stammdaten"],"summary":"Lieferantenerklärung auflisten","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Stammdaten"],"summary":"Lieferantenerklärung anlegen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierDeclaration"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierDeclaration"}}}},"422":{"description":"Validierungsfehler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/supplier-declarations/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Datensatz-ID"}],"get":{"tags":["Stammdaten"],"summary":"Lieferantenerklärung lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierDeclaration"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Stammdaten"],"summary":"Lieferantenerklärung ändern","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierDeclaration"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierDeclaration"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Stammdaten"],"summary":"Lieferantenerklärung löschen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}},"409":{"description":"Noch verknüpft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/products":{"get":{"tags":["Stammdaten"],"summary":"Produkt auflisten","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Stammdaten"],"summary":"Produkt anlegen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"422":{"description":"Validierungsfehler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/products/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Datensatz-ID"}],"get":{"tags":["Stammdaten"],"summary":"Produkt lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Stammdaten"],"summary":"Produkt ändern","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Stammdaten"],"summary":"Produkt löschen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}},"409":{"description":"Noch verknüpft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/reuse-systems":{"get":{"tags":["Stammdaten"],"summary":"Wiederverwendungssystem auflisten","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Stammdaten"],"summary":"Wiederverwendungssystem anlegen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReuseSystem"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReuseSystem"}}}},"422":{"description":"Validierungsfehler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/reuse-systems/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Datensatz-ID"}],"get":{"tags":["Stammdaten"],"summary":"Wiederverwendungssystem lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReuseSystem"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Stammdaten"],"summary":"Wiederverwendungssystem ändern","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReuseSystem"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReuseSystem"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Stammdaten"],"summary":"Wiederverwendungssystem löschen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}},"409":{"description":"Noch verknüpft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/packagings":{"get":{"tags":["Verpackungen"],"summary":"Verpackungen auflisten","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"status","in":"query","schema":{"type":"string","enum":["draft","review","compliant","non_compliant","archived"]}},{"name":"packagingLevel","in":"query","schema":{"type":"string","enum":["sales","grouped","transport","service","ecommerce"]}},{"name":"predominantMaterial","in":"query","schema":{"type":"string"}},{"name":"recyclabilityGrade","in":"query","schema":{"type":"string","enum":["A","B","C","D","E"]}},{"name":"isReusable","in":"query","schema":{"type":"boolean"}},{"name":"hasBlockers","in":"query","schema":{"type":"boolean"}},{"name":"notEvaluated","in":"query","schema":{"type":"boolean"}},{"name":"market","in":"query","schema":{"type":"string"},"description":"ISO-Code eines Zielmarkts"}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Verpackungen"],"summary":"Verpackung anlegen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Packaging"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Packaging"}}}}}}},"/api/v1/packagings/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Verpackungen"],"summary":"Verpackung mit Bestandteilen, Dokumenten und letztem Prüflauf lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PackagingDetail"}}}}}},"put":{"tags":["Verpackungen"],"summary":"Verpackung ändern","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Packaging"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Packaging"}}}}}},"delete":{"tags":["Verpackungen"],"summary":"Verpackung löschen","description":"Wird abgelehnt, wenn Konformitätserklärungen existieren (Aufbewahrungspflicht). Mit `?force=true` erzwingbar (nur admin).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}},"409":{"description":"Aufbewahrungspflicht","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/packagings/{id}/duplicate":{"post":{"tags":["Verpackungen"],"summary":"Verpackung als Variante duplizieren (inklusive Bestandteile)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"ref":{"type":"string"},"name":{"type":"string"}}}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Packaging"}}}}}}},"/api/v1/packagings/{id}/components":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Verpackungen"],"summary":"Bestandteile lesen (inkl. Gewichtsabgleich)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}},"put":{"tags":["Verpackungen"],"summary":"Bestandteile vollständig ersetzen","description":"Ersetzt alle Bestandteile in einer Transaktion — vermeidet Teilzustände.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["components"],"properties":{"components":{"type":"array","items":{"$ref":"#/components/schemas/Component"}}}}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/packagings/{id}/label":{"get":{"tags":["Verpackungen"],"summary":"Kennzeichnungsdaten und Datenträger-Nutzlast (Art. 12, 15)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/packagings/{id}/qr.png":{"get":{"tags":["Verpackungen"],"summary":"QR-Code als PNG","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"size","in":"query","schema":{"type":"integer","default":512}}],"responses":{"200":{"description":"PNG","content":{"image/png":{"schema":{"type":"string","format":"binary"}}}}}}},"/api/v1/packagings/{id}/qr.svg":{"get":{"tags":["Verpackungen"],"summary":"QR-Code als SVG","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"SVG","content":{"image/svg+xml":{"schema":{"type":"string"}}}}}}},"/api/v1/packagings/{id}/technical-file":{"get":{"tags":["Verpackungen"],"summary":"Technische Dokumentation nach Anhang VII mit Lückenliste","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"referenceDate","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TechnicalFile"}}}}}}},"/api/v1/packagings/{id}/technical-file.pdf":{"get":{"tags":["Verpackungen"],"summary":"Technische Dokumentation als PDF (Behördenauskunft)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"PDF","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}}}}},"/api/v1/documents":{"get":{"tags":["Dokumente"],"summary":"Dokumente suchen (inklusive OCR-Volltext)","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"entityType","in":"query","schema":{"type":"string"}},{"name":"entityId","in":"query","schema":{"type":"string"}},{"name":"docType","in":"query","schema":{"type":"string"}},{"name":"source","in":"query","schema":{"type":"string","enum":["upload","scan","generated"]}},{"name":"expiringInDays","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Dokumente"],"summary":"Dateien hochladen (multipart/form-data)","description":"Feld `files` (bis 20 Dateien) plus Metadaten als Formularfelder: `entityType`, `entityId`, `docType`, `title`, `issuedAt`, `validUntil`, `issuer`, `referenceNo`, `runOcr`. Optional `thumbnail` als Data-URL (clientseitig erzeugt). Für jede Datei werden SHA-256, Größe, Bildmaße und PDF-Seitenzahl ermittelt.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["files","entityType","docType"],"properties":{"files":{"type":"array","items":{"type":"string","format":"binary"}},"entityType":{"type":"string"},"entityId":{"type":"string"},"docType":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"issuedAt":{"type":"string","format":"date"},"validUntil":{"type":"string","format":"date"},"issuer":{"type":"string"},"referenceNo":{"type":"string"},"runOcr":{"type":"boolean"},"thumbnail":{"type":"string"}}}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}},"413":{"description":"Datei zu groß","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/documents/scan":{"post":{"tags":["Dokumente"],"summary":"Mehrseitigen Scan als PDF ablegen","description":"Die Seiten werden als Data-URLs (JPEG oder PNG) übergeben — typischerweise aus der Browser-Kamera nach clientseitiger Aufbereitung. Der Server baut daraus ein A4-PDF, erzeugt eine Vorschau und optional OCR-Text.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entityType","docType","title","pages"],"properties":{"entityType":{"type":"string"},"entityId":{"type":"string"},"docType":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"issuedAt":{"type":"string","format":"date"},"validUntil":{"type":"string","format":"date"},"issuer":{"type":"string"},"referenceNo":{"type":"string"},"keepPageImages":{"type":"boolean"},"runOcr":{"type":"boolean"},"pages":{"type":"array","minItems":1,"maxItems":60,"items":{"type":"string","description":"data:image/jpeg;base64,…"}}}}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}}}}},"/api/v1/documents/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Dokumente"],"summary":"Dokument lesen (mit OCR-Text)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}}}},"put":{"tags":["Dokumente"],"summary":"Metadaten und OCR-Text pflegen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}}}},"delete":{"tags":["Dokumente"],"summary":"Dokument löschen","description":"Wird abgelehnt, solange die Aufbewahrungsfrist läuft (Art. 15: 5 Jahre Einweg, 10 Jahre Mehrweg). `?force=true` ist Administratoren vorbehalten.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}},"409":{"description":"Aufbewahrungspflicht","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/documents/{id}/file":{"get":{"tags":["Dokumente"],"summary":"Datei abrufen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"download","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Datei; Header X-Content-SHA256 enthält den Hash."}}}},"/api/v1/documents/{id}/thumbnail":{"get":{"tags":["Dokumente"],"summary":"Vorschaubild abrufen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Bild"}}}},"/api/v1/documents/{id}/ocr":{"post":{"tags":["Dokumente"],"summary":"Texterkennung ausführen","description":"Nutzt tesseract.js, falls installiert. Liefert zusätzlich heuristisch extrahierte Kennwerte (Datum, Berichtsnummer, Schwermetallsumme, PFAS, Rezyklatanteil, Norm) als Vorschlag zur Datenübernahme.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"langs":{"type":"string","example":"deu+eng"}}}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/documents-stats":{"get":{"tags":["Dokumente"],"summary":"Archivstatistik und ablaufende Nachweise","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/compliance/packagings/{id}/evaluate":{"post":{"tags":["Compliance"],"summary":"Prüflauf für eine Verpackung","description":"Bewertet gegen ein Referenzdatum. Ohne Angabe wird das heutige Datum verwendet. Mit einem künftigen Datum (z. B. 2030-01-01) lässt sich prüfen, ob die Verpackung dann noch verkehrsfähig ist.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"referenceDate":{"type":"string","format":"date"},"persist":{"type":"boolean","default":true}}}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceResult"}}}}}}},"/api/v1/compliance/packagings/{id}":{"get":{"tags":["Compliance"],"summary":"Aktuelles Prüfergebnis (live berechnet)","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"referenceDate","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/compliance/packagings/{id}/history":{"get":{"tags":["Compliance"],"summary":"Historie der Prüfläufe","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/compliance/runs/{runId}":{"get":{"tags":["Compliance"],"summary":"Gespeicherten Prüflauf lesen","security":[{"bearerAuth":[]}],"parameters":[{"name":"runId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/compliance/evaluate-all":{"post":{"tags":["Compliance"],"summary":"Massenprüfung über alle nicht archivierten Verpackungen","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"referenceDate":{"type":"string","format":"date"},"persist":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/compliance/findings":{"get":{"tags":["Compliance"],"summary":"Befunde über alle Verpackungen","security":[{"bearerAuth":[]}],"parameters":[{"name":"severity","in":"query","schema":{"type":"string","enum":["blocker","warning","info"]}},{"name":"article","in":"query","schema":{"type":"string"}},{"name":"referenceDate","in":"query","schema":{"type":"string","format":"date"}},{"name":"format","in":"query","schema":{"type":"string","enum":["json","csv"]}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/compliance/roadmap":{"get":{"tags":["Compliance"],"summary":"Verkehrsfähigkeit an den PPWR-Stichtagen","description":"Bewertet jede Verpackung an mehreren Stichtagen (heute, 2028, 2030, 2035, 2038, 2040) und zeigt, welche Anforderung ab wann blockiert.","security":[{"bearerAuth":[]}],"parameters":[{"name":"dates","in":"query","schema":{"type":"string"},"description":"Komma-separierte ISO-Daten"}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/compliance/packagings/{id}/overrides":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Compliance"],"summary":"Manuelle Freigaben lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Compliance"],"summary":"Regel manuell freigeben (Rolle compliance_manager)","description":"Erfordert eine nachvollziehbare Begründung; wird im Audit-Log protokolliert.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["requirementCode","reason"],"properties":{"requirementCode":{"type":"string","example":"ART7-PCR-2030"},"reason":{"type":"string","minLength":10},"evidenceDocumentId":{"type":"string"},"validUntil":{"type":"string","format":"date"}}}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Rolle nicht ausreichend","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/compliance/overrides/{id}":{"delete":{"tags":["Compliance"],"summary":"Freigabe zurücknehmen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}}}}},"/api/v1/declarations":{"get":{"tags":["Konformitätserklärung"],"summary":"Konformitätserklärungen auflisten","security":[{"bearerAuth":[]}],"parameters":[{"name":"packagingId","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["draft","issued","superseded","revoked"]}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Konformitätserklärung"],"summary":"Konformitätserklärung ausstellen (Anhang VIII)","description":"Erzeugt einen unveränderlichen Snapshot von Organisation, Verpackung und Prüfergebnis sowie das PDF. Vorgängerversionen werden auf `superseded` gesetzt. Bestehen blockierende Befunde, muss `allowWithBlockers` gesetzt werden — die Entscheidung wird protokolliert. Rolle: compliance_manager.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeclarationRequest"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Declaration"}}}},"409":{"description":"Blockierende Befunde vorhanden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/declarations-preview/{packagingId}":{"get":{"tags":["Konformitätserklärung"],"summary":"Vorschau der Erklärung inklusive Prüfergebnis","security":[{"bearerAuth":[]}],"parameters":[{"name":"packagingId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/declarations/{id}":{"get":{"tags":["Konformitätserklärung"],"summary":"Erklärung lesen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Declaration"}}}}}}},"/api/v1/declarations/{id}/pdf":{"get":{"tags":["Konformitätserklärung"],"summary":"Erklärung als PDF","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"download","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"PDF","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}}}}},"/api/v1/declarations/{id}/revoke":{"post":{"tags":["Konformitätserklärung"],"summary":"Erklärung widerrufen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Declaration"}}}}}}},"/api/v1/market-placements":{"get":{"tags":["Reporting"],"summary":"Mengen je Verpackung, Mitgliedstaat und Jahr","security":[{"bearerAuth":[]}],"parameters":[{"name":"packagingId","in":"query","schema":{"type":"string"}},{"name":"memberState","in":"query","schema":{"type":"string"}},{"name":"year","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["Reporting"],"summary":"Menge erfassen oder aktualisieren","description":"Ist kein Gewicht angegeben, wird es aus Stückzahl × Verpackungsgewicht abgeleitet. Die Werkstoffverteilung wird aus den Bestandteilen berechnet.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketPlacement"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketPlacement"}}}}}}},"/api/v1/market-placements/{id}":{"delete":{"tags":["Reporting"],"summary":"Menge löschen","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}}}}},"/api/v1/reporting/epr":{"get":{"tags":["Reporting"],"summary":"EPR-Mengenmeldung (Art. 45/56)","description":"Aggregiert je Mitgliedstaat, Verpackungsebene und Werkstoffcode. Warnt, wenn für einen Mitgliedstaat keine aktive Registrierung vorliegt. Meldefrist: 1. Juni des Folgejahres.","security":[{"bearerAuth":[]}],"parameters":[{"name":"year","in":"query","schema":{"type":"integer"}},{"name":"memberState","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EprReport"}}}}}}},"/api/v1/reporting/epr.csv":{"get":{"tags":["Reporting"],"summary":"EPR-Meldung als CSV","security":[{"bearerAuth":[]}],"parameters":[{"name":"year","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"CSV"}}}},"/api/v1/reporting/packagings.csv":{"get":{"tags":["Reporting"],"summary":"Verpackungsstammdaten als CSV","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"CSV"}}}},"/api/v1/reporting/dashboard":{"get":{"tags":["Reporting"],"summary":"Kennzahlen für das Dashboard","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/catalog":{"get":{"tags":["Katalog"],"summary":"Vollständigen Fachkatalog laden","description":"Werkstoffcodes (97/129/EG), Verpackungskategorien (Anhang II), Recyclingfähigkeitsklassen, Rezyklatziele, Anhang-IV-Kriterien, Anhang-V-Verbote, Mitgliedstaaten mit nationalen Registern, harmonisierte Normen, Fristen, Regelsatz.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/catalog/{set}":{"get":{"tags":["Katalog"],"summary":"Einzelne Katalogliste laden","security":[{"bearerAuth":[]}],"parameters":[{"name":"set","in":"path","required":true,"schema":{"type":"string","example":"material-codes"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/obligations":{"get":{"tags":["Fristen"],"summary":"Aufgabe auflisten","parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Fristen"],"summary":"Aufgabe anlegen","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Obligation"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Obligation"}}}},"422":{"description":"Validierungsfehler","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/obligations/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Datensatz-ID"}],"get":{"tags":["Fristen"],"summary":"Aufgabe lesen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Obligation"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Fristen"],"summary":"Aufgabe ändern","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Obligation"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Obligation"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Fristen"],"summary":"Aufgabe löschen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}},"409":{"description":"Noch verknüpft","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/obligations/generate-from-timeline":{"post":{"tags":["Fristen"],"summary":"Aufgaben aus den PPWR-Meilensteinen erzeugen","security":[{"bearerAuth":[]}],"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/obligations-summary":{"get":{"tags":["Fristen"],"summary":"Kennzahlen zu Fristen","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/users":{"get":{"tags":["Verwaltung"],"summary":"Nutzer auflisten (admin)","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}},"post":{"tags":["Verwaltung"],"summary":"Nutzer anlegen (admin)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"responses":{"201":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}}}}},"/api/v1/users/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"put":{"tags":["Verwaltung"],"summary":"Nutzer ändern (admin)","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}}}},"delete":{"tags":["Verwaltung"],"summary":"Nutzer deaktivieren (admin)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResult"}}}}}}},"/api/v1/users-lookup":{"get":{"tags":["Verwaltung"],"summary":"Aktive Nutzer für Auswahlfelder","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/roles":{"get":{"tags":["Verwaltung"],"summary":"Rollen und Rechte","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/audit":{"get":{"tags":["Verwaltung"],"summary":"Audit-Log (admin, auditor, compliance_manager)","security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","schema":{"type":"string"},"description":"Freitextsuche"},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","default":50,"maximum":500}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"order","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}},{"name":"entityType","in":"query","schema":{"type":"string"}},{"name":"entityId","in":"query","schema":{"type":"string"}},{"name":"action","in":"query","schema":{"type":"string"}},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResult"}}}}}}},"/api/v1/public/packagings/{ref}":{"get":{"tags":["Öffentlich"],"summary":"Verpackungsinformation hinter dem Datenträger","description":"Ohne Anmeldung abrufbar — Ziel des QR-Codes nach Art. 12.","security":[],"parameters":[{"name":"ref","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Erfolg","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/p/{ref}":{"get":{"tags":["Öffentlich"],"summary":"Verbraucherseite (HTML) hinter dem QR-Code","security":[],"parameters":[{"name":"ref","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"HTML"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}}}}},"OkResult":{"type":"object","properties":{"ok":{"type":"boolean"}}},"PagedResult":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"page":{"type":"integer"},"pageSize":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}},"User":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"name":{"type":"string"},"role":{"type":"string","enum":["admin","compliance_manager","editor","viewer","auditor"]},"jobTitle":{"type":"string"},"phone":{"type":"string"},"active":{"type":"boolean"},"password":{"type":"string","minLength":12,"writeOnly":true}}},"Organisation":{"type":"object","required":["legalName","street","postalCode","city","country","contactEmail"],"properties":{"legalName":{"type":"string","description":"Anhang VIII Nr. 2"},"tradeNames":{"type":"array","items":{"type":"string"}},"legalForm":{"type":"string"},"street":{"type":"string"},"postalCode":{"type":"string"},"city":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"vatNumber":{"type":"string"},"eoriNumber":{"type":"string","description":"Art. 44 Registrierung"},"registerCourt":{"type":"string"},"registerNumber":{"type":"string"},"naceCode":{"type":"string"},"website":{"type":"string"},"contactEmail":{"type":"string","format":"email","description":"Art. 15(6)"},"contactName":{"type":"string"},"contactPhone":{"type":"string"},"employees":{"type":"integer"},"annualTurnoverEur":{"type":"number"},"isMicroEnterprise":{"type":"boolean","readOnly":true},"operatorRoles":{"type":"array","items":{"type":"string","enum":["manufacturer","authorised_representative","filler","importer","distributor","fulfilment_provider","online_marketplace","final_distributor"]}},"authorisedRep":{"type":"object","nullable":true}}},"Registration":{"type":"object","required":["memberState"],"properties":{"memberState":{"type":"string","minLength":2,"maxLength":2},"registerName":{"type":"string","example":"LUCID"},"registrationNumber":{"type":"string"},"proName":{"type":"string"},"proContractNumber":{"type":"string"},"status":{"type":"string","enum":["planned","pending","active","suspended","expired"]},"validFrom":{"type":"string","format":"date"},"validTo":{"type":"string","format":"date"},"packagingCategories":{"type":"array","items":{"type":"string"}},"distanceSelling":{"type":"boolean"},"authorisedRepName":{"type":"string"},"notes":{"type":"string"}}},"Supplier":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"supplierNo":{"type":"string"},"street":{"type":"string"},"postalCode":{"type":"string"},"city":{"type":"string"},"country":{"type":"string"},"vatNumber":{"type":"string"},"contactName":{"type":"string"},"contactEmail":{"type":"string"},"contactPhone":{"type":"string"},"notes":{"type":"string"}}},"SupplierDeclaration":{"type":"object","required":["supplierId","title"],"properties":{"supplierId":{"type":"string"},"title":{"type":"string"},"declarationNo":{"type":"string"},"coveredArticles":{"type":"array","items":{"type":"string"},"example":["5","7"]},"issuedAt":{"type":"string","format":"date"},"validUntil":{"type":"string","format":"date"},"documentId":{"type":"string"},"status":{"type":"string","enum":["valid","expired","revoked","requested"]},"notes":{"type":"string"}}},"Product":{"type":"object","required":["name"],"properties":{"sku":{"type":"string"},"gtin":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"brand":{"type":"string"},"foodContact":{"type":"boolean"},"netVolumeMl":{"type":"number"},"netWeightG":{"type":"number"}}},"ReuseSystem":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"systemType":{"type":"string","enum":["closed","open","mixed"]},"operator":{"type":"string"},"memberStates":{"type":"array","items":{"type":"string"}},"minRotations":{"type":"integer"},"achievedRotations":{"type":"number"},"takeBackDescription":{"type":"string"},"cleaningProcess":{"type":"string"},"depositCents":{"type":"integer"},"logisticsDescription":{"type":"string"},"notes":{"type":"string"}}},"Component":{"type":"object","required":["name"],"properties":{"position":{"type":"integer"},"name":{"type":"string"},"componentFunction":{"type":"string","example":"closure"},"materialCode":{"type":"string","example":"PP 5"},"materialName":{"type":"string"},"materialGroup":{"type":"string","example":"plastic"},"weightG":{"type":"number"},"sharePercent":{"type":"number"},"thicknessUm":{"type":"number"},"colour":{"type":"string"},"separable":{"type":"boolean"},"recyclable":{"type":"boolean"},"recycledContentPercent":{"type":"number"},"biobasedContentPercent":{"type":"number"},"hasSubstancesOfConcern":{"type":"boolean"},"substancesOfConcern":{"type":"string"},"supplierId":{"type":"string"},"notes":{"type":"string"}}},"Packaging":{"type":"object","required":["ref","name"],"properties":{"ref":{"type":"string","description":"Interne Sachnummer, Basis der Rückverfolgbarkeit"},"name":{"type":"string"},"description":{"type":"string"},"productId":{"type":"string"},"gtin":{"type":"string"},"identificationType":{"type":"string","enum":["type","batch","serial"],"description":"Art. 15(5)"},"identificationValue":{"type":"string"},"packagingLevel":{"type":"string","enum":["sales","grouped","transport","service","ecommerce"]},"formatCode":{"type":"string"},"annex2Category":{"type":"string","description":"Anhang II Tabelle 1"},"predominantMaterial":{"type":"string"},"isReusable":{"type":"boolean"},"foodContact":{"type":"boolean"},"contactSensitive":{"type":"boolean"},"isBeverageBottle":{"type":"boolean"},"compostable":{"type":"boolean"},"compostableRequiredType":{"type":"string","description":"Art. 9 Pflichtformat"},"weightG":{"type":"number"},"grossWeightG":{"type":"number"},"volumeMl":{"type":"number"},"innerVolumeMl":{"type":"number"},"productVolumeMl":{"type":"number"},"lengthMm":{"type":"number"},"widthMm":{"type":"number"},"heightMm":{"type":"number"},"emptySpaceRatio":{"type":"number","minimum":0,"maximum":1,"description":"Art. 24"},"heavyMetalsMgKg":{"type":"number","description":"Art. 5: Summe Pb+Cd+Hg+Cr(VI), ≤ 100"},"pfasIndividualPpb":{"type":"number","description":"Art. 5: < 25 ppb bei Lebensmittelkontakt"},"pfasSumPpb":{"type":"number","description":"Art. 5: < 250 ppb"},"pfasTotalPpm":{"type":"number","description":"Art. 5: < 50 ppm"},"substancesTestedAt":{"type":"string","format":"date"},"substancesLab":{"type":"string"},"substancesMethod":{"type":"string"},"substancesNotes":{"type":"string"},"recyclabilityPercent":{"type":"number","description":"Art. 6"},"recyclabilityGrade":{"type":"string","enum":["A","B","C","D","E"]},"dfrMethod":{"type":"string"},"recycledAtScale":{"type":"boolean","description":"ab 2035 erforderlich"},"recyclabilityAssessedAt":{"type":"string","format":"date"},"recyclabilityNotes":{"type":"string"},"plasticSharePercent":{"type":"number"},"recycledContentPercent":{"type":"number","description":"Art. 7, Post-Consumer"},"recycledContentCategory":{"type":"string","enum":["beverage_bottle","pet_contact_sensitive","other_contact_sensitive","other_plastic"]},"recycledContentMethod":{"type":"string"},"recycledContentYear":{"type":"integer"},"manufacturingPlant":{"type":"string","description":"Quote gilt als Jahresdurchschnitt je Werk"},"recycledContentExemption":{"type":"string"},"biobasedContentPercent":{"type":"number","description":"Art. 8"},"compostabilityStandard":{"type":"string","example":"EN 13432"},"compostabilityCertificateNo":{"type":"string"},"compostabilityCertifier":{"type":"string"},"compostableHome":{"type":"boolean"},"minimisationDone":{"type":"boolean","description":"Art. 10"},"minimisationAssessment":{"type":"string"},"minimisationCriteria":{"type":"array","items":{"type":"string"},"description":"Anhang IV"},"minimisationAssessedAt":{"type":"string","format":"date"},"reuseSystemId":{"type":"string","description":"Art. 11"},"minRotations":{"type":"integer"},"reuseNotes":{"type":"string"},"labelMaterialCodes":{"type":"array","items":{"type":"string"},"description":"Art. 12"},"labelSortingPictogram":{"type":"boolean"},"labelReuseMarking":{"type":"boolean"},"labelDrsMarking":{"type":"boolean"},"labelRecycledContentShown":{"type":"boolean"},"labelCompostableMarking":{"type":"boolean"},"dataCarrierType":{"type":"string","enum":["none","qr","datamatrix","nfc","rfid","digimarc"]},"dataCarrierUrl":{"type":"string"},"manufacturerMarkingApplied":{"type":"boolean","description":"Art. 15(6)"},"importerMarkingApplied":{"type":"boolean","description":"Art. 18"},"annex5FormatCode":{"type":"string","description":"Anhang V, Verbot ab 2030"},"annex5Exemption":{"type":"string"},"status":{"type":"string","enum":["draft","review","compliant","non_compliant","archived"]},"placedOnMarketFrom":{"type":"string","format":"date"},"placedOnMarketUntil":{"type":"string","format":"date"},"targetMarkets":{"type":"array","items":{"type":"string"}},"annualUnits":{"type":"integer"},"retentionUntil":{"type":"string","format":"date","readOnly":true},"notes":{"type":"string"}}},"PackagingDetail":{"allOf":[{"$ref":"#/components/schemas/Packaging"},{"type":"object","properties":{"components":{"type":"array","items":{"$ref":"#/components/schemas/Component"}},"documents":{"type":"array","items":{"$ref":"#/components/schemas/Document"}},"declaration":{"$ref":"#/components/schemas/Declaration"},"lastComplianceRun":{"type":"object"},"marketPlacements":{"type":"array","items":{"$ref":"#/components/schemas/MarketPlacement"}},"suggestedStandards":{"type":"array","items":{"type":"object"}}}}]},"Document":{"type":"object","properties":{"id":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string"},"docType":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"filename":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer"},"sha256":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"pages":{"type":"integer"},"source":{"type":"string","enum":["upload","scan","generated"]},"ocrStatus":{"type":"string","enum":["none","pending","done","failed","unavailable"]},"ocrText":{"type":"string"},"issuedAt":{"type":"string","format":"date"},"validFrom":{"type":"string","format":"date"},"validUntil":{"type":"string","format":"date"},"issuer":{"type":"string"},"referenceNo":{"type":"string"},"retentionUntil":{"type":"string","format":"date"},"downloadUrl":{"type":"string"},"thumbnailUrl":{"type":"string"}}},"ComplianceFinding":{"type":"object","properties":{"article":{"type":"string"},"requirementCode":{"type":"string"},"severity":{"type":"string","enum":["blocker","warning","info","ok"]},"status":{"type":"string","enum":["ok","fail","missing_data","not_applicable","upcoming"]},"title":{"type":"string"},"message":{"type":"string"},"remediation":{"type":"string"},"actualValue":{"type":"string"},"expectedValue":{"type":"string"},"appliesFrom":{"type":"string","format":"date"}}},"ComplianceResult":{"type":"object","properties":{"runId":{"type":"string"},"rulesetVersion":{"type":"string"},"referenceDate":{"type":"string","format":"date"},"score":{"type":"number"},"marketable":{"type":"boolean"},"counts":{"type":"object"},"findings":{"type":"array","items":{"$ref":"#/components/schemas/ComplianceFinding"}},"computed":{"type":"object"}}},"TechnicalFile":{"type":"object","properties":{"regulation":{"type":"string"},"conformityAssessment":{"type":"string"},"completeness":{"type":"number"},"sections":{"type":"array","items":{"type":"object"}},"gaps":{"type":"array","items":{"type":"object"}},"retentionUntil":{"type":"string","format":"date"},"retentionYears":{"type":"integer"}}},"DeclarationRequest":{"type":"object","required":["packagingId","place","signatoryName","signatoryRole"],"properties":{"packagingId":{"type":"string"},"place":{"type":"string","description":"Anhang VIII Nr. 10"},"signatoryName":{"type":"string"},"signatoryRole":{"type":"string"},"issuedAt":{"type":"string","format":"date"},"standards":{"type":"array","items":{"type":"string"},"example":["EN 13428","EN 13430"]},"notifiedBody":{"type":"string"},"additionalInfo":{"type":"string"},"allowWithBlockers":{"type":"boolean"}}},"Declaration":{"type":"object","properties":{"id":{"type":"string"},"packagingId":{"type":"string"},"docNumber":{"type":"string"},"version":{"type":"integer"},"issuedAt":{"type":"string","format":"date-time"},"place":{"type":"string"},"signatoryName":{"type":"string"},"signatoryRole":{"type":"string"},"coveredArticles":{"type":"array","items":{"type":"string"}},"standards":{"type":"array","items":{"type":"object"}},"status":{"type":"string","enum":["draft","issued","superseded","revoked"]},"pdfUrl":{"type":"string"}}},"MarketPlacement":{"type":"object","required":["packagingId","memberState","year"],"properties":{"packagingId":{"type":"string"},"memberState":{"type":"string"},"year":{"type":"integer"},"units":{"type":"integer"},"weightKg":{"type":"number"},"reusableUnits":{"type":"integer"},"refillUnits":{"type":"integer"},"unpackedWeightKg":{"type":"number"},"materialBreakdown":{"type":"object","readOnly":true},"reportedAt":{"type":"string","format":"date"},"reportReference":{"type":"string"},"notes":{"type":"string"}}},"EprReport":{"type":"object","properties":{"reportingPeriod":{"type":"integer"},"deadline":{"type":"string"},"legalBasis":{"type":"string"},"producer":{"type":"object"},"memberStates":{"type":"array","items":{"type":"object"}},"totals":{"type":"object"},"warnings":{"type":"array","items":{"type":"string"}}}},"Obligation":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"description":{"type":"string"},"article":{"type":"string"},"category":{"type":"string"},"dueDate":{"type":"string","format":"date"},"responsibleId":{"type":"string"},"packagingId":{"type":"string"},"priority":{"type":"string","enum":["low","medium","high","critical"]},"status":{"type":"string","enum":["open","in_progress","done","cancelled"]}}}}}}