Entities Service & Data Fetching
Relevant source files
The following files were used as context for generating this wiki page:
The Entities Service is the centralized data access layer for the RoundingWell frontend. Its primary purpose is to decouple UI components and application logic from the underlying data fetching mechanisms. In this architecture, all AJAX requests and server-side data interactions are routed exclusively through the entities service rather than being implemented ad-hoc within views or controllers.
This service works in conjunction with Backbone.Store to provide an "Identity Map," ensuring that only a single instance of a specific model (e.g., a Patient or a Clinician) exists in memory at any given time. This pattern synchronizes state across multiple application modules automatically.
Sources: CLAUDE.md:21, README.md:167, AGENTS.md:21
Core Data Access Architecture
The project enforces a strict boundary for data operations. Ad-hoc fetch logic is prohibited in views; instead, developers must utilize the src/js/entities-service/** modules for all data requirements.
The Identity Map Pattern
By utilizing Backbone.Store, the entities service maintains unique model instances. When a new model is instantiated with an ID that already exists in the store, the existing instance is returned. This ensures that updates to a model in one part of the application are immediately reflected globally.
Sources: README.md:104-120, AGENTS.md:21
Data Fetching Workflow
Data fetching typically occurs during the beforeStart lifecycle phase of a Toolkit.App. This ensures that required data is available and normalized before views are rendered and attached to the DOM.
| Component | Responsibility |
|---|---|
| Toolkit.App | Requests data via Radio.request('entities', ...) and packages it for views. |
| Entities Service | Handles all AJAX calls, URL construction, and response normalization. |
| Backbone.Store | Manages model uniqueness and cross-application state sync. |
| WSService | Manages real-time data push and updates to stored entities. |
Sources: README.md:83-102, README.md:167, src/js/services/ws.test.js:141-160
Real-time Data Synchronization (Websockets)
Real-time updates are handled by the WSService, which manages the lifecycle of a WebSocket connection and coordinates with the Entities Service to update relevant models.
WebSocket Data Flow
When a message is received via WebSocket, the service validates the subscription_version and category. If valid, it retrieves the corresponding model from the entities store and triggers a message event directly on that model.
Sources: src/js/services/ws.test.js:141-177
Subscription Management
The service manages persistent and non-persistent resource subscriptions. It uses a subscriptionVersion to ensure stale updates do not corrupt the local state.
- Persistent Resources: Resources that should remain subscribed across different application states.
- Filters: The service supports filtering subscriptions by attributes such as
teamorworkspace.
Sources: src/js/services/ws.test.js:179-220
Implementation Details
Artifacts Service
The Artifacts entity service provides a specialized interface for saving data with deterministic IDs. It uses namespaces (e.g., RWELL_NS) and composite identifiers (e.g., artifact:identifier) to generate UUIDs, ensuring consistent referencing of resources across the system.
// Example of saving a model through the service
const result = await Artifacts.saveModel({
artifact: 'five9-call',
identifier: 'abc123',
values: { direction: 'outbound' },
});
Sources: src/js/entities-service/artifacts.test.js:7-22
Fetch Utilities
The underlying fetching mechanism is built upon src/js/base/fetch.js and src/js/base/backbone-fetch.js. These utilities standardize:
- Authentication: Automatic inclusion of bearer tokens in headers.
- Error Handling: Centralized processing of API errors.
- URL Resolution: Mapping resource requests to the
VITE_DEV_API_URLor production endpoints.
Sources: README.md:65, src/js/services/ws.test.js:25
Standards and Best Practices
- Strict Centralization: AJAX logic must never be placed inside Views. The View's responsibility is solely DOM interaction and event handling.
- Identity Preservation: Always use
Backbone.Storefor server models to prevent data divergence. - Lifecycle Integration: Fetch data in
beforeStartof the application/component to provide a seamless transition to the "Started" state. - Observable State: Use state models to store operational data and use Radio channels for cross-module communication.
Sources: CLAUDE.md:21, README.md:167, src/js/README.md:53-62
Summary
The Entities Service and Data Fetching system provides a robust, centralized framework for managing the lifecycle of data within the RoundingWell application. By combining the Identity Map pattern of Backbone.Store with a strictly enforced service layer for AJAX and WebSockets, the architecture ensures data consistency, simplifies state management, and provides a predictable interface for UI components to consume and update server-side resources.