Skip to main content
PayPulse Cloud uses two storage technologies: DynamoDB for structured invoice and user data, and S3 for raw invoice files and Lambda deployment artifacts.

DynamoDB tables

There are 11 DynamoDB tables in total. All tables have server-side encryption enabled.

RentalInvoices

Stores parsed rental invoice data. This is the primary table for rental invoice records. GSI: due_date_year-due_date_month-index
  • Hash key: due_date_year (String)
  • Range key: due_date_month (String)
  • Projection: ALL
The DynamoDB stream on RentalInvoices is what triggers send_invoice_notification on every new INSERT. See Event flow for the full pipeline.

Users

Stores user account information including a last_retail_invoice_fetch timestamp used for incremental retail invoice ingestion. GSI: Email-index
  • Hash key: Email (String)
  • Projection: ALL

RetailInvoices (base table)

The base table for all retail invoice records, regardless of category. Detail tables (below) store category-specific fields keyed by InvoiceID. GSI-1: invoice_date-index
  • Hash key: UserID (String)
  • Range key: invoice_date (String)
  • Projection: ALL
  • Use: date-range queries for a single user
GSI-2: sub_type-invoice_date-index
  • Hash key: UserID_SubType (String, composite of UserID + _ + sub_type, e.g. user_abc123_food-delivery)
  • Range key: invoice_date (String)
  • Projection: ALL
  • Use: category + date queries (e.g., “all grocery invoices in March”)
Common fields include: vendor_name, sub_type, total_amount, currency, invoice_date, s3_path.

Retail invoice detail tables

Each retail category has its own detail table. All eight share the same schema. All detail tables use:
  • Partition key: InvoiceID (String)
  • Billing mode: Pay per request
  • Server-side encryption: Enabled

VendorConfig

Drives automated retail invoice fetching. Adding a row here is all that is needed to start fetching invoices from a new vendor — no code changes required. Common fields include: vendor_name, invoice_sub_type, email_patterns, subject_keywords, parser_type, active (boolean).

S3 buckets

rental-invoices-bucket

Stores all invoice files fetched from Gmail. Versioning is enabled and all public access is blocked. Encryption uses AES-256 (SSE-S3). Rental invoices (PDF):
Example:
Retail invoices (HTML):
The {sub_type} path segment is one of: {user_id} is a UUID prefixed with user_, generated at signup. S3 event notifications:

Lambda functions bucket

Contains the deployment ZIP archives for all ZIP-based Lambda functions. Versioning is enabled. Lambda has s3:GetObject permission via a bucket policy. Functions deployed from this bucket:
  • fetch_invoices
  • fetch_latest_invoice
  • fetch_retail_invoices
  • send_invoice_notification
  • get_rental_invoice
  • get_rental_invoices
  • delete_user
  • get_user_profile
  • login_user
  • signup_user
  • gmail_store_tokens
When you upload a new ZIP version, Terraform detects the updated S3 object version and re-deploys the function automatically on the next terraform apply.