The aria-hidden="true" selector matched 27 elements (icons, etc.)
causing cy.click() to fail. Add data-cy="sidebar-backdrop" to the
overlay div and target that specifically in tests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dashboard page accesses metrics.throughput.primary.points which
requires the full DashboardMetrics type structure. The original stub
returned a flat object with wrong fields, causing TypeError in all
authenticated tests. Also adds stubs for boards, agents, activity,
gateways, and board-groups APIs that the dashboard and boards pages
query on load.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Align desktop sidebar width (was w-64/256px) with header column and
grid template (both 260px). Apply missing p-4 md:p-6 responsive
padding to the global approvals page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use React's canonical "store info from previous renders" pattern:
conditional setState during render resets sidebar when pathname
changes, preventing the sidebar from re-opening on back-navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace useRef-based previous pathname tracking (which violated
react-hooks/refs) with a derived state pattern. Sidebar state stores
{open, path} and sidebarOpen is computed as a pure expression,
avoiding both set-state-in-effect and refs-during-render lint errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensure the /app WORKDIR itself is owned by appuser (not just copied
files), preventing runtime failures if the app writes to /app directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move user/group creation before COPY statements so --chown flag can
set ownership at copy time, avoiding the slow recursive chown on
overlay2 filesystems (docker/for-linux#388).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Raise header to z-50 so toggle button stays clickable above backdrop
- Use document keydown listener for Escape instead of onKeyDown on backdrop
- Only render hamburger toggle when signed in
- Make SignedOutPanel col-span responsive (col-span-1 on mobile)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use ref-based previous pathname check instead of useEffect + setState,
which triggers the react-hooks/set-state-in-effect lint rule.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sidebar and backdrop were z-30, same as sticky page headers (live feed,
boards, etc.), causing the hamburger menu to render behind page content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add hamburger menu with off-canvas sidebar drawer on mobile.
Responsive padding, full-width panels, and stacked layouts
for screens under 768px (md breakpoint).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
node:20-alpine uses BusyBox which does not support GNU-style
--system/--ingroup flags. Switch to -S/-G equivalents.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both backend and frontend Dockerfiles ran all processes as root.
Add a dedicated appuser in each runtime stage so container processes
run with minimal privileges, limiting blast radius of any container
escape.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>