Building a Task Notification System for maintenance.queenofsandiego.com: Architecture and Implementation
Overview
When Travis added new maintenance tasks to the Queen of San Diego's maintenance tracking tool, there was no mechanism to surface these additions to the operations team. This created a critical gap: Sergio couldn't see what had changed, and no notification was being sent. This post details the architecture and implementation of a task notification system that bridges this gap, using industry best practices for alert fatigue mitigation and data-driven notification cadence.
What Was Built
We implemented a three-tier notification system:
- Persistence Layer: A new Google Apps Script file (
MaintenanceCalendar.gs) that tracks task state changes - Calendar Integration: Automatic syncing of maintenance tasks to a Google Calendar named "Jada Maintenance" for visibility and scheduling
- Smart Notifications: A handler that sends emails to
jadasailing@gmail.comwith task criticality-based notification logic - Staging/Production Separation: A staging HTML interface at
/tools/maintenance/staging-index.htmlthat routes notifications to test email addresses
Technical Architecture
Google Apps Script (GAS) Modifications
Two new files were created in the /queenofsandiego.com GAS project:
MaintenancePersistence.gs- Handles state management and task comparisonMaintenanceCalendar.gs- Manages Google Calendar synchronization
The BookingAutomation.gs doPost handler was extended to route maintenance-related requests:
// In BookingAutomation.gs doPost handler
if (action === 'log_maintenance') {
const result = MaintenancePersistence.logTask(data);
const notified = MaintenanceCalendar.syncAndNotify(result);
return ContentService.createTextOutput(JSON.stringify({
success: true,
taskId: result.id,
notified: notified
})).setMimeType(ContentService.MimeType.JSON);
}
Persistence Strategy
Rather than querying the HTML form state each time, we implemented a persistent comparison mechanism. When new tasks arrive via POST from the maintenance interface, MaintenancePersistence.gs:
- Retrieves the previous task state from Google Drive (stored as a JSON file in the JADA shared drive)
- Compares the current task payload with the persisted state
- Identifies newly added tasks by comparing task arrays
- Updates the persisted state atomically to prevent race conditions
Notification Logic: Criticality-Based Cadence
Rather than sending an email for every single task change (which would create alert fatigue), the system implements a criticality-driven approach based on research from high-performing incident management teams:
- Critical Tasks (electrical safety, structural issues, compliance): Immediate email notification
- High Priority Tasks (safety features, guest experience blockers): Sent at 6 PM daily digest
- Standard Tasks (cosmetic, maintenance backlog): Weekly digest on Fridays at 9 AM
This prevents notification burnout while ensuring urgent issues are surfaced immediately. The criticality metadata is assigned in the maintenance form itself and stored in the task object.
Infrastructure Changes
S3 and CloudFront
The maintenance tool is served from:
- S3 Bucket:
queenofsandiego.com(main bucket) - S3 Path:
/tools/maintenance/staging-index.html(staging) and/tools/maintenance/index.html(production) - CloudFront Distribution:
maintenance.queenofsandiego.comdistribution
Cache invalidation was required after deploying staging changes:
aws cloudfront create-invalidation \
--distribution-id [DIST_ID] \
--paths "/tools/maintenance/*"
Production vs. Staging Separation
The staging HTML includes a configuration flag that routes all notifications to jadasailing@gmail.com for testing. The production version will route to both Sergio and the appropriate operations email alias once determined. This is configured in the staging HTML's initialization:
const ENVIRONMENT = 'staging';
const NOTIFICATION_EMAIL = 'jadasailing@gmail.com';
const SCRIPT_DEPLOYMENT_ID = '[STAGING_DEPLOYMENT_ID]';
Google Calendar Integration
The MaintenanceCalendar.gs module creates a calendar named "Jada Maintenance" in the jadasailing@gmail.com account if it doesn't exist, and synchronizes tasks as calendar events. This provides:
- Visual timeline of when tasks need to be completed
- Integration with existing Google Calendar workflows
- Automatic reminders via Google Calendar notifications
- A shared view for Sergio and other team members
New tasks are created with a description containing task details, due dates are extracted from the form, and the event is updated whenever the task state changes.
Key Technical Decisions and Rationale
Why Google Apps Script + Google Calendar?
The existing infrastructure already uses Google Apps Script for automation and Google Workspace for team collaboration. Leveraging these tools meant:
- No additional authentication infrastructure needed
- Existing permissions structure (shared drives, team calendars) applies automatically
- Reduced operational overhead compared to Lambda/DynamoDB alternatives
- Team is already familiar with GAS debugging and deployment
Why Criticality-Based Notifications?
Research from incident response teams (PagerDuty, Opsgenie case studies) shows that alert fatigue causes teams to ignore notifications, reducing response times to actual emergencies. By tiering notifications based on urgency:
- Critical safety issues get immediate attention (minutes)
- Important tasks get visibility without interruption (same-day digest)
- Backlog items stay organized without generating noise (weekly digest)
Why Staging Before Production?
The maintenance tool didn't have a clear staging/production separation. By deploying to /tools/maintenance/staging-index.html first, we can:
- Verify the notification system works end-to-end
- Confirm email deliverability and formatting
- Test calendar synchronization without affecting operations
- Establish a pattern for future staging/production deployments
Deployment Process
The deployment involved multiple component updates:
# 1. Deploy modified staging HTML to S3
aws s3 cp tools/maintenance/staging-index.html \
s3://queenofsandiego