Modules

Planning and Appointments

Edit page
Add provider availability, appointment booking, calendars, meetings, and retryable synchronization to service products.

The planning layer, published as @nuxt-customer-portal/planning, extends service products with availability, reservation holds, appointment checkout, customer management, calendar invitations, meeting links, and durable synchronization jobs. It requires products; paid booking and refund invoicing also use invoice-products and invoices.

Provider setup

Organization owners and administrators configure Planning from the Appointments area:

  1. Enable eligible team members and assign them to services.
  2. Set organization booking, change, cancellation, and refund policies.
  3. Let each provider select a timezone, availability, conflict calendars, and a writable calendar.
  4. Connect Google Calendar and Zoom when live products require those providers.

Google and Zoom use dedicated OAuth applications and encrypted tokens. Configure PLANNING_ENCRYPTION_KEY, provider client IDs and secrets, public callback URLs, and scheduled Nitro tasks before enabling live booking. Sandbox bookings can use internal availability without external connections.

Booking lifecycle

Customers choose a timezone, provider or any available provider, and a slot. Planning places a time-limited hold before checkout and confirms the appointment only after the order succeeds. Availability is checked again before confirmation. Late payments cannot reclaim an expired slot and enter the retryable refund flow.

Confirmed appointments preserve their original time, timezone, duration, policy snapshot, calendar UID, and audit history. Customer changes use replacement checkout and leave the existing appointment confirmed until the replacement succeeds. Cancellation releases occupancy immediately and schedules calendar, meeting, email, and eligible refund work.

Synchronization and recovery

Google Calendar mirrors, Zoom meetings, purchase confirmations, invoice emails, later meeting-link emails, changes, cancellations, and refunds use durable jobs with stable identifiers. External API failure does not discard the purchase confirmation: the configured next-steps text tells the customer when a meeting link will follow.

Administrators can inspect appointment details and retry failed work under /admin/planning?tab=synchronization. Reconciliation avoids duplicate provider requests when the desired calendar event or meeting is already present.

Composition

portal.config.ts
layers: [
  '@nuxt-customer-portal/preset',
  '@nuxt-customer-portal/invoices',
  '@nuxt-customer-portal/products',
  '@nuxt-customer-portal/planning',
  '@nuxt-customer-portal/invoice-products'
]

Run migrations after adding the layer. PostgreSQL must permit the btree_gist extension used to prevent overlapping provider reservations.