Skip to content

Scheduler & Calendar Microservice

The Scheduler Microservice (scheduler/) delivers an embeddable, customizable appointment booking engine for cooperative consultations, energy audits, and technical inspections.


1. Directory Structure

scheduler/
├── assets/
│ └── script_v2.js # Client-side booking logic, slots & timezones
├── backend/
│ ├── api.php # Core REST API: slots check & booking execution
│ ├── api_debug.log # Debug log trace for development
│ ├── auth_callback.php # Google OAuth2 authorization code callback
│ ├── auth_start.php # Google OAuth2 handshake initiator
│ ├── config_google.php # Google API client & credentials setup
│ ├── delete_json.php # Calendar configuration purge endpoint
│ └── save_scheduler.php # Calendar settings persistence
├── cookie-banner.php # GDPR / RODO compliance banner
├── data/ # Calendar configuration files ({id}.json)
├── default.php # Default fallback booking template
├── index.php # Interactive booking application entrypoint
├── composer.json # PHP dependencies (google/apiclient, monolog)
└── .htaccess # Apache rewrite rules (if deployed on Apache)

2. Interactive Booking Flow

sequenceDiagram
    autonumber
    actor Customer as Prospect / Member
    participant UI as "Scheduler Frontend (index.php)"
    participant JS as "Client Script (script_v2.js)"
    participant API as "Scheduler API (backend/api.php)"
    participant Google as Google Calendar API
    participant Supabase as Supabase Database

    Customer->>UI: Opens https://scheduler.planovi.app/?id=default
    UI->>JS: Injects calendar configuration & branding
    JS->>Customer: Renders interactive month view with active days
    
    Customer->>JS: Selects Date (e.g., 2026-09-25)
    JS->>API: GET /backend/api.php?id=default&date=2026-09-25
    API->>Google: Query existing events to prevent double-booking
    Google-->>API: Busy periods
    API->>Supabase: Query booked appointments in Supabase
    Supabase-->>API: Confirmed platform bookings
    API-->>JS: Returns open slots: ["09:00", "09:30", "11:00", ...]
    JS->>Customer: Displays available time buttons
    
    Customer->>JS: Selects Slot "11:00" & Enters Name, Email, Notes
    Customer->>JS: Clicks "Confirm Appointment"
    JS->>API: POST /backend/api.php (name, email, time, date)
    API->>Google: Insert Event into Primary Calendar (with Google Meet link)
    API->>Supabase: Insert appointment record for cooperative CRM
    API-->>JS: Success response { "status": "confirmed", "event_id": "..." }
    JS->>Customer: Displays Confirmation Screen with ICS download & Meet link

3. Dynamic Branding & Contrast Luminance Engine

In scheduler/index.php, the booking interface dynamically adopts the tenant’s brand identity while guaranteeing WCAG contrast compliance:

// Contrast detection algorithm in index.php
function isDarkColor($hexColor) {
$clean = str_replace('#', '', $hexColor);
if (strlen($clean) !== 6) return true;
$r = hexdec(substr($clean, 0, 2));
$g = hexdec(substr($clean, 2, 2));
$b = hexdec(substr($clean, 4, 2));
$luminance = (0.2126 * $r + 0.7152 * $g + 0.0722 * $b) / 255;
return $luminance < 0.5;
}
$primary_color = $config['brand_color_primary'] ?? '#14B8A6';
$secondary_color = $config['brand_color_secondary'] ?? '#0D9488';
$bg_color = $config['brand_color_bg'] ?? '#0F172A';
  • If a cooperative selects a light brand background, foreground elements, typography, and borders automatically switch to high-contrast dark tones.
  • If a dark background is selected, sleek dark-mode glassmorphism tokens are applied.

4. Timezone & Localization Engine (script_v2.js)

Scheduling across different time zones is handled reliably in scheduler/assets/script_v2.js:

  • Automatically reads the client browser’s local timezone via Intl.DateTimeFormat().resolvedOptions().timeZone.
  • Converts host slots (default Europe/Warsaw) to the client’s local viewing time.
  • Supports bilingual interface strings (Polish pl and English en) for date pickers, day labels, and booking confirmations.

5. Google Calendar OAuth2 Synchronization

  1. An administrator clicks Connect Google Calendar in their Planovi CRM dashboard, directing to backend/auth_start.php.
  2. The user authenticates with Google and grants Calendar permissions.
  3. Google redirects to backend/auth_callback.php with an authorization code.
  4. The callback exchanges the code for a permanent refresh_token and updates scheduler/data/{id}.json.
  5. When subsequent bookings are made, backend/api.php calls getGoogleClient()->fetchAccessTokenWithRefreshToken() to create the event in real-time.