Skip to content

feat(web): EYT-147 Dispositionswerkbank Slice 1 — die Woche ist die Werkbank - #101

Open
DYAI2025 wants to merge 6 commits into
masterfrom
feat/eyt-147-dispositionswerkbank-slice-1
Open

feat(web): EYT-147 Dispositionswerkbank Slice 1 — die Woche ist die Werkbank#101
DYAI2025 wants to merge 6 commits into
masterfrom
feat/eyt-147-dispositionswerkbank-slice-1

Conversation

@DYAI2025

@DYAI2025 DYAI2025 commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Current status — reconciled 01.09.2026

WIP: EYT-147 only
Architecture gate: EYT-125 ACCEPTED / Jira Fertig / Confluence 41484289
Current head: cc92ceb38dcd1f317c05a7a7caec2561c8d12f4f
Merge status: DO_NOT_MERGE — M1–M8 implementation, tests and Human-PO visual gate are not complete.

Product direction

Der Kalender ist der Überblick – die Woche ist die Werkbank.

The visible primary planning object is the worksite / explicit local WorksiteDay. Employees remain concrete assignments below that planning object. A worksite with multiple employees must not appear as one primary card per employee.

Canonical product decision: Confluence 38993921.
Canonical WorksiteDay/revision/locking/idempotency architecture: Confluence 41484289.

What is already preserved from the original UI slice

The existing PR work provides a tested weekly workbench foundation that should be preserved where compatible with the accepted domain model:

  • seven-day weekly layout;
  • accessible non-modal inspector;
  • plan status / publish presentation;
  • server-confirmed read-through after mutation;
  • reload and second-browser persistence evidence;
  • existing auth, tenant and costs boundaries;
  • existing responsive/accessibility guards.

The old visible model was assignment-centered and failed the Human-PO product gate. It is not the final accepted redesign.

M1 — implemented on current head

Commit cc92ceb… adds the data/security foundation for the worksite-centered model:

  • migration 0019_worksite_days;
  • stable public.worksite_days identity by organization/worksite/local date;
  • revision-bound public.worksite_day_configurations;
  • additive nullable assignments.worksite_day_configuration_id with tenant-bound integrity;
  • bounded idempotency replay payload access;
  • domain-bound assignment removal helper;
  • shared week-draft lock helper;
  • no second publish truth: plan_versions.published_at remains authoritative;
  • no general authenticated assignment UPDATE/DELETE grant;
  • no backfill of historical published assignments.

CI run 33506442308 on exactly cc92ceb… is completed/success with all 11 required jobs green, including db-gates, auth-journey, read-through, web-smoke, builds, typecheck, lint and secret-scan.

M1 is IMPLEMENTED_CI_GREEN / SEMANTIC_REVIEW_PENDING. Green CI is not yet the semantic acceptance of M1 against the full EYT-125 architecture contract.

Remaining accepted implementation sequence

  • M2 Contracts/OpenAPI — OPEN
  • M3 planWorksiteDay — OPEN
  • M4 updateWorksiteDayTeam — OPEN
  • M5 PlanningWindow.worksiteDays[] + draft/publish copy/remap/preservation — OPEN
  • M6 UI conversion from one card per assignment to one primary WorksiteDay card with subordinate team — OPEN
  • M7 real worksite-centered browser journey — OPEN
  • M8 full repository/CI/accessibility/Human-PO gates — OPEN

Do not start EYT-114 or EYT-150 in parallel. WIP remains exactly one.

Slice-1 scope boundary

Included in the accepted first cross-layer slice:

  • WorksiteDay / WorksiteDayConfiguration foundation;
  • two new day/team commands;
  • additive PlanningWindow projection;
  • publish completeness/preservation;
  • worksite-centered weekly workbench;
  • one shared initial interval for multiple employees in the first UI slice.

Not included here:

  • month / rolling multi-week admin calendar (EYT-114);
  • persistent worksite color identity (EYT-150);
  • default generator / range planning / series application;
  • day status, activities, resources, submit;
  • full individualized multi-interval authoring (EYT-121);
  • disabling legacy createAssignment;
  • fake placeholder functionality.

Human-PO gate

Still open:

Would we show this surface to a customer today as EasyTree?

The answer for the current PR state remains no, because the visible worksite-centered M6 redesign has not yet been implemented and accepted.

Review source-of-truth rule

Before any material review or merge decision, reload:

  1. GitHub current PR head + diff + CI;
  2. Jira EYT-147 current scope/status;
  3. Confluence 41484289 architecture contract;
  4. Confluence 38993921 product decision;
  5. Confluence 31948801 current delivery reconciliation.

Older PR text, older heads, historical Jira comments and dated Confluence snapshots are audit history only and must not override newer live truth.

Current verdict

EYT-147 IN_PROGRESS — M1 IMPLEMENTED_CI_GREEN / SEMANTIC_REVIEW_PENDING — PR #101 DO_NOT_MERGE

BenPerro and others added 4 commits August 31, 2026 02:05
…e ihrer Woche legen

Reine Zuordnungsfunktion über die kanonischen Domain-Helfer
(planningWeekDateRange, dayAfter, localBusinessDate): der Kalendertag eines
Einsatzes ist der Tag seines Beginns in der Organisationszone, eine
Nachtschicht bleibt am Tag ihres Beginns. Nichts verschwindet: Einsätze
ausserhalb der Woche wandern sichtbar nach ausserhalb, unbekannte Zone oder
unlesbarer Wochenschlüssel ergeben unbestimmbar mit Grund statt eines leeren
Rasters. Drei Gegenmutationen ausgeführt (UTC-Datumszuordnung,
ausserhalb-Verschlucken, Id-only-Sortierung) — jede macht genau ihren Test
rot; Fixtures widersprechen dem Id-Tiebreak absichtlich.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Die Planungsansicht zeigt die Woche als räumliche Tagesachse Mo–So;
Einsätze stehen als kompakte Karten (Zeit, Baustelle, Person) am Kalendertag
ihres Beginns, der Planstand trägt zusätzlich Form (gestrichelt/Kante) statt
nur Farbe. Das unveränderte Einsatzformular wandert in einen nichtmodalen
seitlichen Inspector hinter „Einsatz anlegen“: anfangs geschlossen, Fokus
beim Öffnen im ersten Feld, Escape und Schließen stellen den Fokus auf den
Auslöser zurück, nach Erfolg bleibt er offen (Erfolgsmeldung überlebt den
Read-through). Genau eine primäre Aktion je Zustand: mit
veröffentlichbarem Entwurf ist es „Plan veröffentlichen“, sonst „Einsatz
anlegen“. Die Standmarke der Publish-Aktion entfällt auf versionslosen
Wochen — es gibt dort keinen Stand zu benennen. Alle Serverwahrheits-,
Testid- und data-Anker bleiben erhalten; CSS nur über die Basisdesign-Tokens,
die Planungsfläche bekommt über :has() die Breite, die eine Wochenachse
braucht, ohne die vermessene Startseiten-Geometrie zu bewegen. Zwei
Gegenmutationen ausgeführt (Inspector anfangs offen; Auslöser unbedingt
primär) — beide rot an den benannten Tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
read-through: wocheOeffnen wartet auf Auslöser+Liste statt auf das nicht
mehr dauerhaft gerenderte Formular; inspectorOeffnen (idempotent) vor jedem
Formularzugriff, auch in den Responsive-/A11y-Fällen 1440/375. auth-journey:
neuer Schritt 9c1b legt in der eigenen Woche 2026-W34 (W32/W33/W35–W37
tragen abgenommene Zahlen bzw. Angriffe) einen Einsatz über den Inspector an
— echte GoTrue-Identität, 201 vom realen Command, serverbestätigte Karte am
Dienstag, Reload mit derselben Id, Woche wird Entwurf; danach zurück in die
Publish-Woche, sonst veröffentlichte 9d den falschen Entwurf (im ersten Lauf
gemessen). Staging-Journey öffnet den Inspector im Anlege-Helfer und misst
die Tastaturöffnung (Enter auf dem Auslöser → Fokus im ersten Feld); dieser
Spec ist aktualisiert, aber mangels Staging-Deploys dieses Heads nicht
ausgeführt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Slices

Versionierte Parity-Matrix am Baseline-Head f8e96e4: jede Vertragsoperation
mit realer UI-Route oder begründetem Nicht-UI-Systempfad; Edit/Löschen/
Drag&Drop/Karten-Konflikte als CAPABILITY_GAP benannt statt erfunden.
Evidenz-README mit Befehlen, gemessenen Zahlen, fünf ausgeführten
Gegenmutationen und den Screenshots aus dem grünen lokalen
auth-journey-Lauf (1440/1920, Entwurf, Inspector, serverbestätigte Karte,
veröffentlicht, zweiter Kontext).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @DYAI2025, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 3 days and 7 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Reviewer's Guide

Der PR verwandelt /planung in eine responsive Wochenarbeitsfläche: Einsätze werden über kanonische Zeitzonen- und Kalenderlogik auf sieben Tage verteilt, über einen fokussierten nichtmodalen Inspector angelegt und weiterhin über unveränderte Server-Commands bestätigt und veröffentlicht; umfangreiche Unit-, E2E- und Evidenzanpassungen sichern Serverwahrheit, Accessibility und bewusst ausgelassene Capability-Gaps ab.

Sequence diagram for creating and publishing a planning assignment

sequenceDiagram
    actor Disponentin
    participant Planung as Planung
    participant Inspector as AssignmentForm
    participant Gateway as PlanningGateway
    participant Server as PlanningAPI

    Disponentin->>Planung: click werkbank-einsatz-anlegen
    Planung->>Inspector: open and focus first field
    Disponentin->>Inspector: fill assignment fields
    Disponentin->>Inspector: click einsatz-speichern
    Inspector->>Gateway: createAssignment
    Gateway->>Server: POST /planung/einsaetze
    Server-->>Gateway: 201 assignment id
    Gateway-->>Planung: server response
    Planung->>Gateway: getPlanningWindow
    Gateway->>Server: GET /planung/fenster
    Server-->>Gateway: assignment and draft version
    Gateway-->>Planung: updated planning window
    Disponentin->>Planung: click planung-veroeffentlichen
    Planung->>Gateway: publishPlan
    Gateway->>Server: POST /planung/versionen
    Server-->>Gateway: published version id
    Gateway-->>Planung: publish result
Loading

State diagram for planning version status and primary action

stateDiagram-v2
    [*] --> KeineVersion
    KeineVersion --> Entwurf: createAssignment / Read-through
    Entwurf --> Veröffentlicht: publishPlan
    Veröffentlicht --> Veröffentlicht: reload / getPlanningWindow

    state KeineVersion {
        [*] --> EinsatzAnlegenPrimaer
    }
    state Entwurf {
        [*] --> VeröffentlichenPrimaer
    }
    state Veröffentlicht {
        [*] --> EinsatzAnlegenPrimaer
    }
Loading

Flow diagram for rendering the weekly planning workbench

flowchart TD
    A[Planning window from server] --> B[wochenraster]
    B --> C{Week key and time zone valid?}
    C -- No --> D[Show warning and flat assignment list]
    C -- Yes --> E[planningWeekDateRange]
    E --> F[localBusinessDate for assignment start]
    F --> G{Start belongs to one of seven days?}
    G -- Yes --> H[Render assignment card in matching day column]
    G -- No --> I[Render in Ausserhalb dieser Woche]
    H --> J[Show time, worksite, and employee]
    I --> J
Loading

File-Level Changes

Change Details Files
Die Planungsansicht wird von einer flachen Einsatzliste zu einer responsiven Dispositionswerkbank mit Wochenraster, Planstandsanzeige und zustandsabhängiger Primäraktion umgebaut.
  • Breite und Toolbar-Anordnung auf der Planungsfläche angepasst, ohne andere Shell-Flächen zu verändern.
  • Sieben Tagesspalten mit Einsatzkarten für Uhrzeit, Baustelle und Person eingeführt.
  • Entwurfs- und Veröffentlichungszustände über Text, Statusbadge und Kartenform dargestellt.
  • Einsätze außerhalb der Woche sichtbar in einem separaten Bereich ausgegeben.
  • Versionslose Wochen von der irreführenden Entwurfsmarke befreit.
apps/web/app/globals.css
apps/web/components/planning-publish-action.tsx
apps/web/components/planning-window-view.tsx
Die Tageszuordnung und Zeitdarstellung werden in einer dedizierten, domainbasierten Rasterlogik gekapselt.
  • Wochenschlüssel und Zeitzone validiert und bei Fehlern auf eine ehrliche flache Liste zurückgefallen.
  • Beginn eines Einsatzes anhand der Organisationszeitzone dem passenden Kalendertag zugeordnet.
  • Nachtschichten, Jahreswechsel, DST-Fälle, Sortierung und Ausnahmen berücksichtigt.
  • Wanduhrzeiten explizit in der Organisationszeitzone formatiert.
apps/web/lib/wochenraster.ts
apps/web/test/wochenraster.test.ts
Das Anlegen eines Einsatzes wird in einen nichtmodalen Inspector mit definiertem Fokus- und Aktionsverhalten verlagert.
  • Formular initial aus dem DOM entfernt und über „Einsatz anlegen“ geöffnet.
  • Fokus beim Öffnen ins erste Formularfeld gesetzt.
  • Escape und Schließen-Schaltfläche schließen den Inspector und stellen den Fokus auf den Auslöser zurück.
  • Primäraktion abhängig von Veröffentlichungsrecht und Planstand auf genau eine Schaltfläche begrenzt.
apps/web/components/planning-window-view.tsx
apps/web/test/dispositionswerkbank.test.tsx
apps/web/test/planning-window-view.test.tsx
Die bestehenden Browser- und Journey-Tests werden auf den Inspector und die reale Wochenreise aktualisiert und um Server-Read-through-Nachweise ergänzt.
  • E2E-Helfer öffnen den Inspector idempotent vor Formularinteraktionen.
  • Reale Anlage, Read-through, Reload, Entwurfsstatus und Folge-Publish in die Auth-Journey aufgenommen.
  • Tastaturfokus, responsive Darstellung und bestehende Serverwahrheitsprüfungen angepasst.
  • Erhöhtes Testtimeout für die belastete Serverwahrheits-Suite dokumentiert.
apps/web/e2e/auth-journey/journey.pwtest.ts
apps/web/e2e/read-through.spec.ts
apps/web/e2e/staging/journey.pwtest.ts
apps/web/test/werkbank-serverwahrheit.test.tsx
Die Slice-Evidenz und Capability-Grenzen werden dokumentiert, ohne API-, Datenbank- oder Dependency-Änderungen einzuführen.
  • Lokale Format-, Lint-, Typ-, Build-, Unit-, Smoke-, Read-through- und Auth-Ergebnisse festgehalten.
  • Bewusste Nicht-Implementierungen wie Bearbeiten, Löschen, Drag-and-Drop und Kartenkonflikte abgegrenzt.
  • Browser-, Accessibility- und Gegenmutations-Evidenz ergänzt.
docs/evidence/2026-08-31-eyt-147-slice-1/README.md
docs/evidence/2026-08-31-eyt-147-slice-1/ui-parity-matrix.md
apps/web/test/planning-publish-action.test.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

…r Maschine

PO-Review-Reparatur des ersten Werkbank-Slices, vier Findings:

- R1: keine rohe Planversions-UUID und kein roher ISO-Zeitstempel mehr im
  sichtbaren Text; die echten Server-Ids bleiben unveraendert in den
  data-*-Seams, der Publish-Instant neu in data-published-at-utc.
- R2: genau EIN sichtbares StatusBadge fuer den Planstand (Wochenansicht);
  planung-stand-marke bleibt als unsichtbarer Seam mit Testanker,
  Screenreader-Text und data-stand erhalten.
- R3: das Einsatzformular im Inspector traegt die Basisdesign-v2-Tokens
  (Feldgruppen, Beginn/Ende nebeneinander, Meldungs-Toene); Semantik,
  Testanker, Validierung und Zeitzonenlogik unveraendert.
- R4: sichtbare Texte auf korrektes Deutsch (Veroeffentlicht -> Veröffentlicht,
  Ausserhalb -> Außerhalb, fuer -> für); technische Werte unveraendert.

Neuer Guard werkbank-oberflaechenguards.test.tsx (UUID-/Instant-Leck,
Seam-Erhalt, Badge-Zaehlung); beide Gegenmutationen ausgefuehrt, rot
gemessen, byte-identisch zurueckgenommen. Browser-Evidenz aus frischem
gruenem auth-journey-Lauf regeneriert.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sourcery-ai[bot]
sourcery-ai Bot previously approved these changes Aug 31, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

@DYAI2025 DYAI2025 changed the title feat(web): EYT-147 Dispositionswerkbank Slice 1 — die Woche ist das Produkt feat(web): EYT-147 Dispositionswerkbank Slice 1 — die Woche ist die Werkbank Aug 31, 2026
Migration 0019 legt das Daten- und Sicherheitsfundament der
baustellenzentrierten Planung an (EYT-125 Architektur, EYT-147 Slice M1):

- public.worksite_days als stabile, versionsuebergreifende Tagesidentitaet
  (I-4 unique auf org_id, worksite_id, local_date; keine Zeiten, kein
  eigener Publish-Marker)
- public.worksite_day_configurations als revisionsgebundener Tagesstand
  (I-3 unique auf plan_version_id, worksite_day_id)
- assignments.worksite_day_configuration_id additiv und nullable, mit
  tenantgebundenem FK und I-1-Zugehoerigkeitstrigger. Kein Backfill.
- idempotency_records.result_payload mit Spalten-Lesegrenze; die einzige
  Lesestelle ist app.read_idempotency_result
- app.remove_assignment_from_worksite_day, app.read_idempotency_result und
  app.lock_week_draft

plan_versions.published_at bleibt die alleinige Publish-Wahrheit. Auf
assignments entsteht keine zweite Schreibpolicy, und update/delete bleiben
entzogen; der INSERT-Grant waechst um genau eine Spalte.

supabase/tests/0014_worksite_days.sql fuehrt 80 Zusicherungen, rot vor der
Migration gemessen. 0005_schema_meta_gate.sql bekommt die zwei neuen
Tabellen und eine auf idempotency_records eingegrenzte Ausnahme, weil 0019
dort das Tabellen-select entzieht.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014DZFb9AFuQTGm12SuneDCA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants