Architecture
Data flow
Package responsibilities
@radarboard/api
11 self-contained API client modules, one per external service. Each module:
- Handles authentication
- Transforms API responses into typed data structures
- Manages rate limiting awareness
@radarboard/types
12 type definition files (one per domain). Shared across all packages.
@radarboard/hooks
React hooks that call the API routes via SWR. One hook per data domain (e.g., useAnalytics, useRevenue).
@radarboard/widget-engine
Widget components and the widget registry. The registry maps widget IDs to components and their metadata.
@radarboard/ui
Shared UI primitives built on Radix UI (Badge, Dialog, ScrollArea, etc.).
@radarboard/charts
Chart components (Sparkline, etc.) built on Recharts.
@radarboard/utils
Pure utility functions (format-number, format-currency, cn).
Caching
All external API calls go through a cache-first strategy:- Check the database cache (unless
forceRefreshis set) - If the entry is fresh (within TTL), return cached data
- If stale or missing, call the external API
- Write the result to cache
- On fetch error, fall back to stale cache data (marked with
_stale: true)