Building Real-Time Maintenance Task Notifications: Architecture for Distributed Team Awareness
The Problem
The maintenance.queenofsandiego.com tool was functioning as a read-only interface for viewing maintenance tasks, but lacked any mechanism to surface newly added tasks to the operations team. When Travis added tasks via the maintenance interface, there was no way for Sergio or other team members to discover them short of manually checking the tool repeatedly. This is a classic operational awareness gap that compounds with distributed teams.
The challenge had three dimensions:
- Task discovery: New tasks added to the system had no notification pathway
- Team notification: No consistent way to alert Sergio and other ops personnel
- Staging/production separation: The maintenance tool hadn't yet implemented environment isolation
Architecture Overview
Rather than implement a notification system naively (sending an email for every single task), we designed a tiered approach based on task criticality and notification cadence. This follows operational best practices from high-performing teams: alert fatigue reduction through intelligent batching, but immediate escalation for critical items.
The architecture consists of four integrated components:
- Persistence Layer (AWS Lambda): Stores task metadata and handles deduplication
- GAS Notification Handler: Routes notifications based on task criticality and time windows
- Calendar Integration: Creates Jada Maintenance calendar entries for persistent visibility
- Email Delivery: Environment-aware notification dispatch to staging/production recipients
Implementation Details
Persistence Layer: MaintenancePersistence.gs and Lambda
We created a new Google Apps Script file at /Users/cb/Documents/repos/sites/queenofsandiego.com/MaintenancePersistence.gs that handles task storage and state management. This connects to a Lambda function that maintains a DynamoDB-backed database of task records.
The persistence layer tracks:
- Task ID and creation timestamp
- Task criticality level (high/medium/low)
- Notification sent status and timestamp
- Task content hash (for deduplication)
Lambda deployment pattern mirrors existing infrastructure (the tips-box Lambda function). The function signature accepts a structured task object from GAS:
POST /maintenance/task
Content-Type: application/json
{
"task_id": "unique-uuid",
"title": "Check electrical breaker C12",
"criticality": "high",
"added_by": "travis",
"created_at": "2026-05-12T14:23:00Z",
"description": "..."
}
The Lambda function returns task metadata needed for notification decisions, including whether this exact task was already notified within the current time window.
GAS Notification Handler: BookingAutomation.gs Routes
We extended BookingAutomation.gs to include a new log_maintenance action handler. When the staging HTML frontend detects a new task, it POSTs to the GAS doPost handler:
case 'log_maintenance':
const persistResult = MaintenancePersistence.recordTask(
actionData.task
);
if (persistResult.shouldNotify) {
NotificationHandler.dispatchMaintenanceAlert(
persistResult.task,
persistResult.criticality
);
}
return ContentService
.createTextOutput(JSON.stringify({status: 'logged'}))
.setMimeType(ContentService.MimeType.JSON);
The NotificationHandler implements tiered notification logic:
- High criticality: Immediate email notification to ops team
- Medium criticality: Added to digest queue for 2-hour batching
- Low criticality: Added to end-of-day digest (sent at 18:00 UTC)
Calendar Integration: MaintenanceCalendar.gs
We created MaintenanceCalendar.gs to provide persistent visibility of maintenance tasks within Google Calendar infrastructure. Each task creates a calendar event in the "Jada Maintenance" calendar associated with jadasailing@gmail.com.
Calendar events include:
- Task title and description
- Criticality as color-coded event type
- Linked resource showing the task in the maintenance tool
- Optional attendees (Sergio and other ops personnel)
This serves two purposes: it provides an alternative surface where team members can discover tasks (many operations teams check calendars daily), and it creates an immutable audit trail of when tasks were added.
Staging vs. Production Environment Separation
The maintenance tool hadn't previously implemented environment separation. We introduced it through several mechanisms:
HTML-Level Configuration: The staging HTML at /tools/maintenance/staging-index.html includes an init-time configuration variable:
const ENVIRONMENT = 'staging';
const NOTIFICATION_EMAIL = 'jadasailing@gmail.com';
const CALENDAR_ID = 'staging-jada-maintenance@group.calendar.google.com';
GAS Handler Logic: The NotificationHandler checks environment before sending emails:
const env = PropertiesService.getScriptProperties()
.getProperty('ENVIRONMENT') || 'production';
const recipientEmail = (env === 'staging')
? 'jadasailing@gmail.com'
: 'sergio@queenofsandiego.com';
CloudFront Distribution Separation: The staging maintenance tool deploys to a distinct CloudFront distribution (separate from the live maintenance.queenofsandiego.com domain). This ensures testing doesn't affect production visibility.
Infrastructure Deployment Details
S3 Buckets:
- Live maintenance assets:
queenofsandiego.com-maintenance - Staging maintenance assets:
queenofsandiego.com-staging(maintenance subdirectory)
CloudFront Invalidations: After deploying staging HTML, we invalidate the cache path /tools/maintenance/staging-index.html to ensure browsers fetch the latest version.
Command example (no actual distribution ID shown for security):
aws cloudfront create-invalidation \
--distribution-id STAGING_DIST_ID \
--paths "/tools/maintenance/*"
GAS Deployment: The Google Apps Script project tracks files via clasp. We added MaintenancePersistence.gs to the tracked manifest by pushing with the --force flag when clasp initially didn't detect the new file:
clasp pull # Sync remote state
clasp push --force # Force detection and upload
Data-Driven Notification Cadence Decision
The tiered notification approach is grounded in operational research from teams like PagerDuty and OpsGenie. Key findings:
- Immediate alerts for high-criticality issues reduce mean-