Eddy Dev Handbook
Architecture

Frontend App Map

A high-level map of the Next.js client, including routing, layout shells, and the main data domains.

Frontend App Map

Source: This page is based on docs/CLIENT_MAP.md

High-level map of the Next.js client: routing, layout shells, and the main data domains.

App shells and providers

  • _app.tsx wraps every page with ChakraProvider, QueryClientProvider (React Query), UserProvider (Auth0), UIProvider, optional PostHogProvider, and WorkspaceContext/UserbackContext.
  • Primary layout shell: components/layouts/PageLayout. Desktop = top header (NavHeader + breadcrumb/topbar), left nav (NavDesktop), central content, optional right-side editor panels. Mobile = NavMobile + sticky top bar. Aside panels show the workflow/page editors when active.
  • Public/marketing and maintenance screens use LandingPageLayout.
  • PortalRenderer renders portaled UI (modals/asides) at the page root.

Route diagram (pages/)

/                              Home dashboard (recent visits, assignments)
├─ /workspaces                 List & create workspaces (/workspaces/new)
│  └─ /workspaces/[groupId]    Workspace area shell (PageLayout + left nav)
│     ├─ /                     Overview (shortcuts, recent sessions, activity)
│     ├─ /handbook[/[pageId]]  Handbook pages + blocks/sections
│     ├─ /workflows            Workflow list; /workflows/new; /workflows/[workflowId]
│     ├─ /sheets               Sheets list/new; /sheets/[sheetId][/[recordId]]
│     ├─ /sessions             Session runs for the workspace
│     ├─ /scheduler            Scheduled/self-service starts; /scheduler/[scheduledStartId]
│     ├─ /members              Membership roster and roles
│     ├─ /settings             Workspace settings
│     └─ /activity             Activity feed
├─ /sessions                   Global sessions overview
├─ /start/[selfServiceStartId] Self-service start flow
├─ /notifications              Inbox
├─ /profile                    Current user profile
├─ /users/[userId]             User detail
├─ /marketplace                Marketplace & workspace templates
├─ /group_invitations/[id]     Invitation landing
└─ /embed/[workflowId]         Embeddable workflow view

Areas, purpose, ownership (fill owner names)

  • Home (/): Personalized dashboard showing recent visits and assignments (RecentVisitsCard, YourAssignmentsGrid). _Owner: __.
  • Workspace shell (/workspaces/[groupId]): Common chrome + nav for all workspace features; sets selected workspace in WorkspaceContext and NavDesktop. _Owner: __.
  • Handbook: Knowledge pages/sections/blocks for a workspace. _Owner: __.
  • Workflows: Workflow list and builder (components/builder/...); supports page/block editors shown in the right-aside panels. _Owner: __.
  • Sheets: Tabular data and records per workspace (pages/workspaces/[groupId]/sheets/...). _Owner: __.
  • Sessions (workflow runs): Run/participate in workflows; includes assignments and run state. _Owner: __.
  • Scheduler: Scheduled/self-service starts for sessions. _Owner: __.
  • Members & Settings: Manage membership, roles, and workspace configuration. _Owner: __.
  • Activity: Workspace event feed. _Owner: __.
  • Notifications: User inbox fed by /api/notifications. _Owner: __.
  • Profile & Users: User details and preferences. _Owner: __.
  • Marketplace: Discover/install workspace templates. _Owner: __.
  • Embed: Lightweight embedded workflow experience. _Owner: __.

Notes for contributors

  • Use PageLayout for any page that should live inside the main app shell; set pageName for breadcrumb/topbar and include an Aside when the page has editors.
  • Left-nav items come from NavDesktop and are driven by WorkspaceContext + current groupId. Add new workspace-scoped routes there for discoverability.
  • Workspace data is loaded via hooks in hooks/ (e.g., useGetCurrentUserAndGroups, useGetWorkspaceHomeEvents, useGetWorkflowRunsByGroupId); prefer adding new data fetches as hooks for consistency and caching.

Data fetching and mutations

  • Query hooks (hooks/*, typically useGet...) wrap useQuery to call /api routes. They set cache keys like workspaceShortcuts${groupId}; reuse keys to share caches.
  • Mutation hooks (useMutation) send writes to /api endpoints. On success, call queryClient.invalidateQueries(<related-key>) to refresh dependent data (e.g., after deleting a shortcut, invalidate workspaceShortcuts${groupId}).
  • Typical lifecycle: fetch with useQuery → mutate with useMutation → invalidate or directly update cached data → UI re-renders from fresh data.

Hooks folder at a glance

  • Location: hooks/. Primary pattern is useGet* (queries) and use*Mutation (writes) wrapping React Query for type-safe data access to /api.
  • Scoping: many hooks accept groupId, workflowId, sheetId, etc., and encode those in cache keys; pass stable IDs to maximize cache hits.
  • UX patterns: hooks usually expose { data, isLoading, error }; pages/components render skeletons/spinners on isLoading and toasts/banners on error.
  • Side-effect hooks: small set for UI/device concerns (e.g., useDeviceType, keyboard, presence) live alongside data hooks; keep them pure and narrowly focused.
  • Subfolders/domains (high level):
    • Workspaces & org: groups, memberships, groupInvitations, groupTags, user, notifications.
    • Content/knowledge: handbooks, pages, pageTransitions, sections, blocks, blockOptions, cells, columns.
    • Workflows & runs: workflows, workflowRuns, workflowRunStages, workflowRunAttachments, workflowRoles, workflowTags, session, sessionAssignments, sessionRoleAssignments.
    • Scheduling/self-serve: scheduledStarts, scheduledStartAssignments, selfServiceStarts, selfServiceAssignments.
    • Data tables: sheets, rows, mentions, agGridFilters.
    • Collaboration/comms: discussions, comments, follows, polls.
    • Shortcuts & home: shortcuts, home, visits.
    • UI/helpers: device, debounce/loading wrappers, mutations helpers, DnD/scroll/graph utils, perf helpers in common/.

Workflow builder page (core UX)

  • Route: pages/workspaces/[groupId]/workflows/[workflowId]/index.tsx.
  • Purpose: Build and orchestrate workflow pages/stages; edit transitions, roles, data connections, and run insights.
  • Layout: PageLayout with BuilderTopBar (stats, modals) and right-side Builder aside when editing a page. Uses NavDesktop chrome.
  • Key surfaces:
    • Stage graph (BuilderStageGraph): React Flow graph of workflow pages; supports drag, orientation toggle, dagre auto-layout, context menu create, delete with confirmation, edge editing, and zoom/fit controls.
    • Edge editor (BuilderGraphEdgeEditor): Rule builder for page transitions with sheet/column-aware filtering; deletes transition with cache invalidation.
    • Modals: Settings (workflow metadata, tags/roles), Activity feed, Data preview, Sessions table (AgGrid), Roles manager, Stage role assignments modal.
  • State and data:
    • React Query hooks: useGetWorkflow, useGetPageTransitionsByWorkflowId, useGetWorkflowRunPreviewByWorkflow, useGetWorkflowRunsByWorkflow, useGetSheetDataByWorkflowId, useGetStageRoleAssignmentsByWorkflowId, useGetWorkflowTags*, useGetWorkflowEvents, membership/assignments hooks.
    • Stores: useWorkflowBuilderStore (current workflow, page builder state), useUIStore (panel toggles, device), useCommonStore (member permissions, workflow preview), modal store for stage-role assignments.
    • Realtime: useChannel (Ably) invalidates workflow run queries on updates.
    • Mutations: useApiMutation/useMutation for node/edge create/update/delete; always follow with invalidateQueries on workflow, pageTransitionsByWorkflow..., stage role assignments, etc.
  • Interaction conventions: ESC closes side panels; graph edges double-click opens edge editor; background context menu "Create Node"; orientation switch persists to /api/workflows/update.

Sheet page (workspace data tables)

  • Route: pages/workspaces/[groupId]/sheets/[sheetId]/index.tsx (Ag Grid-powered table).
  • Purpose: Display workspace records with column/view controls, search + rule-based filters, archived row toggle, and CSV export with value sanitization.
  • Layout: PageLayout + SheetTop (search, query builder, views dropdown, settings/action bar) and the Ag Grid canvas; modals are portaled via Portal.
  • Data: useGetSheetDataBySheet for rows/cells/columns, useGetGroupMemberships for abilities, useGetCurrentUserAndGroups for the actor. Row filter uses filterRow with querybuilder rules; archived rows are client-filtered and persisted per sheet in localStorage.
  • Column/view management: SheetViewsDropDown loads/persists view selections; column hiding uses updateColumnVisibility and getHiddenColumns; column reordering calls useReorderSheetViewsColumn or useReorderColumns depending on whether a view is selected. Moves are debounced via a ref guard.
  • Export: exportData gates on grid readiness, omits the actions column, sanitizes nested values via sanitizeNestedObject/sanitizeRowData, temporarily applies sanitized data to the grid, and triggers CSV download with lowercased booleans.
  • Actions and permissions: SheetTop action bar lets managers toggle edit mode, add columns, export, delete, share, and toggle archived-row visibility (guarded by memberCanManage). Editing mode swaps the sheet title for an input that persists via /api/sheets/update.
  • Column modal: ColumnModal supports add/edit/copy/delete with validation to prevent duplicate names, uses useForm, and invalidates sheet queries on write; deletion confirms via nested DeleteModal.

Session run experience (participants)

  • Route: pages/sessions/workflows/[workflowId]/[workflowRunId]/index.tsx; sets workflowId, workflowRunId, initial stageId, and records visits. Wraps content in PageLayout with SessionTopBar, SessionUserList, and error dialog.
  • Entry component: components/session/Session.tsx; fetches workflow run, dependencies (workflow, pages, transitions, roles, stage role assignments, block options), assignments, cells, columns, and current user. Gated render shows spinner until all data slices are ready, then mounts SessionInner in a ReactFlowProvider.
  • Graph + progression: components/session/SessionGraph.tsx; maps pages to React Flow nodes and transitions to edges (looping vs standard), styles nodes/edges via getSessionGraphState, tracks starting stage centers, centers viewport on the active stage, and surfaces click handlers to open the dialog. Respects workflow style (orientation, edge type) and loop detection.
  • Dialog + stage content: components/session/SessionDialog.tsx; controlled by useSessionStore (sessionDialogOpen, currentStageId). Shows header with run stage status and admin actions, role pills (stage-role assignments), presence avatars (Ably), stage body (SessionStage), and footer controls (SessionDialogFooter) for proceeding/validation/confetti. Resets scroll on stage change.
  • Other supporting UI: SessionTopBar, SessionMobileBanner, SessionRolesPartyFrameGroup (party frames on desktop), SessionCompletionBanner, and SessionErrorDialog.

Session graph state helpers (runtime)

  • Orchestrator: util/sessions/getSessionGraphState.ts builds unified node/edge view models for the participant graph by calling calculateNodeState and calculatePathState with workflow pages, transitions, run stages, assignments, role metadata, loop sets, and current stage context.
  • Node state: util/sessions/getSessionNodeState.ts derives per-stage status/color/user-assignment from run stages + assignments, picks a stage-state enum (handover/role, open/closed/completed), and computes progression hints via getStageProgressionState (current stage only) using mapped next transitions (mapNextTransitionsToStageTransitions). Outputs are merged into React Flow nodes in components/session/SessionGraph.tsx.
  • Edge state: util/sessions/getSessionEdgeState.ts classifies transitions as handover vs role paths, determines open/completed/blocked status from run stage statuses, assignments, and rule evaluation, and selects an edge color tied to role assignment on the target stage. Returned PathState objects are merged into React Flow edges in SessionGraph.tsx.
  • Progression engine: util/sessions/getStageProgressionState.ts evaluates the current stage's available transitions, required-field completion, loop/role scenarios, and session completion to emit a StageProgressionType (e.g., go to stage, mark complete + handover, show map for choice, block). These values feed footer actions in SessionDialog via the node state computed above.

On this page