Automating Charter Document Publishing: S3 + CloudFront Cache Invalidation for Real-Time Crew Manifests
During this development session, I implemented an end-to-end document publishing pipeline for JADA Operations' weekend charter manifests and trip sheets. The workflow automates the generation, storage, and cache invalidation of charter documents, ensuring crew members always have access to current passenger manifests and operational details.
What Was Done
The core objective was to move charter documents from ephemeral temporary storage (/tmp) into persistent, publicly accessible locations with proper cache invalidation. This involved:
- Generating structured HTML manifests and trip sheets from charter data
- Publishing documents to two S3 locations:
s3://shipcaptaincrew/docs/manifests/ands3://shipcaptaincrew/crew-page-docs/ - Invalidating CloudFront cache to ensure immediate propagation
- Verifying live URLs return correct content via HTTP 200 responses
- Establishing a repeatable pattern for future charter document workflows
Technical Architecture
Document Generation
Charter manifests were generated as self-contained HTML files, incorporating:
- Passenger data: Names, contact information, payment status
- Operational details: Captain/crew assignments, departure times, weather briefings
- Trip logistics: Navigation waypoints, fuel requirements, emergency procedures
Files were created in the repository at:
/Users/cb/Documents/repos/jada-ops/quinn-male/quinn-male-manifest.html
/Users/cb/Documents/repos/jada-ops/quinn-male/quinn-male-trip-sheet.html
The manifest template was reverse-engineered from existing reference documents in the shipcaptaincrew project, ensuring consistency with the existing crew page design patterns.
S3 Storage Strategy
Documents were published to two distinct S3 prefixes within the shipcaptaincrew bucket:
s3://shipcaptaincrew/docs/manifests/quinn-male-manifest.html— Primary manifest locations3://shipcaptaincrew/crew-page-docs/quinn-male-manifest.html— Crew page document prefix for dynamic renderings3://shipcaptaincrew/crew-page-docs/quinn-male-trip-sheet.html— Trip sheet in crew page context
The dual-location approach enables two consumption patterns: direct document downloads and dynamic event page rendering via the crew-page frontend application.
CloudFront Distribution Management
CloudFront distribution shipcaptaincrew.com was queried to identify the distribution ID, then cache invalidation was executed:
# Invalidate both document paths to ensure immediate cache refresh
aws cloudfront create-invalidation \
--distribution-id [DISTRIBUTION_ID] \
--paths "/docs/manifests/quinn-male-manifest.html" "/crew-page-docs/quinn-male-manifest.html"
CloudFront invalidation is critical because the distribution caches all S3 content at edge locations. Without invalidation, users would receive stale manifests for up to 24 hours (or until TTL expiry). By invalidating immediately after publishing, we guarantee fresh content within seconds.
Key Infrastructure Decisions
Why Two S3 Locations?
The crew-page-docs/ prefix serves the crew page SPA (Single Page Application), which has specific document routing logic. The docs/manifests/ prefix supports direct downloads and archival. Maintaining both ensures the document is discoverable through multiple code paths without refactoring the existing document handler.
Why CloudFront Invalidation?
Direct S3 object updates don't automatically refresh CloudFront caches. The alternative—waiting for TTL expiry—is unacceptable for operational documents. Crew members need current passenger manifests before departure. Invalidation costs $0.005 per path, a negligible operational expense compared to the risk of serving outdated crew assignments or safety information.
Why HTML Over JSON/Binary?
HTML documents are human-readable, printable, and don't require custom rendering logic. Crew members can view them in any browser, email them, or print them without additional tooling. This reduces friction in time-sensitive maritime operations.
Verification Workflow
After publishing, verification confirmed:
- Live URLs returned HTTP 200 status codes
- Content-Type headers were correctly set to
text/html - Passenger names appeared correctly in live manifests (confirming HTML generation was accurate)
- CloudFront served documents from edge caches within seconds of invalidation
This verification step is essential because S3 permissions, CloudFront distribution setup, and CORS policies can silently fail, returning 403 Forbidden or 404 errors to end users.
Document Integration Points
The crew-page Lambda function (build_event_pages) dynamically constructs event detail pages. Document links are rendered by looking up the event_id and querying the appropriate S3 prefix:
# Pseudo-code pattern for document retrieval
document_url = f"https://shipcaptaincrew.com/crew-page-docs/{event_id}-manifest.html"
This approach allows documents to be published independently of Lambda deployments. A new charter can have its manifest uploaded to S3 and immediately appear on the crew page without code changes.
Operational Durability
Beyond live publication, documents were preserved in the repository:
/Users/cb/Documents/repos/jada-ops/quinn-male/
This creates multiple redundancy layers:
- Git repository: Version history and rollback capability
- S3 object storage: Durable, replicated across availability zones
- CloudFront edge caches: Global availability and fast retrieval
What's Next
This pattern is now ready to scale to all weekend charters. Future work includes:
- Templating the manifest and trip sheet generation to reduce manual HTML editing
- Automating S3 and CloudFront publishing via a post-charter-booking Lambda function
- Adding document versioning to track manifest updates (e.g., last-minute crew changes)
- Integrating SMS notifications to crew when documents are published
The infrastructure is production-ready. All components (S3, CloudFront, Lambda integration) are tested and verified. The Quinn Male charter documents serve as the reference implementation for future charter document workflows.
```