DataTable renders mobile (block md:hidden) and desktop (hidden md:block)
variants. .first() resolved to the hidden mobile element at desktop viewport.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add udp/ prefix to upstream dial addresses for UDP proxy hosts
(Caddy L4 requires udp/ prefix on both listen and dial for UDP)
- Fix TCP "disabled host" test to check data echo instead of connection
refusal (Docker port mapping always accepts TCP handshake)
- Add waitForTcpRoute before "both ports" test to handle re-enable timing
- Increase UDP route wait timeout to 30s for listener startup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix Caddy L4 config to use "udp/:PORT" listen syntax for UDP proxy hosts
(previously used bare ":PORT" which Caddy treated as TCP)
- Fix TCP unused port test to check data echo instead of connection refusal
(Docker port mapping accepts TCP handshake even without a Caddy listener)
- Fix mTLS import test to wait for sheet close and scope cert name to table
- Fix CA certificate generate test to scope name assertion to table
- Remaining L4 routing test failures are infrastructure issues with Docker
port forwarding and Caddy L4 UDP listener startup timing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New l4_proxy_hosts table and Drizzle migration (0015)
- Full CRUD model layer with validation, audit logging, and Caddy config
generation (buildL4Servers integrating into buildCaddyDocument)
- Server actions, paginated list page, create/edit/delete dialogs
- L4 port manager sidecar (docker/l4-port-manager) that auto-recreates
the caddy container when port mappings change via a trigger file
- Auto-detects Docker Compose project name from caddy container labels
- Supports both named-volume and bind-mount (COMPOSE_HOST_DIR) deployments
- getL4PortsStatus simplified: status file is sole source of truth,
trigger files deleted after processing to prevent stuck 'Waiting' banner
- Navigation entry added (CableIcon)
- Tests: unit (entrypoint.sh invariants + validation), integration (ports
lifecycle + caddy config), E2E (CRUD + functional routing)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds two new UI-configurable Caddy patterns that previously required raw JSON:
- Per-path redirect rules (from/to/status) emitted as a subroute handler before
auth so .well-known paths work without login; supports full URLs, cross-domain
targets, and wildcard path patterns (e.g. /.well-known/*)
- Path prefix rewrite that prepends a segment to every request before proxying
(e.g. /recipes → upstream sees /recipes/original/path)
Config is stored in the existing meta JSON column (no schema migration). Includes
integration tests for meta serialization and E2E functional tests against a real
Caddy instance covering relative/absolute destinations, all 3xx status codes, and
various wildcard combinations. Adds traefik/whoami to the test stack to verify
rewritten paths actually reach the upstream.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- accept wildcard proxy host domains like *.example.com with validation and normalization
- make exact hosts win over overlapping wildcards in generated routes and TLS policies
- add unit coverage for host-pattern priority and wildcard domain handling
- add a single test:all entry point and clean up lint/typecheck issues so the suite runs cleanly
- run mobile layout Playwright checks under both chromium and mobile-iphone
- Create tests/e2e/mobile/mobile-layout.spec.ts with 8 tests covering
AppBar/hamburger visibility, drawer open/close, mobile card rendering,
PageHeader button layout, dialog width, card actions, and analytics overflow.
- Fix AnalyticsClient: make Autocomplete full-width on mobile, add
overflow:hidden to outer Stack to prevent body scrollWidth growth.
- Fix WorldMapInner: remove hard-coded minWidth:400 that caused 73px
horizontal overflow on 393px iPhone 15 viewport.
- Fix DashboardLayoutClient: add overflowX:hidden to main content area
to contain chart library elements that exceed viewport width.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>