Worked Answer: SaaS Dashboard
Prompt
Design the frontend architecture for a multi-tenant SaaS dashboard used by support, finance, and account managers. It includes login, dashboard home, customer detail, search/filter tables, exports, notifications, and role-based actions.
1. Clarify
Ask:
- Which workflows are critical: search, customer detail, exports, billing, support?
- What data is tenant-specific and role-specific?
- Which routes are public, authenticated, or admin-only?
- What freshness does each dashboard panel need?
- What scale matters: tenants, rows, dashboard panels, teams, regions?
- What compliance, privacy, and accessibility requirements apply?
Assumption for this answer: the primary risk is not visual complexity. The primary risk is data correctness, authorization, large-table interaction latency, and multiple teams changing the same app.
2. Architecture overview
3. Route rendering matrix
| Route | Strategy | Why |
|---|---|---|
/login | static or SSR shell, no-store auth callback | security-sensitive, minimal JS |
/dashboard | server shell plus panel-level data boundaries | fast structure and independent degradation |
/customers/:id | server composition with client tab islands | role-specific data and interactive tabs |
/orders | hybrid shell plus client-heavy table | filters and table actions need responsiveness |
/exports/:jobId | server shell plus polling/SSE island | side-effecting job state |
4. Data and state
| State/data | Location |
|---|---|
| tenant and role | server session/BFF |
| filters and pagination | URL |
| server data | query/cache layer backed by BFF |
| table row hover/selection | component or feature state |
| export job | server job model |
| notifications optimistic read state | client overlay reconciled with server |
| user density/theme | preference store |
5. Module boundaries
Use a modular monolith:
features/
customers/
orders/
billing/
exports/
notifications/
platform/
auth/
data-client/
observability/
feature-flags/
design-system/
Rules:
- feature modules cannot import each other directly
- shared code enters
platformonly with owner and review - design-system components do not own domain data fetching
- BFF contracts are versioned or contract-tested where shared
6. Quality gates
| Concern | Gate |
|---|---|
| Performance | LCP route budget, INP table budget, third-party budget |
| Accessibility | keyboard table/filter/dialog/notification walkthrough |
| Security | server authorization proof for role-based actions |
| Reliability | panel failure matrix and export idempotency |
| Observability | route, release, tenant class, experiment, trace id |
7. Failure modes
| Failure | Behavior |
|---|---|
| one dashboard panel API times out | panel error only; shell remains usable |
| filter query params are invalid | normalize or show recoverable error |
| permissions change mid-session | protected mutation fails closed |
| export job fails after navigation | job status route and notification explain failure |
| table causes INP regression | roll back table enhancement flag |
8. Tradeoffs
Rejected:
- full CSR: weak first useful state and harder data/permission orchestration
- microfrontends immediately: operational cost not justified unless teams need independent deploy/runtime isolation
- one global store: hides ownership and mixes URL/server/form/UI state
Chosen:
- modular frontend monolith with explicit boundaries
- BFF for frontend-specific contracts
- route-specific rendering
- platform defaults for auth, telemetry, flags, and design system
Strong close
I would launch with dashboard home, customer detail, and order search first, keep exports behind a separate flag, and review the quality scorecard weekly during beta. The architecture is successful if product teams can add features without cross-feature imports, critical route Web Vitals stay within budget, role-based actions are server-authorized, and partial API failures degrade locally instead of breaking the shell.