feat: push interview events to connected calendar integrations #20

Merged
pyr0ball merged 3 commits from feature/calendar-push into main 2026-03-16 21:45:07 -07:00
Owner

Summary

  • Implements idempotent calendar push from the Interviews kanban (phone_screen / interviewing stages)
  • Supports Apple Calendar (CalDAV) and Google Calendar (service account)
  • Button shows "📅 Add to Calendar" on first push, "🔄 Update Calendar" on subsequent pushes — no duplicate events
  • Event title: {Stage}: {Job Title} @ {Company}, 1hr duration at noon UTC, job URL + company brief in description

Changes

  • scripts/db.pycalendar_event_id TEXT migration + set_calendar_event_id() helper
  • scripts/integrations/apple_calendar.pycreate_event() / update_event() via caldav + icalendar
  • scripts/integrations/google_calendar.pycreate_event() / update_event() via google-api-python-client; test() now makes a real API call
  • scripts/calendar_push.py — new orchestration module
  • app/pages/5_Interviews.py — calendar button in date-picker block
  • environment.yml — pin caldav, icalendar, google-api-python-client, google-auth
  • tests/test_calendar_push.py — 9 new tests (486 total, all passing)

Test plan

  • Connect Apple Calendar integration in Settings → Integrations
  • Advance a job to Phone Screen, set an interview date
  • Confirm "📅 Add to Calendar" button appears
  • Click — verify event appears in calendar app (noon, 1hr, correct title)
  • Click again — verify "🔄 Update Calendar" and no duplicate event
  • Confirm button is hidden when no calendar integration is configured
  • Run pytest tests/ — 486 passed

Closes #19

## Summary - Implements **idempotent calendar push** from the Interviews kanban (phone_screen / interviewing stages) - Supports **Apple Calendar (CalDAV)** and **Google Calendar** (service account) - Button shows "📅 Add to Calendar" on first push, "🔄 Update Calendar" on subsequent pushes — no duplicate events - Event title: `{Stage}: {Job Title} @ {Company}`, 1hr duration at noon UTC, job URL + company brief in description ## Changes - `scripts/db.py` — `calendar_event_id TEXT` migration + `set_calendar_event_id()` helper - `scripts/integrations/apple_calendar.py` — `create_event()` / `update_event()` via `caldav` + `icalendar` - `scripts/integrations/google_calendar.py` — `create_event()` / `update_event()` via `google-api-python-client`; `test()` now makes a real API call - `scripts/calendar_push.py` — new orchestration module - `app/pages/5_Interviews.py` — calendar button in date-picker block - `environment.yml` — pin `caldav`, `icalendar`, `google-api-python-client`, `google-auth` - `tests/test_calendar_push.py` — 9 new tests (486 total, all passing) ## Test plan - [ ] Connect Apple Calendar integration in Settings → Integrations - [ ] Advance a job to Phone Screen, set an interview date - [ ] Confirm "📅 Add to Calendar" button appears - [ ] Click — verify event appears in calendar app (noon, 1hr, correct title) - [ ] Click again — verify "🔄 Update Calendar" and no duplicate event - [ ] Confirm button is hidden when no calendar integration is configured - [ ] Run `pytest tests/` — 486 passed Closes #19
pyr0ball added 3 commits 2026-03-16 21:41:43 -07:00
- cloud_session.py: add _ensure_provisioned() called in resolve_session() so
  new Google OAuth signups get a free Heimdall key created on first page load;
  previously resolve returned "free" tier but no key was ever written to
  Heimdall, leaving users in an untracked state
- Home.py: replace conda run invocation in "Score All Unscored Jobs" with
  sys.executable so the button works inside Docker where conda is not present
New cloud users got a "resume_keywords.yaml not found" warning in
Settings → Skills & Keywords because the file was never created during
account provisioning. resolve_session() now writes an empty scaffold
(skills/domains/keywords: []) to the user's config dir on first visit
if the file doesn't exist, consistent with how config/ and data/ dirs
are already created. Never overwrites an existing file.
feat: push interview events to connected calendar integrations (#19)
All checks were successful
CI / test (pull_request) Successful in 53s
c1ec1fc9f6
Implements idempotent calendar push for Apple Calendar (CalDAV) and
Google Calendar from the Interviews kanban.

- db: add calendar_event_id column (migration) + set_calendar_event_id helper
- integrations/apple_calendar: create_event / update_event via caldav + icalendar
- integrations/google_calendar: create_event / update_event via google-api-python-client;
  test() now makes a real API call instead of checking file existence
- scripts/calendar_push: orchestrates push/update, builds event title from stage +
  job title + company, attaches job URL and company brief to description,
  defaults to noon UTC / 1hr duration
- app/pages/5_Interviews: "Add to Calendar" / "Update Calendar" button shown
  when interview date is set and a calendar integration is configured
- environment.yml: pin caldav, icalendar, google-api-python-client, google-auth
- tests/test_calendar_push: 9 tests covering create, update, error handling,
  event timing, idempotency, and missing job/date guards
pyr0ball merged commit a0bdf7677f into main 2026-03-16 21:45:07 -07:00
pyr0ball deleted branch feature/calendar-push 2026-03-16 21:45:18 -07:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Circuit-Forge/peregrine#20
No description provided.