AZ-009 — Mocking Bird developer console
Status
Done
Context
Read README. AZ-008 delivers mail transport interception/capped safe capture and constrained local test-email API. AZ-006 provides authenticated navigation/CSRF, and AZ-002's registry accommodates hidden/developer-only pages. General history cannot display raw mail or token URLs; local synthetic previews are a separate controlled facility.
Goal
Deliver a small, opt-in developer page for choosing fixed mock scenarios and inspecting safe requests/synthetic mail, with backend-enforced absence in hosted deployments.
Requirements
- Add
/developer/mocking-birdthrough the normal page declaration with MUI icon, localized name, authenticated access and developer-only metadata. No separate navigation implementation. Use mobile flow cards/list and an accessible details view, not a horizontally scrolling dense desktop table. Page works with temporary/permanent drawer behavior and version footer. - Introduce public frontend build flag
VITE_ENABLE_DEVELOPER_TOOLS=falseby default. Standard production build excludes developer declaration/page (use conditional/lazy imports appropriately), while explicit local development/tooling builds enable it. Pass this flag explicitly through any necessary Compose/Docker build argument; do not assume runtime frontend env alters a built bundle. Flag is visibility/bundle behavior only, never security authorization. - Backend endpoints are registered only when deployment classification is local/test AND Mocking Bird explicitly enabled. Authenticate/CSRF-protect state changes and rate-limit them; do not add an admin role solely for this dev tool. Local developer access is not a production authorization model. Staging/production invalid enabled config fails startup; disabled route absence is verified via direct HTTP regardless of menu/flag.
- Define small endpoints under
/api/developer/mocking-bird: GET state/history, PATCH scenario, DELETE history, and GET synthetic-mail previews. Document exact chosen subpaths, payloads, limits and statuses in OpenAPI and variant route tests from AZ-008. Only named fixed scenario enums and bounded latency are accepted, no code/expression/URL/header/body editor. Mutations follow AZ-003 safe errors and auth/CSRF; state/history responses use no-store. - Show startup mode as read-only (
mock,real,disabled). Scenario changes apply only in mock mode and affect subsequent requests; cannot switch real/mock at runtime. Warn clearly when a local proof operation would use real mail, but do not provide a browser real-send button in this epic. UI synthetic test-send uses the fixed AZ-008 endpoint only in mock mode. - Display method/path, redacted metadata summary, correlation ID, outcome and duration. Headers are an allowlisted/redacted projection, not raw captured dictionaries. Predefined scenario example: success, provider rejection, timeout; latency remains 0–5000ms. Caps/clear/reset are visible; one developer process owns state, no multi-user persistence/replay promise.
- Synthetic preview shows only allowlisted local fixture recipients/messages and a reset link when AZ-010 adds it. Disable copy/export/history download features; no token-bearing previews in logs or diagnostic artifacts. Real-mode mail bodies/recipients are never visible. Render preview as escaped text; never execute captured provider HTML/scripts or arbitrary links. If offering a reset link, constrain to configured local app origin/path, use safe navigation.
- Use existing endpoint wrappers/TanStack Query; polling is bounded and only active while page is visible. Keep scenario form/dialog state local. Stop/cancel queries when leaving page or logging out; caches from developer previews are cleared on logout. No new websocket/event bus.
- Verify loading/empty/failure states, scenario selection/clear and hidden-route behavior at mobile/desktop sizes. Backend tests inject synthetic capture; E2E logs in a fixture user and performs mock test-send/capture, asserting the real provider transport was not invoked.
Non-goals
No live production developer tool, privileged impersonation, arbitrary outbound interception, response scripting, real-mode switching, request export/replay, persisted history or generic integration dashboard. No claim that hidden navigation secures an endpoint.
Implementation guidance
Reuse registry, MUI, localizations, transport and safe feedback from earlier tasks. Backend config is the authoritative gate; frontend availability may additionally query developer capability, but cannot override it. Extend test harness with enabled-local and disabled-hosted variants. Keep build flags and server runtime flags distinct in documentation. Use input constraints on both client and backend, and content-size limits before capture rather than truncating already stored sensitive raw objects.
Acceptance criteria
- Local mock console sends only fixed synthetic mail, switches named scenarios and bounded latency, views redacted requests, and clears bounded state.
- Preview information cannot leak real-recipient mail, credentials or raw provider HTML.
- Normal builds have no console declaration/menu; direct backend developer URLs return 404 with disabled/hosted config, and unsafe hosted enablement fails before serving requests.
- Auth/CSRF and validation protections apply even with a forged frontend flag.
- Mobile/desktop navigation, focus, empty/error states and logout query cleanup work.
Verification
pnpm quality
pnpm test
pnpm test:coverage
pnpm build
pnpm validate:docker
Add backend enablement/negative validation tests and frontend registry/console RTL tests; add Playwright local mock send/history scenario in both projects. Canonical validation enables the local tooling build/config explicitly for that test. Separately test standard disabled build declaration absence and backend staging/production route absence in controlled fixtures; no need for a second full Docker reset just to repeat unrelated journeys. Inspect 320/360px, keyboard-only detail/clear actions and long sanitized metadata wrapping manually.
Documentation
Update development (enablement matrix, page registration, scenarios/preview caps), Docker (build/runtime flags), testing/CI (enabled-local and disabled-hosted negative proof), OpenAPI, architecture security boundary and current-state/handover. Include safe screenshots only with synthetic token-free content if useful; screenshots are not mandatory acceptance artifacts.
Dependencies
AZ-006 and AZ-008 (including their prerequisites).