Event And Task Domain Model
The event domain is the most cross-cutting part of Compass. Read this before changing event shape, recurrence logic, sync behavior, or local persistence.
Core Event Schema
Primary source:
packages/core/src/types/event.types.ts
Important event fields:
_id: Compass event idstartDate,endDate: ISO datetime or date stringsisAllDay: display semanticsisSomeday: local Compass someday bucket semanticsorigin: where the event came frompriority: shared priority enumgEventId: Google event id when syncedgRecurringEventId: Google recurring parent id when relevantrecurrence.rule: RRULE array for recurring basesrecurrence.eventId: base Compass event id for recurring instances
Display Categories
Categories_Event maps events to visible buckets:
alldaytimedsidebarWeeksidebarMonth
These are UI-facing categories, not storage categories.
Recurrence Categories
Categories_Recurrence models structural state:
STANDALONERECURRENCE_BASERECURRENCE_INSTANCESTANDALONE_SOMEDAYRECURRENCE_BASE_SOMEDAYRECURRENCE_INSTANCE_SOMEDAY
Many sync and parser decisions key off transitions between these states.
For the full recurring-event lifecycle, see Recurrence Handling.
Update Scopes
Recurring edits use RecurringEventUpdateScope:
This EventThis and Following EventsAll Events
If you change recurring edit behavior, check:
packages/core/src/types/event.types.tspackages/backend/src/event/controllers/event.controller.tspackages/backend/src/sync/services/event-propagation/compass-to-google/compass-to-google.event-propagation.ts
Backend Event Shape Semantics
The backend treats recurring events as:
- one base event containing recurrence rules
- zero or more generated instances referencing the base via
recurrence.eventId
When reading instances back, the backend rehydrates the instance with the base event's recurrence rule before returning it.
Primary code:
packages/backend/src/event/services/event.service.tspackages/backend/src/event/classes/compass.event.parser.tspackages/backend/src/event/classes/compass.event.executor.tspackages/backend/src/event/classes/compass.event.generator.ts
Someday Semantics
isSomeday is not just a UI flag.
It affects:
- query behavior
- sync transitions
- SSE notification type
- provider selection when mapping events
For someday events, Compass often behaves as the provider of record instead of Google.
Optimistic IDs
The web can create optimistic ids using a prefix, and the backend strips that prefix before persisting:
- web optimistic flow:
packages/web/src/ducks/events/sagas/event.sagas.ts - backend normalization:
packages/backend/src/event/controllers/event.controller.ts
Do not assume every incoming _id is already a durable Mongo id.
Task Model
Primary source:
packages/web/src/common/types/task.types.ts
Task fields:
_idtitlestatus(todoorcompleted)ordercreatedAtdescriptionuser
Tasks are currently local-storage centric and are stored with a dateKey in the adapter layer, not in the public Task shape.
Storage-Specific Task Shape
The IndexedDB adapter wraps tasks as StoredTask:
- public task data
- plus
dateKey
Source:
packages/web/src/common/storage/adapter/storage.adapter.ts
Invariants To Preserve
- Every persisted event must have a stable Compass
_id. - Instances reference a base event via
recurrence.eventId. - Base recurring events carry the
recurrence.rule. isSomedaychanges downstream sync and notification behavior.- Tasks should normalize through
normalizeTask/normalizeTasksbefore persistence. - Local storage schemas can evolve, but migrations must preserve existing user data.
Before Changing The Domain
Check all three layers:
coretype/schema definitionbackendpersistence and sync behaviorwebediting, rendering, selectors, storage, and tests