From bcff8836885dc4e9b616e63f80d2bcf07d83d208 Mon Sep 17 00:00:00 2001 From: Sami Rusani Date: Tue, 17 Mar 2026 09:40:43 +0100 Subject: [PATCH] Sprint 6C: stabilize web workspace verification --- .ai/active/SPRINT_PACKET.md | 191 ++++++++++------------- BUILD_REPORT.md | 186 +++++++--------------- REVIEW_REPORT.md | 44 +++--- apps/web/components/approval-actions.tsx | 10 +- apps/web/eslint.config.mjs | 21 +++ apps/web/next-env.d.ts | 4 +- apps/web/package.json | 2 +- apps/web/tsconfig.json | 26 ++- 8 files changed, 206 insertions(+), 278 deletions(-) create mode 100644 apps/web/eslint.config.mjs diff --git a/.ai/active/SPRINT_PACKET.md b/.ai/active/SPRINT_PACKET.md index 91a174b..57a9be8 100644 --- a/.ai/active/SPRINT_PACKET.md +++ b/.ai/active/SPRINT_PACKET.md @@ -2,187 +2,156 @@ ## Sprint Title -Sprint 6B: Governed Request Submission and Actionable Approval Workflow +Sprint 6C: Web Workspace Verification Stabilization ## Sprint Type -ui +repair ## Sprint Reason -Sprint 6A delivered the first real AliceBot web shell, but it is still mostly a review surface. The highest-value next MVP gap is not another Gmail or docs sprint; it is turning the shell into a usable governed workflow surface. The backend already ships approval request creation, approval resolution, and task/task-step reads, so the next safe step is to wire those existing seams into the web UI without expanding backend scope. +Sprint 6B successfully turned the shell into a governed workflow surface, but the accepted review still identified two recurring frontend quality issues: `npm run lint` is not a usable non-interactive check, and `next build` still rewrites `apps/web/tsconfig.json` plus `apps/web/next-env.d.ts` during verification. Before stacking more UI work on top of the shell, the web workspace needs one narrow stabilization sprint so future UI delivery is not slowed down by avoidable tooling churn. ## Sprint Intent -Extend the web shell so the operator can submit governed requests, review live approval details, approve or reject them from the UI, and inspect the resulting task/task-step state, using existing backend endpoints only. +Stabilize the `apps/web` workspace so lint and build are clean, repeatable, non-interactive verification steps, while preserving the Sprint 6A and Sprint 6B operator shell behavior and avoiding any backend scope changes. ## Git Instructions -- Branch Name: `codex/sprint-6b-governed-request-approval-ui` +- Branch Name: `codex/sprint-6c-web-workspace-verification-stabilization` - Base Branch: `main` - PR Strategy: one sprint branch, one PR, no stacked PRs unless Control Tower explicitly opens a follow-up sprint - Merge Policy: squash merge only after reviewer `PASS` and explicit Control Tower merge approval ## Why This Sprint -- Sprint 6A proved the web shell can render a calm, high-trust operator interface aligned to `DESIGN_SYSTEM.md`. -- The current shell still leaves the key governed workflow mostly inert: - - requests are not yet clearly submitted through the approval-request seam - - approvals are inspectable but not actionable from the UI - - tasks can be viewed but not as the immediate downstream result of a governed request -- The product brief requires web-based chat and task orchestration with explicit approval for consequential actions. -- The narrowest safe next step is to wire the existing approval and task seams into the shell, not to invent new backend features. +- Sprint 6A opened the first real web shell. +- Sprint 6B made the shell workflow-bearing with governed request submission, approvals, and live task inspection. +- The accepted review for Sprint 6B called out: + - `npm run lint` is still interactive because the web workspace lacks a committed lint setup + - `next build` still rewrites `apps/web/tsconfig.json` and `apps/web/next-env.d.ts` +- Those are not merge blockers for 6B, but they will keep generating review friction and workspace churn if not fixed now. +- The narrowest safe next step is to stabilize the web workspace itself, not to widen UI scope or reopen backend work. ## Design Truth -- `DESIGN_SYSTEM.md` remains in force for this sprint. -- The UI must keep the calm, premium, restrained operator feel established in Sprint 6A. -- Interaction states must feel stable and explicit: - - pending - - submitting - - approved - - rejected - - loading - - empty -- Avoid noisy notification patterns or consumer-chat styling. - -## Exact Screens In Scope - -- `/chat` - - governed request composer - - request mode focused on the shipped approval-request seam - - resulting request summary state -- `/approvals` - - live approval inbox list - - approval detail inspector - - approve action - - reject action -- `/tasks` - - live task list - - selected task summary - - live task-step inspection - - visible linkage from approval outcome to task state when available - -## Exact Components In Scope - -- existing shared shell primitives from Sprint 6A, refined as needed -- governed request form -- approval detail inspector -- approval action bar -- task summary panel -- task-step status list -- inline success/error state messaging for approval actions -- empty/loading state variants for live workflow screens +- `DESIGN_SYSTEM.md` remains the design source of truth. +- This sprint is not a new visual redesign sprint. +- UI behavior and styling should remain materially unchanged except where small markup or styling adjustments are needed to support stable lint/build verification. ## Exact Files In Scope -- `DESIGN_SYSTEM.md` - - reference only; do not rewrite unless the sprint reveals a concrete contradiction that must be corrected +- `apps/web/package.json` +- `apps/web/tsconfig.json` +- `apps/web/next-env.d.ts` +- `apps/web/next.config.mjs` +- `apps/web/eslint.config.mjs` +- `apps/web/app/layout.tsx` +- `apps/web/app/page.tsx` - `apps/web/app/chat/page.tsx` - `apps/web/app/approvals/page.tsx` - `apps/web/app/tasks/page.tsx` +- `apps/web/app/traces/page.tsx` +- `apps/web/app/approvals/loading.tsx` +- `apps/web/app/tasks/loading.tsx` - `apps/web/app/globals.css` -- `apps/web/components/request-composer.tsx` -- `apps/web/components/approval-list.tsx` -- `apps/web/components/task-list.tsx` -- `apps/web/components/task-step-list.tsx` +- `apps/web/components/app-shell.tsx` +- `apps/web/components/page-header.tsx` - `apps/web/components/section-card.tsx` - `apps/web/components/status-badge.tsx` - `apps/web/components/empty-state.tsx` +- `apps/web/components/request-composer.tsx` +- `apps/web/components/approval-list.tsx` - `apps/web/components/approval-actions.tsx` - `apps/web/components/approval-detail.tsx` +- `apps/web/components/task-list.tsx` - `apps/web/components/task-summary.tsx` +- `apps/web/components/task-step-list.tsx` +- `apps/web/components/trace-list.tsx` - `apps/web/lib/api.ts` - `apps/web/lib/fixtures.ts` -- `apps/web/package.json` +- `apps/web/lib/api.test.ts` +- `apps/web/components/approval-actions.test.tsx` +- `apps/web/test/setup.ts` +- `apps/web/vitest.config.ts` +- `BUILD_REPORT.md` ## In Scope -- Wire `/chat` to the existing governed request path using shipped backend behavior only. -- Support governed request submission through existing endpoints such as: - - `POST /v0/approvals/requests` -- Support live approval review using existing endpoints such as: - - `GET /v0/approvals` - - `GET /v0/approvals/{approval_id}` if already available through the current web layer pattern - - `POST /v0/approvals/{approval_id}/approve` - - `POST /v0/approvals/{approval_id}/reject` -- Support live task and task-step review using existing endpoints such as: - - `GET /v0/tasks` - - `GET /v0/tasks/{task_id}` - - `GET /v0/tasks/{task_id}/steps` -- Keep fixture-backed fallback behavior explicit when API configuration is absent. -- Keep all workflow state user-scoped and visibly deterministic. +- Commit a stable non-interactive lint configuration for `apps/web`. +- Ensure `npm run lint` runs without prompting for ESLint initialization. +- Ensure `npm run build` no longer creates uncommitted churn in `apps/web/tsconfig.json` or `apps/web/next-env.d.ts`. +- Adopt or normalize any framework-generated TypeScript config changes deliberately so future builds stay clean. +- Keep the Sprint 6A and 6B screens, routes, and workflow behavior intact. +- Update or add narrow frontend tests only as needed to preserve current behavior while the workspace config is being stabilized. ## Out of Scope - No new backend endpoints. - No backend schema changes. -- No approval execution from the web UI yet. -- No task-step mutations from the web UI beyond review. -- No general trace-event listing backend work. +- No new product workflow features. - No Gmail breadth, Calendar UI, or connector expansion. - No auth redesign. -- No full magnesium reorder workflow yet. +- No new pages or routes beyond what already shipped in 6A/6B. +- No visual redesign of the shell. - No runner-style orchestration UI. ## Required Deliverables -- A governed request submission surface in `/chat`. -- Actionable approve and reject controls in `/approvals`. -- Live task and task-step inspection that reflects governed-request outcomes in `/tasks`. -- Stable loading, empty, success, and failure states for those workflow surfaces. +- A committed non-interactive lint setup for `apps/web`. +- A stable build setup that does not rewrite tracked web config files during routine verification. +- Preserved Sprint 6A and 6B behavior across the shipped routes and workflow surfaces. - Updated `BUILD_REPORT.md` with exact verification results and explicit deferred scope. ## Acceptance Criteria -- `/chat` can submit a governed request through an existing shipped backend path when API configuration is present. -- `/approvals` can approve and reject approvals through existing shipped backend endpoints when API configuration is present. -- `/tasks` reflects live task/task-step state from existing shipped endpoints when API configuration is present. -- When API configuration is absent, the UI falls back to explicit fixture-backed or empty states instead of broken behavior. -- The sprint stays within the exact in-scope screens, components, and files listed above. -- The UI continues to follow `DESIGN_SYSTEM.md` materially. +- `npm run lint` in `apps/web` runs non-interactively and passes. - `npm run build` in `apps/web` passes. -- Any added checks pass if introduced. +- Running `npm run build` after a clean checkout does not create uncommitted churn in `apps/web/tsconfig.json` or `apps/web/next-env.d.ts`. +- The shipped routes remain intact: + - `/` + - `/chat` + - `/approvals` + - `/tasks` + - `/traces` +- The governed request, approval, and task UI behavior from Sprint 6B remains intact. +- No backend scope expansion enters the sprint. ## Implementation Constraints - Keep the sprint narrow and boring. -- Reuse existing backend seams only; do not hide backend feature requests inside the UI sprint. -- Keep the governed-request flow explicit and reviewable, not magical. -- Preserve the visual calm and text containment established in Sprint 6A. -- If an endpoint or payload is not stable enough for live use, degrade cleanly to an explicit unavailable state rather than inventing new backend logic. +- Treat this as workspace stabilization, not a feature sprint. +- Prefer adopting framework-required config intentionally over repeatedly reverting generated files. +- Do not hide UI redesign work inside lint/build cleanup. +- If markup changes are needed to satisfy the committed lint rules, keep them minimal and behavior-preserving. ## Suggested Work Breakdown -1. Refactor the current shell data layer into a clearer shared API helper plus fixtures. -2. Wire governed request submission into `/chat`. -3. Add approval detail plus approve/reject actions in `/approvals`. -4. Strengthen `/tasks` to show the downstream task/task-step state from the governed workflow. -5. Add deterministic loading, success, error, and empty states. -6. Run frontend build and any introduced checks. -7. Update `BUILD_REPORT.md` with executed verification. +1. Add a committed ESLint configuration for `apps/web`. +2. Normalize package scripts so lint/test/build form a stable non-interactive verification set. +3. Resolve the `next build` config churn by adopting or normalizing the generated TypeScript settings deliberately. +4. Run lint, tests, and build to confirm a clean repeatable web workspace. +5. Update `BUILD_REPORT.md` with exact verification and any intentionally adopted config changes. ## Build Report Requirements `BUILD_REPORT.md` must include: -- the exact screens and components implemented or updated -- the exact files changed -- which routes are live-API-backed, fixture-backed, or mixed -- the exact shipped backend endpoints consumed by the UI -- exact commands run -- build and test results -- concise desktop and mobile visual verification notes -- what remains intentionally deferred after this sprint +- the exact workspace/config files changed +- the lint command and build command used +- whether TypeScript or Next-generated config changes were intentionally adopted +- exact verification results for lint, test, and build +- confirmation that Sprint 6A/6B route behavior remained intact +- what remains intentionally deferred after this repair sprint ## Review Focus `REVIEW_REPORT.md` should verify: -- the sprint stayed a UI sprint and did not widen backend product scope -- the governed request, approval, and task workflow uses only existing shipped backend seams -- `DESIGN_SYSTEM.md` was followed materially -- loading, empty, success, and error states are stable and readable -- no hidden Gmail breadth, Calendar, runner, auth-scope, or backend-scope expansion entered the sprint +- the sprint stayed a repair sprint and did not widen backend or product scope +- `npm run lint` is now non-interactive and passes +- `npm run build` is stable and no longer rewrites tracked config files during routine verification +- Sprint 6A/6B route behavior remains intact +- no hidden UI redesign, Gmail breadth, Calendar, auth, runner, or backend-scope expansion entered the sprint ## Exit Condition -This sprint is complete when the AliceBot web shell can submit governed requests, resolve approvals through approve/reject UI actions, and reflect resulting task/task-step state through the existing backend seams, while staying within the current UI and backend boundaries. +This sprint is complete when the `apps/web` workspace has stable non-interactive lint/build verification, no longer creates routine config churn during `next build`, and preserves the shipped operator shell behavior from Sprints 6A and 6B. diff --git a/BUILD_REPORT.md b/BUILD_REPORT.md index 8d1d0a6..cd22fe1 100644 --- a/BUILD_REPORT.md +++ b/BUILD_REPORT.md @@ -2,155 +2,85 @@ ## sprint objective -Implement Sprint 6B: turn the web shell into a governed workflow surface that can submit approval requests, resolve approvals from the UI, and inspect downstream task and task-step state using existing shipped backend seams only. +Implement Sprint 6C: stabilize the `apps/web` workspace so lint and build are clean, repeatable, non-interactive verification steps while preserving the shipped Sprint 6A and Sprint 6B shell routes and workflow behavior. ## completed work -- `/chat` - - replaced the old response-oriented composer with governed approval-request submission - - added explicit request fields for `thread_id`, `tool_id`, `action`, `scope`, optional hints, and JSON attributes - - added resulting request summary cards with decision, approval linkage, task linkage, and trace references -- `/approvals` - - kept the live inbox list - - added a dedicated approval detail inspector component - - added actionable approve and reject controls backed by existing resolution endpoints - - added an explicit route-level `loading.tsx` boundary for slow live reads - - added inline action-state messaging for ready, submitting, success, and failure states -- `/tasks` - - kept the live task list - - added a dedicated task summary panel - - added live task detail reads through `GET /v0/tasks/{task_id}` - - added an explicit route-level `loading.tsx` boundary for slow live reads - - strengthened task-step inspection with sequencing metadata and approval linkage -- shared web layer - - created `apps/web/lib/api.ts` for shared types, config, endpoint helpers, and live-mode detection - - created `apps/web/lib/fixtures.ts` for explicit fixture-backed fallback data - - added new shared components: - - `approval-actions` - - `approval-detail` - - `task-summary` - - added a minimal Vitest-based web test setup with unit coverage for the API helper layer and a UI flow boundary test for approval resolution - - updated styling in `apps/web/app/globals.css` for governed form layout, action bars, responsive field grids, and richer workflow state presentation +- committed a stable ESLint setup in `apps/web` and switched the web lint script to `eslint . --max-warnings=0` so `npm run lint` no longer invokes interactive `next lint` setup +- intentionally adopted the Next-generated TypeScript config updates in `apps/web/tsconfig.json` + - added `esModuleInterop: true` + - added the `next` TypeScript plugin + - added `.next/types/**/*.ts` to `include` +- intentionally adopted the framework-managed `apps/web/next-env.d.ts` header text produced by Next.js +- made one behavior-preserving component change in `apps/web/components/approval-actions.tsx` to satisfy the committed hook lint rule without changing approval UI flow +- verified that `npm run build` no longer changes the contents of `apps/web/tsconfig.json` or `apps/web/next-env.d.ts` after those adopted config updates were in place ## incomplete work -- no approval execution from the web UI -- no task-step mutations from the web UI beyond inspection -- no live request-history read endpoint in `/chat`; the screen submits live requests but keeps local summary history plus explicit fixture fallback -- no Gmail, Calendar, runner, auth, or backend-scope expansion - -## exact screens and components implemented or updated - -- screens -- `/chat` -- `/approvals` -- `/tasks` -- `/approvals/loading` -- `/tasks/loading` -- components - - `request-composer` - - `approval-list` - - `approval-actions` - - `approval-detail` - - `task-list` - - `task-summary` - - `task-step-list` - - `status-badge` +- no backend endpoint, schema, or contract changes +- no new routes or workflow features +- no shell redesign or adjacent UI expansion +- no Gmail, Calendar, auth, runner, or connector scope expansion +- no additional frontend tests beyond the existing narrow verification set ## files changed - `BUILD_REPORT.md` -- `apps/web/app/chat/page.tsx` -- `apps/web/app/approvals/page.tsx` -- `apps/web/app/approvals/loading.tsx` -- `apps/web/app/tasks/page.tsx` -- `apps/web/app/tasks/loading.tsx` -- `apps/web/app/globals.css` -- `apps/web/components/request-composer.tsx` -- `apps/web/components/approval-list.tsx` -- `apps/web/components/approval-actions.tsx` -- `apps/web/components/approval-detail.tsx` -- `apps/web/components/task-list.tsx` -- `apps/web/components/task-summary.tsx` -- `apps/web/components/task-step-list.tsx` -- `apps/web/components/status-badge.tsx` -- `apps/web/lib/api.ts` -- `apps/web/lib/api.test.ts` -- `apps/web/lib/fixtures.ts` -- `apps/web/components/approval-actions.test.tsx` -- `apps/web/test/setup.ts` -- `apps/web/vitest.config.ts` - `apps/web/package.json` - -## route backing - -- `/chat`: mixed - - live submission when `apiBaseUrl` and `userId` are configured - - explicit fixture preview and local summary fallback otherwise -- `/approvals`: mixed - - live inbox, live detail, and live approve/reject when configured - - explicit fixture fallback for list and detail when live data is unavailable - - explicit route-level loading UI while server reads are in flight -- `/tasks`: mixed - - live task list, live task detail, and live task-step reads when configured - - explicit fixture fallback for list, detail, and steps when live data is unavailable - - explicit route-level loading UI while server reads are in flight - -## shipped backend endpoints consumed - -- `POST /v0/approvals/requests` -- `GET /v0/approvals` -- `GET /v0/approvals/{approval_id}` -- `POST /v0/approvals/{approval_id}/approve` -- `POST /v0/approvals/{approval_id}/reject` -- `GET /v0/tasks` -- `GET /v0/tasks/{task_id}` -- `GET /v0/tasks/{task_id}/steps` - -## commands run - -- `npm install --no-package-lock` in `apps/web` -- `npm run test` in `apps/web` -- `npm run build` in `apps/web` +- `apps/web/eslint.config.mjs` +- `apps/web/tsconfig.json` +- `apps/web/next-env.d.ts` +- `apps/web/components/approval-actions.tsx` ## tests run -- `npm run test` in `apps/web` +- `npm run lint` in `apps/web` + - PASS + - non-interactive after the committed ESLint config and script change +- `npm test` in `apps/web` + - PASS + - `2` test files, `5` tests passed - `npm run build` in `apps/web` - -## build and test results - -- `npm run test`: PASS -- production build completed successfully -- generated routes included: - - `/` - - `/chat` - - `/approvals` - - `/tasks` - - `/traces` -- automated coverage now includes: - - API helper request and error-envelope behavior - - approval action-bar UI flow and route refresh behavior - -## concise visual verification notes - -- desktop: split review layouts remain intact for approvals and tasks, the governed request form still uses bounded two-column field groupings, and route-level loading cards now preserve the same shell hierarchy during slow reads -- mobile: the existing responsive breakpoints still collapse the sidebar layouts to one column, and the new loading cards and field groups stack cleanly at narrow widths -- browser screenshots were not captured; these notes are from code-path and responsive-layout verification only + - PASS + - generated shipped routes remained intact: `/`, `/chat`, `/approvals`, `/tasks`, `/traces` + +## exact verification results + +- lint command used: `npm run lint` +- test command used: `npm test` +- build command used: `npm run build` +- TypeScript or Next-generated config changes intentionally adopted: yes + - `apps/web/tsconfig.json` + - `apps/web/next-env.d.ts` +- build stability check: + - `shasum apps/web/tsconfig.json apps/web/next-env.d.ts` was unchanged before vs. after `npm run build` + - pre-build checksum: + - `23632802ddf6784e5989d71338904efe50848844 apps/web/tsconfig.json` + - `f75a118439f630e5ca41d376cedef8db9b6d7fc6 apps/web/next-env.d.ts` + - post-build checksum: + - `23632802ddf6784e5989d71338904efe50848844 apps/web/tsconfig.json` + - `f75a118439f630e5ca41d376cedef8db9b6d7fc6 apps/web/next-env.d.ts` + +## route and behavior confirmation + +- route generation from `next build` still includes `/`, `/chat`, `/approvals`, `/tasks`, and `/traces` +- Sprint 6A and 6B governed request, approval, and task behavior remained intact +- no workflow logic or API contract changes were introduced; the only non-config code change was the `approval-actions` hook dependency cleanup required by lint ## blockers/issues -- `next build` rewrote `apps/web/tsconfig.json` and `apps/web/next-env.d.ts` during type checking; those generated edits were manually reverted to keep the final diff inside the sprint packet’s scoped file list -- `npm run lint` is still not a usable project check because `next lint` drops into interactive ESLint setup instead of running repo-defined rules +- no active blockers after the repair +- initial pre-fix issue reproduced exactly as described in the sprint packet: + - `npm run lint` prompted for ESLint initialization because the workspace had no committed lint config + - `next build` rewrote `apps/web/tsconfig.json` and `apps/web/next-env.d.ts` until those framework-required changes were intentionally adopted ## recommended next step -Open a follow-up UI sprint only if you want to reduce operator friction around request submission, most likely by introducing a bounded live selector for known thread and tool IDs through already-shipped seams or explicitly approved new scope. +Run review against this repair sprint and, if it passes, treat the committed ESLint config plus adopted Next TypeScript settings as the new stable baseline for future `apps/web` UI work. ## intentionally deferred after this sprint -- approval execution UI -- task-step mutation UI -- general trace-event listing work -- connector expansion -- auth redesign +- any new product workflow surface beyond the existing `/`, `/chat`, `/approvals`, `/tasks`, and `/traces` routes +- any backend work +- any visual redesign +- any additional test expansion beyond narrow preservation coverage diff --git a/REVIEW_REPORT.md b/REVIEW_REPORT.md index 961b314..dfd05ad 100644 --- a/REVIEW_REPORT.md +++ b/REVIEW_REPORT.md @@ -6,20 +6,15 @@ PASS ## criteria met -- `/chat` now submits governed requests through the existing approval-request seam and keeps fixture fallback explicit when live API config is absent. -- `/approvals` now uses only shipped approval endpoints for list, detail, approve, and reject flows. -- `/tasks` now uses only shipped task endpoints for list, detail, and task-step inspection, and it exposes approval linkage in the task view. -- `/approvals` and `/tasks` now have explicit route-level loading boundaries that preserve the shell layout during slow live reads. -- Automated coverage now exists for the new web workflow layer: - - API helper request/error behavior - - approval action-bar resolution flow and route refresh behavior -- The sprint stayed a UI sprint. No backend endpoint, schema, auth, Gmail, Calendar, runner, or execution-scope expansion was introduced. -- The new files added are within the Sprint 6B in-scope component and helper surface. -- The UI still materially follows `DESIGN_SYSTEM.md`: restrained palette, bounded cards, stable split layouts, readable chips/badges, and clean mobile stacking are preserved. -- `BUILD_REPORT.md` now matches the implemented state, including the loading boundaries, added tests, and actual commands run. -- Verification run for review: - - `npm run test` in `apps/web`: PASS - - `npm run build` in `apps/web`: PASS +- `apps/web/eslint.config.mjs` is now tracked in git, so the non-interactive lint setup is part of the sprint change set. +- `npm run lint` in `apps/web` runs non-interactively and passes with `eslint . --max-warnings=0`. +- `npm test` in `apps/web` passes: `2` test files, `5` tests passed. +- `npm run build` in `apps/web` passes. +- The build output includes the shipped routes `/`, `/chat`, `/approvals`, `/tasks`, and `/traces`. +- `apps/web/tsconfig.json` and `apps/web/next-env.d.ts` remain byte-stable before and after `npm run build`; the `shasum` values were unchanged. +- The implementation stayed inside the repair sprint scope: no backend endpoint, schema, auth, Gmail, Calendar, runner, or product-scope expansion was introduced. +- The only behavior code change remains the narrow `approval-actions` hook dependency cleanup, and the existing approval flow coverage still passes. +- `BUILD_REPORT.md` now matches the current tracked repair: committed ESLint config, adopted Next TypeScript config normalization, exact verification commands, and explicit deferred scope. ## criteria missed @@ -27,31 +22,28 @@ PASS ## quality issues -- No blocking implementation issues found in the Sprint 6B UI slice. -- Residual non-blocking issue: `npm run lint` is still not a usable repo check because `next lint` drops into interactive ESLint setup. -- Residual non-blocking issue: `next build` still rewrites `apps/web/tsconfig.json` and `apps/web/next-env.d.ts` during verification unless those generated changes are adopted permanently. +- No blocking quality issues found in the current sprint change set. +- Coverage remains intentionally narrow, but it is adequate for this repair sprint because the functional code change is minimal and behavior-preserving. ## regression risks - Low. -- The main residual risk is tooling churn rather than workflow correctness: future builds may continue to touch Next TypeScript config files until the repo either accepts or intentionally normalizes those generated settings. -- Test coverage is now present but still narrow, so additional UI boundaries could regress without broader component or route coverage. +- Residual risk is mostly future UI drift outside this sprint, not the stabilization change itself. Current automated coverage still does not provide route-level smoke tests across all shipped pages. ## docs issues -- No blocking docs issues remain. -- `BUILD_REPORT.md` now reflects the actual loading-state and test coverage added in the follow-up. +- No blocking docs issues found. +- No `ARCHITECTURE.md` update is needed for this repair sprint. ## should anything be added to RULES.md? -- No required rules change. -- Optional future rule only: require a committed non-interactive lint setup for frontend workspaces before treating `lint` as a standard verification step. +- No required change. +- Optional future rule: frontend workspaces should commit a repo-owned non-interactive lint configuration before `lint` is treated as a standard verification gate. ## should anything update ARCHITECTURE.md? -- No. This sprint stayed inside the existing documented backend seams and did not reveal an architecture contradiction. +- No. This sprint stayed in tooling/workspace stabilization and did not reveal an architecture contradiction. ## recommended next action -- Accept Sprint 6B. -- If the team wants a cleanup follow-up, stabilize the web lint/config story so `npm run lint` becomes a real non-interactive check and `next build` stops creating local config churn. +- Accept Sprint 6C and treat the tracked ESLint config plus adopted Next TypeScript settings as the new stable baseline for future `apps/web` work. diff --git a/apps/web/components/approval-actions.tsx b/apps/web/components/approval-actions.tsx index 611d956..8a610d1 100644 --- a/apps/web/components/approval-actions.tsx +++ b/apps/web/components/approval-actions.tsx @@ -20,12 +20,12 @@ type FeedbackState = { message: string; }; -function actionAvailabilityMessage(liveModeReady: boolean, approval: ApprovalItem) { +function actionAvailabilityMessage(liveModeReady: boolean, approvalStatus: ApprovalItem["status"]) { if (!liveModeReady) { return "Approve and reject controls are disabled in fixture mode."; } - if (approval.status !== "pending") { + if (approvalStatus !== "pending") { return "This approval has already been resolved. The action bar is now read-only."; } @@ -41,7 +41,7 @@ export function ApprovalActions({ const router = useRouter(); const [feedback, setFeedback] = useState({ tone: "info", - message: actionAvailabilityMessage(Boolean(apiBaseUrl && userId), approval), + message: actionAvailabilityMessage(Boolean(apiBaseUrl && userId), approval.status), }); const [pendingAction, setPendingAction] = useState<"approve" | "reject" | null>(null); @@ -51,10 +51,10 @@ export function ApprovalActions({ useEffect(() => { setFeedback({ tone: "info", - message: actionAvailabilityMessage(liveModeReady, approval), + message: actionAvailabilityMessage(liveModeReady, approval.status), }); setPendingAction(null); - }, [approval.id, liveModeReady]); + }, [approval.id, approval.status, liveModeReady]); async function handleResolve(action: "approve" | "reject") { if (!apiBaseUrl || !userId) { diff --git a/apps/web/eslint.config.mjs b/apps/web/eslint.config.mjs new file mode 100644 index 0000000..ec5cc8a --- /dev/null +++ b/apps/web/eslint.config.mjs @@ -0,0 +1,21 @@ +import js from "@eslint/js"; +import { FlatCompat } from "@eslint/eslintrc"; +import { dirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, +}); + +const eslintConfig = [ + { + ignores: [".next/**", "node_modules/**", "next-env.d.ts"], + }, + ...compat.extends("next/core-web-vitals"), +]; + +export default eslintConfig; diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts index dc86238..1b3be08 100644 --- a/apps/web/next-env.d.ts +++ b/apps/web/next-env.d.ts @@ -1,5 +1,5 @@ /// /// -// This file is managed by Next.js. - +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/web/package.json b/apps/web/package.json index 8099daa..71a3e05 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -6,7 +6,7 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint", + "lint": "eslint . --max-warnings=0", "test": "vitest run" }, "dependencies": { diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index bbd3768..b569253 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "ES2022", - "lib": ["dom", "dom.iterable", "es2022"], + "lib": [ + "dom", + "dom.iterable", + "es2022" + ], "allowJs": false, "skipLibCheck": true, "strict": true, @@ -11,9 +15,21 @@ "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", - "incremental": true + "incremental": true, + "esModuleInterop": true, + "plugins": [ + { + "name": "next" + } + ] }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], - "exclude": ["node_modules"] + "include": [ + "**/*.ts", + "**/*.tsx", + "next-env.d.ts", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] } -