Exception review UI: multi-exception timeline + layout v1/v2/v3 (exploration)#878
Draft
petervachon wants to merge 5 commits into
Draft
Exception review UI: multi-exception timeline + layout v1/v2/v3 (exploration)#878petervachon wants to merge 5 commits into
petervachon wants to merge 5 commits into
Conversation
Invoice review template, demo API routes, and the Slack escalation server. Rebased onto latest main; prior prototype history (8 commits, incl. a merge) squashed into a single commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…toggle Add the "next" exception-review experience, toggled against "current" via a dev switch in the profile menu (InvoiceVersionProvider + ShellProfileExtras). The center panel reads as a timeline: collapsed agent history, the live exception, and any checks gated behind it. Confident fixes surface in a suggested-fix card (reasoning + apply/alternative) but never auto-resolve. Invoice-level decisions (Approve/Reject/Hold/Flag) move to a header split-button. The right panel drops the Activity tab and merges details. All agent behavior is stubbed; single-exception and cascade invoices render through the same flow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…resolve Rework the next invoice-review workspace around multiple exceptions per invoice and one source of truth across surfaces. - Data: exceptions[] with a canonical exception dictionary (label + tone per type), assignee/status on InvoiceReview, getExceptionSummary/openExceptions; fixtures converted (INV-84471 loop hero, INV-60118 multi-open, high-value as a review reason). revalidateException returns cleared/surfaced. - Shared per-invoice runtime store (InvoiceRuntimeProvider) so the workspace, queue rail, and table reflect resolution live from the same record. - Queue rail derives by assignee filter with a live +N suffix and "Ready to approve"; table exception cell shows lead + N (tooltip) or "Cleared". - Center column: stable exception index (master-detail) with ordinals and a "Viewing" indicator; stage crossfade + staggered entrance. - Phased resolve choreography (confirm -> check -> reveal -> commit): the resolved block collapses in place, nothing inserts above the live exception, and the next exception/surfaced items appear only after re-validation settles. Reduced-motion aware. - Stage headline wraps (no ellipsis); resolved marker uses user-round-check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…scroll follow Build out the invoice-review resolve flow and add the completion end state. - Completion moment: at zero open exceptions the resolve log compresses into a peek and a terminal block appears (solid-success marker, summary built from resolution shortLabels, Approve invoice / Hold wired to the header handlers). - Phased resolve choreography kept, with a cleaner Phase 1 collapse (content fades before the height animates) and no scope labels on the live stage. - Resolution data propagation: a resolution dataPatch (e.g. Link PO-5123) updates the shared record via the runtime store; header PO pill and Details Purchase order reflect it. - Chat-style scroll follow: after a resolve commits (or on selection), the column scrolls so the live block's top lands ~24px below the header, clamping to the bottom when the rest fits; user scroll cancels the follow; reduced motion applies instantly. - Header scrim (fade + blur, tunable --header-scrim-h) over the center column. - "Issue x of x" moved beside "Needs your decision" with a subtle divider. - Split-button: one primary color with a primary-600 rule between the halves. - Copy sweep: removed em-dashes from fixture and UI strings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rename the layout versions to v1 (was current), v2 (was next), and add v3; migrate the stored preference. v2 keeps the bordered exception index; v3 previews an "Up next" strip in its place, selected via an exceptionListVariant prop so the two can be compared from the Layout menu. The strip lists only open, non-active exceptions in standing order: borderless, one quiet line each (tone dot + headline + scope + optional New tag), no ordinals, chips, or "Viewing". Lines pull an exception forward on click (keyboard-focusable); it updates only at the Phase 3 commit. The index component is kept intact behind the flag. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| const LISTENER_PORT = process.env.LISTENER_PORT || "3010"; | ||
|
|
||
| export async function POST(request: NextRequest) { | ||
| let body = "{}"; |
| const LISTENER_PORT = process.env.LISTENER_PORT || "3010"; | ||
|
|
||
| export async function POST(request: NextRequest) { | ||
| let body = "{}"; |
Comment on lines
+3
to
+10
| import { | ||
| createContext, | ||
| type ReactNode, | ||
| useCallback, | ||
| useContext, | ||
| useMemo, | ||
| useState, | ||
| } from "react"; |
There was a problem hiding this comment.
Pull request overview
Exploration/prototype work for the apollo-vertex “Invoice Review / Exception review” UI, adding a multi-exception timeline flow (layout v2/v3) plus a demo-grade Slack roundtrip (Socket Mode listener + Next.js proxy routes) and a shell hook to inject a layout switch into the user profile menu.
Changes:
- Added a new timeline-based exception review surface with multi-exception staging, resolving choreography, and shared per-invoice runtime state.
- Introduced a demo-only Slack listener (isolated npm package) + demo API routes to trigger escalation, post replies, and poll shared state.
- Added shell “profile extras” slot to inject extra menu items (used to switch v1/v2/v3 layouts), plus small supporting tweaks (i18n/lang init, colors, scripts, gitignore, lint ignores).
Reviewed changes
Copilot reviewed 29 out of 31 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Adds repo-level demo scripts to start the prototype + Slack listener together. |
| apps/apollo-vertex/templates/invoice-review/README.md | Documents prototype status and migration expectations for the invoice-review template + demo routes. |
| apps/apollo-vertex/templates/invoice-review/next/SuggestedFixCard.tsx | Adds a “Suggested fix” glass card UI for AI fix suggestions and resolved confirmation state. |
| apps/apollo-vertex/templates/invoice-review/next/invoice-runtime.tsx | Adds a shared in-memory per-invoice runtime store (resolved IDs, surfaced exceptions, data patches). |
| apps/apollo-vertex/templates/invoice-review/next/invoice-review-data.ts | Adds fixtures + types + stubbed revalidation logic for invoice review and multi-exception behavior. |
| apps/apollo-vertex/templates/invoice-review/next/HeaderDecision.tsx | Adds a header split-button decision control (Approve + overflow actions). |
| apps/apollo-vertex/templates/invoice-review/next/ExceptionTimeline.tsx | Implements the timeline UI, multi-exception index/strip variants, resolve choreography, and scroll-follow behavior. |
| apps/apollo-vertex/templates/invoice-review/invoice-version.tsx | Adds v1/v2/v3 layout version selection persisted to localStorage and exposed via profile menu. |
| apps/apollo-vertex/slack/store.js | Adds JSON-file backed shared state store for the Slack demo (atomic writes, message ingestion). |
| apps/apollo-vertex/slack/server.js | Adds Socket Mode Slack listener (posts escalation card, handles actions, ingests replies, exposes local HTTP endpoints). |
| apps/apollo-vertex/slack/reset-demo.js | Adds reset script to delete bot messages and reset the shared demo store. |
| apps/apollo-vertex/slack/README.md | Documents running/configuring the standalone Slack listener demo. |
| apps/apollo-vertex/slack/package.json | Defines the isolated Slack listener npm package and its dependencies. |
| apps/apollo-vertex/slack/escalation-card.js | Adds the Block Kit escalation card builder used by the Slack listener. |
| apps/apollo-vertex/registry/shell/shell-user-profile-menu-items.tsx | Renders injected “profile extras” items in the shell user profile menu. |
| apps/apollo-vertex/registry/shell/shell-profile-extras.tsx | Adds a shell provider + hook for optional profile-menu item injection. |
| apps/apollo-vertex/registry/button/button.tsx | Tweaks button base styles (adds cursor-pointer). |
| apps/apollo-vertex/registry.json | Adds “insight-*” color tokens used by the timeline UI. |
| apps/apollo-vertex/package.json | Adds app-level demo scripts to start UI + Slack listener together. |
| apps/apollo-vertex/locales/en.json | Adds missing “invoices” translation key. |
| apps/apollo-vertex/lib/i18n.ts | Prevents re-initializing i18n, while ensuring <html lang> stays in sync. |
| apps/apollo-vertex/app/invoice-review/page.tsx | Adds a dedicated route to render the invoice review template fullscreen. |
| apps/apollo-vertex/app/api/demo-trigger/route.ts | Adds server-side proxy route to trigger Slack escalation via the local listener. |
| apps/apollo-vertex/app/api/demo-state/route.ts | Adds server route to read the shared JSON demo state for UI polling. |
| apps/apollo-vertex/app/api/demo-reply/route.ts | Adds server-side proxy route to post replies into the Slack thread via the local listener. |
| apps/apollo-vertex/app/_meta.ts | Hides the invoice-review route from navigation. |
| apps/apollo-vertex/.oxlintrc.json | Excludes demo/prototype directories and demo API routes from oxlint. |
| apps/apollo-vertex/.gitignore | Ignores Slack demo runtime state and isolated Slack listener install artifacts. |
| apps/apollo-vertex/.env.example | Adds example env vars for the Slack demo (tokens/channel/port). |
Comment on lines
+17
to
+20
| * Per-invoice disposition control for the page header: a primary Approve | ||
| * split-button with an attached overflow (Reject / Hold / Flag). Approve is | ||
| * locked until the timeline reports the invoice is clear; the overflow stays | ||
| * enabled so a reviewer can always Reject/Hold/Flag. |
Comment on lines
+28
to
+29
| // Accepted for API compatibility; Approve is no longer gated on it. | ||
| canApprove: boolean; |
Comment on lines
+3
to
+10
| import { | ||
| createContext, | ||
| type ReactNode, | ||
| useCallback, | ||
| useContext, | ||
| useMemo, | ||
| useState, | ||
| } from "react"; |
Comment on lines
+1
to
+2
| "use client"; | ||
| import { InvoiceReviewTemplate } from "@/templates/invoice-review/InvoiceReviewTemplate"; |
Comment on lines
+23
to
+24
| "demo": "apps/apollo-vertex/slack/node_modules/.bin/concurrently --names APP,SLACK --prefix-colors cyan,magenta \"pnpm --filter apollo-vertex dev\" \"cd apps/apollo-vertex/slack && npm start\"", | ||
| "demo:reset": "cd apps/apollo-vertex/slack && npm run reset-demo", |
Comment on lines
+10
to
+16
| export async function POST(request: NextRequest) { | ||
| let body = "{}"; | ||
| try { | ||
| body = JSON.stringify(await request.json()); | ||
| } catch { | ||
| body = "{}"; // no body is fine — listener falls back to demo defaults | ||
| } |
Comment on lines
+10
to
+16
| export async function POST(request: NextRequest) { | ||
| let body = "{}"; | ||
| try { | ||
| body = JSON.stringify(await request.json()); | ||
| } catch { | ||
| body = "{}"; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Exception review UI (exploration). Supersedes #872 (closed to re-trigger the deployment).
The invoice-review detail area is reworked around a timeline where the reviewer answers one question at a time. Selectable via the profile-menu Layout switch:
Highlights:
All agent behavior is stubbed; single-exception and cascade invoices render through the same flow.
🤖 Generated with Claude Code