Scenario A: Event CRUD + Sync SYNC
Creating, updating, and deleting events with automatic synchronization to external providers (Google Calendar, Outlook).
User creates "Team Retro" meeting for Friday 2pm
Via calendar UI or chat command
👤
User Action
Create event
📅
CalendarService
createEvent()
🗄
DynamoDB
Store locally
📤
Event Published
calendar.event.created
Provider Sync
Push to Google/Outlook
Sync Status
Connected
-30d
Past Range
+90d
Future Range
847
Events Synced
2m ago
Last Sync
Event Created
Synced to Google Calendar
Fri, 2:00 - 3:00 PM Team Retro Synced
🔄 Optimistic Locking
Events use version tracking to prevent lost updates. If a conflict is detected during sync (remote changed while editing locally), the system stores it in a conflicts table for user review rather than silently overwriting.
Scenario B: On-Demand Fetch LAZY LOAD
When users navigate outside the synced range (-30 to +90 days), the system fetches events directly from the provider without caching.
User scrolls calendar to 6 months ago
Beyond the synced range of -30 days
Sync Range vs User Request
Synced data is cached; outside requests fetch live
← 6 months ago (requested) -30 days Today +90 days Future →
👤
User Scrolls
6 months back
Out of Range
Not in cache
📅
fetchEventsOnDemand()
Direct provider call
Google Calendar API
Live fetch
Events Returned
isOnDemand: true
📡
Live Fetched Events
July 2025 (6 months ago)
Jul 15, 10:00 AM Q2 Planning Session Live
Jul 18, 2:00 PM Client Review Live
Jul 22, 9:00 AM Team Offsite Live
23
Events Found
450ms
Fetch Time
Not Cached
Storage
💡 Why Not Cache Everything?
Syncing unlimited history would create massive storage costs and slow initial loads. The -30/+90 day window covers 95% of use cases. On-demand fetching handles the rare cases where users need historical data without impacting performance.
Scenario C: Meeting Classification AI TAGGING
The MeetingClassifier automatically tags meetings as Work, Personal, or Focus Time based on attendees, title, and context.
Calendar sync completes with 15 new events
MeetingClassifier processes each event
📅
New Events
15 synced
🧠
MeetingClassifier
Analyze context
🏷
Tagged Events
Work/Personal/Focus
💼
8
Work
Standups, 1:1s, Reviews
🏠
4
Personal
Doctor, Gym, Family
🎯
3
Focus Time
Deep Work, Planning
🏷
Classified Events
This week's meetings with tags
Mon, 9:00 AM Team Standup Work
Mon, 2:00 PM 1:1 with Manager Work
Tue, 10:00 AM Dentist Appointment Personal
Wed, 9:00 AM Deep Work Block Focus
Thu, 3:00 PM Sprint Review Work
🤖 Classification Signals
Work: Company domain attendees, work-related keywords, recurring meeting patterns
Personal: No attendees or non-work domains, personal keywords (doctor, gym)
Focus: Self-only events, "focus", "deep work", "blocked" in title
Scenario D: Conflict Detection ALERT
Automatic detection of double-booked time slots, travel time violations, and focus block overlaps.
New meeting scheduled overlapping existing event
ConflictDetector identifies the clash
📅
New Event
Client Call 2pm
Conflict Detected
Overlaps existing
🔔
Alert User
Resolution options
Schedule Conflict Detected
Thursday, 2:00 PM - 3:00 PM
2:00 - 3:00 PM Client Call (NEW) Conflict
2:00 - 2:30 PM Team Standup (EXISTING) Conflict
3
Conflicts This Week
2
Auto-Resolved
1
Pending Review
🚗 Travel Time Conflicts
When events have different locations, the system calculates travel time between them. If back-to-back meetings don't allow sufficient travel time, a conflict is flagged. Uses MobilityService for accurate ETA estimates.
Scenario E: Agent Compose AI ASSIST
Agents can suggest calendar events based on conversation context. The CalendarComposerService packages suggestions as draft events.
"Schedule time to review the Q1 proposal"
Chat message to Hey Umber
💬
User Chat
"Schedule review time"
🤖
General Agent
Extract intent
📅
Calendar Agent
Find best slot
📝
ComposerService
Create draft
Draft Event
User reviews
📅
Suggested Event
Based on your availability and preferences
Tomorrow, 9:00 - 10:30 AM Review Q1 Proposal Focus

Why this time?

  • Morning focus block aligns with your productivity preferences
  • 90 minutes allows thorough review without rushing
  • No conflicts with existing meetings
  • Buffer time before your 11am standup
🧠 Ask the Expert Pattern
The General Agent doesn't directly access calendar tools. Instead, it asks the Calendar Agent (domain expert) to suggest optimal times. This ensures consistent scheduling logic and proper consideration of user preferences, conflicts, and focus time.
// Agent consultation for calendar event
const suggestion = await calendarAgent.consultExpert({
  consultType: 'CALENDAR_SLOT_RECOMMENDATION',
  context: {
    taskDescription: 'Review Q1 Proposal',
    estimatedDuration: '90 minutes',
    preferredTimeOfDay: 'morning',
    userId: userId
  }
});