Frontend Data Flow
Big Picture
Mental Model
Here is how I think about what pieces of the app are responsible for what
| Piece | Responsibility | How | Where |
|---|---|---|---|
| draft event | Quick, understandable, testable | minimal schema | draft functions |
| event (frontend) | exhaustive copy of event from backend | normalizes GET response, exhaustive schema | Redux store |
| middleware | convert draft -> regular event | adds/derives values & validates against types/schemas | frontend typescript functions |
| event (backend) | validates event and persists | zod, node, mongoDB, exhaustive schema | /backend package |
Visual summary of the above:

For more context about this pattern, see this PR discussion
Redux Data Flow
The frontend uses Redux, Redux Saga, and React to manage state. It can be difficult to understand how all of this fits together. This might help.
On Startup
Store & Dispatch initialized
ducks/events/slice.ts
- each slice is initialized with name, props, and reducer
- all slices/reducers are combined into an
eventsReducer->store/reducers.ts - those events reducers are added to the global
reducersobject ->store/index.ts - adds all those reducers to the redux store
- uses store to init
RootStateandAppDispatch
Runtime - Events
The event flow follows this pattern:
-
Component (e.g.,
useWeek.tsor similar hook/component):- Imports the global dispatch from the Redux store
- On render: dispatches
getWeekEventsSlice.actions.request(...)to fetch events - On submit:
- If event exists (has an id): dispatches
editEventSlice.actions.request(...) - If event doesn't exist: dispatches
createEventSlice.actions.request(...)
- If event exists (has an id): dispatches
-
Redux Saga (
sagas.ts):- Listens for dispatched actions
- Getting Events:
getWeekEventsSaga()→getEventsSaga()→ callseventsApi.getEvents()inevents/api.ts - Creating Event:
createEventSaga()→ callseventsApi.createEvent()inducks/events/api.ts- Creates event with new ID
- Adds to running list of events in localStorage (for optimistic updates)
-
API Layer (
events/api.tsorducks/events/api.ts):- Makes HTTP requests to the backend API
- Handles responses and updates the Redux store
Runtime - Someday List
The Someday list follows a similar pattern:
-
Component (
EventsList):- Calls
getEvents()on load to fetch someday events
- Calls
-
Redux Selector (
selectors.ts):SidebarEventContainerusesmapStateToPropsto connect to Redux- Finds events from the
entitiesslice that match someday criteria