Skip to content

release: promote EPIC-09 Dashboard & Project Health Center to main#733

Closed
steilerDev wants to merge 41 commits intomainfrom
beta
Closed

release: promote EPIC-09 Dashboard & Project Health Center to main#733
steilerDev wants to merge 41 commits intomainfrom
beta

Conversation

@steilerDev
Copy link
Owner

Summary

Promotes EPIC-09: Dashboard & Project Health Center from beta to main. This epic adds a comprehensive project health dashboard with customizable cards, real-time data aggregation, and responsive mobile layout.

Stories Included

UAT Fixes

Also Included

Test Plan

  • All 9 stories merged and verified
  • UAT feedback addressed (3 in-scope fixes)
  • E2E tests written and passing
  • Documentation updated
  • 4-reviewer approval on all PRs

🤖 Generated with Claude Code

dependabot bot and others added 30 commits March 9, 2026 17:00
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](docker/setup-qemu-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](docker/metadata-action@v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Replace eslint-plugin-react + eslint-plugin-react-hooks with
@eslint-react/eslint-plugin for ESLint 10 compatibility. Also bumps
babel-loader, css-minimizer-webpack-plugin, webpack, @types/node,
and conventional-changelog-conventionalcommits.

Supersedes #696.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…a/docker/build-push-action-7

chore(deps): bump docker/build-push-action from 6 to 7
…a/docker/setup-buildx-action-4

chore(deps): bump docker/setup-buildx-action from 3 to 4
…a/docker/setup-qemu-action-4

chore(deps): bump docker/setup-qemu-action from 3 to 4
…a/docker/login-action-4

chore(deps): bump docker/login-action from 3 to 4
…a/docker/metadata-action-6

chore(deps): bump docker/metadata-action from 5 to 6
chore(deps): upgrade ESLint to v10 and dev dependencies
…dev-dependencies group across 1 directory (#706)

* chore(deps-dev): bump typescript-eslint

Bumps the dev-dependencies group with 1 update in the / directory: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `typescript-eslint` from 8.56.1 to 8.57.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.57.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.57.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix(gantt): convert GanttSidebar from forwardRef to ref-as-prop pattern

The forwardRef callback/object ref handling caused a TS2349 type error
with typescript-eslint 8.57.0. Using React 19's ref-as-prop pattern
with explicit Ref type resolves the issue.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#707)

- Migration 0018: create user_preferences table with UNIQUE(user_id, key)
- Drizzle schema: add userPreferences table definition
- Shared types: add UserPreference, PreferenceKey, DashboardCardId,
  UpsertPreferenceRequest, PreferencesResponse
- Export new types from @cornerstone/shared index
- Wiki: add dashboard architecture section, fix Schema.md deviations
  (invoice_budget_lines ON DELETE CASCADE, migration renumbering)

Refs #470

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* feat(preferences): implement user preferences API client, hook, and theme sync

Implement EPIC-09 Story #470 frontend infrastructure:

- Add preferencesApi.ts with typed API client functions (listPreferences, upsertPreference, deletePreference)
- Add usePreferences hook for managing user preferences with loading, error, and local state sync
- Enhance ThemeContext with syncWithServer method that:
  - Fetches server preferences on authentication
  - Applies server theme if present, otherwise migrates localStorage to server
  - Silently handles network errors and keeps local theme as fallback
  - Tracks authenticated user ID to enable server sync on preference changes
- Add ThemeServerSync bridge component in App.tsx to sync theme with server when user authenticates
  - Placed inside AuthProvider to access useAuth and useTheme
  - Calls syncWithServer(userId) when user logs in

All functions follow existing patterns from documentLinksApi.ts and useDocumentLinks.ts.

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* feat(preferences): add user preferences infrastructure

Implement server-side user preferences with API endpoints and
integrate theme sync with the preferences API.

Backend:
- Create preferencesService with list/upsert/delete operations
- Add GET/PATCH/DELETE routes at /api/users/me/preferences
- Register routes in app.ts

Frontend:
- Create preferencesApi client with typed functions
- Create usePreferences hook with loading/error states
- Update ThemeContext to sync with server when authenticated
- Add ThemeServerSync bridge component in App.tsx
- Migrate localStorage theme to server on first auth load

Fixes #470

Co-Authored-By: Claude backend-developer (Haiku) <noreply@anthropic.com>
Co-Authored-By: Claude frontend-developer (Haiku) <noreply@anthropic.com>

* test(preferences): add unit and integration tests for story #470

Add 5 test files covering the user preferences infrastructure:

- server/src/services/preferencesService.test.ts — 14 unit tests for
  listPreferences, upsertPreference, and deletePreference using in-memory SQLite

- server/src/routes/preferences.test.ts — 18 integration tests via app.inject()
  covering GET/PATCH/DELETE routes, 401/400/404/204 responses, per-user
  isolation, dot-notation key URL encoding

- client/src/lib/preferencesApi.test.ts — 12 unit tests for the API client
  layer (listPreferences, upsertPreference, deletePreference)

- client/src/hooks/usePreferences.test.ts — 16 unit tests for the usePreferences
  hook (loading state, error handling, upsert/remove optimistic updates, refresh)

- client/src/contexts/ThemeContext.test.tsx — 16 unit tests for ThemeProvider
  covering syncWithServer migration logic, localStorage clearing, network error
  handling, and setTheme server-sync behaviour

Co-Authored-By: Claude qa-integration-tester (Sonnet 4.6) <noreply@anthropic.com>

* docs(security): update wiki ref after PR #708 security audit findings

Co-Authored-By: Claude security-engineer (Sonnet 4.6) <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* feat(dashboard): implement dashboard layout & data shell (story #471)

- Create DashboardCard reusable component with loading, error, and empty states
- Add shimmer animation for skeleton loader and proper touch targets (44px min)
- Create DashboardPage with 8 dashboard cards in responsive grid
- Implement parallel data fetching via Promise.allSettled for all data sources
- Add card visibility preference management via usePreferences hook
- Implement customize dropdown to show/hide cards and manage preferences
- Add per-card error handling with retry button and empty state handling
- Map data sources (budgetOverview, budgetSources, timeline, invoices, subsidyPrograms) to cards
- Responsive grid: 3 columns (desktop), 2 columns (tablet), 1 column (mobile)
- All colors and spacing use CSS custom properties from tokens.css
- Placeholder content "Content coming soon." for all cards (filled by subsequent stories)

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* test(dashboard): add unit and integration tests for DashboardCard and DashboardPage (#471)

12 unit tests for DashboardCard covering all render states (loading, error, empty,
children), priority ordering (loading > error > empty), dismiss/retry interactions,
and prop defaults.

22 integration tests for DashboardPage covering: h1/nav rendering, all 8 card
titles visible post-load, per-data-source loading skeletons, ApiClientError
propagation, empty states for source-utilization and subsidy-pipeline, dismiss
→ upsert flow (including multi-card accumulation), hidden-card suppression,
Customize button visibility, dropdown open/close, and re-enable → upsert.

Also flags Bug #712: DashboardPage.tsx:200 reads `.items` on InvoiceListPaginatedResponse
but the actual field is `.invoices`, preventing the invoice-pipeline empty state
from ever firing.

Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>

* fix(dashboard): use correct invoice field name in empty check

The InvoiceListPaginatedResponse uses `.invoices` not `.items`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(test): correct mock type for upsertPreference in dashboard tests

The jest.fn generic must accept (key, value) arguments to match usage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(dashboard): use 'Project' heading for consistency and fix test timing

DashboardPage h1 changed from 'Dashboard' to 'Project' to match all other
pages in the Project section. Wrapped empty-state assertions in waitFor to
handle async data loading timing. Removed stale Bug #712 note.

Fixes #471

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(dashboard): address PO and UX review findings

- Use <article> + <h2> for semantic card structure with aria-labelledby
- Add card-specific empty messages with contextual action links
- Fix grid gap values, max-width, and breakpoint boundaries per spec
- Use btnSecondaryCompact for retry button via CSS composition
- Fix shimmer gradient tokens and add prefers-reduced-motion guard
- Ensure 44px minimum touch targets at all touch breakpoints
- Use var(--shadow-focus) consistently for focus-visible states

Fixes #471

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude frontend-developer (Haiku) <noreply@anthropic.com>

* fix(dashboard): close article element correctly in DashboardCard

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(dashboard): update tests for new aria-labels and page structure

- DashboardPage.test.tsx: use regex for skeleton aria-label query
- E2E DashboardPage POM: replace description locator with cardGrid
- E2E stub-pages.spec.ts: check cardGrid visibility instead of description

Fixes #471

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* feat(dashboard): add Budget Summary Card with real data (#472)

Add BudgetSummaryCard component that displays available funds, budget
bar visualization, health indicator, planned cost range, actual spend,
subsidy impact, and remaining percentage with color-coded thresholds.
Integrate it into the DashboardPage by storing BudgetOverview state
from the parallel data fetch.

Fixes #472

Co-Authored-By: Claude frontend-developer (Haiku) <noreply@anthropic.com>
Co-Authored-By: Claude qa-integration-tester (Haiku) <noreply@anthropic.com>

* chore: persist review metrics for PR #710

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(dashboard): remove extra .overview access on fetchBudgetOverview result

fetchBudgetOverview() already unwraps BudgetOverviewResponse.overview
and returns BudgetOverview directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
…711)

* feat(dashboard): add Budget Alerts & Source Utilization cards (#473)

Implement dashboard cards for budget monitoring:
- BudgetAlertsCard: Shows budget categories at or over threshold
  - Red alert: actualCost > maxPlanned
  - Yellow alert: 90-100% utilization
  - Sorted by severity and percentage used
- SourceUtilizationCard: Displays budget sources with usage visualization
  - Budget bars showing used vs total amounts
  - Type badges (Bank Loan, Credit Line, Savings, Other)
  - Sorted by high utilization (≥90% or exhausted) first

Both cards integrated into DashboardPage with proper loading and empty states.

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* test(dashboard): add unit tests for BudgetAlertsCard and SourceUtilizationCard (#473)

20 unit tests covering alert threshold logic (red/yellow), sort order,
boundary conditions, budgetLineCount=0 skip, zero maxPlanned, type badges,
currency formatting, BudgetBar presence, and exhausted sort ordering.

Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>

* fix(test): add missing actualAvailableAmount to BudgetSource fixture

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(test): add missing API mocks for DashboardPage in App.test.tsx

DashboardPage now imports budgetOverviewApi, budgetSourcesApi,
subsidyProgramsApi, and preferencesApi which need to be mocked
in the App integration test to prevent fetch errors in jsdom.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: persist review metrics for PR #711

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* feat(timeline): implement timeline status cards dashboard component

Add 4 new dashboard cards for timeline visualization:
- UpcomingMilestonesCard: displays next 5 incomplete milestones with health indicators
- WorkItemProgressCard: SVG donut chart showing work item counts by status
- AtRiskItemsCard: lists up to 5 overdue or late-start items with links
- CriticalPathCard: shows critical path summary with deadline and health color

All components follow existing patterns with CSS modules, design tokens,
and comprehensive data-testid attributes for testing.

Fixes #474
Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* test(dashboard): add timeline status cards unit tests and fix date parsing

Add 40 unit tests across 4 test files for the timeline status card
components. Fix CriticalPathCard date parsing to use correct
Date constructor (year, month-1, day) instead of buggy string
manipulation. Fix health threshold boundary to use <= 14 for
warning range (7-14 days) per acceptance criteria.

Fixes #474

Co-Authored-By: Claude Haiku <frontend-developer> <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet <qa-integration-tester> <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(dashboard): fix CriticalPathCard test import and review findings

- Add missing `jest` import from @jest/globals in CriticalPathCard.test.tsx
- Replace hardcoded color: 'white' with CSS Module badge classes
- Use badgeGreen/badgeRed/badgeYellow CSS classes instead of inline
  backgroundColor for health indicator (dark mode safe)
- Fix link focus-visible to use box-shadow: var(--shadow-focus)
- Use var(--spacing-2) token for legend dot dimensions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(metrics): add review metrics for PR #712

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
…714)

* test(dashboard): add unit tests for QuickActionsCard component

8 tests covering all link hrefs, aria-labels, link count, and absence
of loading/error states for story #477.

Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>

* feat(dashboard): implement Quick Actions card with navigation links

Adds a new Quick Actions section to the project dashboard that provides
quick access to common application features. Includes a prominent "New Work Item"
button and quick navigation links to Work Items, Timeline, Budget, Invoices,
and Vendors. All elements are keyboard accessible with appropriate aria-labels.

Story #477 acceptance criteria:
- New Work Item button navigates to /project/work-items/new
- Quick links to all key sections (Work Items, Timeline, Budget, Invoices, Vendors)
- Visible on all viewports (desktop, tablet, mobile)
- Keyboard accessible with aria-label attributes
- Dark mode support with design tokens

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* fix(dashboard): address UX review feedback on QuickActionsCard

- Use transition tokens (--transition-button, --transition-button-border)
  instead of hardcoded 0.15s ease
- Use --color-bg-hover instead of --color-bg-tertiary for link hover
- Add prefers-reduced-motion guard to disable transitions
- Add min-height: 44px for touch target compliance
- Align aria-labels with visible text to avoid screen reader confusion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>
Co-Authored-By: Claude qa-integration-tester (Haiku 4.5) <noreply@anthropic.com>

* chore(metrics): persist review metrics for PR #714

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* feat(dashboard): implement Invoice Pipeline and Subsidy Pipeline cards

Story #476

- InvoicePipelineCard: display top 5 pending invoices sorted by date, highlight overdue items, show pending total
- SubsidyPipelineCard: display subsidy programs grouped by lifecycle status (eligible/applied/approved/received/rejected), show fixed reduction totals, highlight programs with deadlines within 14 days
- Both components integrated into DashboardPage with proper data fetching and state management
- Uses design tokens exclusively for styling; follows existing component patterns for empty states and links

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* test(dashboard): add unit tests for InvoicePipelineCard and SubsidyPipelineCard

- 12 tests for InvoicePipelineCard: empty state, pending filter, oldest-first
  sort, 5-item cap, overdue badge logic (yesterday/future/null dueDate), null
  invoiceNumber fallback, pending total display, footer link, amount formatting
- 13 tests for SubsidyPipelineCard: empty state, group rendering, lifecycle
  order (eligible→applied→approved→received→rejected), deadline warning at
  0-14 days inclusive, fixed reduction aggregation, percentage exclusion,
  footer link, badge text for all statuses

Closes #476 (partial — QA coverage)

Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>

* fix(dashboard): add missing data-testid on invoice pending total

Add data-testid="pending-total" to the InvoicePipelineCard footer total
div and update the corresponding test to assert on the testid.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>
Co-Authored-By: Claude qa-integration-tester (Haiku 4.5) <noreply@anthropic.com>

* chore(metrics): persist review metrics for PR #713

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* test(dashboard): add unit tests for MiniGanttCard component

10 tests covering: empty state (no items, items outside window),
SVG rendering, work item bars, today marker, milestone diamonds
(in-window and out-of-window), navigation, date filtering, and
dependency line rendering.

Fixes #475

Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>

* feat(dashboard): implement Mini Gantt Preview Card

Adds a compact, read-only SVG Gantt chart showing the next 30 days on the
dashboard. Work items colored by status, today marker, milestone diamonds,
dependency arrows, and critical path highlighting. Clicking navigates to
/schedule. Empty state when no work items in the window.

Fixes #475

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* fix(dashboard): address review findings for Mini Gantt Preview Card

- Replace useMemo color cache with useState + MutationObserver pattern
  matching GanttChart.tsx for proper dark mode theme switching
- Add keyboard accessibility: role="button", tabIndex, aria-label,
  onKeyDown handler for Enter/Space on clickable container
- Add focus-visible styling with box-shadow: var(--shadow-focus)
- Replace hardcoded '#dc2626' fallback with readCssVar('--color-danger')
- Use --color-milestone-complete-fill for completed milestones instead
  of colors.gridMajor
- Remove unused useRef import
- Update test to verify keyboard accessibility attributes

Fixes #475

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>
Co-Authored-By: Claude qa-integration-tester (Haiku 4.5) <noreply@anthropic.com>

* fix(dashboard): remove invalid 'blocked' WorkItemStatus from MiniGanttCard

WorkItemStatus only has not_started, in_progress, and completed — there is
no 'blocked' status. Remove it from barColors and statusMap to fix type error.

Fixes #475

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
steilerDev and others added 10 commits March 10, 2026 07:46
)

* feat(dashboard): add responsive mobile sections, ARIA landmarks, and chart fallbacks

- Mobile (<768px): group cards into collapsible sections using <details>/<summary>
  - Primary cards (budget summary, alerts, invoices, quick actions) always visible
  - Timeline and Budget Details sections collapsed by default with summary text
- Add role="region", aria-label, aria-live="polite" to dashboard grid
- Add role="img" and dynamic aria-label to MiniGanttCard SVG
- Add sr-only utilization percentage text to SourceUtilizationCard
- Section summary shows loading state ("…") and data-driven counts
- Chevron rotation animation with prefers-reduced-motion guard

Fixes #478

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* test(dashboard): add tests for responsive sections, ARIA landmarks, and chart fallbacks

- DashboardPage: verify ARIA region landmark, aria-live, mobile <details>
  elements, timeline/budget summary text in various states
- MiniGanttCard: verify SVG role="img" and aria-label with item counts
- SourceUtilizationCard: verify sr-only utilization percentage text

Fixes #478

Co-Authored-By: Claude qa-integration-tester (Haiku 4.5) <noreply@anthropic.com>

* test(dashboard): fix dual-layout duplicate element errors in DashboardPage tests

DashboardPage renders cards in both a desktop grid and a mobile sections
layout simultaneously. In jsdom, CSS media queries don't apply, so both
layouts are in the DOM and every card appears twice. Switch all singular
getByRole/getByText queries for card elements to getAllByRole/getAllByText[0],
and update the loading skeleton count from 7 to 14 (7 cards × 2 layouts).

Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
Adds aria-live="polite" and aria-atomic="false" to the mobile sections
container to match the desktop grid's ARIA attributes, ensuring screen
reader users on mobile viewports receive state change announcements.

Fixes review finding from product-owner on PR #718.

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
…OM (#721)

Adds comprehensive Playwright E2E browser tests for the Project Dashboard
(/project/overview) introduced in EPIC-09. Covers all 8 cards, dismiss/
re-enable customization, responsive mobile collapsible sections, keyboard
navigation (Mini Gantt → /schedule), dark mode, ARIA accessibility, and
no-horizontal-scroll checks across all viewports.

Fixes #9

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* chore: retrigger CI (flaky App.test.tsx)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add dashboard guide and update roadmap for EPIC-09

Add new dashboard guide page documenting the project overview page with
its eight information cards, card customization, responsive layout, error
handling, and accessibility features. Update intro.md feature list and
quick links, mark EPIC-09 as completed in roadmap, update README.md
features and roadmap, and write RELEASE_SUMMARY.md for the epic.

Co-Authored-By: Claude docs-writer (Opus 4.6) <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* fix(dashboard): address UAT round 10 feedback (#729, #730, #731)

**Fix #731 — Invoice Pipeline Click-Through**
- Wrap invoice row content in Link component
- Navigate to /budget/invoices/{id} on click
- Add itemLink CSS class for flex layout and focus states

**Fix #730 — Split Timeline Status into Separate Cards**
- Replace timeline-status card ID with three new IDs: upcoming-milestones, work-item-progress, critical-path
- Remove cardSection and sectionHeader wrapper divs from sub-card components
- Add milestone title Link to /schedule/milestones/{id}
- Add critical path deadline Link to /work-items/{id}
- Delete unused TimelineStatusCards.tsx wrapper and AtRiskItemsCard.tsx
- Update CARD_DEFINITIONS to render 3 separate cards instead of composite

**Fix #729 — Mini Gantt Current Week Redesign**
- Change layout: ROW_HEIGHT 24→36, BAR_HEIGHT 16→24, BAR_HEIGHT_OFFSET 4→6, HEADER_HEIGHT 24→32
- Compute Monday-anchored week instead of 30-day window
- Change header labels: day-of-month → day-of-week (Mon, Tue, etc.)
- Simplify grid: 31 mixed-weight lines → 8 uniform day-boundary lines
- Update today marker to compute relative to week start, only render if within bounds
- Add title text labels on bars (truncated if width < 40px)
- Remove dependency arrow rendering entirely
- Update empty state: "next 30 days" → "this week"
- Update SVG aria-label to reference "this week"

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

* test(dashboard): update unit tests for UAT fixes #729, #730, #731

- Delete AtRiskItemsCard.test.tsx (component removed in #730 split)
- InvoicePipelineCard: add Test 13 verifying each invoice row links to
  /budget/invoices/<id> (Fix #731 click-through)
- UpcomingMilestonesCard: add Test 11 verifying milestone title links
  to /schedule/milestones/:id (Fix #730 heading/link changes)
- CriticalPathCard: add Test 11 verifying deadline links to
  /work-items/:id (Fix #730 heading/link changes)
- MiniGanttCard: add daysFromMonday() helper, update all date fixtures
  to use Mon-Sun week window, update empty state text to
  "No work items scheduled this week", replace dependency-arrow line
  count test with grid-line stability assertion (8 lines, no dep
  arrows), update SVG aria-label assertion to include "this week"
  (Fix #729 mini Gantt current week redesign)
- DashboardPage: replace 'Timeline Status' with 'Upcoming Milestones',
  'Work Item Progress', 'Critical Path' in ALL_CARD_TITLES, update
  skeleton count 14→18 (9 data-backed cards × 2 layouts), fix Test 18
  sibling card assertion to use 'Upcoming Milestones'

Fixes #729, #730, #731

Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>

* fix(mini-gantt, tokens): address UX review findings and cleanup dead code

- MiniGanttCard.tsx: Remove dead dependency arrow code (itemRowMap, visibleDependencies useMemo blocks, arrowDefault/arrowCritical color properties) — dependency arrows were previously removed, leaving stale code behind
- MiniGanttCard.tsx: Replace hardcoded fill="white" on bar text with design token (--color-text-inverse) for dark mode compatibility
- tokens.css: Add missing --color-warning-bg token (light: #fff7ed, dark: rgba(251, 146, 60, 0.1)) used by .badgeYellow in TimelineStatusCards and HouseholdItemDetailPage

Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>

---------

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
…net column sign (#726)

Budget overview was subtracting subsidy reductions from minPlanned/maxPlanned
AND adding payback back in remaining calculations, double-counting the subsidy
benefit. Now minPlanned/maxPlanned reflect raw projected costs (pre-subsidy),
and remaining calculations work correctly.

Cost breakdown Net column was showing positive values (cost - payback) instead
of negative values (payback - cost) for normal items where cost exceeds payback.

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
The timeline-status card was split into 3 separate cards (upcoming-milestones,
work-item-progress, critical-path) during UAT fixes. Update the E2E POM and
tests to match: 10 cards instead of 8, replace Timeline Status references.

Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
@steilerDev
Copy link
Owner Author

Closing: E2E test fix (PR #735) has been merged to beta. Creating a new promotion PR that includes the fix.

@steilerDev steilerDev closed this Mar 11, 2026
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