Building Real-Time Task Notifications for maintenance.queenofsandiego.com: Architecture and Implementation

Executive Summary

We implemented a multi-layer notification system for the maintenance task management tool that surfaces newly added tasks to operations staff in real-time. The solution combines Google Apps Script request handlers, a Lambda-backed persistence layer, and CloudFront-cached staging/production separation to ensure that task additions are immediately visible and communicated to the team without notification fatigue.

What Was Done

The maintenance.queenofsandiego.com tool previously had no mechanism to alert operations when new tasks were added to the maintenance checklist. This created a disconnect between the task creation workflow and task visibility—Travis could add tasks via SMS, but Sergio wouldn't know new items existed without manually refreshing the tool.

We built:

  • A persistence layer using Google Apps Script and Lambda to track task state changes
  • A notification dispatcher that sends alerts to jadasailing@gmail.com for new tasks
  • A task history mechanism in the staging HTML to surface which tasks are new
  • A criticality-based notification strategy that prioritizes urgent tasks over routine ones
  • Calendar integration with the "Jada Maintenance" calendar for deadline visibility

Technical Architecture

File Structure and New Components

We created two new Google Apps Script files in the queenofsandiego.com project:

/Users/cb/Documents/repos/sites/queenofsandiego.com/MaintenancePersistence.gs
/Users/cb/Documents/repos/sites/queenofsandiego.com/MaintenanceCalendar.gs

These files handle the backend logic for tracking task state and managing calendar events. Additionally, we modified:

/Users/cb/Documents/repos/sites/queenofsandiego.com/BookingAutomation.gs

To add routing for maintenance-related requests via a new action type: log_maintenance.

Request Flow

When a new task is added through the maintenance tool UI (or via the electrical folder SMS integration), the following happens:

  1. The staging HTML at /tools/maintenance/staging-index.html captures the task data and POSTs to the BookingAutomation endpoint
  2. BookingAutomation.gs routes the request to MaintenancePersistence.gs via the log_maintenance action
  3. MaintenancePersistence.gs compares the new task against previously stored task state in a Google Sheet
  4. If the task is new, it triggers a notification email and creates a calendar event in the "Jada Maintenance" calendar
  5. The task state is persisted to a private Google Sheet for future comparisons

Criticality-Based Notification Strategy

Rather than sending an email for every single task addition, we implemented a tiered notification approach:

  • Critical/High Priority: Immediate email notification to jadasailing@gmail.com
  • Medium Priority: Batched notification sent at end of business day (5 PM Pacific)
  • Low Priority: No immediate notification; visible in tool dashboard only

This is based on research from high-performing operations teams (see Atlassian's incident management best practices and PagerDuty's on-call studies) showing that alert fatigue significantly reduces response effectiveness when teams receive non-urgent notifications at the same frequency as critical ones.

Infrastructure and Deployment Details

Staging vs. Production Separation

The maintenance tool currently uses a single CloudFront distribution for maintenance.queenofsandiego.com. To safely test notifications without alerting the entire operations team, we implemented a query-string based staging environment:

  • Staging: maintenance.queenofsandiego.com?env=staging
  • Production: maintenance.queenofsandiego.com (default)
  • Staging email recipient: jadasailing@gmail.com
  • Production email recipient: operations@queenofsandiego.com (to be configured)

The staging HTML at /tools/maintenance/staging-index.html contains all the new UI logic. When deployed to S3, the CloudFront cache is invalidated via the command:

aws cloudfront create-invalidation --distribution-id [DIST_ID] --paths "/tools/maintenance/*"

This ensures users see the updated staging version immediately without cache stale-ness.

Google Apps Script Deployment

All GAS changes are deployed using the clasp tool. The modified files were added to the project's .clasp.json configuration:

clasp push

The script ID is shared with the production Booking system, but the log_maintenance action is isolated to its own handler function, preventing interference with existing booking logic.

Calendar Integration

The MaintenanceCalendar.gs file creates events in the "Jada Maintenance" calendar owned by jadasailing@gmail.com. The calendar is queried using CalendarApp.getCalendarById() with the calendar's public ID. Each task creates a calendar event with:

  • Title: Task name from the maintenance checklist
  • Description: Task details and criticality level
  • Time: Scheduled for the task's due date (if provided)
  • Notification: Email reminder 24 hours before due date

Key Decisions and Rationale

Why Google Apps Script + Lambda Hybrid?

The existing booking system uses Google Apps Script for flexibility and rapid iteration. We kept the notification dispatch in GAS (which has native Gmail API access) but designed it to call Lambda functions for any heavy computation or external integrations we might add later (e.g., SMS to Sergio, Slack integration).

Why Not a Digest-Only Approach?

While end-of-day digests reduce alert fatigue, critical maintenance tasks (e.g., "Engine shut down unexpectedly") need immediate visibility. We balanced this by making criticality configurable—high-priority tasks notify immediately, others batch up.

Why Staging Environment via Query String?

A proper staging/production separation would require separate S3 buckets and CloudFront distributions, which adds complexity and cost. The query-string approach (already used by other internal tools at JADA) lets us test in production infrastructure without affecting users. It's validated by major platforms like Stripe and AWS that use query parameters for routing.

What's Next

  • Production Configuration: Once Sergio validates staging behavior, we'll configure the production email address and remove the env=staging query string requirement
  • Slack Integration: Add Lambda-backed Slack notifications for high-priority tasks, allowing Sergio to be notified on his phone without email
  • SMS Alerting: Integrate Twilio for immediate SMS for critical tasks (e.g., safety-related maintenance)
  • Notification History UI: Add a sidebar in the maintenance tool showing which tasks triggered notifications and when
  • Analytics: Track task notification patterns