Eddy Dev Handbook
Architecture

Session (Workflow Run) Architecture

An overview of the Session experience, covering core concepts, UI components, data flow, and state management.

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

This document provides a developer-focused overview of the Session experience in Project Eddy. It covers the core concepts, key components, data flow, and state management that power a user's journey through a live workflow run.

For details on the backend logic that governs progression, see the Session Progression Rules documentation.

1. Core Concepts

A "Session" is a live, running instance of a Workflow, technically referred to as a workflow_run. It represents a single execution of a defined process, involving one or more participants.

  • Workflow Run (workflow_run): The top-level record for a session, tracking its overall status (e.g., completed_at, archived_at).
  • Run Stage (workflow_run_stage): A record that links a workflow_run to a specific Page from the workflow template. It tracks the status of that stage within the session (pending, active, or completed).
  • Session Role Assignment (session_role_assignment): Assigns a specific user to a workflow_role for the duration of a session. This is how participants are defined (e.g., "Alice is the Reviewer for this run").
  • Session Assignment (session_assignment): A dynamic record created when a stage becomes active. It grants a specific user access to that stage based on their assigned role, defining their permissions (can_write, can_progress).
  • Progression: The act of moving from one stage to the next. This is governed by completing the current stage, evaluating outgoing page_transitions, and activating the next valid stage(s).

2. Key UI Components & Functional Areas

The session experience is primarily orchestrated from the main page at /sessions/workflows/[workflowId]/[workflowRunId].

A. The Session Graph (Primary Map & Navigator)

This is the main visual interface, providing an overview of the entire workflow and the user's current position within it.

  • Component: app/components/session/SessionGraph.tsx
  • Technology: React Flow.
  • Functionality:
    • Displays workflow pages as nodes (SessionGraphNode.tsx) and transitions as edges (SessionGraphEdge.tsx).
    • Node and edge styling dynamically reflects the state of the session (e.g., completed, active, blocked) based on logic from getSessionGraphState.
    • Nodes are clickable, serving as the primary entry point to interact with a specific stage by opening the Stage Dialog.
    • Displays user presence icons (SessionPresenceIcon.tsx) on nodes to show which users are currently viewing that stage.

B. The Stage Dialog (Main Interaction Surface)

This is the modal where users interact with the content of a single stage.

  • Component: app/components/session/SessionDialog.tsx
  • Functionality:
    • Opens when a node on the graph is clicked. Its state is managed by useSessionStore.
    • Header (SessionDialogHeader.tsx): Displays the stage title, status (Active/Completed), and admin-only actions like "Rewind" or "Reopen Stage".
    • Body (SessionStage.tsx): Renders the actual page content using SessionRenderer.tsx, which displays all the blocks and fields for the user to interact with.
    • Footer (SessionDialogFooter.tsx): Contains the primary progression controls. The main button's text and action are dynamically determined by the progression state (e.g., "Next", "Handover", "Complete Session"). It also handles client-side validation for required fields.

C. The Top Bar & Supporting Dialogs

The top bar provides access to session-wide information and actions.

  • Component: app/components/session/SessionTopBar.tsx
  • Functionality:
    • Displays the session name and breadcrumbs.
    • Provides an auto-save indicator.
    • Offers access to several key dialogs:
      • Docs (DialogDocs.tsx): Shows the workflow's documentation.
      • Data (DialogData.tsx): Displays all data collected in the session via SessionSheets.tsx.
      • Role Assignments (DialogAssignments.tsx): Allows session admins to manage session_role_assignments.
    • Includes a SessionOptionsMenu.tsx for actions like archiving or reopening the session.

D. Participants & Presence

UI elements dedicated to showing who is involved in the session and who is currently online.

  • Party Frames (SessionPartyFrameGroup.tsx): On desktop, these frames provide a detailed view of each workflow_role, its description, and the users assigned to it.
  • User List (SessionUserList.tsx): A fixed panel showing which assigned users are currently online or offline, powered by Ably presence.
  • Mobile Banner (SessionMobileBanner.tsx): On mobile, provides a button to open an overlay (SessionPartyFrameOverlay.tsx) showing the party frames.

3. Data Flow & State Management

The session view is a complex, data-driven interface that relies on coordinated data fetching, client-side state, and real-time updates.

  • Initial Load: The entry page (/pages/sessions/.../index.tsx) and the main Session.tsx component orchestrate the initial data fetch using a series of React Query hooks:

    • useGetWorkflowRun: Fetches the main session record.
    • useGetWorkflowRunDependencies: A crucial hook that fetches the static workflow structure (pages, transitions, roles, etc.).
    • useGetWorkflowRunStagesByWorkflowRunId: Fetches the status of each stage for this specific run.
    • useGetSessionAssignmentsByWorkflowRunId: Fetches all user assignments.
    • useGetCellsByWorkflowRun: Fetches all data entered into blocks.
    • The UI remains in a loading state until all critical data has been successfully fetched.
  • Client-Side State (Zustand): The useSessionStore is the single source of truth for UI state, managing:

    • currentStageId: The ID of the stage currently being viewed in the dialog.
    • sessionDialogOpen: A boolean to control the visibility of the SessionDialog.
    • showConfetti: Toggled on session completion to trigger a celebration effect.
    • autoSaveIndicator: Tracks the state of background data saves.
  • Real-time Updates (Ably):

    • The usePresence hook is used to track which users are online and what stage they are currently viewing. This powers the SessionUserList and the presence icons on the graph.
    • The useChannel hook listens for messages from other clients (e.g., when another user updates a cell or completes a stage) and invalidates the relevant React Query keys, ensuring all participants see the most up-to-date information.

4. Progression Logic & State Calculation

While the backend enforces progression rules, the frontend is responsible for interpreting the current state to provide a clear and accurate UI to the user.

  • Central Logic Hub: The util/sessions/getSessionGraphState.ts utility is the brain of the session view. It takes all the fetched data (pages, transitions, run stages, assignments, cell data) and computes a unified view model for the graph.
  • Node & Edge State: getSessionGraphState calls helper functions to determine the precise state of each node and edge:
    • calculateNodeState: Determines if a stage is open-handover-stage, completed-role-stage, blocked-handover-stage, etc.
    • calculatePathState: Determines if a transition is an open-handover-path, closed-role-path, etc.
    • This calculated state is passed directly to the SessionGraphNode and SessionGraphEdge components to control their appearance (color, border style, animation).
  • Determining the Next Action: For the currently open stage, getStageProgressionState.ts is called. This function analyzes the current state and returns a StageProgressionType object that describes exactly what the user's next action should be (e.g., GO_TO_STAGE, MARK_COMPLETE_AND_HANDOVER, OPEN_SESSION_COMPLETION_DIALOG, BLOCKED_HANDOVER).
  • Driving the UI: The progression object returned by this logic is passed to SessionDialogFooter.tsx, which uses it to set the text of the main button and to determine what happens when it's clicked. This creates a clear, state-driven user experience where the UI always reflects the valid next step.

On this page