Skip to main content
PayPulse Cloud uses two S3 buckets, both defined in aws-infra-terraform/s3.tf.

rental-invoices-bucket

Stores all invoice files — rental PDFs and retail HTML — uploaded by ingestion Lambda functions.

wallenstam-lambda-bucket

Stores zipped Lambda source code. Uploading a new zip triggers a function update.

rental-invoices-bucket

This bucket holds every invoice file processed by PayPulse. It is configured with versioning, AES-256 server-side encryption, and full public access blocking.

Path structure

All invoices are stored under the invoices/ prefix. The path encodes the user ID, invoice type, and (for retail) the sub-category and vendor. Rental invoices (PDF)
Retail invoices (HTML)
Where {sub_type} is one of: User IDs are UUIDs prefixed with user_, generated at signup (e.g., user_a1b2c3d4-...).

wallenstam-lambda-bucket

This bucket holds the deployment artifacts for all zip-deployed Lambda functions.
A bucket policy grants lambda.amazonaws.com s3:GetObject access so Lambda can pull deployment packages:

Versioning and deployment

Each Lambda function reads its source code from an S3 object. S3 versioning is enabled so every upload creates a new object version. When a zip file is updated and terraform apply is run, Terraform detects the new S3 object version and updates the Lambda function accordingly. Functions deployed this way include: login_user, signup_user, fetch_invoices, fetch_latest_invoice, fetch_retail_invoices, get_rental_invoice, get_rental_invoices, get_user_profile, gmail_store_tokens, delete_user, and send_invoice_notification.
The parse_invoice function is deployed as a Docker image pushed to an ECR repository, not as a zip file in this bucket.

S3 event triggers

Uploads to rental-invoices-bucket trigger Lambda functions automatically via S3 event notifications:
When fetch_latest_invoice or fetch_invoices uploads a PDF to invoices/{user_id}/rental/, S3 fires the notification, which invokes parse_invoice. That function parses the PDF and writes the result to DynamoDB, which in turn triggers send_invoice_notification via the DynamoDB stream.