Building a Referral Tracking System for the JADA Vendor Program: Lambda, DynamoDB, and CloudFront Integration
What Was Done
We deployed a complete referral tracking infrastructure for the Queen of San Diego vendor partnership program, enabling real-time click attribution and automated vendor outreach workflows. The system tracks when guests click vendor-specific referral links, logs the events to DynamoDB, and redirects users with UTM parameters for GA4 integration.
The deployment included:
- A new
GET /ref/{code}endpoint in the SCC Lambda function - CloudFront distribution behavior configuration for the
/ref/*path - DynamoDB referral click tracking with vendor attribution
- HTML preview pages and dashboard approval cards for vendor email campaigns
- Lambda code updates to handle public (unauthenticated) referral requests
Technical Architecture
Routing & CloudFront Configuration
The referral endpoint lives behind CloudFront distribution d2f5m3x4kp8qw1.cloudfront.net, which serves the domain shipcaptaincrew.queenofsandiego.com. Initially, referral requests were failing because the /ref/* path was being routed to the S3 origin instead of the Lambda origin.
We added a new CloudFront behavior with the following configuration:
- Path Pattern:
/ref/* - Origin: SCC API Gateway (not S3)
- Allowed Methods: GET, HEAD, OPTIONS
- Caching: 0 seconds (to prevent stale redirects)
- Compress: Disabled (unnecessary for redirects)
The distribution was deployed via AWS CloudFront API with a cache invalidation on /ref/* to ensure the new behavior took effect immediately.
Lambda Handler Implementation
The SCC Lambda function (/tmp/scc-deployed/lambda_function.py) was modified to handle referral requests before the authorization gate. This is critical: the referral endpoint must be public, as it's shared with external vendors who have no AWS credentials.
The relevant handler section checks the request path early in the execution flow:
if event.get('rawPath', '').startswith('/ref/'):
return handle_referral_click(event)
The handle_referral_click() function:
- Extracts the vendor code from the path (e.g.,
boardbrewfrom/ref/boardbrew) - Logs the click to DynamoDB with a timestamp and running count
- Constructs a redirect URL to
queenofsandiego.comwith UTM parameters - Returns a 302 HTTP redirect response
Example redirect: https://queenofsandiego.com/?utm_source=vendor_referral&utm_medium=referral&utm_campaign=boardbrew
DynamoDB Tracking Table
Referral clicks are persisted in a DynamoDB table with the following schema:
- Partition Key:
vendor_code(e.g., "boardbrew", "solare", "smallgoods") - Sort Key:
timestamp(ISO 8601 format) - Attributes:
click_count— Running total of clicks from this vendoruser_agent— Browser/device informationip_address— Anonymized request source
We queried the table via AWS CLI to validate that clicks were being recorded correctly:
aws dynamodb query \
--table-name referral-clicks \
--key-condition-expression "vendor_code = :code" \
--expression-attribute-values '{":code":{"S":"boardbrew"}}' \
--region us-west-2
Vendor Referral Links
Seven vendor partners are now active in the referral program:
- Solare:
https://shipcaptaincrew.queenofsandiego.com/ref/solare - Smallgoods:
https://shipcaptaincrew.queenofsandiego.com/ref/smallgoods - Puesto:
https://shipcaptaincrew.queenofsandiego.com/ref/puesto - Board & Brew:
https://shipcaptaincrew.queenofsandiego.com/ref/boardbrew - Whole Foods:
https://shipcaptaincrew.queenofsandiego.com/ref/wholefoods - Total Wine:
https://shipcaptaincrew.queenofsandiego.com/ref/totalwine - Gianni Buonomo Vintners:
https://shipcaptaincrew.queenofsandiego.com/ref/gbvintners
Key Decisions & Rationale
Why Public (Unauthenticated) Endpoint?
The referral endpoint had to bypass the Lambda's authorization gate because vendor partners (who are not system users) need to share working links. The authorization layer checks for valid API tokens, which external parties don't possess. By routing the /ref/* path before the auth check, we maintain security for authenticated endpoints while enabling public sharing.
CloudFront Behavior Ordering
CloudFront evaluates path patterns in order from most-specific to least-specific. We ensured the /ref/* behavior was defined before the default S3 behavior to guarantee correct routing. Existing API routes (e.g., /dashboard, /tasks) are defined with higher specificity and remain routed to the API Gateway origin.
Zero-Cache Redirect Strategy
Referral redirects have a TTL of 0 seconds in CloudFront. If we cached them, an updated redirect rule or vendor code change would require a cache invalidation. By disabling caching, every click hits the Lambda immediately, ensuring click counts are accurate and real-time.
Deployment Commands & Validation
The Lambda function was redeployed via AWS Lambda API:
aws lambda update-function-code \
--function-name shipcaptaincrew \
--zip-file fileb://lambda_function.zip \
--region us-west-2
CloudFront distribution was updated via the AWS CLI:
aws cloudfront create-invalidation \
--distribution-id d2f5m3x4kp8qw1 \
--paths "/ref/*" \
--region