Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Feature: CE-21 Calendar & Scheduling Integration

Overview

Calendar integration allows staff to connect Google or Microsoft calendars for two-way event sync and meeting scheduling from within CE.

Configuration

Module Settings

Three organization-level settings control calendar behavior (CE Settings):
SettingDefaultRangeDescription
Default meeting duration30 min15–480 minPre-filled duration for new meetings
Sync poll interval15 min5–60 minHow often the system checks for new events
Pre-meeting notification15 min5–1440 minMinutes before meeting to send reminder

Permissions

Assign these permissions via the Roles & Permissions settings:
PermissionPurpose
ce.calendar.connectAllow users to connect/disconnect calendar accounts
ce.calendar.scheduleAllow users to schedule meetings from CE
ce.calendar.viewAllow users to view their own synced events
ce.calendar.view-allAllow users to view all organization calendar events

OAuth Provider Setup

Calendar OAuth requires provider credentials configured as Supabase secrets:
  • Google: GOOGLE_CALENDAR_CLIENT_ID, GOOGLE_CALENDAR_CLIENT_SECRET
  • Microsoft: MICROSOFT_CALENDAR_CLIENT_ID, MICROSOFT_CALENDAR_CLIENT_SECRET

Sync Architecture

  • Events sync bi-directionally between external calendars and ce_calendar_events
  • Outbound meetings (scheduled from CE) create activities linked via activity_id
  • Inbound events are stored with sync_direction = 'inbound'
  • Token encryption uses Supabase Vault for access_token_encrypted and refresh_token_encrypted

Security

  • All calendar data is tenant-isolated via organization_id RLS
  • Tokens are encrypted at rest
  • Connection ownership enforced by ce_user_owns_calendar_connection() SECURITY DEFINER function
  • Cross-user visibility requires ce.calendar.view-all permission

BYO Google OAuth (PF-104)

By default, calendar OAuth uses the Encore-managed Google client (GOOGLE_CALENDAR_CLIENT_ID / GOOGLE_CALENDAR_CLIENT_SECRET configured at the platform level). Tenants who require their own Google client (for branding on the consent screen, internal-only OAuth scopes, or workspace admin policies) can register a per-organization Google Workspace connection.

Setup steps

  1. In Google Cloud Console, create an OAuth 2.0 Client ID of type Web application.
  2. Add the Encore callback URL to Authorized redirect URIs: https://<your-encore-domain>/functions/v1/calendar-oauth-callback.
  3. In Encore, navigate to CE → Settings → Calendar Connections.
  4. In the Google credentials banner, click Configure organization credentials to open the Google Workspace integration settings.
  5. Paste the oauth_client_id and oauth_client_secret from Google Cloud Console. They are stored in the PF-76 Credential Vault (encrypted at rest, never returned to the browser after save).
  6. New calendar connections from this organization will automatically use the BYO client and be linked via gws_connection_id. Existing connections continue to use whichever client was active at connect time.

Status indicator

The Calendar Connections page shows which client is active per connection:
  • Your organization — connection used the BYO Google Workspace client.
  • Encore platform default — connection used the platform-managed client.

Vault token migration (PF-101 WS4)

Calendar connections created before PF-101 stored access and refresh tokens as plaintext in ce_calendar_connections.access_token_encrypted and refresh_token_encrypted. Those rows are flagged with migration_required = true.

Running the backfill

Org admins (org_admin or platform_admin) will see a Vault migration available banner on the Calendar Connections page when at least one legacy row exists. Click Run vault migration to execute the backfill:
  • The UI calls the calendar-token-backfill edge function in batches of 25 connections until none remain.
  • For each row, the function moves any present plaintext token into the PF-76 Credential Vault, links it via access_token_credential_id / refresh_token_credential_id, clears the legacy column, and sets migration_required = false + migrated_at = now().
  • The migration is idempotent and safe to re-run.

Verification

After migration:
SELECT count(*) FILTER (WHERE migration_required) AS pending,
       count(*) FILTER (WHERE NOT migration_required) AS migrated
FROM   ce_calendar_connections
WHERE  organization_id = '<org-id>';
pending should be 0. Edge functions (calendar-freebusy, calendar-schedule, calendar-sync) automatically resolve tokens vault-first via getFreshCalendarAccessToken() and fall back to legacy columns only for rows the backfill has not yet processed, so service continuity is preserved during the transition.

Logs & observability

  • Edge Function logs include a correlationId per backfill batch and per token refresh; no token material or attendee email is ever logged.
  • Token refresh failures are logged with error_code (e.g. invalid_grant) so admins can prompt the user to reconnect.