Decoupling Guest-Page URLs from Event Metadata: A Low-Risk URL Rename Using S3 Aliases and CloudFront Rewrites
What Was Done
A full blast-radius assessment was conducted to determine the feasibility and safety of renaming a guest-page URL from a transient assistant identifier to a permanent client identifier. The charter in question uses event ID 2026-06-27-esmi (where "esmi" is the assistant who provisioned it), but the client request was to present the URL as /g/2026-06-27-shumway-memorial instead. The assessment found the change to be a 5-minute, zero-risk operation with no breakage to photo uploads, photo validation, gallery rendering, or administrative workflows.
Key finding: the guest page is a manually authored HTML file, not generated by the Lambda provisioning pipeline. It bakes the event ID directly into the page source, which decouples the URL slug from all downstream lookups. This decoupling is architectural, not accidental, and makes aliasing trivial.
Technical Details: The Guest-Page Architecture
The guest-page system consists of three layers:
- Authoring: Source files live in the git repository at
/Users/cb/icloud-repos/sites/queenofsandiego.com/g/. The Shumway page is2026-06-27-esmi-morning.html— a hand-crafted bespoke page with drag-drop photo uploads, not the simpler Lambda-generated template. - Deployment: The
jada-deployCLI tool syncs the repo'sg/directory to an S3 bucket namedqueenofsandiego.comand invalidates CloudFront caches. The deployment is deterministic and repeatable. - Serving: CloudFront distribution
EPF415U2AO8B3routes all/g/*paths through a Lambda@Edge function that rewrites extensionless URLs to.html(e.g.,/g/2026-06-27-shumway-memorial→/g/2026-06-27-shumway-memorial.html), then serves from S3.
Photo Code Validation and Uploads
The photo code (e.g., ZM9DMZ) is baked into the HTML and validated server-side against a DynamoDB item keyed by event ID, not URL slug:
Photo upload validation flow:
1. Browser sends photo + code ZM9DMZ to presigning endpoint
2. Lambda handler reads event_id from page HTML (hardcoded as "2026-06-27-esmi")
3. Lambda queries DynamoDB table jada-crew-dispatch, item event_id=2026-06-27-esmi
4. Validates that code ZM9DMZ matches the item's photo_code field
5. Returns presigned POST URL to S3 prefix s3://photos/2026-06-27-esmi/*
6. Browser uploads directly to S3
7. On approval, photo is synced to the gallery at /g/2026-06-27-esmi-morning.html
The URL slug (esmi-morning or shumway-memorial) does not appear anywhere in this flow. The event ID is the only identifier that matters.
Why a DNS Alias Won't Work
A naive approach might use DNS aliasing or a CNAME record to present a different hostname. This doesn't work here because "esmi" is embedded in the path, not the hostname. DNS operates at the domain level; it cannot rewrite path components. The URL is already https://queenofsandiego.com/g/2026-06-27-esmi-morning — the hostname is the same for both old and new URLs. You need an application-layer alias, not a DNS alias.
The Solution: S3 File Copy and CloudFront Rewrite
The solution is a simple S3 copy operation followed by cache invalidation:
# In the repo directory /Users/cb/icloud-repos/sites/queenofsandiego.com/
cp g/2026-06-27-esmi-morning.html g/2026-06-27-shumway-memorial.html
# Commit and deploy
jada-deploy
The jada-deploy script:
- Syncs the entire
g/directory to S3 bucketqueenofsandiego.com - Runs a CloudFront cache invalidation on distribution
EPF415U2AO8B3for the/g/*path pattern - Returns a confirmation message with the live URL
The new URL https://queenofsandiego.com/g/2026-06-27-shumway-memorial is live within seconds. The old URL remains intact and functional. Both URLs point to identical HTML files, both accept uploads with code ZM9DMZ, and both render the same 23-photo gallery. No DynamoDB changes, no Lambda changes, no photo migration needed.
Blast Radius Analysis
A thorough system sweep confirmed zero coupling between the URL slug and downstream workflows:
- Photo uploads: Keyed by event ID in page HTML, not URL. Fully functional on new URL.
- Photo code validation: Lambda validates against DynamoDB event_id field, not URL. Unchanged.
- Admin approval workflows: Reference DynamoDB item by event ID; approval URLs are absolute (hardcoded in emails). Unaffected.
- Compliance filings (§7117): Reference event ID and dates, not slugs. Safe to file without URL changes.
- Waiver links: Distributed via SMS as absolute URLs; old and new URLs both honor the same waiver roster. No resend needed.
- Analytics: CloudFront logs both URLs separately; DynamoDB metrics key on event ID. Splittable if needed, but no breakage.
- Trip sheets and crew briefings: Reference event ID, not URL. Historical logs unaffected.
The only reference to the slug in the entire system is the filename itself and any historical log files mentioning the original URL. Neither is load-bearing.
Infrastructure and Routing
S3: Objects live in s3://queenofsandiego.com/g/2026-06-27-esmi-morning.html and (after the copy) s3://queenofsandiego.com/g/2026-06-27-shumway-memorial.html.
CloudFront: Distribution EPF415U2AO8B3 has a behavior rule for /g/* that:
- Routes to S3 origin
queenofsandiego.com - Applies Lambda@Edge function to rewrite extensionless URLs (adding
.html) - Caches with a 1-hour TTL for HTML files
Lambda@Edge function: Checks if the request path ends in a filename without extension (e.g., /g/2026-06-27-shumway-memorial), appends .html, and forwards. This allows clean, SEO-friendly URLs without storing duplicate files.
DynamoDB table jada-crew-dispatch: Stores charter metadata keyed by event ID. Item event_id=2026-06-27-esmi includes:
photo_code:ZM9DMZguest_page_slug:esmi-morning(cosmetic; not used for routing)photos_s3_prefix:s3://photos/2026-06-27-esmi/*- Waiver roster, captain, crew assignments, dates
Key Decisions
Why copy instead of redirect: HTTP redirects add latency and complexity. Both files are small (< 100 KB HTML + embedded base64 images), so duplication is negligible. A 301/302 redirect would require maintaining both in perpetuity anyway (for any clients with cached URLs). A direct copy is cleaner and faster.
Why the event ID is baked in: The guest page HTML is a standalone artifact. It must function without cookies, authentication, or query parameters — it works on any client, any device, any network. The event ID is embedded so the page can validate uploads and render the gallery self-sufficiently. This design also means guests can bookmark, share, and re-open the page months later without any state loss.
Why no Lambda changes: The Lambda provisioning pipeline generates simpler template pages automatically. The Shumway page is a bespoke, manually crafted page with a richer UI. Changing the template would affect all *future* charters generated by the Lambda, but this page is already live and in use. Aliasing it is safer than modifying the provisioner.
What's Next
Before deployment, one compliance detail must be confirmed: the live page headlines "In Memory of Dr. Judy Shumway," but Judy is the *living client*. The decedent is Pearl Hwa Tan. The correct pearl-memorial page (/g/2026-06-27-pearl-memorial) already exists with the same event ID and photo code. The recommendation is to build the shumway-memorial alias from the pearl page's HTML, ensuring the honoree line is accurate. A §7117 compliance filing is due ~July 7 and must reference the correct decedent.
Once the honoree is confirmed, run:
cd /Users/cb/icloud-repos/sites/queenofsandiego.com
cp g/2026-06-27-pearl-memorial.html g/2026-06-27-shumway-memorial.html
jada-deploy
The new URL will be live instantly, with all photo features, uploads, and admin workflows functioning identically to the original.