Building a Real-Time Maintenance Task Notification System for maintenance.queenofsandiego.com

What Was Done

We implemented a multi-layered notification system to surface newly added maintenance tasks to both the web UI and critical team members via email. The system distinguishes between routine and urgent tasks, using task criticality to determine notification frequency and delivery method. This addresses the challenge of Travis adding tasks via SMS without them being immediately visible in the maintenance tool interface.

Architecture Overview

The solution spans three primary layers:

  • Persistence Layer: New MaintenancePersistence.gs in Google Apps Script handles task state management and change detection
  • Notification Layer: Lambda function processes task changes and sends notifications based on criticality
  • UI Layer: Staging HTML at /tools/maintenance/staging-index.html now displays a task notification banner
  • Calendar Integration: New MaintenanceCalendar.gs syncs critical tasks to the "Jada Maintenance" Google Calendar

Core Infrastructure Changes

Google Apps Script Files

Two new GAS files were created in the queenofsandiego.com Apps Script project:

  • MaintenancePersistence.gs – Manages task state, detects new entries, and tracks last notification timestamps
  • MaintenanceCalendar.gs – Interfaces with Google Calendar API to create/update "Jada Maintenance" calendar events for critical tasks

The BookingAutomation.gs doPost handler was extended with two new action routes:

if (action === "log_maintenance") {
  // Route to MaintenancePersistence.logNewTask()
}

if (action === "notify_task_changes") {
  // Route to MaintenancePersistence.checkAndNotify()
}

This maintains the existing request routing pattern while adding dedicated handlers for maintenance operations.

S3 Deployment

The staging maintenance HTML was deployed to the existing S3 bucket serving maintenance.queenofsandiego.com. Key changes include:

  • Modified HTML stored at the CloudFront origin path for staging-index.html
  • New JavaScript section parses task criticality and renders notification banners
  • Banner styling differentiates between priority levels: critical (red), high (orange), routine (blue)

The CloudFront distribution was invalidated post-deployment to ensure cache refresh.

Technical Implementation Details

Task State Management

MaintenancePersistence.gs implements a simple but effective state pattern:

  • Stores task metadata in a Google Sheet tied to the Apps Script project
  • Tracks task_id, added_timestamp, criticality (1-5 scale), last_notified, and notified_count
  • On each check cycle, compares incoming tasks against stored state to identify new entries
  • Implements exponential backoff for routine tasks; immediate notification for critical tasks

The function signature for new task logging:

function logNewTask(taskData) {
  // taskData: { title, description, criticality, assignee }
  // Returns: { success: boolean, taskId: string }
}

Notification Logic

Task criticality drives notification strategy:

  • Criticality 4-5 (Critical): Immediate email to both jadasailing@gmail.com and ops team; added to calendar within 5 minutes
  • Criticality 2-3 (High): Email notification after 30 minutes; digest collection for end-of-day summary
  • Criticality 1 (Routine): Daily digest only; no individual notifications

This tiered approach prevents notification fatigue while ensuring urgent issues surface immediately.

Calendar Integration Pattern

MaintenanceCalendar.gs creates recurring calendar events in the "Jada Maintenance" calendar. Design rationale:

  • Why Google Calendar? Existing team workflow; integrates with JADA's calendar-based operations planning. This is where charter schedules live, so maintenance tasks belong in the same system of record.
  • Recurring events: Multi-day tasks use recurring patterns. For example, a paint job lasting 3 days creates a 3-day recurring event rather than three separate entries.
  • Only critical tasks: Filtering to criticality 4-5 prevents calendar spam while keeping urgent work visible during daily planning.

Testing and Staging Strategy

The challenge: maintenance.queenofsandiego.com currently lacks environment separation. Our approach:

  • Staging HTML: Deployed to a separate path in the same S3 bucket; served via CloudFront with a staging-specific origin header
  • GAS Functions: Accept an optional environment parameter (defaults to "production"). Staging requests include environment=staging
  • Email Delivery: Staging notifications go to jadasailing@gmail.com
  • Calendar Target: Staging events write to a separate "Jada Maintenance - Staging" calendar for testing without polluting the live calendar

This provides functional isolation without requiring separate infrastructure, keeping deployment complexity low.

Key Decisions and Rationale

Criticality-Based Notification Frequency

Rather than notifying on every new task, we implement intelligent batching for routine items. Industry research (citing practices from high-performing operations teams like those at incident response platforms) shows that frequent low-urgency notifications reduce effective signal-to-noise ratio and lead to alert fatigue. By reserving individual notifications for truly critical tasks and batching routine items into daily digests, we maintain team responsiveness while preserving focus.

Google Apps Script as the Persistence Layer

Why not a dedicated database? The queenofsandiego.com project already uses Google Sheets for various operational logs. Leveraging the same pattern:

  • No additional infrastructure or authentication to manage
  • Team members can view task history directly in Sheets if needed
  • Reduces operational surface area
  • Cost: zero (within existing Google Workspace quotas)

Email as Primary Notification Channel (for now)

We chose email over SMS or Slack for initial implementation because:

  • Works across all team roles without additional tooling onboarding
  • Creates an audit trail of notifications sent
  • Can be templated with rich formatting and context
  • Integrates seamlessly with the GAS ecosystem

SMS or Slack integration can be added later as a second-layer notification for critical tasks if team feedback warrants it.

Deployment Commands

# Deploy staging HTML to S3
aws s