Skip to content

feat: Smart Availability Solver — find times for everyone - #34

Merged
WFord26 merged 1 commit into
mainfrom
feat/availability-solver
Apr 15, 2026
Merged

WFord26 merged 1 commit into
mainfrom
feat/availability-solver

Conversation

@WFord26

@WFord26 WFord26 commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements issue #16 — Smart Availability Solver: Find Times for Everyone.

Backend

  • New endpoint: GET /api/v1/projects/:id/availability-solver

    • Query params: from (ISO datetime), to (ISO datetime), limit (max suggestions)
    • Gets all engineers assigned to the project via time_block_engineers
    • For engineers with Microsoft Calendar connections: queries Graph API /calendarview for busy intervals
    • 5-minute in-memory cache for calendar data to respect MS Graph rate limits
    • Finds windows of session_length_minutes where ALL engineers are free
    • Excludes existing time blocks to avoid double-scheduling
    • Returns sorted suggestions with available/unavailable engineers per slot
    • Graceful fallback: engineers without calendars shown in engineers_without_calendar array
  • New utility: fetchCalendarBusyIntervals() in microsoftCalendar.ts

    • Queries MS Graph /me/calendarview with pagination support
    • Filters out events marked as "free" (showAs: 'free')
    • Handles UTC timezone normalization

Frontend

  • AvailabilitySolverModal — new component showing suggested time slots

    • Loading state with spinner while querying calendars
    • Warning banner when some engineers lack calendar connections
    • Empty state messaging when no windows found
    • Scrollable suggestion list with date, time, and engineer count
  • "Find a Time for Everyone" button on ProjectDetailPage

    • Visible when project has ≥2 assigned engineers and user is PM/Admin
    • Opens solver modal
  • One-click block creation — clicking "Create Block" on a suggestion:

    • Closes solver modal
    • Opens AddTimeBlockModal prefilled with the suggested date/time

Shared

  • AvailabilitySuggestion and AvailabilitySolverResponse types
  • availabilitySolverQuerySchema Zod validation for query params
  • AvailabilitySolverQuery contract type

Acceptance Criteria

  • Solver returns correct windows where all team members are free
  • Session length from project config respected
  • One-click creates a time block from a suggested slot
  • Graceful degradation when some engineers lack calendar connections
  • Engineers without calendars shown with warning message
  • Loading state during calendar queries
  • Rate-limited via 5-minute cache to avoid Microsoft Graph throttling
  • Works correctly across timezones (UTC-normalized)

Closes #16

- Add GET /api/v1/projects/:id/availability-solver endpoint
- Query Microsoft Graph calendarview API for engineer free/busy data
- 5-minute cache for calendar data to respect Graph API rate limits
- Find windows of session_length_minutes where all engineers are free
- Exclude existing time blocks to prevent double-scheduling
- Add AvailabilitySolverModal component with loading/error/empty states
- Show 'Find a Time for Everyone' button when project has ≥2 engineers
- One-click block creation from solver suggestions (prefills AddTimeBlockModal)
- Graceful degradation when engineers lack calendar connections
- Add Zod schema for query params (from, to, limit)
- Add shared types: AvailabilitySuggestion, AvailabilitySolverResponse
@WFord26
WFord26 merged commit 6634fa6 into main Apr 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Smart Availability Solver: Find Times for Everyone

1 participant