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:
- The staging HTML at
/tools/maintenance/staging-index.htmlcaptures the task data and POSTs to the BookingAutomation endpoint - BookingAutomation.gs routes the request to MaintenancePersistence.gs via the
log_maintenanceaction - MaintenancePersistence.gs compares the new task against previously stored task state in a Google Sheet
- If the task is new, it triggers a notification email and creates a calendar event in the "Jada Maintenance" calendar
- 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=stagingquery 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