Key Technical Points
Authentication & API Client
- Auth: localStorage.auth_token drives useAuth() / checkAuth() and protected-route redirects. 401 responses clear the token and route to /auth.
- API client: zenspaceApi.request() (src/common/helpers/api.ts) returns a parsed ApiResponse
<T>; non-OK HTTP responses are returned (not thrown) — call sites check res?.success. - The public magic-link page is the exception — it uses raw fetch via joinBackendUrl().
Organization Context
- OrganizationProvider reads ?orgId= and loads org into Redux (organization slice).
- Protected pages read the org from Redux. All API calls, breadcrumbs, and timezone formatting use this context.
Redux Slices
common.hardRefresh is the cross-feature invalidation signal — ListViewTable refetches whenever it changes.
List Views
- Most lists use ListViewTable with a shared URL contract: page, limit, sortBy, sortOrder, search, plus direct filter params.
Plaintext API Keys
Magic Link
- Raw fetch to /magic-links/:token/context; iframe sandbox is allow-scripts only.
- The route must remain unauthenticated.
Backends
- ZenCore — REST API at VITE_BACKEND_URL.
- ZenEdge — Realtime WebSocket at VITE_WEBSOCKET_SERVICE_URL.
See CLAUDE.md for full terminology and API contracts.