der Loeschantrag aus dem Portal bekommt einen Leser (W6, Art. 17)
Das Bewerber-Portal setzt erasureRequestedAt seit W3 und sagt im eigenen Kommentar, der Vollzug sei W6. Bis heute hatte das Feld KEINEN Leser: der Bewerber klickte, und danach geschah nie etwas.
Ein Antrag sticht die restliche Frist, aber NICHT die Schutzregeln — eine eingestellte Bewerbung und eine LAUFENDE bleiben unberuehrt (wer zuruecktreten will, nutzt withdraw; danach laeuft die Frist). Beide Faelle werden benannt gemeldet statt verschwiegen.
Antraege werden getrennt geholt und entdoppelt, damit der Bericht 'auf Antrag' von 'Frist abgelaufen' unterscheidet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Neuapplications
Recruiting-Kennzahlen + Fristen-Status an der Flaeche (W6 Reporting)
Time-to-Hire, Trichter je Stelle/Stufe, Absagequoten nach Kategorie — 13 Proben.
Gemessener Grund, warum das EIN Endpunkt ist und nicht drei Widget-Definitionen: Time-to-Hire ist die Differenz zweier Datumsfelder, der generische Widget-Motor kennt nur Akkumulatoren ueber EINEM Feld, und die Fluchttuer dataSource.pipeline liest allein der Prerender-Worker (nicht platform/states). Drei Kennzahlen ueber zwei Wege WAEREN das Parallel-System.
Flaeche: Loeschfrist + Anonymisierungs-Stempel als Spalten, Zeitraum-Filter, Schnellfilter Anonymisiert. actionsForEntity(Applications) jetzt verdrahtet — die Bedingung des frueheren Kommentars ist erfuellt, alle sechs Aktionen sind echt.
Gemessen statt gezaehlt: ein grep auf refuseUnimplementedAction liefert 11 Treffer, davon sind 8 Kommentare; die Messgroesse ist der IMPORT.
W2-Waechter mitgezogen und seine Positiv-Kontrolle auf applicants/merge umgehaengt — sonst belegten die sechs not.toContain nichts mehr.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Aktionen an der Bewerbung, alle drei mit dem AGG-/Art.-22-Riegel BAULICH statt nur im Prompt:
POST /applications/:id/actions/ai-screen -> schreibt aiScreening POST /applications/:id/actions/ai-reply-draft -> liefert nur zurueck POST /applications/:id/actions/ai-interview-questions -> liefert nur zurueck
- redactProtectedAttributes() entfernt die AGG-Traeger (Geburtsdatum, Anrede, Anschrift, Staatsangehoerigkeit, Religion, Behinderung, Lichtbild) VOR dem Modell-Aufruf. Was nicht mitreist, kann nicht gewichtet werden. - filterInadmissibleQuestions() wirft unzulaessige Gespraechsfragen aus dem ERGEBNIS und WEIST SIE AUS statt sie still zu schlucken. - Eine unlesbare Modell-Antwort wird zum Fehler, nie zu score 0 — ein Rueckfall saehe aus wie die Bewertung "ungeeignet". - Keine der drei Aktionen ruft transitionEntity oder versendet etwas; nur ai-screen schreibt, und nur das Feld aiScreening.
Alle drei Lesezugriffe (Bewerbung, Stelle, Bewerber) mandanten-gescopt einzeln. Rechte kaskadenfrei ueber additionalRights, drei getrennte.
66 neue Proben mit Negativ- UND Positiv-Kontrollen; die Art.-22-Strukturprobe ist kommentar-bewusst (der erste Wurf fiel an der eigenen Kopfzeile). Volle Reihe 1054/1054, Bau gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012CLtxDVijYPDaZcJryaWjK
Fixapplications
einen Fehler mit eigenem Status nicht auf 500 ueberschreiben
Gefunden an der LIVE-Probe, nicht an den 987 gruenen Proben: ein Uebergang auf eine nicht sichtbare Kennung meldete "Error 500: Applications not found".
Ursache: `customerMongoose.findById` gibt bei Nicht-Fund kein leeres Ergebnis zurueck, sondern WIRFT (`RessourceNotFoundError`, core methods/find/findOne.js:35) — und der Fehler traegt seinen Status (404) bereits im zweiten super-Parameter. Der `if (!doc)`- Zweig ist damit unerreichbar, und der pauschale 500er im Fang-Zweig machte aus JEDEM Aufruf mit fremder oder falscher Kennung eine Dienst-Stoerung.
Der Fang-Zweig respektiert jetzt `e.status` (4xx/5xx) und protokolliert ein 4xx als `warn` statt `error` — dieselbe Klassifikation wie im Fang-Zweig von createApplication. Ein Bedienfehler weckt damit niemanden in der Ueberwachung.
⚠ Die Klasse ist breiter als dieser Weg — eine Parallel-Sitzung arbeitet an derselben Sache im Kern (core-updateone-wickelt-404-in-500). Hier ist der Verbraucher behoben.
Proben 988/988. Flip-Probe: Status ignorieren faerbt genau 1 rot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fixapplications
Ablehnungen sagen im Rumpf denselben Status wie auf der Leitung
Am laufenden Dienst gemessen (2026-08-22): GET /applicationprocesses/<erfunden> antwortete mit HTTP 404 und `meta.code: 500`. Die ay-CLI liest den Rumpf und meldete deshalb "Error 500" fuer einen Bedienfehler — in der Ueberwachung eine Stoerung.
Ursache: der HTTP-Status kommt aus `res.locals.status` (returnResponse), der `meta.code` aber aus `err.status || 500` (defaultAPIAnswerError) bzw. einem HARTKODIERTEN 400 (defaultAPIAnswerRequestFailed). Beide lesen `res.locals` nicht. Damit kam auch die ganze GUARD_STATUS-Abbildung der Motor-Ablehnungen (403/409/422) als 400 beim Aufrufer an — der Kern von W2 war im Rumpf unsichtbar.
Neue Naht `lib/antwortMitStatus.ts` haengt den Status an den Fehler, damit `err.status` greift; alle Ablehnungen der drei W2-Wege laufen darueber.
⚠ Die zwei Antwort-Bauer in `platform/core` sind NICHT angefasst — sie liegen ausserhalb der claim_paths, und eine Aenderung dort traefe ~330 Verbraucher. Die Codegen-Vorlage traegt denselben Widerspruch (actionJobOfferSend).
⚠ Der strukturelle Waechter allein reichte NICHT: eine Flip-Probe, die der Naht das Anhaengen wegnimmt, liess ihn gruen — er prueft, DASS sie benutzt wird, nicht DASS sie wirkt. Deshalb zusaetzlich `antwortMitStatus.test.ts` (7 Faelle inkl. Negativ-Kontrolle am rohen Bauer). Mit ihr beisst die Flip-Probe: 6 rot.
Proben 986/986 (49 Reihen, vorher 979/48).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fixapplications
NUL-Byte aus dem Pruefer entfernen — git fuehrte die Datei als binaer
Der Dubletten-Schluessel trug ein literales NUL als Trenner. Folge: git stuft die Datei als binaer ein und zeigt keinen Diff mehr — eine Codeueberpruefung saehe Aenderungen daran nie. Gefunden am "Bin 0 -> 8496 bytes" im Commit-Statistik-Block, nicht an einem Fehlschlag: Bau und Proben waren die ganze Zeit gruen.
Ersetzt durch eine verschachtelte Karte (Map<from, Set<event>>) statt eines zusammengesetzten Schluessels — damit entfaellt die Trenner-Frage ganz. Ein Escape half nicht: es wurde auf dem Schreibweg erneut zu einem echten NUL.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fixapplications
die neun neuen W2-Dateien nachreichen — sie fielen aus dem Vorgaenger-Commit
130e28a committete mit , und das nimmt UNVERSIONIERTE Dateien nicht auf: die zwoelf geaenderten Dateien gingen mit, die neun neuen nicht. Der lokale Bau blieb gruen (er sieht den Arbeitsbaum), die Kette #174 fiel mit neun — genau den neun fehlenden Dateien.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Neuapplications
der Bewerbungsprozess laeuft — Anlege-Naht, fuenf echte Statuswechsel, Konfigurations-Flaeche
Bewerbermanagement W2. W1 hat die Flaechen und den Prozess-Seed gebaut, aber die Strecke war nicht bedienbar: alle sechs Aktions-Ruempfe lehnten mit 422 ab, und `POST /applications` konnte gar nicht gelingen — das Schema fuehrt drei Pflichtfelder (`_workflow`, `currentStatus`, `statusSince`), die kein Schreibweg setzte.
- Anlege-Naht `custom/applications/routerApplicationCreate`: loest den geltenden Prozess ueber die dreistufige Kette auf (Stelle -> Mandanten-Kopie -> Plattform-Vorgabe), setzt die drei Felder und loest die Eingangsbestaetigung ueber den Orchestrator aus. Verwirft `_workflow`/`currentStatus`/`statusSince` AUS DEM RUMPF. - Fuenf Aktionen echt ueber `core/lib/workflow/transitionEntity` (transition/reject/send-offer/hire/withdraw); `anonymize` bleibt ehrlich abgelehnt (W6). - Mandanten-Riegel: der Motor laedt roh (`model.findById`), die Naht laedt VORHER ueber `customerMongoose` — sonst waere die Bewerbung eines fremden Mandanten schaltbar. - `statusSince` + `stageHistory` werden nachgeschrieben (der Motor schreibt die Namen des Piloten `ITask`, `strict` verwirft sie hier still). - Konfigurations-Route `custom/applicationprocesses` (Liste/Lesen/Aendern/Uebernehmen) mit einem Pruefer, der sieben Graph-Fehler abfaengt, die der Motor NICHT abfaengt. - SDUI: Flaeche `hr.applicationprocesses` + Modul-Verweis; Status-Aktionen am Bearbeitungs-Zustand verdrahtet (Hausregel "erst befuellen, dann verdrahten" erfuellt). - Rechte `hr.applicationprocesses.view|edit` kaskadenfrei ueber `additionalRights`.
Proben 978/978 (48 Reihen, vorher 954/47). Drei Flip-Proben, je genau 1 rot, mit nachgewiesener Ersetzung: Mandanten-Riegel, Punkt-Pfad-Riegel, Aktions-Verdrahtung.
Es gibt KEINE `ApplicationProcesses`-Entitaet und soll keine geben — das Fundament sagt es woertlich (`IApplication`). Der Prozess IST ein `Workflows`-Dokument.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>