Skip to content

feat(requests): list and start page lead with the next work decision - #95

Merged
Fluory merged 6 commits into
mainfrom
claude/feat-list-next-action-77
Sep 28, 2026
Merged

Fluory merged 6 commits into
mainfrom
claude/feat-list-next-action-77

Conversation

@Fluory

@Fluory Fluory commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Warum

Fixes #77 · Showcase-Review 2026-09-27, P2 (Epic #19)

Arbeitsstand

  • Ziel: Eine Sachbearbeiterin erkennt sofort, welche Anfrage Aufmerksamkeit braucht und warum; die Startseite führt direkt zur Arbeit oder zum Musterfall.
  • Nicht-Ziele: neue Filter, Sortierung nach Kunde.
  • Erledigt: Zusammenfassung je Anfrage (Kunde, Prüfbedarf) nach denselben Regeln wie die Detailseite (gemeinsame Korrektur-Hilfsfunktion), drei Abfragen je Listenseite; nächste Aktion je Zeile; Diagnose aufklappbar; Tabelle ohne Querscrollen bei 1280 px; „Nächster Schritt“ auf der Startseite; Notizen aus dem Issue (Einheit „Stk.“, keine doppelte Freigabe-Meldung); Tests; CHANGELOG.
  • Offen: nichts – Review-Befunde umgesetzt, CI grün. Folge-Issue feat(review): accept "Stk." in a unit correction and store the ERP unit #96 (Einheit „Stk.“ bei Korrekturen normalisieren).
  • Annahmen: keine.
  • Nächster kleinster Schritt: Merge, danach Showcase-Deploy prüfen.

Was ist passiert (Klartext)

Die Anfragenliste zeigte bisher vor allem Technik: Versuche, letzten Fehler, nächsten Termin – und sie war so breit, dass man seitlich scrollen musste. Jetzt beginnt jede Zeile mit dem, was man zum Arbeiten braucht: dem Kunden, wie viele Werte zu prüfen sind (dieselbe Zahl wie auf der Detailseite) und der nächsten Aktion, etwa „Prüfen“ oder „Duplikat entscheiden“. Die technischen Angaben stecken in einem aufklappbaren „Details“ je Zeile. Die Startseite sagt oben, was als Nächstes zu tun ist – und führt zum vorbereiteten Musterfall, wenn gerade nichts offen ist. Auf der Detailseite heißt die Einheit jetzt „Stk.“ statt „pcs“, und nach dem Freigeben erscheint die Bestätigung nur noch einmal.

Plan-Pflicht (SYSTEM.md §4)

  • Kein Auslöser – keine Modulgrenze, öffentliche API, Migration, Auth/Rechte, kein Zahlungs-/Daten-/Infrapfad, höchstens zwei Module, keine Architekturvarianten, umkehrbar
  • Auslöser zutreffend – Impact Manifest ausgefüllt (Plan vor Code)

Impact Manifest

  • Betroffene Module: mehr als zwei – review (summary.ts: summarizeReview, gemeinsame Korrektur-Hilfsfunktionen; listReviewSummaries), extraction (latestRunsWithFields), requests (findSampleForVisitors), app (Liste, Startseite, Detailseite, CSS). Keine neue Abhängigkeit.
  • Schnittstellen / Datenänderungen: keine Schema- oder API-Änderung; neue lesende Modul-Funktionen. loadReview und currentLineItemValues nutzen jetzt die gemeinsame Korrektur-Regel (applicableCorrection) – gleiches Verhalten, eine Stelle.
  • Akzeptanzkriterien: die aus feat(requests): list and start page lead with the next work decision #77, dazu die zwei Notizen aus dem Issue-Kommentar. Prüfbedarf = dieselbe Zählung wie „n Werte brauchen Aufmerksamkeit“ auf der Detailseite (unsicher + nicht belegt); fehlende Kopfangaben werden daneben gezählt – eine abweichende Zahl in Liste und Detail wäre genau der Fehler aus fix(requests): consistent processing state and pick-up of due retries on the showcase #70.
  • Testplan: Unit – summarizeReview (5 Fälle inkl. Korrektur vor/nach dem Lauf), nextAction (13 Fälle), displayValue (8 Fälle). Integration – Zusammenfassung stimmt für echte Daten mit loadReview überein. E2E – Startseite zeigt den nächsten Schritt; Listenzeile des Musterfalls mit Kunde, Prüfbedarf, „Prüfen“; kein Querscrollen bei 1280 px.
  • Verifizierte Fakten: .requests-table hatte min-width: 1080px bei 8 Spalten; main ist bei 1280 px höchstens 1224 px breit; die Detailseite zählt uncertain + unverified ohne korrigierte Werte; Positionskorrekturen vor einem neueren Lauf gelten nicht (feat(review): line items and all formats in the review UI #25).
  • Offene Annahmen: keine.
  • Nicht-Ziele: Filter, Sortierung.
  • Risiken und Rollback: zwei zusätzliche Abfragen je Listenseite (für bis zu 50 Zeilen, nicht je Zeile); Rollback per Revert.

Geändert

  • src/features/review/summary.ts (+ Test, neu): summarizeReview, correctionKey, applicableCorrection, latestCorrections
  • src/features/review/review.ts, index.ts: gemeinsame Korrektur-Regel; listReviewSummaries
  • src/features/extraction/repository.ts, index.ts: latestRunsWithFields (DISTINCT ON)
  • src/features/requests/repository.ts, index.ts: findSampleForVisitors
  • src/app/requests/row-view.ts (+ Test): nextAction
  • src/app/requests/page.tsx, src/app/components.css: neue Spalten, Diagnose als <details>, min-width 760 px
  • src/app/page.tsx, src/app/globals.css: „Nächster Schritt“
  • src/app/requests/[id]/value-label.ts (+ Test, neu), [id]/page.tsx: „Stk.“; keine doppelte Freigabe-Meldung
  • tests/integration/review.test.ts: Zusammenfassung = Detailseite; tests/e2e/sample-smoke.spec.ts: Startseite, Listenzeile, 1280 px
  • CHANGELOG.md

Nachweis (SYSTEM.md §11)

  • verify:changed: grün – summary.test.ts 5/5 (zuerst rot: Modul fehlte), row-view.test.ts 16/16 (zuerst rot: nextAction fehlte), value-label.test.ts 8/8 (zuerst rot); vitest src/features/review 14/14; typecheck, lint (0 Fehler), depcruise (Exit 0)
  • verify: grün – CI-Lauf 36447368074 (check, Kopf f289e19): Unit 278/278, Integration 144/144 gegen Postgres + S3 (inkl. „Zusammenfassung = Detailseite“), depcruise, build, audit; AI-Service 452 passed (lokal ist Docker aus)
  • verify:full / E2E-Spec: grün – derselbe Lauf, Label verify-full: E2E 3/3; sample-smoke prüft Startseite, Listenzeile, kein Überlauf im Tabellen-Container bei 1280 px, Diagnose per Tastatur geöffnet
  • Manueller Prüfnachweis: Screenshots nach dem Deploy
  • Frischer Review (P1 vor Ready-for-review; Architektur/API/DB immer): unabhängiger Subagent, Urteil „changes requested“ (1 Blocker, 2 Important, 3 Notes) → alle umgesetzt, siehe feat(requests): list and start page lead with the next work decision #95 (comment)

Doku-Entscheidung (genau eine)

  • Keine langlebige Doku betroffen – Begründung: –
  • Doku betroffen und im selben PR aktualisiert:

Entferntes oder Umbenanntes: docs/ + README gegrept, Treffer bereinigt: Spalten „Versuche/Letzter Fehler/Nächster Versuch/Duplikat“ der Liste – in docs/ nicht beschrieben

Dateigrößen und neue Bausteine (SYSTEM.md §7)

Dateien über 500 Zeilen im Diff (Ausnahmen: generierter Code, Lockfiles, Fixtures, Migrationen, Schemas, Ressourcen, Doku, Konfiguration):

  • keine
  • bewusst belassen – Begründung: –
  • im selben PR nach fachlicher Verantwortung geteilt
  • Folge-Issue –

Über 800 Zeilen mit neuer Fachlogik oder über 1000 Zeilen (P1/P2): nicht betroffen

Neue Shared-Komponente, Utility-Datei, Adapter oder fachlicher Service:

  • nein
  • ja – gesucht nach: vorhandener Status-/Korrektur-Logik (needsAttention, currentCorrections, currentFieldValues, requestRowView); gefunden: die Korrektur-Regel stand zweimal in review.ts (Detailseite, Positionswerte) – sie ist jetzt eine gemeinsame Funktion in summary.ts, die auch die Liste nutzt; needsAttention (App-Schicht) zählt dasselbe wie summarizeReview

Subagent-Einsätze

  • 1 × frischer Review (read-only, keine Änderungen) – Ergebnis und Umsetzung im PR-Kommentar.

Risiken / offene Punkte

  • Siehe Impact Manifest.

🤖 Generated with Claude Code

Fluory and others added 4 commits September 28, 2026 17:02
…the list

The list should lead with customer and need for review (#77). The
summary uses the review page's rules - a shared correction helper now
serves loadReview, the export values and the summary, so list and
detail cannot drift. A page of 50 rows costs three queries.

Refs #77

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…tion; start page shows the next step

The request list led with attempts, last error and next retry and
scrolled sideways at 1280 px (#77). Rows now start with the customer,
the need for review (same count as the detail page) and the next work
decision; the diagnosis moves into an expandable details element per
row. The start page names the next step: open reviews, failed requests,
or the prepared sample when nothing is open.

Refs #77

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…for list and start page

Two notes on #77 from the live test: the review page showed the
canonical unit 'pcs' to German clerks and repeated 'Freigegeben – der
Export ist eingeplant.' right after an approval. The unit now reads
'Stk.' (stored value and correction input stay canonical for the ERP);
the approved callout is skipped while the action's own message shows.
The sample E2E now checks the start page's next step and that the list
row leads with customer, need for review and next action without
sideways scrolling at 1280 px.

Refs #77

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Fluory Fluory added the verify-full Run verify:full (integration + E2E) in CI label Sep 28, 2026
@vercel

vercel Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
requestflow Ready Ready Preview Sep 28, 2026 4:02pm UTC
requestflow-ai Ready Ready Preview Sep 28, 2026 4:02pm UTC

The list row now also holds the "Prüfen: <subject>" link (#77), so a substring
match on the subject resolved to two links (strict mode violation in CI).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… diagnosis

- E2E measures the scrolling .table-wrap itself; the page can never overflow
  because the wrap scrolls, so the old check could not fail.
- Each diagnosis disclosure names its request (visually hidden, like the
  action links) and the E2E opens one by keyboard.
- "alles belegt" only when nothing is uncertain and nothing is missing.
- Recognised unit reads "Stk." in the panel too; the unit correction says it
  takes the ERP abbreviation (pcs), so "Stk." is not stored by accident.
- Start page fallback says "nothing waits for your review" instead of "no
  open work": a NEW request with an open duplicate decision is counted once
  processed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Fluory

Fluory commented Sep 28, 2026

Copy link
Copy Markdown
Owner Author

Frischer Review (unabhängiger Subagent, liest nur, Stand 552e01b + CHANGELOG)

  1. [Blocker] – tests/e2e/sample-smoke.spec.ts:26 – CI check (verify:full) ist rot: getByRole("link", { name: "Anfrage Rohrbogen und Flansche fuer Werk Ost" }) matcht als Teilstring auch den neuen „Prüfen“-Link (aria-label „Prüfen: “) → strict mode violation. – Alles nach Zeile 26 bleibt ungeprüft (Detailseite, exportierter Musterfall), der PR ist nicht ready-for-review. – exact: true am Locator setzen, CI erneut laufen lassen. Das aria-label nicht ändern (erfüllt label-in-name).
  2. [Important] – sample-smoke.spec.ts:19 – document.documentElement.scrollWidth <= 1280 kann bei der Tabelle nie fehlschlagen, denn .table-wrap { overflow-x: auto } (components.css:61) fängt jeden Überlauf ab. – Das Kriterium „kein Querscrollen bei 1280 px“ ist unbewiesen, ein Test, der nicht fehlschlagen kann (testing.md). – scrollWidth <= clientWidth auf .table-wrap prüfen (per Test-ID).
  3. [Important] – requests/page.tsx Diagnose-Spalte – Der Testplan von feat(requests): list and start page lead with the next work decision #77 („diagnosis reachable – E2E with role/label locators“) fehlt, kein Test öffnet ein <details>. Alle Disclosures heißen nur „Details“, während Aktion und „Erneut verarbeiten“ den Betreff im Namen tragen. – Kriterium 2 ist nicht belegt, Screenreader hören bis zu 50 × „Details“ ohne Bezug. – Betreff visually-hidden in die Summary, im E2E eine Diagnose aufklappen und den Inhalt prüfen.
  4. [Note] – requests/page.tsx Prüfbedarf – „alles belegt“ steht auch neben „n Angaben fehlen“, das widerspricht sich. – Pille nur bei missing === 0 zeigen oder umbenennen („keine unsicheren Werte“).
  5. [Note] – [id]/page.tsx:281/294 – Das Panel zeigt „Stk.“, aber „erkannt: pcs“ und das Korrekturfeld mit „pcs“ vorbelegt. Wer „Stk.“ eintippt, speichert eine nicht-kanonische Einheit, die laut ERP-Vertrag „as written“ exportiert wird. Gespeicherte und exportierte Werte ändert die Anzeige nachweislich nicht. – Hinweis „(pcs)“ ergänzen oder Folge-Issue für normalisierte Einheiten-Korrektur.
  6. [Note] – src/app/page.tsx – nextAction wertet einen NEW-Request mit offenem Duplikat als Arbeit („Duplikat entscheiden“), die Startseite zeigt dann trotzdem „Keine offene Arbeit“. – Mitzählen oder bewusst ausschließen und begründen.

Geprüft ohne Befund: applicableCorrection ist äquivalent zu beiden alten Bedingungen (itemIndex in currentLineItemValues immer Zahl). Stabiler Sort über dieselbe aufsteigende Eingabe wie vorher, Tie-Verhalten unverändert. attention ≡ needsAttention (zod strippt unbekannte Item-Keys, eine gemergte Zeile je Feld). Positionskorrektur vor neuerem Lauf, korrigierte und im Lauf fehlende Felder korrekt. DISTINCT-ON-Reihenfolge korrekt. Leere Eingabe: 0 Abfragen, sonst ≤ 3. Tenant-Scope via tenantOf + erzwungenes RLS (wie latestRun), auch findSampleForVisitors. Nur öffentliche Modul-APIs, depcruise grün, keine neue Abhängigkeit. Doppelte Freigabe-Meldung behoben. CHANGELOG und Klartext vorhanden. Unit lokal 44/44, Integration in CI 144/144.

Urteil: „changes requested“ – verify:full ist rot, und der Querscroll-Test belegt das 1280-px-Kriterium nicht.


Umsetzung

# Befund Umsetzung
1 Strict-mode-Verstoß im E2E 1757755: alle Klicks auf den Betreff-Link mit exact: true (auch review-smoke/line-items-smoke, dort ist derselbe Wettlauf möglich, sobald die Anfrage in REVIEW ist). CI-Lauf 36444771942 grün, 3/3 E2E
2 1280-px-Prüfung kann nicht fehlschlagen f289e19: E2E misst scrollWidth - clientWidth am .table-wrap (Test-ID requests-table-wrap)
3 Diagnose ohne Test und ohne Bezug f289e19: Summary „Details zu “ (Betreff visually-hidden), E2E fokussiert die Summary, öffnet sie mit Enter und prüft „Versuche“
4 „alles belegt“ neben „fehlt“ f289e19: Pille nur bei 0 unsicheren und 0 fehlenden Angaben
5 „Stk.“ vs. „pcs“ im Korrekturfeld f289e19: „erkannt:“ zeigt ebenfalls „Stk.“, unter der Einheiten-Korrektur steht „Einheit als ERP-Kürzel: pcs (= Stk.), mm, cm, m, kg oder t.“ Normalisierung als Folge-Issue #96
6 Startseite „Keine offene Arbeit“ f289e19: bewusst ausgeschlossen, Text jetzt „Nichts wartet auf Ihre Prüfung – …“. Ein NEW-Request mit offenem Duplikat wird nach der Verarbeitung als REVIEW oder ERROR gezählt, die Entscheidung bietet die Liste an

@Fluory
Fluory marked this pull request as ready for review September 28, 2026 16:04
@Fluory
Fluory merged commit 3e9ba75 into main Sep 28, 2026
8 of 9 checks passed
@Fluory

Fluory commented Sep 28, 2026

Copy link
Copy Markdown
Owner Author

Manueller Prüfnachweis nach dem Deploy (Showcase, Produktion 3e9ba75, Playwright 1280 × 900, Rolle Sachbearbeitung):

  • Liste: requests-table-wrap ohne Überlauf (scrollWidth − clientWidth = 0). Jede Zeile zeigt Kunde, Prüfbedarf (z. B. „⚠ 1 Wert prüfen · 1 Angabe fehlt“) und nächste Aktion („Prüfen“ oder „–“).
  • Diagnose: Die erste Summary per Tastatur fokussiert und mit Enter geöffnet (open = true), sie zeigt „Versuche 1“.
  • Startseite: „Nächster Schritt – 2 Anfragen warten auf Ihre Prüfung – Jetzt prüfen“.

This branch was successfully deployed

2 active deployments
Preview – requestflow — f289e196 Deployed Sep 28, 2026 by vercel[bot]
Preview – requestflow-ai — f289e196 Deployed Sep 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

verify-full Run verify:full (integration + E2E) in CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(requests): list and start page lead with the next work decision

1 participant