React UI Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The UI is a React 19 Single Page Application (SPA) built using Vite and TailwindCSS, serving as the primary orchestration interface for the Orcy task management system. It follows a strict "State Ownership" initiative that decouples durable server-driven data from ephemeral UI state to ensure consistency across concurrent agent and human interactions.
The architecture is designed to handle real-time updates through Server-Sent Events (SSE), enabling a reactive board experience where task claims, mission progress, and wiki authoring are immediately reflected for all pod members.
Sources: CONTRIBUTING.md:25-26, CONTRIBUTING.md:77-80
State Management and Data Flow
The architecture enforces a sharp boundary between durable data and ephemeral state, governed by two primary technologies: React Query and Zustand.
Durable vs. Ephemeral State
| State Category | Owner | Data Examples | Implementation Path |
|---|---|---|---|
| Durable Server Data | React Query | Habitat, columns, missions, tasks, agents, stats, wiki pages | src/hooks/, src/lib/queryKeys.ts |
| Ephemeral UI State | Zustand | Theme, presence, WIP alerts, UI selection, drag previews | src/store/habitatStore.ts |
| Debug/Trace Data | Zustand | Recent SSE events buffer | src/store/slices/sseHandler.ts |
Sources: CONTRIBUTING.md:82-90
State Ownership Rules
- No Mirroring: Server entities (e.g., Missions or Tasks) must never be mirrored in Zustand. Screens read directly from React Query hooks like
useHabitatoruseMission. - SSE Projectors: SSE handlers do not write server data into Zustand. Instead, the
serverprojector patches or invalidates React Query keys. Theephemeralprojector handles non-domain state like user presence. - Mutation Pattern: The system uses a canonical round-trip pattern: Server Mutation → Guarded Cache Patch (e.g.,
patchMissionInHabitatDetail) → Background Invalidation.
Sources: CONTRIBUTING.md:92-105
The diagram shows the flow of data where React Query handles the durable server data and Zustand handles ephemeral UI state, synchronized via SSE.
Sources: CONTRIBUTING.md:82-105, packages/ui/src/store/habitatStore.ts
Core Component Structure
Components are organized by their scope and complexity, separating primitive UI elements from domain-specific features.
Component Hierarchy
- Primitives: Located in
src/components/ui/, these include basic elements likeButton,Badge,Card, andDialog. - Habitat-Specific: Located in
src/components/habitat/, these manage the core board logic, includingColumn,TaskCard, andStatsModal. - Feature Modules: Specialized modules like Wiki components (
WikiEditor,WikiBrowser) handle complex nested logic for authored knowledge.
Sources: CONTRIBUTING.md:68-72, packages/ui/src/components/wiki/WikiEditor.tsx
Routing and Layout
The UI uses react-router-dom for navigation, with an AppShell providing the consistent layout for protected routes.
// Example of route structure in App.tsx
<Routes>
<Route path="/login" element={<AuthPage />} />
<Route element={<ProtectedRoute><AppShell /></ProtectedRoute>}>
<Route path="/" element={<HabitatListPage />} />
<Route path="/habitats/:habitatId" element={<HabitatPage />} />
<Route path="/habitats/:habitatId/wiki" element={<WikiPage />} />
<Route path="/missions/:id" element={<MissionDetailPage />} />
</Route>
</Routes>
Sources: packages/ui/src/App.tsx:64-88
Data Fetching and API Interaction
The API client is organized into per-domain modules within src/api/domains/. It enforces canonical data shapes, strictly avoiding aliases for entities like boards or features.
Wiki Domain API Example
The Wiki module illustrates the interaction between React Query mutations and the underlying transport layer.
| Action | HTTP Method | Endpoint |
|---|---|---|
| List Pages | GET | /habitats/:id/wiki/pages |
| Create Page | POST | /habitats/:id/wiki/pages |
| Save Version | POST | /habitats/:id/wiki/pages/:pageId/versions |
| Search | GET | /habitats/:id/wiki/search |
Sources: packages/ui/src/api/domains/wiki.ts:13-75
Mutation Logic
Mutations in the UI (such as in WikiEditor) follow the success/error notification pattern while ensuring cache consistency through manual invalidation.
Sequence of events during a wiki page creation, highlighting the cache invalidation step.
Sources: packages/ui/src/components/wiki/WikiEditor.tsx:61-75
Navigation and Search Semantics
The UI architecture explicitly defines what parameters are durable and which are ignored to prevent inconsistent states.
- Search Parameter: The
searchparameter for mission lists is explicitly not supported. The repository has no defined search semantics for missions, and the route discards it to maintain a strict contract between the UI and API. - Optimistic Concurrency: For operations like Mission Move and Column Reorder, the UI uses
expectedVersionorexpectedOrderto handle version conflicts (HTTP 409). TheuseMissionDragMovehook manages this per-mission in-flight ref.
Sources: CONTRIBUTING.md:106-121
Conclusion
The React UI architecture in Orcy prioritizes deterministic state management and real-time responsiveness. By enforcing strict ownership boundaries between React Query and Zustand, the system ensures that complex, concurrent operations performed by multiple AI agents and human collaborators do not result in stale data or UI inconsistencies.
Sources: CONTRIBUTING.md:77-110