# Auftrag an Aria — Feedback MO-23 zu SupplierPulse validieren, entscheiden, umsetzen

| | |
|---|---|
| **Quelle** | `20260624_Feedback_App_MO-23.xlsx`, Blatt `Tabelle1`, 60 Einträge, 7 Melder, 2 eingebettete Screenshots |
| **Erhebung** | 24.06.2026 · **Auftrag erstellt** 16.07.2026 · **Auftraggeber** Kais |
| **Zielsystem** | SupplierPulse (App-48999, EA ITPLCG-1019), Repo `~/KADi/backend-nextjs` |
| **Melder** | Dickens (13) · Löffler (18) · Klockenhoff (11) · Gruber (9) · Kurzmiller (5) · Ping (2) · Hagen (2) |
| **Diese Datei ist** | Auftrag **und** Arbeitsstand. Aria pflegt sie fort. Es wird kein zweites Backlog angelegt. |

---

## 0 · Der Auftrag in fünf Sätzen

1. Prüfe jeden der 60 Punkte einzeln am aktuellen Code — **kein Punkt wird ungeprüft umgesetzt und keiner ungeprüft verworfen.**
2. Setze nur um, was nach der Prüfung fachlich, technisch und rechtlich Sinn ergibt; wo der Vorschlag des Melders das Symptom trifft und nicht die Ursache, schlage die bessere Lösung vor und begründe sie.
3. Was du nicht allein entscheiden darfst (§3.3, Klasse B), sammelst du — du blockierst nicht, du arbeitest weiter.
4. Berichte fortlaufend, welche Punkte erledigt sind, welche nicht, und warum (§9).
5. Neue Funde, die dir unterwegs auffallen, nimmst du als `NEU-xx` auf (§8) und behandelst sie nach denselben Regeln.

> **Der wichtigste Satz dieser Datei:** Das Feedback beschreibt **Beobachtungen von Anwendern, keine Diagnosen**. Es enthält nachweislich Verwechslungen, Tippfehler und Copy-Paste-Fehler (Belege in §5.0). Jede Behauptung darin wird am Code verifiziert, bevor eine Zeile geändert wird.

---

## 1 · Kontext (gilt als bekannt — trotzdem verifizieren, nicht glauben)

**Stack:** Next.js 16 · Supabase (Postgres, RLS-Rollout läuft, PRs #13–#22) · Vitest · PWA mit Dexie-Offline · i18n DE/EN/ZH · ~75k LOC TS/TSX, 479 Dateien
**Module:** `assessment`, `fabrikanalyse`, `oee`, `lsc-workshop`, `planning`, Owner/Admin-APIs, Multi-Tenant-Control-Plane
**Betrieb:** Adesso auf BMW AWS Cloud Room · **Nutzer dieses Feedbacks:** MO-23-Team (interne Fachanwender, keine Lieferanten)

**Bekannte Schwachstellen, die für diesen Auftrag relevant sind:**

| Schwachstelle | Konsequenz für diesen Auftrag |
|---|---|
| Nur 13 Vitest-Dateien auf ~75k LOC, `app/`-Komponentenlogik weitgehend ungetestet | Jeder Fix bringt mindestens einen Test mit (G9). Kein Fix „auf Sicht". |
| `CLAUDE.md` ist veraltet, **README ist die Quelle der Wahrheit** | `CLAUDE.md` wird nicht als Beleg zitiert. |
| 25 flache `supabase-*.sql` im Repo-Root, kein Supabase-CLI-Verzeichnis, Reihenfolge implizit | Neue Migration = neue Datei nach bestehendem Schema. Bestehende werden **nie** editiert (G3). |
| RLS-Rollout mitten in der Umsetzung (PRs #13–#22) | Ein großer Teil dieses Feedbacks ist mutmaßlich **Folge dieses Rollouts** (§5, H1–H3). Vor jedem Eingriff prüfen, ob eine offene PR den Punkt bereits berührt. |

**gstack (Lite-Mode), verbindlich:**

| Situation | Skill |
|---|---|
| Vor **jedem** PR | `/review` |
| Änderungen an RLS / Auth | `/cso` |
| Änderungen unter `app/` (Komponenten) | `/qa` |
| DB- / Migrationsarbeit | `/careful` bzw. `/guard` |
| **Immer zuerst** bei RLS-, Auth- oder Tenant-Isolation-Fehlern | `/investigate` |

**Zeitachse — zuerst klären, sonst arbeitest du an Gespenstern:**
Das Feedback ist vom **24.06.2026**, dieser Auftrag vom **16.07.2026** — dazwischen liegen gut drei Wochen Entwicklung.

- `git log --since=2026-06-20 --oneline` und die PRs #13–#22 durchsehen.
- Feststellen, **gegen welchen Stand** das Team getestet hat (Deployment-Datum der getesteten Umgebung).
- Punkte, die seither behoben wurden, bekommen Status `BEREITS BEHOBEN` **mit Commit-Beleg** — nicht mit Vermutung.

---

## 2 · Guardrails — nicht verhandelbar

Diese Regeln stehen über jedem einzelnen Feedback-Punkt. Ein Punkt, der nur durch Bruch einer dieser Regeln umsetzbar wäre, wird **nicht** umgesetzt, sondern eskaliert.

**G1 — RLS wird nie abgeschwächt.**
Verboten: `alter table … disable row level security`; Policies mit `using (true)` / `with check (true)` für Nutzerrollen; Service-Role-Key im Client- oder Edge-Pfad; `security definer` ohne fest gesetzten `search_path`. Ein RLS-Fehler wird durch die **richtige Policy** behoben, nicht durch Abschalten. Zuerst `/investigate`, vor dem PR `/cso`.

**G2 — Es wird nichts gelöscht.**
Keine Tabellen, Spalten, Policies, Migrationen, Dateien, Daten. „Entfernen" im Feedback heißt für dich zunächst: **aus UI/Route nehmen bzw. Feature-Flag aus**. Löschen im Datenmodell ist immer Klasse B (Kais entscheidet).

**G3 — Migrationen: nur additiv.**
Bestehende `supabase-*.sql` werden nie geändert. Neue Migration = neue Datei, Namensschema und Reihenfolge des Repos beibehalten, Rollback-Abschnitt dokumentieren. Während DB-Arbeit `/careful` bzw. `/guard`.

**G4 — Kein Commit auf `main`.**
Ein Branch + ein PR pro Karte oder Cluster. Vor jedem PR `/review`, bei `app/`-Änderungen zusätzlich `/qa`. PR-Titel trägt die Feedback-Nummer, z. B. `fix(kalender): Einsatzdauer beim Bearbeiten vorbelegen [FB-05]`.

**G5 — Keine Produktivdaten.**
Prüfungen laufen gegen Test-Tenant / Seed-Daten. Kein Schreiben in Prod, kein Kopieren von Prod-Daten in Test, keine echten Lieferanten- oder Personendaten in Fixtures.

**G6 — README schlägt `CLAUDE.md`.** Veraltete Doku wird nicht als Beleg verwendet, sondern am Ende als Fund gemeldet.

**G7 — Nichts erfinden.**
Keine BMW-Regel, kein Fachbegriff, kein Prozess, keine Abkürzung wird angenommen. Unklar → Karte auf `WARTET AUF MELDER` bzw. `WARTET AUF KAIS`, Frage in **Anhang C** eintragen, nächsten Punkt bearbeiten. Eine plausible Vermutung ist kein Beleg.

**G8 — Beweisniveau vor Umsetzung.**

| Stufe | Bedeutung |
|---|---|
| **N1** | Zur Laufzeit reproduziert (Screenshot/Log/Netzwerk-Antwort) — bester Beleg |
| **N2** | Am Code belegt: Datei:Zeile + nachvollziehbare Ableitung |
| **N3** | Nur Hypothese |

**Umgesetzt wird erst ab N2.** N3 rechtfertigt Recherche, niemals eine Codeänderung.

**G9 — Ein Punkt = eine belegte Änderung + mindestens ein Test.** Regressionstest bevorzugt: erst der Test, der den Fehler zeigt, dann der Fix.

**G10 — Kein Scope-Creep.** Neue Funde → §8 als `NEU-xx`. Sofort mitfixen nur, wenn trivial **und** im selben Codepfad **und** im selben PR nachvollziehbar.

**G11 — Keine personenbezogenen Leistungs- oder Anwesenheitsauswertungen.** Weder neu bauen noch bestehende erhalten (§5, H5). Im Zweifel: nicht bauen, Kais fragen.

**G12 — Sicherheitsfunde sofort an Kais**, nicht still fixen und nicht in einer öffentlichen PR-Beschreibung ausbreiten.

**G13 — Interne BMW-Links (z. B. `hr-portal.bmwgroup.net`) sind für dich nicht abrufbar.** Sie werden als Beleg des Melders zitiert — nicht bewertet, nicht interpretiert, nicht als geprüft ausgegeben.

---

## 3 · Arbeitszyklus pro Punkt

### 3.1 Die sechs Schritte

1. **Verstehen** — Karte lesen: Originalzitat, Ausgeschrieben, betroffener Bereich. Bei Widerspruch zwischen Zitat und Deutung gilt das **Zitat**.
2. **Verifizieren** — Beobachtung am aktuellen Stand prüfen. Ergebnis: bestätigt / teilweise / nicht reproduzierbar / bereits behoben. Beweisniveau notieren (G8).
3. **Ursache** — die *Ursache* finden, nicht das Symptom. Bei RLS/Auth/Tenant zuerst `/investigate`. Ergebnis: Datei:Zeile oder Policy-Name.
4. **Sinn-Check** — die sieben Fragen aus §3.2.
5. **Entscheiden** — Klasse A, B oder C (§3.3). Ergebnis in die Fortschrittstabelle §6.2.
6. **Umsetzen & Nachweisen** — Fix + Test + `/review` + PR. Prüfprotokoll an die Karte anhängen (§9.2).

### 3.2 Der Sinn-Check — sieben Fragen, alle beantworten

1. **Stimmt die Beobachtung** am heutigen Stand noch?
2. **Trifft der Vorschlag die Ursache** — oder kuriert er ein Symptom? (Beispiel: „Dummy-Lieferant aufnehmen" kuriert womöglich nur, dass ein Feld zu Unrecht Pflicht ist.)
3. **Widerspricht der Vorschlag einem anderen Feedback-Punkt?** (Konfliktliste in Anhang B — es gibt mindestens einen echten Konflikt.)
4. **Widerspricht er BMW-Regeln** (Betriebsvereinbarung, Datenschutz) **oder der MO-23-Methodik**?
5. **Bricht er bestehende Daten, Nutzer oder Schnittstellen?** Was passiert mit Datensätzen, die es schon gibt?
6. **Ist der Nutzen Aufwand und Risiko wert?** Nutzerkreis ist das gesamte MO-23-Team, nicht ein einzelner Melder.
7. **Löst eine Ursache mehrere Punkte gleichzeitig?** → §5 zuerst.

Ein Punkt, bei dem eine dieser Fragen unbeantwortet bleibt, geht nicht in Umsetzung.

### 3.3 Entscheidungsklassen

| Klasse | Wer entscheidet | Was |
|---|---|---|
| **A** | **Aria allein** | Bugfix mit klarer Ursache, UX-Detail, Beschriftung/Wording, Validierung, Test, Performance — solange Datenmodell, Scope und Compliance unberührt bleiben |
| **B** | **Kais** | Funktion entfernen · Datenmodell/Migration bestehender Daten · Scope- und Produktfragen · externe Systeme (LDB, MVZ, Outlook, Mailversand) · alles mit Compliance-Bezug · methodische Festlegungen (OEE-Konventionen) |
| **C** | **Melder** | Beobachtung unklar, nicht reproduzierbar oder widersprüchlich → präzise Rückfrage in Anhang C |

**Regel:** Im Zweifel **B**. Eine B-Entscheidung wird nie durch „ist ja nur eine Kleinigkeit" zu A. Umgekehrt gilt: eine A-Entscheidung wird auch getroffen — kein Rückfragen-Ping-Pong bei Dingen, die eindeutig sind.

**Wenn blockiert:** nicht raten, nicht warten. Karte auf `WARTET AUF …`, Frage sauber formuliert ablegen, **nächsten Punkt nehmen.** Alle B-Entscheidungen kommen gebündelt in **eine** Entscheidungsvorlage (§9.3) — Kais wird nicht einzeln gefragt.

---

## 4 · Status und Priorität

### 4.1 Statuswerte (exakt diese Schreibweise, damit `grep` funktioniert)

`OFFEN` · `PRÜFUNG` · `BESTÄTIGT → UMSETZEN` · `BESTÄTIGT → ANDERE LÖSUNG` · `NICHT REPRODUZIERBAR` · `BEREITS BEHOBEN` · `ABLEHNUNG EMPFOHLEN` · `WARTET AUF KAIS` · `WARTET AUF MELDER` · `IN UMSETZUNG` · `UMGESETZT (PR #x)` · `ERLEDIGT` · `ZURÜCKGESTELLT`

**Der Status steht ausschließlich in der Fortschrittstabelle §6.2.** Die Karten enthalten keinen Status, nur Inhalt und Prüfprotokoll. So gibt es keine zwei widersprüchlichen Stände.
`ERLEDIGT` vergibst du erst, wenn die Definition of Done (§10) vollständig erfüllt ist.

### 4.2 Prioritäten

| Prio | Bedeutung |
|---|---|
| **P0** | Compliance / Recht — sofort, vor allem anderen |
| **P1** | Blocker oder Datenverlust — Kernfunktion unbenutzbar oder Daten gehen still verloren |
| **P2** | Funktionsfehler / Datenqualität |
| **P3** | UX, Beschriftung, Verständlichkeit |
| **P4** | Neue Funktion / Scope — braucht Entscheidung, nicht Code |

---

## 5 · Querschnitts-Hypothesen — **das hier zuerst**

Sieben Ursachen erklären mutmaßlich rund die Hälfte der 60 Punkte. Wer die Punkte einzeln abarbeitet, fixt fünfmal dasselbe an fünf Stellen. Deshalb: **Welle 0 ist reine Befundaufnahme, kein Code.**
Eine bestätigte Hypothese ersetzt trotzdem **nicht** die Einzelprüfung: jeder Punkt wird einzeln verifiziert und einzeln berichtet.

### 5.0 Belege dafür, dass die Quelle Fehler enthält (Begründung für G8)

1. **Dieselbe Fehlermeldung an drei verschiedenen Stellen.** `new row violates row-level security policy for table "project_notes"` steht bei Nr. 48 (Projektnotizen), Nr. 49 (PMO-Teammitglieder) **und** Nr. 51 (Datenablage). Drei Funktionen, eine Tabelle. Entweder laufen alle drei über denselben Codepfad — oder der Melder hat kopiert. **Die tatsächlich betroffene Tabelle ist pro Fall selbst zu ermitteln.**
2. **Nr. 38 nennt einen Feiertag, der nicht in den genannten Zeitraum fällt.** Angegeben ist „02.06. bis 05.06.2026 (Pfingsmontag)". Pfingstmontag 2026 ist der **25.05.2026**. Im genannten Zeitraum liegt **Fronleichnam, Donnerstag 04.06.2026** — Feiertag u. a. in Bayern und Hessen, nicht bundesweit. Entweder hat der Melder den Feiertag verwechselt, **oder die App beschriftet ihn falsch**. Beides ist zu prüfen und führt zu unterschiedlichen Fixes.
3. **Spaltenversatz bei Nr. 27–35** (siehe §5.1) — die Punkte lesen sich falsch, wenn man den Spaltenüberschriften traut.
4. **Durchgängige Tippfehler** („Kaleder", „Moat", „komlett", „SuplierPulse", „ncht"). Alle Zitate in dieser Datei sind **unverändert** übernommen, inklusive Fehler — das ist Absicht.
5. **Nr. 22 („siehe Billy") und Nr. 24 („siehe Nr. 36") sind Querverweise**, keine eigenständigen Beobachtungen.

### 5.1 Spaltenversatz bei Nr. 27–35 (Gruber, OEE) — vor dem Lesen dieser Karten beachten

Die Kopfzeile lautet `Beobachtung | Was verbessern? | Beispiel / Referenz | Gerät`. Gruber hat aber so ausgefüllt:

| Spalte | Kopfzeile sagt | Gruber meint tatsächlich |
|---|---|---|
| D | Beobachtung | **Abschnitt** der OEE-Maske („2. Zeitbasis", „3. Leistung", „4. Qualität", „allgemein") |
| E | Was verbessern? | **Beobachtung** bzw. betroffenes Feld |
| F | Beispiel / Referenz | **Verbesserungsvorschlag** |
| G | Gerät | bei Nr. 29: **noch ein Verbesserungsvorschlag** („Gutmenge umbenenen auf First Part Yield") |

In den Karten unten sind die Zitate **mit Spaltenangabe** wiedergegeben, damit nichts verrutscht.

### 5.2 · H1 — Leere Auswahllisten
**Betrifft:** Nr. 2 / 22 / 57 (Grund bei „Verrechnungsmöglichkeit: Nein") · Nr. 23 / 56 (Kommunikationssprache) · Nr. 19 (KPI-Board DE/international) · evtl. Nr. 54, Nr. 3

**Hypothese:** Die Auswahllisten kommen aus Stammdaten-/Lookup-Tabellen. Wenn im laufenden RLS-Rollout `enable row level security` gesetzt wurde, **ohne** eine SELECT-Policy für normale Nutzerrollen zu ergänzen, liefert die Abfrage **null Zeilen ohne Fehlermeldung**. Die UI rendert eine leere Liste und meldet nichts. Für den Anwender sieht das exakt aus wie „kaputtes Drop-Down".
Alternativen, in dieser Reihenfolge auszuschließen: Seed-Daten fehlen im getesteten Tenant · die Liste hängt an einer Bedingung, die nie zutrifft (z. B. Filter auf ein Feld, das erst nach dem Speichern gesetzt wird) · fehlende i18n-Keys → Optionen werden leer gerendert.

**Prüfschritt (als normaler Nutzer, *nicht* mit Service-Role-Key — sonst siehst du den Fehler nie):**
```sql
select c.relname,
       c.relrowsecurity                                   as rls_an,
       count(p.polname) filter (where p.polcmd in ('r','*')) as select_policies
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
left join pg_policy p on p.polrelid = c.oid
where n.nspname = 'public' and c.relkind = 'r'
group by 1, 2
order by select_policies asc, 1;
```
Tabellen mit `rls_an = true` und `select_policies = 0` sind die Kandidaten. Danach pro Lookup-Tabelle mit einem echten Nutzer-JWT `select count(*)` über die REST-API.

**Wenn wahr:** Eine additive Migration mit SELECT-Policies für Stammdaten (lesbar für alle authentifizierten Nutzer des jeweiligen Tenants) löst vier bis sechs Punkte auf einmal. **Trotzdem jeden Punkt einzeln verifizieren und einzeln berichten.**
**Unabhängig davon ein Fund:** Eine leere Auswahl ohne Hinweis ist immer ein UX-Fehler. Lade-, Leer- und Fehlerzustand müssen unterscheidbar sein → als `NEU-xx` aufnehmen.

### 5.3 · H2 — Schreiben schlägt fehl, teils lautlos
**Betrifft:** Nr. 48, 49, 51 (sichtbarer RLS-Fehler) · Nr. 6 (lautloser Fehlschlag) · evtl. Nr. 15, 18, 58

**Hypothese A (sichtbar):** INSERT-Policy fehlt, oder ihr `with check` verlangt Spalten (`tenant_id`, `created_by`, `project_id`), die der Client nicht mitschickt → genau die gemeldete Fehlermeldung.

**Hypothese B (lautlos) — die wichtigere:** Bei **UPDATE und DELETE** ohne passende Policy liefert PostgREST/Supabase **keinen Fehler**, sondern Erfolg mit **null betroffenen Zeilen**. Die UI zeigt „gespeichert", tatsächlich ist nichts passiert. Das ist die naheliegendste Erklärung für Nr. 6 („Einsatz kann weder Überschrieben noch gelöscht werden") und für jeden „geht nicht, aber es kommt keine Fehlermeldung"-Punkt. **Diese Möglichkeit wird bei solchen Punkten zuerst geprüft, nicht zuletzt.**

**Prüfschritt:** `select tablename, policyname, cmd, roles, qual, with_check from pg_policies where schemaname='public' order by tablename, cmd;` — pro betroffener Tabelle: gibt es für jedes benötigte Kommando eine Policy? Dazu die Netzwerkantwort ansehen: Status 200/204 mit leerem Ergebnis-Array = lautloser Fehlschlag.

**Fix-Muster (mit `/investigate` beginnen, mit `/cso` abschließen):** `with check` prüft Tenant-/Projektzugehörigkeit gegen den JWT-Claim · der Client setzt `tenant_id` **nicht** selbst, sondern ein `before insert`-Trigger oder ein Spalten-Default aus dem Claim setzt sie · eine UPDATE-Policy braucht **beides**, `using` **und** `with check` (sonst kann man Zeilen aus dem eigenen Tenant heraus­schreiben) · für jede Policy ein Test: eigener Tenant darf, fremder Tenant darf nicht.

**Fund für die App-Ebene (`NEU-xx`):** `update`/`delete` ohne anschließendes `.select()` und Prüfung der Trefferzahl ist app-weit ein Fehlerbild. Lautlose Fehlschläge müssen als Fehler erkennbar werden.

### 5.4 · H3 — „Angelegt, aber danach nicht zu sehen"
**Betrifft:** Nr. 15, 18 (neuer Lieferant) · Nr. 58 (neues Projekt im Kalender) · evtl. Nr. 54

**Prüfreihenfolge — nicht umdrehen:**
1. **Datenfehler:** Der Datensatz wird geschrieben, aber ohne `tenant_id`/`created_by` → die SELECT-Policy filtert ihn sofort wieder weg. Der Nutzer legt an, bekommt keinen Fehler, sieht nichts. **Prüfbar:** mit Service-Role nachsehen, ob die Zeile existiert. **Existiert sie → es ist RLS, nicht der Cache.**
2. **Cache:** `router.refresh()` / `revalidatePath` fehlt, oder der SWR-/React-Query-Key wird nach dem Anlegen nicht invalidiert.
3. **Dexie:** Der PWA-Offline-Cache liefert die alte Liste.

Wer (2) fixt, obwohl (1) vorliegt, erzeugt **unsichtbare Waisendatensätze in Produktion** — die Liste wird neu geladen und der Datensatz fehlt trotzdem, nur merkt es dann keiner mehr. Deshalb: **immer erst in der Datenbank nachsehen.**

### 5.5 · H4 — `gen_random_bytes` (Nr. 13)
`function gen_random_bytes(integer) does not exist` ist `pgcrypto`. In Supabase liegen Extensions per Konvention im Schema `extensions`, nicht in `public`. Typische Ursachen: Extension nicht installiert · installiert, aber der aufrufende Kontext hat `extensions` nicht im `search_path` (klassisch bei `security definer`-Funktionen mit `set search_path = public`) · Aufruf in einer Migration ohne Schema-Qualifizierung.

**Optionen — eine wählen und die Wahl begründen:**
1. `create extension if not exists pgcrypto with schema extensions;` + Aufruf als `extensions.gen_random_bytes(32)` + `extensions` im `search_path` der Funktion ergänzen.
2. Token in Node erzeugen: `crypto.randomBytes(32).toString('base64url')` — löst die Kopplung an die DB-Extension ganz auf.
3. `gen_random_uuid()` ist **kein Ersatz** für einen geheimen Link-Token — nur zulässig, wenn der Wert keinen Geheimnischarakter hat.

**Sicherheitsanforderungen an den Einreichungs-Link, unabhängig von der Wahl (`/cso`):** ≥128 Bit Entropie aus einem CSPRNG · Token nur einmal im Klartext ausgeben, in der DB als Hash ablegen · Ablaufdatum · Widerruf möglich · kein Token in Logs. Fehlt davon etwas: **G12 — sofort an Kais, nicht still fixen.**

### 5.6 · H5 — Compliance-Klammer: personenbezogene Anwesenheits- und Leistungsdaten
**Betrifft:** Nr. 36 (+24) Arbeitsort · Nr. 41 Berater-Auslastung · Nr. 45 Besuchstage pro Monat · **zu prüfen:** Nr. 4 (Reisezeit), Nr. 52 (Kundenzufriedenheit) · **Konflikt:** Nr. 14

Löffler stützt seinen Einspruch auf zwei Aussagen: die Protokollnotiz 3 vom 17.10.2024 zur BMW-Betriebsvereinbarung „Mobilarbeit" (außerhalb der systemgeführten Zeitwirtschaft dürfen keine personenbezogenen Daten zu Anwesenheiten und Mobilarbeitszeiten erfasst werden), und zweimal die Feststellung, MA-Auslastungsanalysen seien bei BMW verboten.

**Für dich verbindlich:** Du bewertest die Rechtslage nicht und legst sie nicht aus (G13). Du behandelst die Aussagen als das, was sie sind: **begründeter Einspruch eines Fachanwenders gegen ein Feature** — mit Quellenangabe, von einem Kollegen, der die Regel kennt. Daraus folgt:

- Alle Punkte dieser Klammer sind **P0** und **Klasse B**.
- **Was du sofort tust:** die betroffenen Stellen im Code **vollständig auflisten** — Felder, Spalten, Charts, Exporte, API-Endpunkte, Migrationen. Kais soll mit einer belastbaren Liste entscheiden, nicht mit einem Gefühl. Diese Liste ist dein eigentlicher Beitrag hier.
- **Was du darfst:** den UI-Zugang über Feature-Flag deaktivieren.
- **Was du nicht tust:** Spalten oder Daten löschen (G2), oder eine „anonymisierte Variante" bauen, weil die dir harmlos vorkommt.

**Echter Konflikt im Feedback:** Nr. 14 (Ping) schlägt „Persönliche Abwesenheit" als Oberkategorie vor — **ausdrücklich inklusive HO**. Das würde genau die Erfassung wiederherstellen, gegen die sich Nr. 36 (Löffler) richtet. **Nicht beides umsetzen.** → Anhang B, Entscheidung Kais.

### 5.7 · H6 — Hartkodierte Stammdaten statt pflegbarer Listen
**Betrifft:** Nr. 54 (ZDSC Campus fehlt) · evtl. Nr. 19, 23/56, 2/22/57, 3

Wenn ein fehlender Listeneintrag nur per Code-Deploy ergänzt werden kann, ist nicht der Eintrag der Fehler, sondern das Modell. **Prüfen:** Kommt die Liste aus einer Tabelle oder aus einem TS-Array/Enum? Bei Array/Enum **und** fachlich veränderlicher Liste (Projekte, Standorte, Sprachen, Gründe) → Lookup-Tabelle + Pflege im Admin-Bereich vorschlagen (Klasse B, Datenmodell). Den fehlenden Eintrag kurzfristig ergänzen darfst du (Klasse A) — aber du meldest das Muster.

### 5.8 · H7 — Zeit- und Kalenderlogik
**Betrifft:** Nr. 25 (KW), Nr. 38 (Feiertage), Nr. 9 (Monatsexport)

1. **Kalenderwoche:** Deutschland rechnet ISO-8601 (Woche beginnt Montag, Woche 1 enthält den ersten Donnerstag). US-Nummerierung weicht bis zu einer Woche ab. `getISOWeek`/`getISOWeekYear` verwenden, nie `getWeek` ohne Locale. Jahreswechsel testen: 29.12.2025–04.01.2026.
2. **Feiertage sind regional, nicht national.** Fronleichnam ist in Bayern und Hessen Feiertag, in Berlin nicht. SupplierPulse plant Einsätze bei Lieferanten in Mexiko, Ungarn, Rumänien, Marokko, China — deren Feiertage sind nicht die deutschen. Ein globaler Kalender „DE" ist fachlich falsch. Prüfen: Woher kommen die Feiertage (Bibliothek, Tabelle, hartkodiert)? Ist Land/Region überhaupt modelliert? Wenn nicht → Klasse B.
3. **Zeitzone:** Alles, was Tagesgrenzen zählt, rechnet in `Europe/Berlin` bzw. der Zeitzone des Standorts — nicht in UTC. Sonst kippen Monats- und Tagesgrenzen um einen Tag. Nebenverdacht bei Nr. 9.

---

## 6 · Reihenfolge und Fortschritt

### 6.1 Wellen

| Welle | Inhalt | Regel |
|---|---|---|
| **0** | Querschnitts-Hypothesen H1–H4 prüfen | **Kein Code-Fix.** Nur Befund: welche Hypothese trägt, welche Punkte hängen daran. Ergebnis vor Welle 2 berichten. |
| **1** | **P0 Compliance** — Nr. 36 (+24), 41, 45 | Bestandsaufnahme + Feature-Flag + Entscheidungsvorlage. Kein Löschen. |
| **2** | **P1 Blocker / Datenverlust** — 48, 51, 13, 6, 5, 2 (+22, +57), 23 (+56), 15, 18, 58, 59, 14a (+55) | Hier liegt der größte Nutzen fürs Team. |
| **3** | **P2 Funktionsfehler** — 8, 9, 7, 33, 35, 38, 39, 49a, 50, 12, 11, 54 | |
| **4** | **P3 UX / Wording** — 25, 26, 32, 34, 37, 42, 20 | Billig, sichtbar, macht Vertrauen. |
| **5** | **P4 Entscheidungen** — 1 (+17), 3 (+60), 4, 10, 16, 19, 21, 27 (+28, +31), 29, 30, 40, 43 (+44), 46, 47, 49b, 52, 53 | Nicht einzeln fragen: **eine** Entscheidungsvorlage (§9.3). |

Die Prio in §6.2 ist eine **Ersteinschätzung aus der Aktenlage**. Wenn die Prüfung etwas anderes zeigt, änderst du sie — und schreibst in einem Satz dazu, warum.

### 6.2 Fortschrittstabelle — **einzige Quelle für den Status**

Aria pflegt ausschließlich die Spalten `Status` und `Notiz` (Notiz = ein Halbsatz, kein Aufsatz — der Rest steht im Prüfprotokoll der Karte).

| Nr. | Melder | Bereich | Karte | Prio | Klasse | Status | Notiz |
|---|---|---|---|---|---|---|---|
| 1 | Dickens | Anlage Lieferant / LDB | FB-01 | P4 | B | OFFEN | |
| 2 | Dickens | Verrechnungsmöglichkeit | FB-02 | P1 | A | PRÜFUNG | W0: nicht RLS; Kais 17.07.: Werte waren nicht gepflegt; kein Pflichtfeld |
| 3 | Dickens | Dummy-Lieferant | FB-03 | P4 | B | OFFEN | |
| 4 | Dickens | Kalender · Dienstreise-Schalter | FB-04 | P3 | B | OFFEN | H5? |
| 5 | Dickens | Kalender · Einsatz bearbeiten | FB-05 | P1 | A | OFFEN | Datenverlust |
| 6 | Dickens | Kalender · Löschen/Ändern | FB-06 | P1 | A | PRÜFUNG | W0: H2-B belegt, N1-Repro in W2 |
| 7 | Dickens | Kalender · Monatsansicht | FB-07 | P2 | A | OFFEN | |
| 8 | Dickens | Kalender · Mitarbeiterverwaltung | FB-08 | P2 | A | OFFEN | |
| 9 | Dickens | Kalender · Excel-Export | FB-09 | P2 | A | OFFEN | H7 |
| 10 | Dickens | Kalender · Drucken | FB-10 | P4 | B | OFFEN | |
| 11 | Dickens | Reporting · PPT/PDF-Export | FB-11 | P2 | B | OFFEN | |
| 12 | Dickens | Reporting · PDF-Formatfehler | FB-12 | P2 | C | OFFEN | Beleg fehlt |
| 13 | Dickens | Auftragseingang · Einreichungs-Links | FB-13 | P1 | A | BESTÄTIGT → UMSETZEN | W0/H4: pgcrypto-Schema vs search_path (N2) |
| 14 | Ping | Kalender · Pflichtfeld + Kategorien | FB-14 | P1/P4 | A/B | OFFEN | Konflikt mit 36 |
| 15 | Ping | Projekt anlegen · Formularverlust | FB-15 | P1 | A | PRÜFUNG | W0: H3-Cache-Fenster belegt (Teilaspekt) |
| 16 | Klockenhoff | Projekt anlegen · KW / Terminkonflikt | FB-16 | P4 | C/B | OFFEN | |
| 17 | Klockenhoff | Bestandslieferanten / Migration | FB-01 | P4 | B | OFFEN | → FB-01 |
| 18 | Klockenhoff | Neuer Lieferant nicht sichtbar | FB-18 | P1 | A | PRÜFUNG | W0: SELECT offen; Kais 17.07.: Berater-Anlage GEWOLLT mit Admin-Prüfung → Policy vs. Workflow (W2) |
| 19 | Klockenhoff | KPI-Board DE/international | FB-19 | P4 | B | PRÜFUNG | W0: wie FB-02 (master_data_values) |
| 20 | Klockenhoff | KIFAG · Fachbereichsbezeichnung | FB-20 | P3 | C | OFFEN | Begriff unklar |
| 21 | Klockenhoff | KIFAG · Kurzzeichen / MVZ | FB-21 | P4 | B | OFFEN | |
| 22 | Klockenhoff | Verrechnungsmöglichkeit („siehe Billy") | FB-02 | P1 | A | OFFEN | → FB-02 |
| 23 | Klockenhoff | Kommunikation · Sprache | FB-23 | P1 | A | PRÜFUNG | W0: wie FB-02; Feld = Fragebogen-Sprache, NEU-05 |
| 24 | Klockenhoff | Einsatzplanung · Homeoffice | FB-36 | P0 | B | OFFEN | → FB-36 |
| 25 | Klockenhoff | Kalender · KW anzeigen | FB-25 | P3 | A | OFFEN | H7 |
| 26 | Klockenhoff | Einsatz anlegen · Namensauswahl | FB-26 | P3 | A | OFFEN | |
| 27 | Gruber | OEE · Zeitbasis Schicht | FB-27 | P4 | B | OFFEN | Methodik |
| 28 | Gruber | OEE · Leistung/Menge ohne Bezug | FB-27 | P4 | B | OFFEN | → FB-27 |
| 29 | Gruber | OEE · Qualität / Nacharbeit / FPY | FB-29 | P4 | B | OFFEN | |
| 30 | Gruber | OEE · Wartungszeit / Schichtwechsel | FB-30 | P4 | B | OFFEN | Methodik |
| 31 | Gruber | OEE · Geplante Pausen | FB-27 | P4 | B | OFFEN | → FB-27 |
| 32 | Gruber | OEE · Pflichtfeld-Kennzeichnung | FB-32 | P3 | A | OFFEN | |
| 33 | Gruber | OEE · Zahleneingabe bleibt 0 | FB-33 | P2 | A | OFFEN | app-weit |
| 34 | Gruber | OEE · Zykluszeit vs. Taktzeit | FB-34 | P3 | A | OFFEN | |
| 35 | Gruber | OEE · keine Plausibilisierung | FB-35 | P2 | A | OFFEN | |
| 36 | Löffler | Kalender · Arbeitsort | FB-36 | **P0** | B | UMGESETZT (PR #331, O1) | Flag `workModeCapture` live (bmw=aus), überall durchgesetzt inkl. v1-API+Kopier-Pfade; O2 Anzeige/Export = Folge-PR |
| 37 | Löffler | Kalender · Terminart vs. Auftragsart | FB-37 | P3 | A/B | OFFEN | |
| 38 | Löffler | Kalender · Feiertage / Werktage | FB-38 | P2 | A/B | OFFEN | H7 |
| 39 | Löffler | Einsatzplanung · Termine bearbeiten | FB-39 | P2 | A | PRÜFUNG | W0: wie FB-06 (H2-B) |
| 40 | Löffler | Reporting · CT > Kundentakt | FB-40 | P4 | B | OFFEN | |
| 41 | Löffler | Reporting · Berater-Auslastung | FB-41 | **P0** | B | UMGESETZT (PR #331) | Flag `consultantLoadReport` live (bmw=aus), Render + PDF/PPTX-Export gegated |
| 42 | Löffler | Fabrikanalyse · Status „Entwurf" | FB-42 | P3 | A | OFFEN | |
| 43 | Löffler | Reporting · Projekte nach Standort | FB-43 | P4 | B | OFFEN | |
| 44 | Löffler | Reporting · Projekte nach Abteilung | FB-43 | P4 | B | OFFEN | → FB-43 |
| 45 | Löffler | Reporting · Besuchstage pro Monat | FB-45 | P3 | A | BESTÄTIGT → ANDERE LÖSUNG | Kais-Go 17.07. (TG 8810): P0→P3, kein Personenbezug im Chart (W1-Beleg); Reparatur statt Entfernen → W3, mit NEU-08 |
| 46 | Löffler | Reporting · OEE-Übersicht | FB-46 | P4 | B | OFFEN | Scope |
| 47 | Löffler | Reporting · Kapazität | FB-47 | P4 | B | OFFEN | Datenverfügbarkeit |
| 48 | Löffler | Projektnotizen speichern | FB-48 | P1 | A | UMGESETZT (PR #332) | additive team-write RLS-Policies, Migration appliziert (Prod live) |
| 49 | Löffler | PMO · Teammitglieder + Scope | FB-49 | P1/P4 | A+B | 49a UMGESETZT (PR #332); 49b→Vorlage | Fehler (a) gefixt: team-write RLS, Option B (Team teilt alles, Prod live); Scope-Frage (b) bleibt Entscheidungsvorlage |
| 50 | Löffler | Datenablage · Ablauf | FB-50 | P2 | A | OFFEN | |
| 51 | Löffler | Datenablage · funktioniert nicht | FB-51 | P1 | A | PRÜFUNG | W0: documents b1/b2-verschärft; Delete/Move-UI blind |
| 52 | Löffler | PMO · Kundenzufriedenheitsbefragung | FB-52 | P4 | B | OFFEN | H5 prüfen |
| 53 | Löffler | PMO · Projektfilter | FB-53 | P4 | B | OFFEN | |
| 54 | Kurzmiller | Projekt anlegen · ZDSC Campus fehlt | FB-54 | P2 | A/B | PRÜFUNG | W0: Wert existiert seit 05.06. („Coming Soon"); Scope-Frage |
| 55 | Kurzmiller | Kalender · Urlaub braucht Projekt | FB-14 | P1 | A | OFFEN | → FB-14 |
| 56 | Kurzmiller | Projektanlage · Sprache | FB-23 | P1 | A | OFFEN | → FB-23 |
| 57 | Kurzmiller | Projektanlage · Verrechnung | FB-02 | P1 | A | OFFEN | → FB-02 |
| 58 | Kurzmiller | Kalender · neues Projekt fehlt | FB-58 | P1 | A | PRÜFUNG | W0/H3: kein revalidate + 30s-Router-Cache |
| 59 | Hagen | Kalender · Lieferant nicht synchron | FB-59 | P1 | A | PRÜFUNG | W0-Kandidat: 5-Min-Sync-Fenster andere Sessions |
| 60 | Hagen | Tier-2 ohne Lieferantennummer | FB-03 | P4 | B | OFFEN | → FB-03 |

**Zählprobe:** 60 Punkte → 50 Karten (10 Punkte sind Dubletten/Querverweise, siehe Anhang B). Im Abschlussbericht werden trotzdem **alle 60 Nummern einzeln** ausgewiesen — der Melder will seinen Punkt wiederfinden, nicht den Cluster.

---

## 7 · Backlog — 50 Karten

**Lesehinweis für jede Karte:** Der Block `>` ist das **wörtliche Original** aus der Excel, unverändert inklusive Tipp- und Flüchtigkeitsfehlern. Alles darunter ist **Deutung und Vorschlag** — also genau das, was du prüfen sollst, nicht das, was du glauben sollst. **Bei Widerspruch zwischen Zitat und Deutung gilt das Zitat.**

### E1 · Lieferantenstammdaten

#### FB-01 — LDB-Anbindung und Bestandslieferanten · deckt Nr. 1, 17
`Nr. 1` Dickens · Anlage Lieferant · PC | `Nr. 17` Klockenhoff · Lieferant anlegen · **P4 · Klasse B**

> **Nr. 1 — Beobachtung:** „Verbindung zu LDB?"
> **Nr. 1 — Was verbessern?:** „Lieferantennummer direkt im SuplierPulse "finden""
> **Nr. 17 — Beobachtung:** „kein Zugriff auf schon angelegte Lieferanten (altes Tool)"
> **Nr. 17 — Was verbessern?:** „migration der schon angelegten Lieferanten oder direkter Zugriff auf LDB"

**Gemeint ist:** Zwei Melder wollen dasselbe — Lieferantenstammdaten nicht abtippen. Dickens will die BMW-Lieferantennummer **in** SupplierPulse nachschlagen können; Klockenhoff will die im Vorgängertool bereits angelegten Lieferanten wiederfinden. Zwei Wege: Live-Anbindung an die LDB oder einmalige Übernahme des Bestands.

**Prüfen:** Gibt es im Repo oder in den EA-Unterlagen (ITPLCG-1019, DRP-Conformity-Check) irgendeinen Bezug zu einer LDB-Schnittstelle? (`rg -i "ldb|lieferantennummer|supplier_no"`) · Ist die Nummer heute Freitext, gibt es ein Format? · Existiert der Altbestand als Datei/Export, und wie groß ist er?

**Warum Klasse B:** Externe Schnittstelle heißt Datenschutz, Berechtigungen, EA-Freigabe, Betrieb im BMW AWS Cloud Room. Nichts davon entscheidest du, und nichts davon löst du mit Code.

**Was du liefern sollst:** eine Entscheidungsvorlage mit drei Optionen und ehrlicher Aufwands-/Risikoeinschätzung —
**O1 Live-Anbindung LDB:** beste Datenqualität, höchster Aufwand, braucht EA + Datenschutz + Betrieb.
**O2 Einmal-Import (CSV/Excel) + Pflege in SupplierPulse:** schnell, löst Nr. 17 sofort, veraltet mit der Zeit.
**O3 Typeahead-Suche über den importierten Bestand:** Kompromiss, Bestätigung durch den Anwender.
**Wichtig:** O2 entschärft Nr. 1, 3, 17, 18 **und** 60 gleichzeitig. Deshalb zuerst herausfinden, ob eine Bestandsliste als Datei beschaffbar ist — das ist möglicherweise die billigste Verbesserung im ganzen Backlog.

**Fertig, wenn:** Entscheidungsvorlage steht. **Kein Code ohne Kais.**

#### FB-03 — Lieferant ohne BMW-Nummer / „Dummy-Lieferant" · deckt Nr. 3, 60
`Nr. 3` Dickens · Kalender, Projektanlage · PC | `Nr. 60` Hagen · Neue Lieferanten hinzufügen · **P4 · Klasse B**

> **Nr. 3 — Beobachtung:** „Kein "Dummy-Lieferant" vorhanden."
> **Nr. 3 — Was verbessern?:** „>Dummy-Lieferant< aufnehmen"
> **Nr. 60 — Beobachtung:** „Tier 2 Lieferanten haben nicht immer eine BMW Lieferantennummer. "
> **Nr. 60 — Was verbessern?:** „definition von dummy nummer oder sonderfall/abwahl in der anlage"

**Gemeint ist:** Zwei verschiedene Bedürfnisse hinter einem Wort. Hagen beschreibt das echte fachliche Problem: Tier-2-/N-Tier-Lieferanten haben keine BMW-Lieferantennummer und lassen sich deshalb nicht anlegen — obwohl MO-23 dort arbeitet. Dickens vermisst einen Platzhalter, vermutlich um Einträge ohne echten Lieferantenbezug überhaupt speichern zu können.

**Zuerst prüfen — und das ist der ganze Punkt:** *Wofür* braucht ein Anwender einen Dummy? Wenn die Antwort „weil Lieferant/Projekt Pflichtfeld ist, auch bei Urlaub" lautet, dann ist der Dummy die Krücke und **FB-14 die Lösung**. Wer hier einen Dummy-Datensatz in die Stammdaten legt, baut Datenmüll ein, der garantiert zweckentfremdet wird und jede spätere Auswertung verseucht.
Weiter prüfen: Ist `bmw_supplier_no` heute Pflicht und/oder Unique? Wie viele Datensätze gäbe es ohne Nummer?

**Vorschlag (statt Dummy-Datensatz):** Lieferantennummer **optional** + Typkennzeichen (`Tier-1 mit BMW-Nummer` / `Tier-n ohne Nummer` / `intern`) · interne ID immer vergeben · Eindeutigkeit nur dort erzwingen, wo eine Nummer existiert:
```sql
create unique index if not exists suppliers_bmw_no_uniq
  on public.suppliers (bmw_supplier_no) where bmw_supplier_no is not null;
```
**Fertig, wenn:** Entscheidungsvorlage mit diesem Vorschlag **plus** Aussage, ob heute Datensätze existieren, die den Constraint verletzen würden.

#### FB-18 — Neu angelegter Lieferant erscheint nicht · Nr. 18 (verwandt: 15)
`Nr. 18` Klockenhoff · neuer Lieferant · **P1 · Klasse A · H3**

> **Beobachtung:** „neu angelegt - wurde aber anschließend nicht gezeigt "

**Gemeint ist:** Nach dem Anlegen taucht der Lieferant nicht in Liste oder Auswahl auf. Ping meldet dasselbe (Nr. 15, dritter Satz). **Zwei Melder unabhängig voneinander → sehr wahrscheinlich reproduzierbar.**

**Prüfen — Reihenfolge aus §5.4 strikt einhalten:** erst mit Service-Role in der DB nachsehen, ob die Zeile existiert und `tenant_id`/`created_by` gesetzt sind. Existiert sie → RLS-SELECT, nicht Cache. Erst danach Revalidation und Dexie.

**Wenn die Zeile ohne `tenant_id` existiert:** Das ist kein Anzeigefehler, sondern ein Datenfehler, der bereits **unsichtbare Waisendatensätze in Produktion** erzeugt haben kann. Dann: zählen, an Kais melden, **nicht selbst bereinigen** (G2).

**Fertig, wenn:** Ursache auf N1/N2 belegt, Fix + Integrationstest „anlegen → erscheint in der Liste", Waisenzahl berichtet.

### E2 · Projektanlage und Stammdatenfelder

#### FB-02 — „Verrechnungsmöglichkeit: Nein" → Grund-Auswahl ist leer · deckt Nr. 2, 22, 57
`Nr. 2` Dickens · PC | `Nr. 22` Klockenhoff | `Nr. 57` Kurzmiller · **P1 · Klasse A · H1**

> **Nr. 2 — Beobachtung:** „Bei Auswahl "Nein" keine Auswahlmöglichkeit im Drop-Down"
> **Nr. 2 — Was verbessern?:** „Reparieren"
> **Nr. 22 — Beobachtung:** „siehe Billy"
> **Nr. 57 — Beobachtung:** „Feld Verrechnungsmöglichkeit bei Nein Grund keine Auswahlmöglichkeiten."

**Gemeint ist:** Wird „Verrechnungsmöglichkeit = Nein" gewählt, erscheint das abhängige Feld „Grund" — aber ohne Optionen. **Drei von sieben Meldern** haben das notiert (Nr. 22 „siehe Billy" ist der Verweis auf Dickens' Punkt, kein eigener Befund). Das ist sicher reproduzierbar und für das Team sehr sichtbar.

**Prüfen:** §5.2/H1. Woher kommen die Optionen — Tabelle, Enum/TS-Array oder i18n? Bei Tabelle: SELECT-Policy + Seed im getesteten Tenant. Bei Array: Filterbedingung, die nie zutrifft. Bei i18n: fehlende Keys → leere Labels.
**Die entscheidende Zusatzfrage:** Ist „Grund" ein Pflichtfeld? Wenn ja und es gibt keine Option, **kann niemand ein Projekt mit „Verrechnung: Nein" anlegen** — dann ist das kein Schönheitsfehler, sondern eine blockierte Kernfunktion, und P1 ist eher noch untertrieben.

**Wenn bestätigt:** Ursache beheben. Zusätzlich (Klasse A, gleicher PR): Ein Auswahlfeld ohne Optionen darf nicht so aussehen, als sei es funktionsfähig — Lade-, Leer- („Keine Gründe hinterlegt") und Fehlerzustand unterscheidbar machen.
**Fertig, wenn:** Optionen erscheinen · Test, der die Optionsquelle **mit Nutzerrechten** (nicht Service-Role) liest · Leerzustand hat einen Text · Aussage zur Pflichtfeld-Frage im Bericht.

#### FB-15 — Projektanlage: Eingaben gehen verloren, Lieferant muss vorher existieren · Nr. 15
`Nr. 15` Ping · Projekt Anlegen · **P1 · Klasse A**

> **Beobachtung:** „Zwischenspeichern ist nicht möglich. Wenn ich irgendwo anders hinklickt, muss ich wieder von vorne anfangen. Z.B. Neuen Lieferanten muss unbedingt zuerst angelegt werden als Voraussetzung vor Projekt Anlegen.
> Nach Anlegen für neuen Lieferanten, wurde anschließend nicht gezeigt. "
> **Was verbessern?:** „Eine Bedingung hinzufügen: Prüfen, ob ein neuer Lieferant angelegt wurde."

**Gemeint ist:** Drei Teilprobleme in einem Absatz. **(a)** Klick außerhalb des Dialogs → alle Eingaben weg (klassisch: das Modal schließt bei „interact outside", der Formularstate stirbt mit der Komponente). **(b)** Man muss die Projektanlage verlassen, um einen Lieferanten anzulegen — und verliert dabei wegen (a) alles. **(c)** Der neue Lieferant ist danach nicht auswählbar → FB-18 / H3.

**Zum Vorschlag des Melders:** „Eine Bedingung hinzufügen: prüfen, ob ein Lieferant angelegt wurde" behandelt das Symptom. Die Ursache ist der Bruch im Ablauf. Besser, in dieser Reihenfolge:
1. Dialog nicht bei Klick daneben schließen (`onPointerDownOutside` / `onInteractOutside` abfangen) — oder Rückfrage „Eingaben verwerfen?".
2. Lieferant **aus der Projektanlage heraus** anlegen (Unterdialog), danach automatisch ausgewählt zurückkehren.
3. Entwurf halten (Formularstate, ggf. Dexie) — nur wenn 1 und 2 nicht reichen. Nicht mit dem Teuersten anfangen.

**Prüfen:** Welche Dialog-Komponente, wo lebt der State, gibt es schon einen Entwurfsmechanismus im Repo? Ist Lieferant bei der Projektanlage Pflicht?
**Fertig, wenn:** Klick daneben verliert nichts · Lieferant inline anlegbar und danach vorausgewählt · Test für beides.

#### FB-16 — „Zeitraum bei KW – Erstbesuch" + Terminkonfliktprüfung · Nr. 16
`Nr. 16` Klockenhoff · Projekt Anlegen · **P4 · Klasse C (Teil 1) / B (Teil 2)**

> **Beobachtung:** „Zeitraum bei KW - erscheint Erstbesuch entfernen"
> **Was verbessern?:** „kann er auf meinen Kalender zugreifen, ob ggf. andere Termine einen gewünschten Termin blockiert?"

**Teil 1 ist nicht eindeutig.** Mögliche Lesarten: (i) Bei Eingabe des Zeitraums als KW erscheint zusätzlich „Erstbesuch" — das soll weg. (ii) Im KW-Zeitraum wird fälschlich ein „Erstbesuch" angezeigt. (iii) Eine Notiz an sich selbst. **Nicht raten (G7).** Aber vorher selbst nachsehen: `rg -i "erstbesuch"` — gibt es in der Projektanlage nur ein Vorkommen, klärt sich die Frage vielleicht am Code (dann N2, Klasse A). Sonst Rückfrage → Anhang C.

**Teil 2 — Konfliktprüfung.** Zwei völlig verschiedene Dinge:
**(a) Gegen den SupplierPulse-Kalender:** sinnvoll, machbar, **Klasse A**. Beim Anlegen prüfen, ob im Zeitraum bereits Einsätze der beteiligten Personen liegen, und **warnen, nicht blockieren** — Doppelbelegung kann gewollt sein.
**(b) Gegen Outlook/Exchange:** externe Schnittstelle **und** personenbezogene Kalenderdaten → **Klasse B**, und §5.6/H5 mitdenken. Nicht anfangen zu bauen.
**Fertig, wenn:** Rückfrage zu Teil 1 gestellt · Teil 2a umgesetzt inkl. Test · Teil 2b in der Entscheidungsvorlage.

#### FB-23 — Kommunikationssprache nicht auswählbar · deckt Nr. 23, 56
`Nr. 23` Klockenhoff · Kommunikation | `Nr. 56` Kurzmiller · Projektanlage · **P1 · Klasse A · H1**

> **Nr. 23 — Beobachtung:** „Sprache nicht hinterlegt"
> **Nr. 56 — Beobachtung:** „Feld Komunikation Sprache nicht auswählbar."

**Gemeint ist:** Das Feld existiert, aber es gibt nichts auszuwählen. Zwei Melder → H1, gleiche Prüfung wie FB-02.

**Der Punkt, den du hier nicht übersehen darfst:** Die **Kommunikationssprache mit dem Lieferanten** ist nicht die **UI-Sprache** der App (DE/EN/ZH). Wenn im Code beides dieselbe Liste ist, ist genau das der eigentliche Fehler: Ein ungarischer oder mexikanischer Ansprechpartner spricht HU oder ES, ohne dass die App das je können muss. Prüfen, ob die Listen getrennt sind.

**Wenn bestätigt:** Sprachliste als Stammdaten (ISO 639-1) mit sinnvoller Auswahl für die MO-23-Standorte (DE, EN, ZH, ES, HU, RO, PL, FR, CS, PT, TR …), Vorbelegung DE/EN. Pflicht/optional dem bestehenden Formular entsprechend, nicht neu erfinden.
**Fertig, wenn:** Auswahl gefüllt · Trennung UI-/Kommunikationssprache belegt · Test.

#### FB-54 — Projekt „ZDSC Campus" fehlt in der Auswahl · Nr. 54
`Nr. 54` Kurzmiller · Projekt Anlegen · PC · **P2 · Klasse A/B · H6**

> **Beobachtung:** „Projekt ZDSC Campus fehlt bei der Auflistung."
> **Was verbessern?:** „Auswahl erweitern / aktualisieren"

**Gemeint ist:** In einer Auswahlliste bei der Projektanlage fehlt ein Eintrag. **Zuerst zu klären: welche Liste überhaupt?** „Projekt" ist in SupplierPulse zweideutig — die eigenen Projekte (Format `2026_061`) oder eine übergeordnete BMW-Liste (Baureihe, Standort, Werk). Der Melder spricht von „aktualisieren", meint also eine gepflegte Auswahl.

**Prüfen:** Liste finden. Kommt sie aus einer Tabelle → Eintrag fehlt (Stammdatenpflege, Klasse A, **Wert von Kais bestätigen lassen** — G7, du weißt nicht, was „ZDSC Campus" korrekt heißt). Kommt sie aus einem TS-Array/Enum → §5.7/H6: der Modellfehler ist der eigentliche Befund, Klasse B.
**Fertig, wenn:** Eintrag vorhanden (Wert bestätigt) **und** eine klare Aussage im Bericht, ob die Liste ohne Deploy pflegbar ist.

#### FB-59 — Lieferantenwechsel im Projekt schlägt nicht auf den Kalender durch · Nr. 59
`Nr. 59` Hagen · Kalender · **P1 · Klasse A oder B — siehe unten**

> **Beobachtung:** „Nach Änderung des Lieferanten in der Projektanalge wird im Kalender nach wie vor der bei der Erstellung des Projekts angegebene Lieferant angezeigt"
> **Was verbessern?:** „Fehler korrigieren / synchronisieren"

**Gemeint ist:** Der Kalendereintrag zeigt weiter den alten Lieferanten. Naheliegende Ursache: Der Lieferant wurde beim Anlegen des Einsatzes **kopiert** (denormalisiert), statt über das Projekt gelesen zu werden.

**Hier liegt die eigentliche Prüfarbeit — und ein Fall, in dem „Fehler korrigieren" falsch sein kann:** Ist die Kopie **Absicht oder Versehen**? Es gibt einen guten Grund für Denormalisierung: Ein vergangener Einsatz soll historisch zeigen, bei welchem Lieferanten man tatsächlich war, auch wenn das Projekt später umgehängt wird. Wer das „synchronisiert", fälscht rückwirkend die Historie.
**Entscheidungsregel:** Zeigt der Kalender den **geplanten aktuellen Zustand** → Lieferant aus dem Projekt ableiten (Join/View), Kopie weg → **Klasse A**. Braucht das System eine **historische Wahrheit** → Kopie behalten, beim Ändern des Projekt-Lieferanten aber explizit fragen („3 offene Einsätze mitziehen?") und vergangene Einsätze unberührt lassen → **Klasse B**.
Anhaltspunkte für „Absicht": Kommentar im Code, Spaltenname wie `supplier_snapshot`, Historientabelle, Verwendung in Reports.
**Fertig, wenn:** eine der beiden Varianten belegt umgesetzt ist · Test „Projekt-Lieferant ändern → Kalender zeigt das erwartete Verhalten" · Begründung der Wahl im Prüfprotokoll.

### E3 · Kalender und Einsatzplanung

#### FB-04 — Schalter „Dienstreise (Reisezeit erforderlich)" ohne erkennbare Funktion · Nr. 4
`Nr. 4` Dickens · Kalender, Einsatz Bearbeiten · PC · **P3 · Klasse B · Screenshot: Anhang D**

> **Beobachtung:** „Button "Dienstreise (Reisezeit erforderlich""
> **Was verbessern?:** „Für was ist das gedacht? Es gibt keine weitere Eingabemöglichkeit."

**Gemeint ist:** Im Dialog „Einsatz bearbeiten" gibt es einen Schalter „Dienstreise (Reisezeit erforderlich)" — aber nirgends ein Feld, um eine Reisezeit einzutragen. Der Melder versteht nicht, wozu der Schalter da ist.

**Prüfen:** **(1)** Was macht das Flag heute? Wird es gespeichert, und wird es **irgendwo gelesen** — Report, Export, Berechnung, Filter? (`rg` auf den Feldnamen). Wenn nirgends gelesen: toter Schalter. **(2)** §5.6/H5: Wäre „Reisezeit" eine personenbezogene Zeitangabe? Falls ja, gehört dieser Punkt in dieselbe Klammer wie Nr. 36 — dann heißt die Antwort **nicht** „Eingabefeld ergänzen".

**Drei mögliche Ausgänge:** (a) Flag ohne Wirkung → aus der UI nehmen (G2: nur UI/Flag, keine Spalte löschen). (b) Flag wirkt, ist nur unerklärt → Beschriftung + Tooltip, der die Wirkung benennt. (c) Feature war halbfertig gedacht → Kais entscheidet, ob es fertig gebaut oder verworfen wird — **und ob es überhaupt gebaut werden darf**.
**Fertig, wenn:** Die Wirkung des Flags ist mit Datei:Zeile und allen Lesestellen belegt, und eine der drei Optionen steht begründet in der Entscheidungsvorlage.

#### FB-05 — Bearbeiten-Dialog belegt nur den ersten Tag vor · Nr. 5 · **Datenverlust-Verdacht**
`Nr. 5` Dickens · Kalender, Einsatz Bearbeiten · PC · **P1 · Klasse A · Screenshot: Anhang D**

> **Beobachtung:** „Einsatz Bearbeiten wird nur der erste Tag vom System ausgewählt"
> **Was verbessern?:** „Komplette Einsatzdauer default mässig auswählen"

**Gemeint ist:** Öffnet man einen mehrtägigen Einsatz zum Bearbeiten, ist nur der Starttag vorausgewählt statt des vollen Zeitraums.

**Warum das P1 ist und nicht P3 — das ist der Kern dieser Karte:** Wenn der Dialog beim Speichern den vorbelegten Zustand zurückschreibt, wird aus einem Einsatz Mo–Fr **stillschweigend ein Einsatz Mo**. Jemand korrigiert einen Tippfehler in der Beschreibung und verliert vier Tage Planung, ohne es zu merken. **Genau das ist der erste Test: mehrtägigen Einsatz öffnen → nichts ändern → speichern → Datensatz vorher/nachher vergleichen.** Schrumpft der Zeitraum, ist es ein Datenverlustfehler (P1 bleibt). Schrumpft er nicht, ist es Bedienärger (P3, dann Prio in §6.2 korrigieren und begründen).

**Prüfen:** Formular-Initialisierung — wird nur `start_date` in den State gelesen und `end_date` ignoriert? Der Screenshot zeigt eine Tagesleiste, in der Tage einzeln markiert werden; vermutlich wird dieses Array beim Öffnen nicht aus dem Zeitraum aufgebaut.
**Wenn bestätigt:** Zeitraum vollständig vorbelegen (Start bis Ende, inklusive Markierung aller Tage in der Leiste).
**Fertig, wenn:** Regressionstest „mehrtägigen Einsatz öffnen, ohne Änderung speichern → Start und Ende unverändert" **und** „Zeitraum ist beim Öffnen vollständig markiert". Falls Datenverlust bestätigt: an Kais melden, damit geprüft werden kann, ob in Prod bereits Einsätze verkürzt wurden.

#### FB-06 — Einsatz lässt sich weder löschen noch überschreiben · Nr. 6
`Nr. 6` Dickens · Kalender, Einsatz Bearbeiten · PC · **P1 · Klasse A · H2-B · `/investigate` Pflicht**

> **Beobachtung:** „Einsatz Löschen funktioniert nicht."
> **Was verbessern?:** „Einsatz kann weder Überschrieben noch gelöscht werden."

**Gemeint ist:** Weder Ändern noch Löschen wirkt. Der Melder berichtet **keine Fehlermeldung** — und das ist der entscheidende Hinweis.

**Prüfen — zuerst §5.3/H2-B:** Fehlt die UPDATE-/DELETE-Policy, antwortet PostgREST mit **Erfolg und null betroffenen Zeilen**. Die UI meldet „gespeichert", passiert ist nichts. Das ist die wahrscheinlichste Ursache und deshalb der erste Test, nicht der letzte. `/investigate` ist hier Pflicht.
Erst danach: Handler verdrahtet? Bestätigungsdialog schließt, ohne zu senden? Optimistisches UI blendet die Zeile aus, und der Reload holt sie zurück?

**Wenn RLS:** passende UPDATE- **und** DELETE-Policy (`using` **und** `with check` bei UPDATE), Tests „eigener Tenant darf / fremder Tenant darf nicht". Niemals `using (true)` (G1). `/cso` vor dem PR.
**Unabhängig von der Ursache:** Der lautlose Fehlschlag muss sichtbar werden — `.select()` nach `update`/`delete`, Trefferzahl prüfen, Fehler anzeigen. Das betrifft die ganze App → als `NEU-xx` aufnehmen, hier **nicht** mitfixen (G10).
**Fertig, wenn:** Löschen und Ändern funktionieren · RLS-Test grün · `/cso` durch · der 0-Zeilen-Fall erzeugt eine sichtbare Fehlermeldung.

#### FB-07 — Monatsansicht ab Bildschirmmitte abgeschnitten · Nr. 7
`Nr. 7` Dickens · Kaleder, Monats-Button · PC · **P2 · Klasse A**

> **Beobachtung:** „Monat wird nicht komlett angezeigt, ab Bildschirm-Mitte"
> **Was verbessern?:** „Ganzen Monat sichtbar machen"

**Gemeint ist:** In der Monatsansicht ist der Monat nur bis etwa zur Bildschirmmitte sichtbar.

**Prüfen:** Die Reproduktion braucht die richtige Umgebung. **Windows-Notebook, 1920×1080, 125 % Skalierung** ist bei BMW der Normalfall — und genau die Konstellation, in der feste Pixelhöhen kippen. Verdächtig: `overflow-hidden` auf einem Elternelement · feste `height`/`max-h` statt `min-h` · ein Popover/Portal, das am Container geclippt wird · `100vh` zusammen mit Sticky-Header.
**Wenn bestätigt:** Layout korrigieren, nicht das Symptom scrollbar machen.
**Fertig, wenn:** Vollständiger Monat bei 1366×768, 1920×1080 und 125 %/150 % Skalierung · Screenshot im Prüfprotokoll.

#### FB-08 — „Mitarbeiter Verwaltung" führt zur Datenablage · Nr. 8
`Nr. 8` Dickens · Kalender, Mitarbeiter · PC · **P2 · Klasse A**

> **Beobachtung:** „Button "Mitarbeiter Verwaltung" führt zur "Datenablage""
> **Was verbessern?:** „Verknüpfung korrigieren."

**Gemeint ist:** Falsches Ziel hinter dem Button. Der kleinste Punkt im Backlog — und einer der wenigen, die in Minuten Vertrauen zurückbringen.

**Prüfen:** `href`/`router.push`-Ziel. **Zweite Frage, die man leicht überspringt:** Gibt es die Mitarbeiterverwaltung überhaupt? Zeigt der Link ins Leere, weil die Seite nie gebaut wurde, ist „Verknüpfung korrigieren" nicht die Lösung — dann ist es entweder ein toter Button (raus, G2) oder eine fehlende Funktion (Klasse B).
**Nebenprüfung:** Wer darf Mitarbeiter verwalten? Ist der Button für alle sichtbar, gehört das in die RBAC-Betrachtung.
**Fertig, wenn:** Button führt ans richtige Ziel oder ist begründet entfernt · Test auf die Route.

#### FB-09 — Excel-Export liefert immer den aktuellen Monat · Nr. 9
`Nr. 9` Dickens · Kalender, Excelausleitung · PC · **P2 · Klasse A · H7-3**

> **Beobachtung:** „Egal welcher Moat ausgewählt wird ist die Ausleitung in Excel immer der aktuelle Monat"
> **Was verbessern?:** „Ausleitung für angewählten Monat befähigen"

**Gemeint ist:** Der Export ignoriert den in der Ansicht gewählten Monat und nimmt immer den heutigen.

**Prüfen:** Der Export-Handler bildet den Zeitraum vermutlich selbst (`new Date()`), statt den Zustand der Ansicht zu übernehmen — prüfen, ob der gewählte Monat überhaupt bis zur Export-Funktion durchgereicht wird (Client-State vs. Server-Action).
**Nebenverdacht (§5.8/H7-3):** Zeitzone. Wird der Monat aus einem UTC-Datum abgeleitet, kippen der erste und der letzte Tag.
**Wenn bestätigt:** Zeitraum durchreichen · **Dateiname trägt den Zeitraum** (`Einsatzplanung_2026-03.xlsx`) — dann fällt derselbe Fehler beim nächsten Mal sofort auf · Zeitraum zusätzlich in die Kopfzeile des Blatts.
**Fertig, wenn:** Test „März wählen → Export enthält ausschließlich März" · Monatsgrenzen abgedeckt (1. und letzter Tag, 23:30 Ortszeit).

#### FB-10 — Drucken funktioniert nicht · Nr. 10
`Nr. 10` Dickens · Kaleder, Drucken · PC · **P4 · Klasse B**

> **Beobachtung:** „Funktioniert nicht"
> **Was verbessern?:** „Wenn benötigt gleich Querformat als Default setzen"

**Gemeint ist:** Die Druckfunktion tut nichts. Der Melder stellt selbst infrage, ob sie gebraucht wird („**wenn** benötigt").

**Prüfen:** Gibt es überhaupt eine Druckfunktion oder nur einen Button? Existiert Print-CSS?
**Die eigentliche Frage ist nicht technisch:** Wenn es Excel- und PDF-Export gibt — braucht der Kalender dann einen eigenen Druck? **O1:** Button entfernen (UI, G2), auf PDF verweisen — billig und ehrlich. **O2:** Print-Stylesheet bauen: `@media print` + `@page { size: A4 landscape; margin: 10mm; }`, Navigation und Buttons ausblenden, Seitenumbrüche an Wochengrenzen.
Nicht bauen, bevor Kais gesagt hat, dass gedruckt wird — aber einen kaputten Button stehen zu lassen ist auch keine Option.
**Fertig, wenn:** Entscheidung eingeholt und umgesetzt.

#### FB-14 — Urlaub verlangt ein Projekt · Begriff „Reise" · Kategorienmodell · deckt Nr. 14, 55
`Nr. 14` Ping · Kalender, Einsatz Bearbeiten · PC | `Nr. 55` Kurzmiller · Kalender, Einsatzplanung · **Teil a: P1 · Klasse A** — **Teil b: P4 · Klasse B**

> **Nr. 14 — Beobachtung:** „1. Bei der Eintragung 'Urlaub' oder 'Freizeit' muss noch 'Projekt' ausfüllen.
> 2.Einsatz Anlegen: Was heisst Reise? Unterwegs in DR wie z.B. Autofahren? Flug? "
> **Nr. 14 — Was verbessern?:** „1.‚Projekt' soll bei der Eintragung von Urlaub kein Pflichtfeld sein.
> 2.Im VSM IT‑Plattform wird „Persönliche Abwesenheit" als übergeordnete Kategorie verwendet, inkl. Urlaub, Zeitabbau, HO."
> **Nr. 55 — Beobachtung:** „Bei Auftragsart Urlaub, muss immer ein Projekt ausgewählt werden (Pflichtfeld)"
> **Nr. 55 — Was verbessern?:** „Bei bestimmten Auftragsarten Projekt kein Pflichtfeld"

**Teil a — Pflichtfeld (P1, Klasse A).** Zwei Melder unabhängig. Wer Urlaub einträgt, muss ein Projekt angeben, das es fachlich nicht gibt. Die Folge ist nicht Ärger, sondern **Datenmüll**: Anwender wählen irgendein Projekt, und jede Projektauswertung wird still falsch. Deshalb P1. Nebenbei erklärt das womöglich auch den Wunsch nach einem „Dummy-Lieferanten" (FB-03).
*Umsetzung:* Pflichtfelder je Terminart bedingt machen (z. B. Zod-`discriminatedUnion` über die Terminart), Projektbezug nur bei projektbezogenen Arten. **Welche Arten einen Projektbezug brauchen, ist eine fachliche Liste, keine Programmiererentscheidung** → Vorschlag an Kais, technische Umsetzung ist A.
*Bestandsdaten:* Existieren bereits Urlaube mit Fantasie-Projekt → zählen und melden, **nicht ändern** (G2).

**Teil b — Kategorienmodell (P4, Klasse B).** Ping schlägt „Persönliche Abwesenheit" als Oberkategorie vor, wie in der VSM-IT-Plattform, **inkl. HO**.
> **Achtung, echter Konflikt:** Genau dieses „inkl. HO" ist das, was Löffler in Nr. 36 unter Berufung auf die Betriebsvereinbarung Mobilarbeit **entfernt** haben will. **Nicht beides umsetzen. Nicht selbst schlichten** (G13, H5). → Entscheidungsvorlage, gemeinsam mit FB-36 und FB-37 als **ein** Paket „Terminarten und Kategorien".

**Teil c — Begriff „Reise".** Ping versteht nicht, was „Reise" bedeutet (Anreise? Fahrzeit? Flug?). Zusammen mit FB-04 (Dienstreise-Schalter) und FB-37 (Auftragsart vs. Terminart) ergibt sich dasselbe Bild: **die Terminarten sind nirgends definiert.**
*Vorschlag:* **eine** Definitionsliste — Terminart → Bedeutung → Projektbezug ja/nein → zählt als Einsatztag ja/nein — von Kais bestätigt; Beschriftungen und Tooltips werden daraus abgeleitet. Diese eine Liste löst FB-04, FB-14b, FB-37 und FB-38 gemeinsam.
**Fertig, wenn:** Teil a umgesetzt + Test · Teile b/c als Paket in der Entscheidungsvorlage.

#### FB-25 — Kalenderwoche anzeigen · Nr. 25
`Nr. 25` Klockenhoff · Einsatz anlegen · **P3 · Klasse A · H7-1**

> **Beobachtung:** „KW?"
> **Was verbessern?:** „Könnte man bei der Kalenderdarstellung die KW anzeigen lassen ?"

**Gemeint ist:** In der Kalenderdarstellung soll die Kalenderwoche zu sehen sein. In der Lieferantenplanung wird in KW gesprochen, nicht in Datumsspannen — billig und offensichtlich sinnvoll.

**Prüfen:** Wird die KW woanders bereits angezeigt? Der Screenshot in Anhang D zeigt im Bearbeiten-Dialog eine Zeitraumzeile im Format „KW 26 · 22.06.2026 – 26.06.2026". Dann existiert die Formatierung schon → **wiederverwenden statt neu bauen** — und dabei prüfen, ob sie **ISO-korrekt** rechnet (§5.8/H7-1). Wenn nicht, ist genau das der eigentliche Fund.
**Fertig, wenn:** KW in Monats- und Wochenansicht sichtbar · Test inkl. Jahreswechsel (29.12.2025–04.01.2026 → KW 1) und 31.12.2026.

#### FB-26 — Personenauswahl läuft über Vornamen · Nr. 26
`Nr. 26` Klockenhoff · Einsatz anlegen · **P3 · Klasse A**

> **Beobachtung:** „Namensauswahl auf Vornamen - wieso?"
> **Was verbessern?:** „durchgängige Auswahlmethode oder beide zur Anwendung bringen"

**Gemeint ist:** Personen werden über den Vornamen ausgewählt/sortiert, was im BMW-Kontext ungewohnt ist und bei gleichen Vornamen mehrdeutig wird. **Der Kern des Einwands ist „durchgängig"** — Uneinheitlichkeit stört mehr als die Wahl selbst.

**Prüfen:** Wie werden Personen heute dargestellt, sortiert und gesucht — und ist das an **allen** Stellen gleich? Erst alle Fundstellen suchen, dann anfassen.
**Vorschlag:** Anzeige „Nachname, Vorname" (+ Kurzzeichen, falls FB-21 kommt) · Sortierung nach Nachname · Suche über **beide** Namensteile und das Kurzzeichen · eine gemeinsame Komponente für alle Personenauswahlen.
**Fertig, wenn:** einheitliche Darstellung/Suche in allen Personenfeldern · Test.

#### FB-37 — „Auftragsart" ist der falsche Name · Nr. 37
`Nr. 37` Löffler · Kalender, Einsatz anlegen · **P3 · Klasse A (UI) / B (Datenmodell)**

> **Beobachtung:** „Die Kategorisierung der >Terminarten< wird als >Auftragsart< benannt "
> **Was verbessern?:** „>Terminarten< sollen so heißen und nicht >Auftragsart<"
> **Beispiel / Referenz:** „Schulung, Urlaub, Reise, Feiertag, Freizeit sind keine Auftragsarten"

**Gemeint ist:** Das Feld heißt „Auftragsart", enthält aber Werte, die keine Aufträge sind. Der Einwand ist fachlich richtig: Urlaub ist kein Auftrag — und solange das Feld so heißt, wird jede Auswertung über „Aufträge" falsch gelesen.

**Prüfen:** Alle Fundstellen — UI-Labels, i18n-Keys **in allen drei Sprachen (DE/EN/ZH)**, Exporte, Reports, PDF/PPT, Spaltennamen, Enum-Werte, API-Felder. Der Punkt ist billig in der UI und teuer, wenn man das Datenmodell mitzieht.
**Zweistufig umsetzen:** **(1) Klasse A:** Beschriftungen und i18n ändern — sofort, risikolos, aber vollständig (auch in Exporten, sonst steht in der Excel weiter „Auftragsart"). **(2) Klasse B:** Umbenennung im Datenmodell (Spalte/Enum) nur mit Kais, additiv migriert, und nur wenn es mehr bringt als Kosmetik.
**Achtung:** Wenn FB-14b (Kategorienmodell) kommt, ändert sich hier ohnehin mehr → **zusammen entscheiden**, sonst wird zweimal umbenannt.
**Fertig, wenn:** UI und i18n durchgängig „Terminart", auch in Exporten · DB-Frage in der Vorlage.

#### FB-38 — Feiertag wird als Werktag mitgezählt · Nr. 38
`Nr. 38` Löffler · Kalender, Einsatz anlegen · **P2 · Klasse A (a, b) / B (Regionalisierung) · H7-2**

> **Beobachtung:** „Feiertage werden zwar im Kalender angezeigt, aber wenn ein Einsatz davor beginnt und danach endet, dann wird der Tag mitgezählt, selbst wenn man bei >nur Werktage< einen Haken macht."
> **Was verbessern?:** „Die >Einsatztage< nicht als >Einsätze< bezeichnen und Feiertage nicht als Werktage zählen"
> **Beispiel / Referenz:** „02.06. bis 05.06.2026 (Pfingsmontag)"

**Gemeint sind drei Dinge:**
**(a) Zählfehler:** Der Haken „nur Werktage" wirkt offenbar nur auf die **Ränder** des Zeitraums, nicht auf die Tage **dazwischen**. Ein Einsatz Di–Fr über einen Feiertag zählt vier statt drei Tage.
**(b) Beschriftung:** Die Anzeige nennt Einsatz**tage** „Einsätze". Vier Tage bei einem Lieferanten sind **ein** Einsatz, nicht vier — das verfälscht jede Zählung, die auf „Einsätze" schaut (und damit auch Reporting-Kennzahlen).
**(c) Der Beleg des Melders stimmt nicht — und das ist die interessante Spur:** Im genannten Zeitraum **02.06.–05.06.2026 liegt kein Pfingstmontag** (der war am **25.05.2026**). Es liegt **Fronleichnam, Donnerstag 04.06.2026** — Feiertag u. a. in Bayern und Hessen, **nicht bundesweit**. Entweder hat Löffler den Feiertag verwechselt (dann nur (a) und (b) fixen) **oder die App beschriftet den Feiertag falsch** (dann ist die Feiertagsquelle selbst defekt — ein größerer Fehler als der gemeldete). **Erst klären, dann fixen.**

**Prüfen:** Feiertagsquelle finden — Bibliothek, Tabelle oder hartkodierte Liste? Dann §5.8/H7-2: Ist Land/Bundesland überhaupt modelliert? SupplierPulse plant Einsätze in Mexiko, Ungarn, Rumänien, Marokko, China. Ein Kalender „DE" ist dort fachlich falsch — und in Berlin ist Fronleichnam kein Feiertag.
**Umsetzung:** (a) und (b) → Klasse A mit Tests. Regionalisierung → Klasse B (Datenmodell + Stammdaten), aber **mit Nachdruck vorschlagen**: ohne sie ist die Werktagszählung für **jeden** Auslandseinsatz falsch.
**Fertig, wenn:** Test „02.06.–05.06.2026, nur Werktage, Standort Bayern → 3 Tage" · Beschriftung „Einsatztage" · Befund zur Feiertagsquelle im Bericht.

#### FB-39 — Termine lassen sich nicht bearbeiten · Nr. 39
`Nr. 39` Löffler · Kalender, Einsatzplanung · **P2 · Klasse A**

> **Beobachtung:** „Termine lassen sich nicht bearbeiten (scheint über rechte Maustaste geplant zu sein)"

**Gemeint ist:** Der Melder findet keinen Weg zu bearbeiten und vermutet die rechte Maustaste. Zwei Möglichkeiten, die auseinanderzuhalten sind: **(i)** Bearbeiten ist technisch defekt (→ dieselbe Ursache wie FB-06 / H2-B?) oder **(ii)** es geht, aber niemand findet es.

**Prüfen:** Erst (i) ausschließen — wenn es dieselbe Ursache wie FB-06 ist, zusammen fixen und im Bericht verknüpfen. Dann (ii): Wie ist Bearbeiten heute erreichbar?
**Zur Bedienung:** Ein Kontextmenü als **einziger** Weg ist aus zwei Gründen unzureichend: Es ist nicht auffindbar, und auf Touch-Geräten gibt es keine rechte Maustaste. SupplierPulse ist eine PWA mit Offline-Fähigkeit — sie wird im Werk auf dem Tablet benutzt. **Getestet wurde hier ausschließlich auf dem PC.**
**Umsetzung:** Linksklick/Tap öffnet Detail oder Bearbeiten · Kontextmenü darf als Abkürzung bleiben · sichtbare Aktion (Stift-Icon).
**Fertig, wenn:** Bearbeiten ohne Kontextmenü erreichbar · auf Touch geprüft · Test.

#### FB-58 — Neu angelegtes Projekt fehlt in der Kalenderauswahl · Nr. 58
`Nr. 58` Kurzmiller · Kalender, Einsatz anlegen · **P1 · Klasse A · H3**

> **Beobachtung:** „Neu angelegtes Projekt (2026_061) im Kalenderauswahl nicht vorhanden (bei Änderung)
> bei Neuanlage übernimmt er das Projekt nicht"

**Gemeint sind zwei Beobachtungen:** **(a)** Beim **Ändern** eines Einsatzes fehlt das frisch angelegte Projekt `2026_061` in der Auswahl. **(b)** Beim **Neuanlegen** wird das Projekt „nicht übernommen" — vermutlich aus dem Kontext vorausgewählt, aber nicht gesetzt, oder beim Speichern verworfen.

**Prüfen:** (a) ist H3 — **erst in der Datenbank nachsehen**, ob `2026_061` mit korrekter `tenant_id` existiert, bevor der Cache verdächtigt wird. Existiert das Projekt und die Auswahl zeigt es trotzdem nicht: **Filtert die Auswahl?** Nach Status („nur aktive"), nach Zeitraum, nach Zuordnung des Nutzers? Ein Filter, der frisch angelegte Projekte ausschließt, ist plausibel — und eine ganz andere Ursache als der Cache.
(b) separat reproduzieren: kann derselbe Fehler sein oder ein zweiter.
**Fertig, wenn:** beide Teile einzeln belegt und behoben · Test „Projekt anlegen → sofort im Einsatzdialog wählbar".

### E4 · Compliance und Personenbezug — **P0, vor allem anderen**

> Für alle drei Karten gilt §5.6/H5 und **G13**: Du bewertest die Rechtslage nicht, du legst sie nicht aus, du suchst keine Gegenargumente. Du behandelst den Einspruch als das, was er ist — ein begründeter Einwand eines Kollegen, der die Regel kennt. Dein Beitrag ist **die vollständige Fundstellenliste**, damit Kais auf Fakten entscheidet statt auf Erinnerung.

#### FB-36 — Arbeitsort „Vor Ort / Homeoffice / Remote" · deckt Nr. 36, 24
`Nr. 36` Löffler · Kalender, Einsatz anlegen | `Nr. 24` Klockenhoff · Einsatzplanung · **P0 · Klasse B · Screenshot: Anhang D**

> **Nr. 36 — Beobachtung:** „Es lässt sich beim Arbeitsort angeben "Vor Ort / Homeoffice / Remote"."
> **Nr. 36 — Was verbessern?:** „Die Auswahl des Arbeitsortes komplett aus dem System entfernen, auch wenn es das bei Interligent bereits gab"
> **Nr. 36 — Beispiel / Referenz:** „In der Protokollnotiz 3 vom 17.10.2024 zur BMW Betriebsvereinbarung "Mobilarbeit" vom 23.10.2013 wurde geregelt, dass außerhalb der systemgeführten Zeitwirtschaft keine personenbezogenen Daten zu Anwesenheiten und Mobilarbeitszeiten erfasst werden dürfen.
> https://hr-portal.bmwgroup.net/documents/2496840/8061953/BV309_PN3_Gemeinsames+Verst%C3%A4ndnis_zur+BV+Mobilarbeit_17.10.2024.pdf/98494e03-af02-cd69-e70f-15be5ae8532b"
> **Nr. 24 — Beobachtung:** „Homeoffice ?  ist gewollt?"
> **Nr. 24 — Was verbessern?:** „siehe Nr. 36"

**Gemeint ist:** Beim Anlegen/Bearbeiten eines Einsatzes lässt sich der Arbeitsort angeben. Löffler will das Feld vollständig entfernt und begründet das mit der Protokollnotiz 3 zur BV Mobilarbeit. Klockenhoff stellt unabhängig davon dieselbe Frage. **Zwei Melder, einer davon mit Quellenangabe** — der Screenshot zu Nr. 4/5 zeigt das Feld übrigens ebenfalls.

**Was du jetzt tust — Bestandsaufnahme, vollständig:**
1. **Alle Fundstellen des Arbeitsorts:** UI-Komponenten, Formularfelder, Zod-Schemas, DB-Spalten, Migrationen, Indizes, API-Routen, Filter, Reports/Charts, Exporte (Excel/PDF/PPT), i18n-Keys DE/EN/ZH, Seeds/Fixtures, Dexie-Offline-Schema. **Lückenlos** — ein vergessener Export macht die ganze Maßnahme wertlos.
2. **Datenbestand zählen:** Wie viele Datensätze tragen heute einen Arbeitsort ≠ „Vor Ort", seit wann? **Nur zählen, nichts ändern** (G2, G5).
3. **Abhängigkeiten:** Hängt eine Auswertung daran (z. B. FB-41)? Verknüpfen.
4. **Zusammenhang zu FB-04** (Reisezeit) prüfen — womöglich dieselbe Klammer.

**Was du darfst:** UI-Zugang per Feature-Flag deaktivieren, damit **nichts Neues** erfasst wird. Reversibel, sofort wirksam, kein Datenverlust.
**Was du nicht tust:** Spalte oder Daten löschen (G2) · eine „anonymisierte Variante" bauen · das Feld still auf „Vor Ort" vorbelegen — das erfasst weiter, nur unsichtbar, und ist die schlechteste aller Varianten.
**Konflikt:** FB-14b will HO als Kategorie **einführen**. Nicht beides. Ein Paket, eine Entscheidung.
**Zum Link:** internes BMW-Portal, für dich nicht abrufbar (G13). Nicht versuchen, nicht bewerten, als Beleg des Melders zitieren.
**Fertig, wenn:** Fundstellenliste + Datenzählung + drei bewertete Optionen liegen Kais vor; Feature-Flag umgesetzt, sobald Kais das freigibt.

#### FB-41 — Reporting: „Berater-Auslastung (letzte 90 Tage)" · Nr. 41
`Nr. 41` Löffler · Reporting Übersicht · **P0 · Klasse B · H5**

> **Beobachtung:** „Berater-Auslastung (letzte 90 Tage)"
> **Was verbessern?:** „Entfernen"
> **Beispiel / Referenz:** „MA-Auslastungsanalysen sind bei BMW verboten"

**Gemeint ist:** Das Reporting zeigt eine Auslastungsauswertung pro Berater über 90 Tage. Löffler sagt, solche Analysen seien bei BMW verboten, und will sie weg.

**Warum das der dringlichste Punkt der 60 ist:** Von allen Feedbacks ist dieser derjenige, der am schnellsten aus einem Produktthema ein anderes macht. Eine personenbezogene Auslastungsauswertung, die in der falschen Demo auftaucht, diskutiert niemand mehr als Feature. **P0, sofort auf den Tisch, keine Diskussion über Aufwand.**

**Was du tust:** Fundstellen (Chart, Query, API, Export) auflisten · beantworten, **ob die Auswertung personenbezogen ist**: Namen? Kurzzeichen? Und vor allem — ist sie bei kleinen Gruppen auf Einzelpersonen rückrechenbar? · UI-Flag aus · Vorlage.
**Achtung, naheliegende Falle:** Eine „aggregierte" oder „anonymisierte" Variante ist **keine Lösung, die du entscheidest**. Bei Teamgrößen in dieser Größenordnung ist Aggregation oft trivial rückrechenbar. Wenn Kais eine Alternative will, ist das ein eigener, bewusst entschiedener Punkt — nicht ein Nebenprodukt deines Fixes.
**Fertig, wenn:** Fundstellen + Analyse des Personenbezugs + Flag + Vorlage.

#### FB-45 — Reporting: „Besuchstage pro Monat" · Nr. 45
`Nr. 45` Löffler · Reporting: Auftragsform & Einsätze · **P0 (bis geklärt) · Klasse B**

> **Beobachtung:** „Unklar ist, was "Besuchstage pro Monat" sein könnte, evtl. Einsatztage mit 24h am Lieferantenstandort ohne Anreise/Rückreise?"
> **Was verbessern?:** „Entfernen"
> **Beispiel / Referenz:** „MA-Auslastungsanalysen sind bei BMW verboten"

**Gemeint sind zwei Einwände:** **(a)** Die Kennzahl ist nicht definiert — niemand weiß, was gezählt wird. **(b)** Sie könnte eine Auslastungsauswertung sein.

**Prüfen:** Was zählt die Kennzahl tatsächlich (Query lesen)? **Wonach gruppiert sie** — Person, Projekt oder Lieferant? Davon hängt alles Weitere ab:
- **Personenbezogen** → gleiche Behandlung wie FB-41: P0, Flag aus, Vorlage.
- **Projekt-/lieferantenbezogen** → kein H5-Fall, sondern ein Definitionsproblem: Kennzahl klar benennen und im Tooltip definieren („Einsatztage am Lieferantenstandort, ohne An- und Abreise") — oder entfernen, wenn sie niemand braucht. Dann Prio auf P3 korrigieren und begründen.

**Der eigentliche Fund, unabhängig von der Compliance-Frage:** Der Melder **rät** („evtl. …"). Eine Kennzahl, deren Bedeutung ein erfahrener Anwender erraten muss, ist kaputt — egal, wie richtig sie rechnet.
**Fertig, wenn:** Definition am Code belegt · Gruppierung beantwortet · Behandlung entsprechend, Prio ggf. korrigiert.

### E5 · Reporting und Ausleitung
#### FB-11 — PowerPoint-Export defekt, PDF-Report ohne Grafiken · Nr. 11
`Nr. 11` Dickens · Reporting · PC · **P2 · Klasse B**

> **Beobachtung:** „Ausleitung in PowerPoint geht nicht, Ausleitung in PDF ohne Grafiken??"
> **Was verbessern?:** „Nach meiner Erfahrung müssen Grafiken im Report sein!"

**Gemeint ist:** Zwei Fehler in einem Punkt. **(a)** Der PPT-Export läuft auf einen Fehler — welchen, sagt der Melder nicht, also im Log nachsehen. **(b)** Der PDF-Report enthält keine Diagramme, nur Text und Tabellen. Dickens' Einwand ist fachlich, nicht ästhetisch: Ein Fabrikanalyse- oder OEE-Report ohne Grafik ist beim Lieferanten wertlos.

**Prüfen:** Wie werden die Reports erzeugt (serverseitig? Headless-Browser? Bibliothek?) und wo bleiben die Charts? Häufigste Ursache: Die Diagramme werden **clientseitig** gerendert (z. B. als SVG im Browser); der serverseitige Report-Bau kennt sie nicht und lässt den Platz leer.
**Lösungswege, nach Aufwand:** gerendertes SVG mitschicken und einbetten · Charts serverseitig rendern · Headless-Browser für die Report-Seite. Welcher passt, hängt an der bestehenden Architektur — **erst schauen, dann vorschlagen.**
**Hinweis:** Kais hat bereits ein PowerPoint-Skill für BMW-Decks. Vor einem Neubau prüfen, ob der Export daran andocken kann, statt eine zweite Erzeugungslogik aufzubauen.
**Fertig, wenn:** PPT-Export läuft fehlerfrei (Test) · PDF enthält die Diagramme (Sichtprüfung + Test auf Anzahl eingebetteter Objekte) · Vorgehen begründet.
#### FB-12 — Formatierungsfehler im PDF-Report bei OEE „Linie-Werk" · Nr. 12
`Nr. 12` Dickens · Reporting · PC · **P2 · Klasse C → A**

> **Beobachtung:** „Formatierungsfehler im PDF-Report, siehe OEE bei Linie-Werk"

**Gemeint ist:** Im PDF-Report ist bei der OEE-Darstellung „Linie-Werk" etwas verrutscht. Was genau — abgeschnittener Text, Umbruch, Überlappung — sagt der Melder nicht.

**Prüfen — erst selbst reproduzieren, bevor du fragst:** Report mit Testdaten erzeugen, in denen Werks- und Liniennamen **lang** sind (z. B. „Hirschmann Automotive Oujda – Linie 3 Vormontage"). Lange Labels sind der mit Abstand häufigste Grund für genau dieses Bild. Reproduzierbar → Klasse A, fixen.
`NICHT REPRODUZIERBAR` vergibst du erst nach einem echten Versuch mit realistischen Daten — dann Rückfrage an Dickens mit konkreter Bitte (betroffenes PDF oder Screenshot, Projekt und Datum) → Anhang C. Keine Spekulation, kein „vermutlich schon behoben".
**Fertig, wenn:** Fehler belegt und behoben — oder Rückfrage gestellt, Status `WARTET AUF MELDER`.

#### FB-19 — KPI-Board DE/international: keine Auswahl, und wozu überhaupt? · Nr. 19
`Nr. 19` Klockenhoff · KPI-Board DE / international · **P4 · Klasse B · H1**

> **Beobachtung:** „keine Auswahlmöglichkeit - warum überhaupt?"
> **Was verbessern?:** „entfallen lassen"

**Gemeint sind zwei Fragen in einer:** **(a)** Die Auswahl DE/international ist leer (H1). **(b)** Wozu gibt es die Unterscheidung überhaupt?

**Prüfen — mit (b) anfangen, nicht mit (a):** Was macht der Umschalter? Filtert er Projekte nach Region? Zeigt er andere Kennzahlen? Tut er nichts → toter Schalter, raus (UI, G2). Tut er etwas → dann ist die leere Auswahl ein H1-Fall, und „warum überhaupt" beantwortet sich über die Funktion.
**Wichtig:** „entfallen lassen" ist der Vorschlag **eines** Melders, der nicht wusste, was der Schalter tut. Wenn die Unterscheidung fachlich begründet ist — MO-23 arbeitet deutschlandweit **und** international, möglicherweise mit anderen Kennzahlensätzen — wäre Entfernen falsch. Klasse B.
**Fertig, wenn:** Funktion des Umschalters belegt · Vorlage mit drei Optionen (entfernen / reparieren / erklären).

#### FB-40 — „Projekte mit CT > Kundentakt" bei „Bottlenecks über Takt" · Nr. 40
`Nr. 40` Löffler · Reporting Übersicht · **P4 · Klasse B**

> **Beobachtung:** „Anzahl der >Projekte mit CT > Kundentakt< bei "Bottlenecks über Takt" macht keinen Sinn"
> **Was verbessern?:** „Entfernen"
> **Beispiel / Referenz:** „Wenn der Lieferant ein anderes Arbeitszeitmodell hat als der Kunde (mehr Schichten pro Tag oder mehr Tage pro Woche), dann ist immer CT>Kundentakt."

**Gemeint ist:** Der Einwand ist fachlich stark und trifft zu. Zykluszeit gegen Kundentakt zu vergleichen ist nur zulässig, wenn beide auf dieselbe Betriebszeit bezogen sind. Fährt der Lieferant drei Schichten und wird der Kundentakt auf BMW-Betriebszeit gerechnet, ist CT > Takt praktisch immer erfüllt. **Ein Bottleneck-Indikator, der immer anschlägt, ist schlimmer als keiner** — er trainiert das Team, ihn zu ignorieren.

**Aber „Entfernen" ist nur eine von zwei Antworten.** Die methodisch saubere Alternative: nicht Zeiten vergleichen, sondern **Mengen** — Kapazität (Stück/Woche bei der tatsächlichen Betriebszeit des Lieferanten) gegen Bedarf (Stück/Woche). Gleiche Aussage, ohne den Denkfehler, und es ist die Kennzahl, die MO-23 ohnehin braucht.
**Prüfen:** Wie ist die Kennzahl heute berechnet (Formel/Query)? Wird die Betriebszeit des Lieferanten überhaupt irgendwo erfasst — Schichtmodell, siehe FB-27? **Wenn ja, ist die Alternative rechenbar. Wenn nein, ist sie es nicht** — dann ist Entfernen tatsächlich die ehrlichere Wahl, und das ist ein Argument, kein Rückzug.
**Fertig, wenn:** Berechnung belegt · beide Optionen bewertet · Abhängigkeit zu FB-27 benannt · in der Vorlage.

#### FB-42 — Status „Fabrikanalyse-Entwurf" im Kreisdiagramm · Nr. 42
`Nr. 42` Löffler · Fabrikanalyse-Übersicht · **P3 · Klasse A (Labels) / B (Statussatz)**

> **Beobachtung:** „Bei dem Kreisdiagramm mt der Status-Verteilung gibt es einen "Fabrikanalyse-Entwurf""
> **Was verbessern?:** „Falls "Projektvorbereitung" gemeint ist, dies so nennen, ansonsten löschen"

**Gemeint ist:** Im Status-Kreisdiagramm taucht ein Status auf, den der Melder im MO-23-Prozess nicht kennt.

**Prüfen:** Welche Status gibt es (Enum/Tabelle), wie werden sie gesetzt, welcher Prozessschritt ist gemeint? **Die entscheidende Unterscheidung:** Ist „Entwurf" ein **technischer Zustand** (angelegt, noch nicht abgeschickt) oder eine **Prozessphase**?
**Warum das kein Trivialfall ist:** Bedeutet „Entwurf" technisch etwas anderes als „Projektvorbereitung", darf man ihn **nicht** einfach umbenennen — dann steht ein Prozessbegriff für einen technischen Zustand im Diagramm, und das ist irreführender als der unbekannte Name. Erst klären, dann beschriften.
**Umsetzung:** Statusbezeichnungen an die MO-23-Prozessbegriffe angleichen (Labels = A; Änderung des Statussatzes = B). Den korrekten Begriff von Kais bestätigen lassen (G7).
**Fertig, wenn:** Statusliste belegt · Beschriftung deckt sich mit dem Prozess, oder Frage in der Vorlage.

#### FB-43 — Diagramme „Projekte nach Standort" und „Projekte nach Abteilung" · deckt Nr. 43, 44
`Nr. 43` Löffler · Reporting: Abteilung & Standort | `Nr. 44` Löffler · Reporting: Projekte nach Abteilung · **P4 · Klasse B**

> **Nr. 43 — Beobachtung:** „Das Diagramm "Projekte nach Standort" wird mit Realdaten nicht mehr lesbar sein"
> **Nr. 43 — Was verbessern?:** „Entfernen"
> **Nr. 44 — Beobachtung:** „Das Diagramm "Projekte nach Abteilung" wird mit Realdaten nicht mehr lesbar sein"
> **Nr. 44 — Was verbessern?:** „Entfernen"

**Gemeint ist:** Zweimal dieselbe Kritik für zwei Dimensionen. Der Einwand ist berechtigt und vorausschauend: Mit Testdaten (fünf Standorte) sieht das Diagramm gut aus; mit Realdaten (dutzende Standorte, viele Abteilungen) wird es unlesbar. **Der Melder denkt über die Demo hinaus — das ist die wertvollste Sorte Feedback und verdient mehr als ein „ok, gelöscht".**

**Die richtige Frage ist nicht „behalten oder löschen", sondern: Welche Frage soll das Diagramm beantworten?** Stellt sie niemand → weg. Stellt sie jemand → richtige Darstellung: Top-N + „Sonstige" · horizontale Balken statt Kreis · Sortierung · Filter · Drilldown · oder schlicht eine sortierbare Tabelle statt eines Charts.
**Prüfen:** Wie viele verschiedene Standorte und Abteilungen sind realistisch zu erwarten? Im Testtenant steht das nicht — **also Kais fragen statt schätzen** (G7).
**Fertig, wenn:** je Diagramm die Kernfrage benannt (oder festgestellt, dass es keine gibt) · Optionen in der Vorlage.

#### FB-46 — Reporting: OEE-Übersicht mischt Lieferanten, Werke und Linien · Nr. 46
`Nr. 46` Löffler · Reporting: OEE-Übersicht · **P4 · Klasse B · Scope**

> **Beobachtung:** „Eine bunte Mischung von Lieferanten, deren Werke und einzelner Produktionslinien"
> **Was verbessern?:** „Entfernen"
> **Beispiel / Referenz:** „Soll dies das neue MARS-System werden, bitte auf die eigene Arbeit fokusieren"

**Gemeint sind zwei Ebenen:** **(a) Handwerklich:** Die Übersicht mischt Hierarchieebenen (Lieferant / Werk / Linie) in einer Darstellung — unbrauchbar, weil Unvergleichbares nebeneinander steht. **(b) Strategisch:** Löffler fragt, ob SupplierPulse hier ein anderes BMW-System nachbaut, und mahnt Fokus an.

**Trenne die beiden sauber, das ist hier deine Hauptleistung.** (b) ist eine Produktfrage, die Wissen braucht, das du nicht hast (was das andere System abdeckt, was der EA-Scope hergibt) → Kais. (a) kannst du konkret vorbereiten: Hierarchie modellieren, Drilldown Lieferant → Werk → Linie statt Mischung, Filter auf die eigenen Projekte.
**Für die Vorlage wichtig:** OEE ist ein **Kernmodul** von SupplierPulse. „Entfernen" hieße, ein zentrales Modul aus dem Reporting zu nehmen — das ist keine Kleinigkeit und braucht Kais' ausdrückliche Entscheidung. Notiere ausdrücklich, dass der Melder hier nicht das Modul, sondern die **Darstellung** kritisiert — beides zu verwechseln wäre der teuerste Fehler in diesem Backlog.
**Fertig, wenn:** Vorlage mit (a) konkretem Verbesserungsvorschlag und (b) der Scope-Frage, klar getrennt.

#### FB-47 — Reporting: Kapazität (Installiert vs. Eingekauft vs. Ist) · Nr. 47
`Nr. 47` Löffler · Reporting: Kapazität · **P4 · Klasse B**

> **Beobachtung:** „Wir wissen nicht was von BMW eingekauft wurde und auch nicht, was durch spätere Programmvorschauen vom Lieferant akzeptiert wurde"
> **Was verbessern?:** „Entfernen"
> **Beispiel / Referenz:** „Soll dies das neue MARS-System werden, bitte auf die eigene Arbeit fokusieren"

**Gemeint ist:** Kein Geschmacksurteil, sondern ein **Datenverfügbarkeitsproblem**: MO-23 hat die eingekaufte Menge nicht und weiß nicht, welche Programmvorschau der Lieferant akzeptiert hat. Eine Auswertung, die eine Größe zeigt, die niemand kennt, zeigt entweder Platzhalter oder Erfundenes.

**Prüfen:** Woher kommt „Eingekauft" heute — ein Feld, das jemand tippt? Ein Default? Leer? **Wenn das Feld existiert und leer bleibt, zeigt das Diagramm eine Lücke, die aussieht wie ein Befund** — das ist gefährlicher als gar kein Diagramm, weil es im Lieferantengespräch als Aussage gelesen wird.
**Optionen für die Vorlage:** (a) Serie „Eingekauft" raus, Rest behalten (Installiert vs. Ist vs. Bedarf laut Lieferantenangabe) — die nützliche Aussage bleibt · (b) ganzes Diagramm raus · (c) Serie bleibt, aber ausdrücklich als „vom Lieferanten angegeben" gekennzeichnet, mit sichtbarem „keine Daten" statt Null.
**Fertig, wenn:** Datenherkunft je Serie belegt · Optionen bewertet · in der Vorlage.

### E6 · OEE-Analyse

> **Zwei Dinge vorab, sonst gehen diese neun Punkte schief:**
> **(1) §5.1 lesen** — bei Nr. 27–35 sind die Spalten verrutscht. Die Zitate unten tragen deshalb die Spaltenangabe.
> **(2) Diese Punkte sind überwiegend *methodisch*, nicht technisch.** Sie legen fest, **wie SupplierPulse OEE rechnet** — das ist eine MO-23-Methodenentscheidung, keine Programmierentscheidung, und Gruber ist erkennbar derjenige im Team, der die Materie beherrscht. **Dein Beitrag ist hier nicht Code, sondern eine präzise Dokumentation des Ist-Zustands** (welche Felder, welche Einheiten, welche Formeln), damit Kais und Gruber auf einer Faktenbasis entscheiden können. Wer hier ohne diese Grundlage umbaut, ändert stillschweigend die Kennzahlen aller bisherigen Fabrikanalysen.

#### FB-27 — Zeitmodell: Bezugsgröße Schicht statt Tag · deckt Nr. 27, 28, 31
`Nr. 27, 28, 31` Gruber · OEE Analyze · **P4 · Klasse B**

> **Nr. 27 —** (Spalte D) „2. Zeitbasis" · (Spalte E) „von STD/ TAG auf STD/SCHICHT wechseln"
> **Nr. 28 —** (Spalte D) „3. Leistung" · (Spalte E) „Produzierte Menge ohne Zeitangabe" · (Spalte F) „definieren Produzierte Menge pro Schicht oder Woche, etc."
> **Nr. 31 —** (Spalte D) „2. Zeitbasis" · (Spalte E) „Geplante Pausen" · (Spalte F) „Auf schicht oder Woche beziehen. Aber exakt"

**Gemeint ist:** Drei Punkte, ein Problem. Die OEE-Maske mischt Bezugsgrößen — Zeiten in Std/Tag, Mengen ohne Bezug, Pausen unklar worauf bezogen. Grubers Forderung ist einheitlich: **eine** Bezugsgröße, und zwar die Schicht. „Aber exakt" ist dabei kein Nebensatz, sondern der Kern.

**Warum er recht hat:** Werden Zeiten pro Tag und Mengen pro Woche eingegeben, sind Verfügbarkeit, Leistung und Qualität nicht mehr auf denselben Nenner bezogen. Das Ergebnis sieht plausibel aus **und ist falsch** — die gefährlichste Fehlerart in einem Werkzeug, dessen Zahlen im Lieferantengespräch landen.

**Dein Hauptbeitrag — Ist-Dokumentation:** Für **jedes** Eingabefeld der OEE-Maske: Name · Einheit · Bezugsgröße · wo es in die Formel eingeht. Dazu die drei Kennzahlenformeln aus dem Code ableiten. Ergebnis: eine Tabelle **„Feld → Einheit → Bezug → verwendet in"**. Darin sieht man in einer Minute, wo der Bruch ist — und Gruber kann in fünf Minuten entscheiden, statt zu vermuten.
**Umsetzung (erst nach Entscheidung):** eine Bezugsgröße festlegen — Vorschlag: **Schicht**, mit „Schichten/Tag" und „Tage/Woche" als eigene Felder; alles andere ist daraus ableitbar. Alle Felder darauf beziehen, **Einheit im Label sichtbar** („min/Schicht", „Stück/Schicht").
**Achtung Bestandsdaten:** Bestehende OEE-Datensätze wurden nach dem alten Modell erfasst. Eine Umstellung braucht eine Migrationsentscheidung — umrechnen (mit welchem Faktor?), als „altes Modell" kennzeichnen oder verwerfen. Das ist kein Nebenprodukt, das ist der eigentliche Aufwand.
**Bezug:** FB-40 braucht dasselbe Schichtmodell → zusammen entscheiden.
**Fertig, wenn:** Ist-Dokumentation liegt vor · Vorschlag + Migrationsfrage in der Vorlage.

#### FB-29 — Qualität: Nacharbeit und „Gutmenge" · Nr. 29
`Nr. 29` Gruber · OEE Analyze · **P4 · Klasse B**

> (Spalte D) „4. Qualität" · (Spalte E) „Nacharbeit" · (Spalte F) „aus der Produzierter Menge, aus den Ausschuss, wird die Gutmenge durch Nacharbeit höher?" · (Spalte G, Kopfzeile „Gerät") „Gutmenge umbenenen auf First Part Yield"

**Gemeint ist:** Gruber fragt, ob nachgearbeitete Teile in SupplierPulse die Gutmenge **erhöhen** — und schlägt vor, „Gutmenge" umzubenennen. Dahinter steht die klassische OEE-Konvention: Für die Qualitätsrate zählt nur, was **im ersten Durchlauf** in Ordnung war. Nacharbeit ist ein Verlust, kein Gutteil — sonst versteckt die Kennzahl genau das Problem, das sie zeigen soll.

**Prüfen:** Wie rechnet der Code heute? Existiert überhaupt ein Feld „Nacharbeit"? Geht es in die Gutmenge ein? Das ist eine **Ja/Nein-Frage, die man am Code beantwortet** — und die Antwort entscheidet, ob hier ein Rechenfehler vorliegt (dann ist es dringender als P4) oder nur ein Benennungsproblem.
**Vorschlag:** „Produzierte Menge", „Ausschuss", „Nacharbeit" getrennt erfassen · Qualitätsrate = (Produzierte Menge − Ausschuss − Nacharbeit) / Produzierte Menge · Formel im Tooltip zeigen.
**Zur Benennung, und das bitte ehrlich ansprechen:** Der übliche Fachbegriff ist **First Pass Yield (FPY)**; Gruber schreibt „First Part Yield". Vorschlag: „Gutmenge im ersten Durchlauf (First Pass Yield)" — **mit Gruber kurz abstimmen, statt ihn stillschweigend zu korrigieren.**
**Fertig, wenn:** Ist-Rechnung belegt (Ja/Nein: erhöht Nacharbeit die Gutmenge?) · Vorschlag inkl. Benennung in der Vorlage.

#### FB-30 — Wartungszeit und Schichtwechsel-Stillstand · Nr. 30
`Nr. 30` Gruber · OEE Analyze · **P4 · Klasse B**

> (Spalte D) „2. Zeitbasis" · (Spalte E) „Wartungszeit ist Teil den gaplanten Pausen." · (Spalte F) „Wartungszeit nicht separat aufnehmen. Stattdesen hinzu den Stillstand für den Schicht Change aufnehmen"

**Gemeint ist:** Wartung findet in den geplanten Pausen statt, braucht also kein eigenes Feld — dafür fehlt eines für den Stillstand beim Schichtwechsel.

**Das ist eine Konventionsfrage, keine Bugfrage.** Wie Wartung in der OEE verbucht wird — als geplante Stillstandszeit, die die Planbelegzeit reduziert, oder als Verfügbarkeitsverlust — ist je nach Konvention unterschiedlich, und **beide Wege sind vertretbar**. Wer hier ohne Rücksprache umbaut, ändert die Kennzahl **aller** Fabrikanalysen rückwirkend.
**Prüfen und dokumentieren:** Wie verbucht der Code die Wartungszeit heute — reduziert sie die Planbelegzeit oder zählt sie als Verlust? Existiert der Schichtwechsel-Stillstand irgendwo?

> **Die wichtigste Erkenntnis aus Grubers neun Punkten — bitte so an Kais weitergeben:** FB-27, FB-29, FB-30 und FB-34 sind **einzeln nicht sinnvoll entscheidbar**. Sie hängen alle an derselben fehlenden Grundlage: **einer verbindlichen OEE-Konvention für MO-23** — ein Dokument, eine Seite, welche Zeitart wohin zählt und auf welche Bezugsgröße. Mit dieser Festlegung fallen vier Karten zusammen und die Maske ist daraus ableitbar. Ohne sie wird jede einzelne Änderung geraten. **Das ist der Vorschlag, der hier zählt.**

**Fertig, wenn:** Ist-Verbuchung dokumentiert · Vorschlag „OEE-Konvention MO-23" in der Vorlage.

#### FB-32 — Pflichtfelder kennzeichnen · Nr. 32
`Nr. 32` Gruber · OEE Analyze, allgemein · **P3 · Klasse A**

> (Spalte D) „allgemein" · (Spalte E) „Pflichtfelder mit einen *"

**Gemeint ist:** In der OEE-Maske ist nicht erkennbar, welche Felder Pflicht sind. Einfach, richtig, sofort machbar.
**Umsetzung:** `*` am Label · `aria-required` · Fehlermeldung **am Feld**, nicht nur als Toast · Legende „* Pflichtfeld".
**Der Punkt, den man hier verschenkt:** Erst prüfen, ob es eine gemeinsame Formularkomponente gibt, und dort ansetzen. Sonst hat man die Kennzeichnung in einer Maske und in den anderen zwanzig nicht — und Gruber meldet in drei Monaten dasselbe für die Fabrikanalyse.
**Fertig, wenn:** Pflichtfelder gekennzeichnet · Aussage im Bericht, ob es app-weit greift · Test.

#### FB-33 — Zahlenfeld: Leeren hinterlässt „0", Pfeiltasten wirkungslos · Nr. 33
`Nr. 33` Gruber · OEE Analyze, allgemein · **P2 · Klasse A**

> (Spalte D) „allgemein" · (Spalte E) „Beim löschen des Inhaltes bleibt immer die 0, muss mit der Maus klicken, weil der Pfeil auf der Tastatur nicht reagiert "

**Gemeint sind zwei Bedienfehler:** Leert man ein Zahlenfeld, steht sofort wieder „0" darin; und die Pfeiltasten wirken nicht, man muss zur Maus greifen.

**Warum das P2 ist und nicht P3:** **0 und „leer" sind fachlich nicht dasselbe.** „0 Ausschuss" ist eine Aussage, „nicht erhoben" ist keine. Macht das Feld leere Eingaben zu 0, **erfindet die Maske Daten** — und die OEE rechnet damit weiter. Das ist kein Komfortthema.
**Prüfen:** Kontrolliertes Input mit `value={x ?? 0}` → der leere String wird sofort zu 0. Pfeiltasten: `type="text"` statt `number`, ein `onKeyDown` mit `preventDefault`, oder eine eigene Stepper-Komponente, die die Tasten nicht behandelt.
**Umsetzung:** Leerzustand als eigenen Zustand zulassen (String-State, Parsen bei Blur/Submit) · `null` speichern statt 0 · Pfeiltasten (↑/↓, mit Shift größere Schritte).
**Und der eigentliche Hebel:** Das Problem betrifft mit hoher Wahrscheinlichkeit **alle** Zahlenfelder der App, nicht nur OEE. Gemeinsame Komponente suchen; gibt es eine → dort fixen und alle Masken prüfen. Gibt es keine → das ist selbst ein Fund (`NEU-xx`).
**Fertig, wenn:** Feld lässt sich leeren und bleibt leer · leer wird als `null` gespeichert · Pfeiltasten funktionieren · Test · Aussage zur app-weiten Verbreitung.

#### FB-34 — „Optimale Zykluszeit" vs. „Optimale Taktzeit" · Nr. 34
`Nr. 34` Gruber · OEE Analyze · **P3 · Klasse A (B, falls ein Feld entfällt)**

> (Spalte D) „2. Zeitbasis" · (Spalte E) „Optimale Zyklus Zeit vs. Optimale Taktzeit" · (Spalte F) „verstehe ich nicht was es macht"

**Gemeint ist:** Zwei Felder mit fast identischen Namen, deren Unterschied selbst dem OEE-Fachmann nicht klar ist. **Wenn Gruber es nicht versteht, versteht es niemand im Team.** Das ist ein ernstes Signal, kein Detail — und ein Feld, das man nicht versteht, füllt man falsch aus.

**Fachlich sind es zwei verschiedene Dinge:** Die **ideale Zykluszeit** ist eine Eigenschaft der Anlage (Sekunden je Teil im Bestfall) und geht in die **Leistungsrate** ein. Der **Kundentakt** ist eine Eigenschaft der Nachfrage (verfügbare Zeit ÷ Bedarf) und dient dem **Kapazitätsvergleich**. Sie gehören weder in dieselbe Feldgruppe noch unter fast denselben Namen.
**Prüfen:** Was macht der Code mit **jedem** der beiden Felder? **Wird eines gar nicht verwendet?** Ein Feld, das nichts tut, wird nicht umbenannt, sondern entfernt (dann Klasse B).
**Umsetzung:** eindeutige Namen + Einheit + Tooltip mit der Formel („Ideale Zykluszeit (s/Teil) — Bestwert der Anlage, geht in die Leistungsrate ein" · „Kundentakt (s/Teil) — verfügbare Zeit ÷ Kundenbedarf") · räumlich trennen.
**Bezug:** FB-40 und FB-27 — zusammen betrachten.
**Fertig, wenn:** Verwendung beider Felder belegt · Benennung und Tooltips klar · ungenutztes Feld in der Vorlage.

#### FB-35 — Keine Plausibilisierung der Eingaben · Nr. 35
`Nr. 35` Gruber · OEE Analyze, allgemein · **P2 · Klasse A**

> (Spalte D) „allgemein" · (Spalte E) „Beim logische Fehler kommt keine Fehler Meldeng, das schlechte Input daten. Beispiel: Die Schichtzeit ist kleiner als die Pausen, etc. Das System sagt nicht das es bullshit ist"

**Gemeint ist:** Die Maske akzeptiert logisch unmögliche Eingaben widerspruchslos — sein Beispiel: Pausen länger als die Schicht. Ergebnis: eine OEE, die gerechnet, exportiert und dem Lieferanten gezeigt wird, obwohl die Eingabe unmöglich war.

**Warum das Grubers wichtigster technischer Punkt ist:** SupplierPulse-Ergebnisse gehen in Lieferantengespräche. **Eine falsch gerechnete OEE, die niemand bemerkt, kostet mehr als eine Maske, die zickt.**

**Umsetzung — feldübergreifende Regeln (z. B. Zod `superRefine`). Startmenge, mit Gruber abzustimmen:**
- Summe der Pausen < Schichtzeit
- Laufzeit ≤ Planbelegzeit ≤ Schichtzeit
- Ausschuss + Nacharbeit ≤ produzierte Menge
- ideale Zykluszeit > 0 · produzierte Menge × ideale Zykluszeit ≤ Laufzeit (sonst wurde schneller produziert als physikalisch möglich)
- Verfügbarkeit, Leistung, Qualität jeweils > 0 % und ≤ 100 %
- **Warnung statt Blockade** bei ungewöhnlichen, aber möglichen Werten (z. B. OEE > 95 %)

**Der Unterschied zwischen „unmöglich" (Fehler, blockiert) und „unwahrscheinlich" (Hinweis, blockiert nicht) ist hier die ganze Kunst** — wer alles blockiert, sperrt echte Sonderfälle aus und die Anwender tragen die Zahlen wieder in Excel ein.
Fehler **am Feld** anzeigen, nicht als anonymer Toast, und die verletzte Regel im Klartext nennen.
**Fertig, wenn:** Regelsatz umgesetzt · je Regel ein Test (positiv und negativ) · Regelliste über Kais mit Gruber abgestimmt.

### E7 · Auftragseingang, Projektnotizen und Datenablage

> **Drei der vier Karten hier tragen dieselbe Fehlermeldung** (`project_notes`). **§5.3/H2 lesen, bevor du eine davon anfasst** — und §5.0: Ein Melder hat die Meldung mit hoher Wahrscheinlichkeit dreimal kopiert. **Ermittle die betroffene Tabelle je Fall selbst.** Wer der Meldung glaubt, repariert dreimal dieselbe Policy und wundert sich, dass zwei Fehler bleiben.

#### FB-13 — Einreichungs-Links: `gen_random_bytes(integer) does not exist` · Nr. 13
`Nr. 13` Dickens · Auftragseingang · PC · **P1 · Klasse A · H4 · `/cso` Pflicht**

> **Beobachtung:** „Link Erzeugung "Einreichungs-Links" bring Fehlermeldung "Fehler: function gen_random_bytes(integer) does not exist""

**Gemeint ist:** Die Erzeugung von Einreichungs-Links bricht mit einem Postgres-Fehler ab. Die Funktion ist damit komplett unbenutzbar — nicht „unschön", sondern tot.

**Prüfen und umsetzen:** §5.5/H4 vollständig lesen — dort stehen die Ursachen, drei Optionen und die Sicherheitsanforderungen an den Token.
**Zusatzprüfung, die über den gemeldeten Punkt hinausgeht:** Wenn diese Funktion noch nie gelaufen ist, ist der **gesamte Einreichungs-Link-Pfad ungetestet**. Prüfen, ob Ablauf, Widerruf und Berechtigungsprüfung des Links überhaupt existieren. Fund → **G12: an Kais, nicht in die PR-Beschreibung.**
**Fertig, wenn:** Link-Erzeugung läuft · Test dafür · Token-Anforderungen aus §5.5 erfüllt oder als Fund gemeldet · `/cso` durch.

#### FB-48 — Projektnotizen lassen sich nicht speichern · Nr. 48
`Nr. 48` Löffler · Projektnotizen · **P1 · Klasse A · H2-A · `/investigate` zuerst, `/cso` Pflicht**

> **Beobachtung:** „Lassen sich nicht speichern"
> **Was verbessern?:** „Fehler korrigieren"
> **Beispiel / Referenz:** „Fehlermeldung "new row violates row-level security policy for table "project_notes""

**Gemeint ist:** Projektnotizen lassen sich nicht anlegen; Postgres weist den INSERT wegen RLS ab.

**Von den drei Meldungen mit diesem Fehlertext ist das die eine, bei der Tabelle und Funktion zusammenpassen** — Projektnotizen → `project_notes`. Behandle sie deshalb als **Leitfall**: Wenn du hier die Ursache verstanden hast, weißt du auch, wonach du bei FB-49 und FB-51 suchst. Reihenfolge: **erst 48, dann 49/51.**

**Prüfen (§5.3/H2-A, Ablauf dort steht vollständig):**
1. `/investigate` — Pflicht (G8, gstack-Regel für RLS-Bugs).
2. Alle Policies der Tabelle listen:
   ```sql
   select policyname, cmd, roles, qual, with_check
   from pg_policies where tablename = 'project_notes';
   ```
3. **Die entscheidende Stelle ist `with_check` der INSERT-Policy.** Typische Ursachen: `with_check` fehlt ganz (dann ist jeder INSERT verboten) · die Policy erwartet eine `tenant_id`, die das Frontend nicht mitschickt · sie prüft gegen `auth.uid()`, die Zeile trägt aber eine andere Autoren-Spalte · die Spalte wird per Default gefüllt, der Default greift aber **nach** der Policy-Prüfung nicht so, wie gedacht.
4. Prüfen, welche Felder das Frontend beim Insert tatsächlich sendet (Netzwerk-Tab / Supabase-Client-Aufruf) — **gegen die Policy halten**. Der Fehler sitzt in ~80 % der Fälle in dieser Differenz, nicht in der Policy selbst.

**Umsetzung:** **Nie die Policy aufweichen (G1).** Wenn das Frontend eine Pflichtspalte nicht liefert → Frontend korrigieren. Wenn die Policy eine Bedingung prüft, die fachlich falsch ist → Policy **präzisieren**, nicht öffnen, und `/cso` drüber.
**Achtung:** Diese Karte liegt mitten im laufenden RLS-Rollout (PRs #13–#22). **Zuerst prüfen, ob der Fehler dort schon behoben ist** (G-Zeitachse, §1) — sonst baust du gegen einen bereits gemergten Fix.
**Fertig, wenn:** Ursache benannt (nicht „RLS halt") · Notiz lässt sich anlegen · **Test, der die Policy *positiv und negativ* prüft** (eigener Tenant darf, fremder Tenant darf nicht — sonst hast du die Isolation kaputt gemacht und es fällt niemandem auf) · `/cso` durch.

#### FB-50 — Datenablage: Lieferant zweimal auswählen · Nr. 50
`Nr. 50` Löffler · Datenablage · **P2 · Klasse A**

> **Beobachtung:** „Ineffizienter Ablauf, weil man zuerst einen Lief. Auswählt, dann das Dokument klassifiziert und am Schluss soll man das Dokument mit einem Lief. Verknüpfen"
> **Was verbessern?:** „Nur einmal das Dokument einem Lieferanten zuordnen"

**Gemeint ist:** Der Ablauf fragt den Lieferanten zweimal — einmal am Anfang, einmal am Ende. Der Vorschlag ist offensichtlich richtig: **einmal reicht.**

**Trotzdem erst prüfen, was die beiden Schritte technisch tun** — und das ist hier keine Formalie. Möglich ist: **(a)** Der erste Schritt ist nur ein **Navigationsfilter** („in welchem Lieferantenordner bin ich"), der zweite die **fachliche Zuordnung** (welchem Lieferanten *gehört* das Dokument). Dann sind es zwei verschiedene Dinge mit demselben Namen — und die beiden zusammenzuwerfen wäre falsch, richtig wäre, den zweiten Schritt **vorzubelegen** und als bestätigbar zu zeigen. **(b)** Es ist wirklich zweimal dasselbe → zweiter Schritt raus.
**Erst diese Frage beantworten, dann bauen.** Sie entscheidet zwischen „Feld entfernen" und „Feld vorbelegen", und nur eine der beiden Antworten ist richtig.
**Umsetzung (Fall b):** Auswahl aus Schritt 1 durchreichen, Zuordnung am Ende nur noch anzeigen · bei Abweichung änderbar lassen (Dokumente werden manchmal im falschen Ordner hochgeladen).
**Bonus, der nichts kostet:** Wenn du ohnehin im Upload-Pfad bist — prüfe, ob nach dem Upload eine Erfolgsmeldung kommt und ob ein Fehlschlag sichtbar wird (Bezug FB-51).
**Fertig, wenn:** Rolle beider Schritte belegt · Ablauf fragt einmal · Test · `/qa`.

#### FB-51 — Datenablage funktioniert nicht · Nr. 51
`Nr. 51` Löffler · Datenablage · **P1 · Klasse A · H2-A · `/investigate` zuerst, `/cso` Pflicht**

> **Beobachtung:** „Funktioniert nicht"
> **Beispiel / Referenz:** „Fehlermeldung "new row violates row-level security policy for table "project_notes""

**Gemeint ist:** Die Datenablage ist unbenutzbar. Die Beobachtung ist zwei Wörter lang — **das ist keine Nachlässigkeit, sondern ein Befund: Wenn ein erfahrener Anwender nur noch „Funktioniert nicht" schreibt, hat er es mehrfach versucht und aufgegeben.**

**Der Fehlertext ist hier höchstwahrscheinlich falsch** (§5.0): Eine Datenablage schreibt in eine Dokumenten-/Storage-Tabelle, nicht in `project_notes`. **Ermittle die echte Tabelle selbst**, statt der Meldung zu glauben.
**Prüfen — Datenablage hat zwei Ebenen, beide prüfen:**
1. **Storage:** Existiert der Bucket? Wie heißen die Storage-Policies (`storage.objects`)? Storage-RLS ist ein eigener Policy-Satz und wird beim RLS-Rollout gern vergessen — **das ist mein Hauptverdacht.**
2. **Metadaten:** Welche Tabelle nimmt den Datensatz auf? Deren Policies wie in FB-48 prüfen.
3. Reproduzieren und die **echte** Fehlermeldung mitschreiben (N1). Ohne sie rätst du.

**Umsetzung:** wie FB-48 — Ursache beheben, Policy nie aufweichen (G1), `/cso`.
**Und unabhängig von der Ursache:** „Funktioniert nicht" heißt auch, dass der Fehler den Anwender ungefiltert erreicht hat. **Roh durchgereichte Postgres-Meldungen sind kein Fehlerbild** — sie sagen dem Anwender nichts und verraten nach außen die Tabellenstruktur. Fehlt eine saubere Fehlerbehandlung im Upload-Pfad, ist das ein eigener Fund → `NEU-xx`, §8.
**Fertig, wenn:** echte Fehlermeldung dokumentiert · Ursache benannt · Upload läuft · Test (positiv **und** Tenant-negativ) · `/cso` durch.

### E8 · PMO

#### FB-49 — PMO: Teammitglieder lassen sich nicht speichern + „Wollen wir wirklich ein PMO sein?" · Nr. 49
`Nr. 49` Löffler · PMO · **P1 (Fehler) / P4 (Scope) · Klasse A + B · H2-A**

> **Beobachtung:** „Wollen wir wirklich ein PMO sein? Teammitglieder lassen sich nicht speichern."
> **Was verbessern?:** „Fehler korrigieren, ggf. Funktion PMO komplett entfernen"
> **Beispiel / Referenz:** „Fehlermeldung "new row violates row-level security policy for table "project_notes""

**Hier stecken zwei völlig verschiedene Dinge in einer Zeile — und sie dürfen nicht dasselbe Schicksal teilen. Trenne sie strikt:**

**(a) Der Fehler — P1, Klasse A, du allein.**
Teammitglieder lassen sich nicht speichern. **Die genannte Tabelle passt nicht:** Teammitglieder gehören in eine Zuordnungstabelle (`project_members` o. ä.), nicht in `project_notes` — der Melder hat den Fehlertext mit hoher Wahrscheinlichkeit aus Nr. 48 kopiert. **Echte Tabelle selbst ermitteln**, dann wie FB-48 vorgehen.
**Ein zusätzlicher Verdacht, der hier speziell ist:** Bei Zuordnungstabellen (n:m) hängt die Policy oft an einer **Unterabfrage** auf die Elterntabelle („darf dieser Nutzer dieses Projekt bearbeiten?"). Fehlt dem Nutzer die **SELECT**-Berechtigung auf die Elterntabelle, schlägt der INSERT fehl, obwohl die INSERT-Policy korrekt aussieht. **Genau dort zuerst schauen** — dieser Fall kostet sonst einen halben Tag.

**(b) Die Frage — P4, Klasse B, Kais.**
„Wollen wir wirklich ein PMO sein?" ist **keine Bugmeldung, sondern eine Produktfrage** — ob SupplierPulse Projektmanagement-Funktionen führen soll oder sich auf Lieferantenentwicklung beschränkt. Das entscheidet nicht die KI, und es entscheidet auch nicht ein einzelner Melder in einer Excel-Zelle.

> **Und jetzt der Punkt, an dem man diese Karte kaputt macht: Das „ggf." im Vorschlag ist keine Erlaubnis.** Ein Modul zu entfernen, weil ein Melder eine rhetorische Frage gestellt hat, wäre die teuerste Fehlentscheidung dieses Backlogs — irreversibel, mit Datenverlust, auf Basis eines Halbsatzes. **G2 und G10 gelten. Repariere (a). Rühre (b) nicht an.**
> **Reihenfolge ist hier sogar inhaltlich wichtig:** Erst reparieren, dann diskutieren. Über ein Modul, das nicht funktioniert, kann niemand fair urteilen — die Frage „brauchen wir das?" beantwortet man anders, wenn es tut, was es soll. **Diesen Satz bitte so in die Vorlage schreiben.**

**Fertig, wenn:** (a) Teammitglieder lassen sich speichern · Ursache benannt · Test (positiv und Tenant-negativ) · `/cso` durch **und** (b) die Scope-Frage liegt unbeantwortet und unverfälscht in der Entscheidungsvorlage, zusammen mit FB-52 und FB-53 (alle drei betreffen dasselbe Modul → **eine** Entscheidung, nicht drei).

#### FB-52 — PMO: Kundenzufriedenheitsbefragung per E-Mail · Nr. 52
`Nr. 52` Löffler · PMO · **P4 · Klasse B · H5 prüfen**

> **Beobachtung:** „Ich vermisse die Funktion, dass mit dem Tool per E-Mail ein Link mit unserer Kundenzufriedenheitsbefragung zugeschickt wird"
> **Was verbessern?:** „Kundenzufriedenheitsbefragung zum Projektabschluss aufnehmen"

**Gemeint ist:** Zum Projektabschluss soll das Tool automatisch einen Befragungslink per E-Mail verschicken. Ein echter Funktionswunsch, kein Fehler — sinnvoll und anschlussfähig (die Einreichungs-Link-Mechanik aus FB-13 ist genau dieser Baukasten).

> **Bevor irgendetwas gebaut wird — die Frage, die in der Meldung nicht steht und die hier den Ausschlag gibt: Was genau wird bewertet?**
> **Das Projektergebnis** → unkritisch, normale Feature-Entscheidung.
> **Die Arbeit einer namentlich benannten Person** → **das ist eine personenbezogene Leistungsbewertung**, und damit liegt der Punkt bei §5.6/H5, mitbestimmungspflichtig, in derselben Kategorie wie FB-41. Eine Zufriedenheitsbefragung zu einem Projekt, das genau ein Berater betreut hat, **ist** faktisch eine Bewertung dieses Beraters — auch wenn im Fragebogen kein Name steht. **Das ist der Punkt, der übersehen wird, und deshalb steht er hier so deutlich.**
> Solange das nicht geklärt ist, wird **nicht gebaut**. Das kostet fünf Minuten Klärung und spart im Zweifel eine Rückabwicklung.

**Weitere Klärungen für die Vorlage:** Welcher Fragebogen (existiert er schon — z. B. ein bestehendes BMW-Umfragewerkzeug?) · **Empfänger sind vermutlich externe Lieferantenkontakte → Versand personenbezogener Daten nach außen, eigene Prüfung** · Welches Mailsystem darf SupplierPulse überhaupt nutzen? Ein Mailversand aus dem BMW AWS Cloud Room ist eine Architektur- und Freigabefrage, nicht ein `sendMail()` · anonym oder zugeordnet?
**Deine Vorarbeit (nur das, kein Code):** Prüfen, ob es bereits Mailversand in der App gibt (dann ist der Weg da) · prüfen, ob die Token-Mechanik aus FB-13 wiederverwendbar wäre · beides in die Vorlage.
**Fertig, wenn:** H5-Frage klar gestellt · technische Machbarkeit skizziert · in der Vorlage, gebündelt mit FB-49/FB-53.

#### FB-53 — PMO: Projekte filtern und auswerten · Nr. 53
`Nr. 53` Löffler · PMO · **P4 · Klasse B**

> **Beobachtung:** „Ich vermisse die Funktion, laufende und abgeschlossene Projekte mit Filtern auswerten zu können (Name, Jahr, Auftragsart, Projektstatus, etc.)"
> **Was verbessern?:** „Funktion implementieren"

**Gemeint ist:** Eine Projektliste mit Filtern — Name, Jahr, Auftragsart, Status. Nüchtern betrachtet **die nützlichste Anforderung im ganzen Reporting-Block**: Sie ist konkret, sie ist billig, und sie ersetzt vermutlich die Hälfte der Diagramme, die derselbe Melder in FB-43/FB-44/FB-46/FB-47 loswerden will.

> **Das ist der Zusammenhang, den du sichtbar machen sollst — er steht in keiner einzelnen Zeile, ergibt sich aber aus vier Zeilen desselben Melders:** Er will keine bunten Kreisdiagramme, er will **eine filterbare Liste seiner Projekte**. Vier „Entfernen"-Vorschläge und ein „Implementieren"-Vorschlag sind **eine** Aussage. Das gehört in die Entscheidungsvorlage — es macht aus fünf Streitpunkten eine Produktentscheidung.

**Prüfen zuerst:** Gibt es die Liste schon (Projektübersicht) und fehlen nur die Filter? Dann ist es **kein neues Feature, sondern eine kleine Erweiterung** — und die Einstufung P4 wäre zu ändern. **Prüfen, bevor du „neues Feature" in die Vorlage schreibst.**
**Sind die Felder überhaupt da?** „Auftragsart" — siehe FB-37, dort ist die Benennung strittig; „Projektstatus" — siehe FB-42, dort ist der Statussatz strittig. **Filter auf Felder zu bauen, deren Benennung gerade geklärt wird, ist verfrüht.** Erst FB-37 und FB-42 entscheiden, dann filtern.
**Vorschlag für die Vorlage:** Server-seitige Filterung + Sortierung + Excel-Export der gefilterten Liste (der Melder will auswerten, nicht scrollen) · Filterzustand in der URL (teilbar).
**Fertig, wenn:** Ist-Zustand der Projektübersicht belegt · Aufwand grob geschätzt · Abhängigkeit zu FB-37/FB-42 benannt · in der Vorlage.

### E9 · KIFAG

> **Zu beiden Karten vorab:** Die Meldungen sind knapp, mit Tippfehlern, und beide setzen BMW-internes Wissen voraus (KIFAG, MVZ, Kurzzeichen, „Mx"). **Rate nicht** (G7). Beide Karten sind vor allem eine Aufgabe im **sauberen Fragen**, nicht im Programmieren — und sie gehören zusammen, weil sie dieselbe Sache von zwei Seiten beschreiben.

#### FB-20 — KIFAG: Bezeichnung der Fachbereiche statt Kurzzeichen · Nr. 20
`Nr. 20` Klockenhoff · KIFAG · **P3 · Klasse C**

> **Beobachtung:** „wieso erscheint dann die Bezeichnung der Fachbereiche ncht nur ?  Mx reicht doch aus"

**Gemeint ist — Lesart, ausdrücklich als Vermutung gekennzeichnet:** In der KIFAG-Ansicht werden Fachbereiche mit ihrer **ausgeschriebenen Bezeichnung** angezeigt; Klockenhoff findet, das **Kurzzeichen** („Mx", also die BMW-Abteilungskürzel im Stil MO-23) genüge und sei lesbarer.

> **Der Satz ist verstümmelt** („ncht nur ?"), und **die Lesart könnte auch die gegenteilige sein** — dass die Bezeichnung eben *nicht* erscheint und erscheinen soll. **Beide Lesarten sind mit dem Satz vereinbar.** Deshalb: **nichts umbauen, bis geklärt ist, welche gemeint war.** Genau dafür gibt es Klasse C.

**Was du trotzdem tun kannst und sollst — die Rückfrage vorbereiten, statt sie nur zu stellen:** Feststellen, **was heute tatsächlich angezeigt wird** (Feld, Quelle, Datei:Zeile) — mit einem Screenshot des Ist-Zustands. Dann lautet die Frage an Klockenhoff nicht „wie meinen Sie das?", sondern **„Heute steht dort *X*. Sie hätten lieber *Y* — richtig?"** Auf so eine Frage kommt eine Antwort in einer Zeile; auf die andere kommt keine.
**Bezug:** FB-21 — beide betreffen Kurzzeichen in KIFAG. **Zusammen fragen, nicht zweimal.**
**Fertig, wenn:** Ist-Zustand dokumentiert · eine präzise, beantwortbare Rückfrage in Anhang C · Status `WARTET (C)`.

#### FB-21 — KIFAG: Kurzzeichen hinterlegen wie in Kontakten/MVZ · Nr. 21
`Nr. 21` Klockenhoff · KIFAG · **P4 · Klasse B**

> **Beobachtung:** „kann man die Kurzzeichen nicht hinterlgen - wie in Kontakte MVZ hinterlegt "
> **Was verbessern?:** „kann man sicherlich eine KI-Verknüpfung erstellen"

**Gemeint ist:** Kurzzeichen (BMW-Personen-/Abteilungskürzel) sollen in KIFAG hinterlegbar sein — so, wie sie es in „Kontakte" bzw. **MVZ** bereits sind. Der Zusatz „kann man sicherlich eine KI-Verknüpfung erstellen" ist die Vermutung des Melders, wie es gehen könnte — **nicht** die Anforderung. Die Anforderung ist: *Kurzzeichen sollen da sein.*

> **Und deshalb baust du hier keine KI.** Bau das Feld. Ein Textfeld mit Validierung löst diesen Punkt vollständig. Wer aus „sicherlich eine KI-Verknüpfung" ein KI-Feature ableitet, hat den Wunsch des Melders verfehlt und G7 verletzt.

**Zu klären, bevor irgendetwas entschieden wird:**
- **Was ist „MVZ"?** Ohne diese Antwort ist der Punkt nicht bearbeitbar. Rückfrage (G7, Anhang C).
- **Ist MVZ ein BMW-System mit Schnittstelle?** Falls ja: Anbindung = Architektur- und Freigabefrage (Cloud Room, Berechtigungen, Datenschutz) → Kais. **Nicht selbst versuchen, irgendein internes BMW-System anzusprechen** (G13).
- **Ist es nur ein Feld in „Kontakte"?** Dann ist die Antwort das gleiche Feld in KIFAG — klein, Klasse A, sofort machbar.
- **Personenbezug:** Kurzzeichen identifizieren Personen. Wo sie gespeichert werden, gelten dieselben Fragen wie in §5.6/H5 — zumindest kurz gegenprüfen.

**Deine Vorarbeit:** In „Kontakte" nachsehen, **wie** das Kurzzeichen dort umgesetzt ist (Feld? Lookup? Import?) — mit Datei:Zeile. Das beantwortet die halbe Frage aus dem Code heraus, und Kais muss nur noch über den Rest entscheiden.
**Bezug:** FB-20 — zusammen behandeln.
**Fertig, wenn:** Ist-Zustand in „Kontakte" belegt · MVZ-Frage in Anhang C · Optionen (Feld / Anbindung / nichts) in der Vorlage.

---

## 8 · Neue Funde — Register `NEU-xx`

Kais' Auftrag enthält einen Satz, der leicht überlesen wird: **„Falls du neue Punkte findest, nimm sie mit auf."** Das ist keine Nettigkeit. Die 60 Meldungen stammen aus **einem Nachmittag Klicken durch eine Demo**. Was dabei niemand gesehen hat — lautlose Fehler, fehlende Prüfungen, unbenutzte Pfade — findest **du**, weil du im Code bist und die Melder es nicht sind. **Das ist der Teil dieses Auftrags, der über die Excel hinausgeht, und der Teil mit dem höchsten Wert.**

### 8.1 Regeln

1. **Ein Fund ist keine Erlaubnis.** Gefunden → aufschreiben → weiterarbeiten an der Karte, die du gerade hast (G10). Nicht spontan mitfixen. Ein Fund, der die aktuelle Karte kaputt macht, ist trotzdem eine eigene Karte.
2. **Aufnahmekriterium:** falsches Verhalten, Datenverlust, Sicherheits- oder Compliance-Risiko, oder ein Punkt, der **mehrere** Karten gleichzeitig erklärt. Geschmack und Stil gehören nicht hierher. Ein „ich hätte das anders gebaut" ist kein Fund.
3. **Nummerierung** `NEU-01`, `NEU-02`, … · gleiche Kartenstruktur wie in §7 · Status in **§6.2 ergänzen** (die Tabelle bleibt die einzige Statusquelle, §4).
4. **Beleg oder Hypothese** — Evidenzstufe angeben (G8). `NEU` ohne Beleg ist ein Verdacht, kein Fund, und wird auch so bezeichnet.
5. **Sicherheitsfunde nicht hier.** G12: direkt an Kais, nicht in eine öffentliche PR-Beschreibung, nicht in dieses Dokument.
6. **Priorität wie in §4.2** — ein `NEU`-Fund darf P0 oder P1 sein und **darf gemeldete Punkte überholen.** Ein echter Datenverlustfehler ist wichtiger als eine Kalenderwoche in der Kopfzeile, auch wenn ihn niemand gemeldet hat.

### 8.2 Vorbelegt — diese drei sind beim Lesen der Excel bereits aufgefallen

Sie stehen hier als **Verdacht (N3)**, nicht als Befund. Bestätige oder verwirf sie beim ersten Kontakt mit dem jeweiligen Code — und trage das Ergebnis ein.

| ID | Fund | Herkunft | Prio | Status |
|---|---|---|---|---|
| NEU-01 | Lautlose `update`/`delete` ohne Rückmeldung | H2-B, §5.3 · aufgefallen bei FB-06, FB-39 | P1 | **BESTÄTIGT (W0, N2)** — kein zentraler Daten-Layer (API_SPEC.md:3-5); ~234 Schreibpfade: ~12% prüfen Trefferzahl, 0/100 deletes; Vorbild-Muster existiert (qaf-differences KAR-846+, gdpr/deletion.ts, count:'exact' im Seeder). Architekturfrage → Klasse B |
| NEU-02 | Auswahllisten ohne Lade-, Leer- und Fehlerzustand | H1, §5.2 · aufgefallen bei FB-02, FB-19, FB-23 | P2 | **BESTÄTIGT (W0, N2)** — use-master-data.ts:15-46 verwirft error, loading ungenutzt, leeres Ergebnis session-lang gecacht ohne Retry |
| NEU-03 | Zahlenfelder: kein Leerzustand, Tastatur tot | FB-33 · vermutlich app-weit | P2 | OFFEN |
| NEU-04 | Projekt ohne Abteilung ist für Abteilungs-Kollegen unsichtbar: `projects_dept_visible` verlangt `department_id IS NOT NULL`, Formularfeld optional + unvalidiert (new-project-form.tsx:858-868) | W0/H3 · Kandidat-Erklärung für „Kollege sieht Projekt nicht" | P1 | BESTÄTIGT (W0, N2) — Verhalten lautlos |
| NEU-05 | `customer_satisfaction_language` hat legacy CHECK `IN ('Deutsch','English')` (bootstrap:1437), UI liest aber dynamische Stammdaten — dritter Admin-Wert scheitert beim Speichern | W0 · bei FB-23 | P2 | BESTÄTIGT (W0, N2) |
| NEU-06 | API-Route `app/api/v1/suppliers` insertet ohne `created_by` (Zod-Schema kennt Feld nicht, kein Default/Trigger) → NULL-Owner-Zeilen | W0/H3 · Flow A | P3 | BESTÄTIGT (W0, N2) |
| NEU-07 | Einsatz-Anlage umgeht dokumentierten Offline-Schreibweg (OFFLINE_ARCHITECTURE.md:100-114): direkter Online-Write, offline schlägt Anlage fehl statt zu queuen; Sync-Engine markiert 0-Zeilen-Updates als 'synced' (sync-engine.ts:118-124) | W0/H3 · Flow C | P2 | BESTÄTIGT (W0, N2) |
| NEU-08 | „Besuchstage pro Monat": Titel „12 Monate" auf 90-Tage-Daten (~3 gefüllte Balken, widerspricht eigenem Footer) UND zählt jede Terminart mit (appointment_type nicht geladen) — irreführende Kennzahl | W1 · bei FB-45 | P2 | BESTÄTIGT (W1, N2) — reporting-dashboard.tsx:468-474,1609-1649 |
| NEU-09 | WORK_MODE-Stammdaten-Karte existiert nur als Frontend-Dictionary (stammdaten-overview-client.tsx:33,51), keine master_data_types-Zeile → erscheint nie in der Stammdaten-Übersicht; Wertebereich zweifach hartkodiert (TS-Union + DB-CHECK) | W1 · bei FB-36 | P3 | BESTÄTIGT (W1, N2) |

**NEU-01 — Lautlose Schreibfehler.** Supabase liefert bei `update`/`delete` **kein** `error`, wenn die RLS-Policy null Zeilen trifft — es passiert schlicht nichts, und die Oberfläche meldet Erfolg. **Das ist die gefährlichste Klasse von Fehlern in dieser App:** Der Anwender glaubt, gespeichert zu haben. Prüfen: Gibt es einen zentralen Daten-Layer, oder ruft jede Komponente Supabase selbst? Gibt es einen → dort `.select()` erzwingen und die Zeilenzahl prüfen, ein Fix für alles. Gibt es keinen → **das ist der eigentliche Fund**, und die Karte lautet nicht „Fehler beheben", sondern „Schreibpfade vereinheitlichen". Das ist eine Architekturfrage → Kais.

**NEU-02 — Zustände von Auswahllisten.** Eine leere Liste kann heißen: lädt noch · ist wirklich leer · Fehler beim Laden · RLS blockt. **Heute sehen alle vier gleich aus — nämlich leer.** Genau deshalb konnten die Melder in FB-02, FB-19 und FB-23 nur „keine Auswahl möglich" schreiben; mehr gab die Oberfläche nicht her. Werden die drei Zustände unterschieden, meldet der nächste Anwender „Fehler beim Laden der Gründe" statt „geht nicht" — **und du sparst dir die Hälfte der nächsten Feedbackrunde.** Gemeinsame Select-Komponente prüfen; gibt es keine, ist das der Fund.

**NEU-03 — Zahlenfelder.** Details in FB-33. Der Fund ist nicht das OEE-Feld, sondern die **Vermutung, dass es alle Zahlenfelder betrifft**. Beleg: einmal quer durch die Masken suchen (`type="number"`), Ergebnis mit Zahl im Bericht nennen — „12 von 14 Zahlenfeldern betroffen" ist eine Aussage, „vermutlich app-weit" ist keine.

### 8.3 Wo du zusätzlich hinsehen sollst, wenn du ohnehin dort bist

Kein Auftrag zur Suche, sondern zum **Hinsehen** — die Melder konnten diese Dinge nicht sehen, du schon:

- **Tenant-Isolation** — bei jeder Policy, die du für FB-48/49/51 anfasst: Trifft sie *wirklich* nur den eigenen Mandanten? SupplierPulse ist mehrmandantenfähig; ein Leck ist ein P0-Fund (G12: an Kais, nicht in die PR).
- **Fehlerbehandlung an der Oberfläche** — rohe Postgres-Meldungen beim Anwender (FB-13, FB-48, FB-51) heißen: Es gibt keine. Das ist ein Fund für sich, kein Detail von drei Karten.
- **`created_by` / `updated_at` / Mandanten-ID** — werden sie beim Insert überhaupt gesetzt? Fehlen sie, erklärt das die halbe H2-Familie auf einen Schlag.
- **Zeitzonen** (H7) — `timestamp` statt `timestamptz` irgendwo? Dann sind FB-38 und FB-09 nur die zwei Symptome, die jemand bemerkt hat.
- **Offline/Dexie** — die PWA hält Daten lokal. Erklärt das FB-18/FB-58 („angelegt, aber nicht zu sehen") besser als RLS? §5.4 lesen. **Zuerst prüfen, ob die Zeile in der Datenbank steht** — das ist eine Ein-Minuten-Abfrage und beantwortet die Frage endgültig.

---

## 9 · Berichten

Kais' Auftrag: **„Berichte mir den Fortschritt — welche Punkte sind erledigt."** Das ist eine Bringschuld. Er soll nicht nachfragen müssen, und er soll nicht in Commits blättern müssen.

### 9.1 Rhythmus

- **Nach jeder abgeschlossenen Welle** (§6.1): Kurzbericht. Fünf Zeilen genügen, siehe 9.4.
- **Sofort, ohne Wellenende:** P0-Funde · Sicherheitsfunde (G12) · Datenverlust · jeder Punkt, bei dem du gegen eine Guardrail laufen würdest. **Nicht sammeln. Melden.**
- **Wenn Wave 0 fertig ist:** der wichtigste Bericht des ganzen Auftrags — siehe 9.2.
- **Wenn du blockiert bist:** nicht warten. Status `WARTET (B)` bzw. `WARTET (C)`, Frage in die Vorlage, **nächste Karte** (§3.3). **Ein blockierter Punkt darf nie den Rest anhalten** — das ist der häufigste Weg, wie so ein Auftrag stirbt.

### 9.2 Der Bericht nach Wave 0 — „Was ist überhaupt wahr?"

Wave 0 ist reine Untersuchung, **kein Code** (§6.1). Danach berichtest du **einmal** sauber, und dieser Bericht bestimmt alles, was danach passiert:

1. **Welche Hypothesen (H1–H7) haben sich bestätigt, welche nicht?** Mit Beleg. Eine widerlegte Hypothese ist ein genauso gutes Ergebnis wie eine bestätigte — **sag es deutlich, statt sie stillschweigend fallen zu lassen.**
2. **Welche gemeldeten Punkte sind bereits behoben?** (§1, Zeitachse — drei Wochen Entwicklung liegen zwischen Feedback und Auftrag.) **Nur mit Commit-Beleg.** `BEREITS BEHOBEN` ohne Commit ist eine Behauptung.
3. **Welche Punkte sind nicht reproduzierbar?** Mit dem, was du stattdessen gesehen hast — nicht nur „geht bei mir".
4. **Welche Punkte sind größer als gemeldet?** (Der häufigste Fall: Ein Melder sieht ein Symptom in einer Maske; die Ursache betrifft zehn.)
5. **Welche Punkte sind kleiner als gemeldet?** (Auch das kommt vor — und erspart Kais eine Diskussion.)
6. **Wie viele Karten sind Klasse B?** Das ist die Zahl, die Kais' Kalender bestimmt.

**Erst nach diesem Bericht wird Code geschrieben.** Nicht, weil das Vorschrift ist, sondern weil dieser Bericht die Reihenfolge aller weiteren Arbeit ändern kann — und weil hier entschieden wird, ob die 50 Karten wirklich 50 Probleme sind oder 15 Ursachen.

### 9.3 Prüfprotokoll je Karte

Gehört **in die Karte** in §7, direkt unter den Text, angehängt — **nicht** in die Fortschrittstabelle (§4). Kurz. Kein Aufsatz.

```markdown
**Prüfprotokoll — FB-xx** · Stand: TT.MM.JJJJ
- Reproduziert: ja / nein / teilweise — [wie, wo]
- Befund: [was tatsächlich passiert — Datei:Zeile / SQL / Log]
- Evidenz: N1 / N2 / N3
- Sinn-Check: [Antwort auf die entscheidende der sieben Fragen aus §3.2]
- Entscheidung: umgesetzt / VERWORFEN [Begründung] / WARTET (B|C) [Frage]
- Änderung: [Dateien, PR-Nummer]
- Test: [Testdatei, was er prüft]
- Nebenbefund: NEU-xx / keiner
```

**Zu „VERWORFEN": Ein verworfener Punkt braucht die *beste* Begründung im ganzen Dokument, nicht die kürzeste.** Ein Melder, der seinen Punkt mit „macht keinen Sinn" abgebügelt sieht, meldet beim nächsten Mal nichts mehr — und das ist ein größerer Schaden als jeder einzelne dieser 60 Punkte. Die Begründung muss so geschrieben sein, dass **der Melder selbst** sie liest und zustimmen kann. Wenn du das nicht hinbekommst, ist der Punkt nicht VERWORFEN, sondern Klasse B.

### 9.4 Kurzbericht nach jeder Welle

```markdown
## Wave n — abgeschlossen TT.MM.JJJJ
Erledigt: FB-xx, FB-yy (Nr. 5, 6, 15) · PRs: #nn, #mm
Verworfen: FB-zz (Nr. 40) — [ein Satz]
Wartet auf Kais: FB-aa (Nr. 36) · Wartet auf Melder: FB-bb (Nr. 20)
Neu gefunden: NEU-04 [ein Satz]
Nächste Welle: n+1 — [was drin ist]
Kais muss jetzt entscheiden: [nur was blockiert]
```

### 9.5 Abschlussbericht

Am Ende **eine** Tabelle mit **allen 60 Nummern** — nicht 50 Karten, **60 Zeilen** (§6.2, Zählprobe). Spalten: `Nr. | Melder | Kurztext | Ergebnis | Beleg (PR/Commit/Frage)`. Ergebnis ist eines von: umgesetzt · bereits behoben · verworfen (+ Grund) · wartet auf Entscheidung · nicht reproduzierbar.

**Der Grund für die 60 statt 50:** Jeder Melder muss **seine** Nummer wiederfinden. Klockenhoff hat Nr. 22 gemeldet und will neben „22" ein Ergebnis lesen — nicht den Hinweis, dass sein Punkt in FB-02 aufgegangen ist. Cluster sind eine Arbeitshilfe für dich, keine Antwort an ihn.

Dazu: die Entscheidungsvorlage (§3.3, **eine** für alle Klasse-B-Punkte, gebündelt, nicht tröpfchenweise) und die Rückfragen an die Melder (Anhang C, **eine** Mail, nicht sieben).

---

## 10 · Definition of Done

**Für eine einzelne Karte:**
- [ ] Reproduziert oder als nicht reproduzierbar belegt (N1/N2 — nicht N3, §G8)
- [ ] Sinn-Check beantwortet (§3.2), Ergebnis steht im Prüfprotokoll
- [ ] Umgesetzt **oder** begründet verworfen **oder** als Frage in der Vorlage
- [ ] Bei Umsetzung: **mindestens ein Test**, der ohne den Fix rot wäre (G9)
- [ ] Bei RLS/Auth: `/cso` durch · Test positiv **und** Tenant-negativ
- [ ] Bei `app/`-Komponenten: `/qa` durch · bei DB/Migration: `/careful` oder `/guard`
- [ ] `/review` vor der PR · PR-Titel trägt die FB-Nummer und die Original-Nr. (G4)
- [ ] Status in §6.2 gesetzt · Prüfprotokoll an der Karte
- [ ] Nebenbefunde als `NEU-xx` eingetragen, nicht nebenbei mitgefixt (G10)

**Für den Gesamtauftrag:**
- [ ] Alle 60 Nummern haben ein Ergebnis — **keine Zeile ohne Antwort**
- [ ] Wave 0 berichtet (§9.2), bevor die erste Zeile Code entstand
- [ ] Alle P0-Punkte (FB-36, FB-41, FB-45) sind entschieden oder abgeschaltet — **keiner ist offen und live**
- [ ] Eine gebündelte Entscheidungsvorlage für alle Klasse-B-Punkte
- [ ] Eine Rückfrage-Mail für alle Klasse-C-Punkte
- [ ] `NEU`-Register gepflegt und berichtet
- [ ] Keine Migration hat Daten gelöscht (G3) · nichts wurde auf `main` committet (G4)
- [ ] Sicherheitsfunde gingen an Kais, nicht in eine PR-Beschreibung (G12)
- [ ] Abschlussbericht liegt vor (§9.5)

> **Die eine Frage, an der du dich am Ende messen lässt:** Kann Kais mit diesem Bericht vor das MO-23-Team treten und **jedem der sieben Melder** sagen, was aus seinem Punkt geworden ist und warum? Wenn ja, ist der Auftrag erfüllt — **auch dann, wenn die Hälfte der Punkte verworfen wurde.** Wenn nein, hilft auch die schönste PR nicht.

---

## Anhang A · Die sieben Melder

Kein Beiwerk. Du wirst Punkte verwerfen müssen, und dafür musst du wissen, **wer** was aus **welcher** Perspektive geschrieben hat. Die Verteilung ist selbst ein Befund.

| Melder | Punkte | Nummern | Schwerpunkt | Was das für dich heißt |
|---|---|---|---|---|
| **Löffler** | 18 | 36–53 | Reporting, PMO, Datenablage, Compliance | Der schärfste Kritiker — **und der mit den zwei P0-Punkten** (36, 41, 45). Schlägt oft „Entfernen" vor. Nimm den Befund ernst, den Vorschlag als eine Option von mehreren. |
| **Dickens** | 13 | 1–13 | Kalender, Lieferantenanlage, Export | Hat systematisch durchgeklickt, meldet **Fehler statt Meinungen**. Seine Punkte sind fast alle Klasse A. Beide Screenshots stammen von ihm. |
| **Klockenhoff** | 11 | 16–26 | Stammdaten, KIFAG, Sprache | Knappe, teils verstümmelte Notizen mit BMW-Fachbegriffen (KIFAG, MVZ, Mx). **Hier ist Nachfragen die Arbeit, nicht das Ausweichen.** |
| **Gruber** | 9 | 27–35 | OEE ausschließlich | **Der Fachmann.** Methodisch, präzise, unbequem („Das System sagt nicht das es bullshit ist"). Bei seinen Punkten liegt der Wert in der Methode, nicht im Code. **§5.1 beachten — Spaltenversatz.** |
| **Kurzmiller** | 5 | 54–58 | Projektanlage, Kalender | Bestätigt überwiegend Punkte anderer (56→23, 57→2, 55→14). **Unabhängige Bestätigung ist wertvoll** — kein Ausreißer, sondern reproduzierbar. |
| **Ping** | 2 | 14, 15 | Kalender, Projektanlage | Wenige, aber gehaltvolle Punkte mit Referenz auf die **VSM IT-Plattform**. Nr. 14 steht im Konflikt mit Nr. 36 (Anhang B). |
| **Hagen** | 2 | 59, 60 | Kalender-Sync, Tier-2 | Zwei präzise Treffer, beide echte Fehler. |

> **Was in dieser Tabelle steht und in keiner einzelnen Zeile:** **Sieben Leute, ein Nachmittag, 60 Punkte — und keine zwei Melder haben denselben Bereich abgedeckt.** Löffler war nie im OEE-Modul, Gruber nie im Reporting. Das heißt: Diese 60 Punkte sind **keine Bestandsaufnahme der App**, sondern sieben Stichproben. Wo niemand hingesehen hat, ist es nicht sauber — es ist **ungeprüft**. Genau deshalb existiert §8.

---

## Anhang B · Dubletten, Querverweise, Konflikte

### B.1 Die zehn Punkte, die in anderen aufgehen

| Nr. | Melder | geht auf in | Warum |
|---|---|---|---|
| 17 | Klockenhoff | FB-01 | Beide: Bestandslieferanten / LDB-Anbindung |
| 22 | Klockenhoff | FB-02 | Zellinhalt ist nur „siehe Billy" — Verweis auf Dickens' Nr. 2 |
| 24 | Klockenhoff | FB-36 | Zellinhalt: „Homeoffice ?  ist gewollt?" / „siehe Nr. 36" — expliziter Verweis |
| 28 | Gruber | FB-27 | Menge ohne Zeitbezug = dasselbe Bezugsgrößenproblem |
| 31 | Gruber | FB-27 | Pausen ohne Bezug = dasselbe |
| 44 | Löffler | FB-43 | Wortgleich zu 43, andere Dimension |
| 55 | Kurzmiller | FB-14 | Beide: Urlaub verlangt ein Projekt |
| 56 | Kurzmiller | FB-23 | Beide: Kommunikationssprache nicht wählbar |
| 57 | Kurzmiller | FB-02 | Beide: Verrechnungsmöglichkeit / leere Auswahl |
| 60 | Hagen | FB-03 | Beide: Lieferant ohne BMW-Nummer (Tier-2) |

**60 − 10 = 50 Karten.** Im Abschlussbericht trotzdem **60 Zeilen** (§9.5).
**Und der Nebeneffekt, der zählt:** Nr. 2/22/57 wurden von **drei** Meldern unabhängig gemeldet, Nr. 23/56 von zwei, Nr. 3/60 von zwei. **Das sind keine Einzelmeinungen, das sind reproduzierte Fehler.** Wer die Cluster nur als Aufwandsersparnis sieht, übersieht ihren eigentlichen Wert: Sie sagen dir, was **sicher** kaputt ist.

### B.2 Der eine echte Widerspruch — **hier nicht selbst entscheiden**

| | Nr. 14 (Ping) | Nr. 36 (Löffler) |
|---|---|---|
| **Will** | „Persönliche Abwesenheit" als Oberkategorie **inkl. HO** — analog VSM IT-Plattform | Arbeitsort „Vor Ort / Homeoffice / Remote" **komplett entfernen** |
| **Homeoffice** | **hinein** ins System | **heraus** aus dem System |
| **Begründung** | Prozessanalogie zu einem bestehenden BMW-Werkzeug | „auch wenn es das bei Interligent bereits gab" |

Beide Melder haben aus ihrer Sicht recht, und **beide können nicht bekommen, was sie wollen.** Ping denkt in Kategorienmodellen, Löffler denkt an die Betriebsvereinbarung. **Das ist keine Geschmacksfrage, die man mit einem Kompromiss löst** — es ist eine Entscheidung mit Mitbestimmungsbezug (§5.6/H5).
**Deine Aufgabe:** beide Positionen **unverfälscht** nebeneinanderstellen, den Compliance-Rahmen dazu, und **keine Empfehlung, die so tut, als wäre es eine technische Frage.** Sie ist es nicht. → Vorlage, gebündelt mit FB-36/41/45.
**Was du bis zur Entscheidung tust:** Bei FB-36 gilt P0 — die Erfassung wird abgeschaltet (Feature-Flag), **nicht gelöscht** (G2). Das nimmt keine der beiden Entscheidungen vorweg und beendet trotzdem sofort den kritischen Zustand.

### B.3 Das Paket „Terminarten" — vier Karten, eine Entscheidung

**FB-04** (Schalter „Dienstreise") · **FB-14** (Kategorien, „Reise" undefiniert) · **FB-37** („Auftragsart" falsch benannt) · **FB-38** (Feiertag als Werktag)

Vier Melder haben vier Symptome derselben Lücke beschrieben: **Es gibt kein festgelegtes Modell dafür, welche Arten von Einträgen der Kalender kennt und wie sie zusammenspielen.** „Auftragsart", „Reise", „Dienstreise", „Urlaub", „Freizeit", „Persönliche Abwesenheit" — jeder Begriff kommt vor, keiner ist definiert.
**Einzeln gelöst geben diese vier Karten vier Flickstellen und in drei Monaten dieselbe Meldung.** Zusammen gelöst sind sie **eine Tabelle**: Terminart → Pflichtfelder → zählt als Arbeitstag ja/nein → Reisezeit ja/nein → Projektbezug Pflicht/optional/verboten. **Diese Tabelle ist der Vorschlag**, nicht vier Bugfixes.
**Klasse B, eine Entscheidung, vier Karten** — und der beste Beitrag, den dieser Auftrag zum Kalendermodul leisten kann.

### B.4 Zusammenhänge, die man leicht übersieht

| Beobachtung | Karten | Konsequenz |
|---|---|---|
| Derselbe RLS-Fehlertext, drei Funktionen | FB-48, FB-49, FB-51 | **Nur bei FB-48 passt die Tabelle.** Zweimal kopiert (§5.0) — echte Tabelle je Fall ermitteln. FB-48 zuerst als Leitfall. |
| Leere Auswahlliste, drei Bereiche | FB-02, FB-19, FB-23 | Wahrscheinlich **eine** Ursache (H1) → **eine** PR statt drei. |
| „Angelegt, aber nicht sichtbar" | FB-18, FB-58, (FB-15) | H3 — **zuerst in der Datenbank nachsehen**, nicht im Cache. |
| Löffler will vier Diagramme weg und **einen** Filter | FB-43/44/46/47 ↔ FB-53 | **Eine** Produktentscheidung, nicht fünf. Siehe FB-53. |
| OEE-Methodik ohne Konvention | FB-27, FB-29, FB-30, FB-34 | Eine Seite „OEE-Konvention MO-23" löst alle vier. Siehe FB-30. |
| Schichtmodell fehlt | FB-27 ↔ FB-40 | FB-40 ist ohne FB-27 nicht rechenbar. |
| Benennungen strittig | FB-37, FB-42 ↔ FB-53 | Filter erst bauen, wenn die Feldnamen stehen. |
| Token-Mechanik | FB-13 ↔ FB-52 | Der Einreichungs-Link ist der Baukasten für den Befragungslink. |
| Pflichtfeld-Kennzeichnung `*` | FB-32 ↔ Anhang D | **Der Kalenderdialog kennzeichnet Pflichtfelder mit `*`, die OEE-Maske nicht.** Die Konvention existiert bereits in der App — es ist kein Konzeptthema, sondern eine Inkonsistenz. |

---

## Anhang C · Rückfragen an die Melder (Klasse C)

**Eine** Mail, nicht sieben. Sammeln, bis Wave 0 durch ist, dann gebündelt über Kais.

| Karte | An | Frage | Warum du sie nicht selbst beantworten kannst |
|---|---|---|---|
| FB-12 | Dickens | Bei welchem Projekt / welcher Linie trat der PDF-Formatfehler auf? Bitte die PDF-Datei. | Ohne den Fall nicht reproduzierbar. Rein raten hieße, ein Layout „schön" zu machen, ohne den Fehler zu kennen. |
| FB-16 | Klockenhoff | „Zeitraum bei KW – Erstbesuch": Soll die KW **angezeigt** oder als **Eingabe** möglich sein? | Der Satz lässt beides zu. |
| FB-20 | Klockenhoff | Soll in KIFAG **nur das Kurzzeichen** („Mx") stehen statt der ausgeschriebenen Bezeichnung — oder umgekehrt? Heute steht dort: *[Ist-Zustand einsetzen]*. | Der Satz ist verstümmelt, beide Lesarten sind möglich. |
| FB-21 | Klockenhoff | Was ist „MVZ"? Wo genau ist das Kurzzeichen dort hinterlegt? | BMW-internes Kürzel, nicht auflösbar (G7). |
| FB-29 | Gruber (via Kais) | „First Part Yield" — ist **First Pass Yield** gemeint? | Fachbegriff bestätigen, nicht stillschweigend korrigieren. |
| FB-35 | Gruber (via Kais) | Bitte die Plausibilitätsregeln bestätigen/ergänzen (Liste liegt bei). | Nur er kennt die Grenzfälle, die möglich, aber unwahrscheinlich sind. |
| FB-38 | Löffler | 02.–05.06.2026: Gemeint ist vermutlich **Fronleichnam (Do, 04.06.)**, nicht Pfingstmontag (25.05.). Welcher Standort? | §5.0 — die Quelle enthält hier nachweislich einen Fehler; **oder die App beschriftet den Feiertag falsch.** Beides ist möglich, und die Antwort entscheidet, wo der Fehler sitzt. |
| FB-46/47 | Löffler (via Kais) | „MARS-System": Welche Funktion deckt es ab, die SupplierPulse nicht doppeln soll? | Scope-Frage, kein Codewissen. |

**Formuliere jede Frage so, dass sie mit einem Satz beantwortbar ist.** Eine Frage, die eine Recherche auslöst, wird nicht beantwortet — und dann steht die Karte still. Wo möglich: **Ist-Zustand mitliefern und um Bestätigung bitten**, statt eine offene Frage zu stellen (siehe FB-20).

---

## Anhang D · Die beiden Screenshots

Die Excel enthält zwei eingebettete Bilder, beide ohne Beschriftung, beide frei über den Zeilen schwebend. **Es gibt keine Zuordnung in der Spalte „Screenshot" — die ist bei allen 60 Zeilen leer.** Die Zuordnung unten ergibt sich aus dem Ankerpunkt und ist damit eine **Interpretation, kein Fakt** (N3).

Dateien: `screenshot-1_einsatz-bearbeiten.png` · `screenshot-2_monatsleiste.png`

### D.1 Screenshot 1 — Dialog „Einsatz bearbeiten"

**Anker:** ab Zeile 5 (Nr. 4), über Zeile 17 reichend → **aus Dickens' Block (Nr. 1–13), Gerät PC.**

**Vollständige Abschrift der Maske** (damit du sie ohne das Bild verwenden kannst):

| Feld | Inhalt / Typ | Pflicht |
|---|---|---|
| *Titel* | **Einsatz bearbeiten** | — |
| Zeitraum von | `29.06.2026` (Datumsfeld) | `*` |
| bis | `29.06.2026` (Datumsfeld) | `*` |
| Mitarbeiter | `William Dickens` (Auswahl) | `*` |
| **Auftragsart** | `Einsatz (Beim Lieferant)` (Auswahl) | `*` |
| Projekt **(optional)** | `Kein Projekt` (Auswahl) | — |
| Kunde/Lieferant | (leer) | — |
| Einsatzort | (leer) | — |
| Status | `Fest` (Auswahl) | `*` |
| **Arbeitsort** | Optionsfelder: `Vor Ort` · `Homeoffice` · `Remote` | — |
| Bemerkung | (leer, mehrzeilig) | — |
| ☐ | **✈ Dienstreise (Reisezeit erforderlich)** (Kontrollkästchen) | — |
| *Schaltflächen* | `Löschen` · `Abbrechen` · `Änderungen speichern` | — |

> **Dieser eine Screenshot belegt oder widerlegt sechs Karten. Lies ihn deshalb gründlich, bevor du irgendetwas im Kalender anfasst:**
>
> - **FB-36 (P0):** Das Feld **Arbeitsort** mit `Vor Ort / Homeoffice / Remote` ist hier **im Bild belegt** — Löfflers Meldung ist damit nicht nur plausibel, sie ist **bewiesen**. Der dringendste Punkt des Backlogs hat einen Beleg, den sein Melder gar nicht mitgeschickt hat.
> - **FB-04:** Das Kontrollkästchen **„✈ Dienstreise (Reisezeit erforderlich)"** existiert. Die Frage ist also nicht, *ob* es da ist, sondern **was es bewirkt** — genau das, was Dickens meldet.
> - **FB-05:** **`von 29.06.2026` und `bis 29.06.2026` sind identisch.** Wenn Dickens einen mehrtägigen Einsatz zum Bearbeiten geöffnet hat, ist das der **Beleg für den Datenverlust-Verdacht** — der Dialog hat den Zeitraum auf einen Tag reduziert. **Diese Zelle ist der wichtigste Pixel der ganzen Excel.** Reproduzieren: mehrtägigen Einsatz anlegen, öffnen, speichern, DB prüfen.
> - **FB-37:** Das Feld heißt tatsächlich **„Auftragsart"** und enthält den Wert `Einsatz (Beim Lieferant)`. Löfflers Kritik trifft die reale Beschriftung.
> - **FB-14:** Das Projektfeld ist hier **ausdrücklich mit „(optional)" beschriftet** — bei `Auftragsart = Einsatz`. Ping meldet, dass es bei `Urlaub` **Pflicht** wird. **Damit weißt du, wo du suchen musst:** nach der Stelle, die Pflichtfelder abhängig von der Auftragsart umschaltet. Das ist keine Hypothese mehr, das ist eine Adresse.
> - **FB-32:** Diese Maske **kennzeichnet Pflichtfelder mit `*`** — die OEE-Maske laut Gruber nicht. Die Konvention existiert also bereits. Grubers Punkt ist damit keine neue Anforderung, sondern eine **Inkonsistenz** — und das macht ihn billiger und zwingender zugleich.

### D.2 Screenshot 2 — Monatsleiste

**Anker:** ab Zeile 6 (Nr. 5), über Zeile 8 reichend → ebenfalls **Dickens' Block**.
**Inhalt:** eine waagerechte Schaltflächenleiste mit den zwölf Monaten `Jan` `Feb` `Mär` `Apr` `Mai` `Jun` `Jul` `Aug` `Sep` `Okt` `Nov` `Dez`; ein Monat ist hervorgehoben.
**Wozu er gehört, ist nicht sicher** — der Anker liegt bei Nr. 5, inhaltlich passt er zu **FB-07** (Monatsansicht abgeschnitten) oder **FB-09** (Export nimmt immer den aktuellen Monat). **Rate nicht, welcher.** Nimm ihn als das, was er ist: der Beleg, dass die Monatsauswahl **eine Leiste ohne Jahresangabe** ist.

> **Und das ist der Punkt, den man hier findet, ohne dass ihn jemand gemeldet hat:** **In der Leiste steht kein Jahr.** Wer im Januar 2027 auf „Dez" klickt — sieht er Dezember 2026 oder Dezember 2027? Wenn der Kalender jahresübergreifend arbeitet (und das tut ein Einsatzkalender), ist das ein Fehler, der bisher nur deshalb niemandem aufgefallen ist, **weil die Demo im Juni lief.** Prüfen; falls bestätigt → `NEU-xx` (§8), Bezug H7 (§5.8).

---

## Zum Schluss

Dieses Dokument ist **deine Arbeitsdatei**, nicht Kais' Lesestoff. Du pflegst sie fort: Status in §6.2, Prüfprotokolle an den Karten, neue Funde in §8. Sie ist am Ende der Nachweis, was aus 60 Meldungen geworden ist.

Und noch einmal der Satz aus §0, weil er die einzige Regel ist, aus der alle anderen folgen:

> **Feedback beschreibt, was jemand gesehen hat — nicht, was die Ursache ist und erst recht nicht, was zu tun ist. Prüfe jede Aussage am Code, bevor du eine Zeile änderst. Setz um, was sich als richtig erweist. Verwirf begründet, was sich als falsch erweist. Frag, wo du nicht entscheiden darfst. Und berichte alles drei.**

**Sechzig Menschen-Minuten stecken in dieser Excel — sieben Kollegen, die sich einen Nachmittag Zeit genommen haben, obwohl sie keine Zeit hatten. Geh entsprechend damit um.**
