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.
PropertyValue
Partition keyUserID (String)
Sort keyInvoiceID (String)
Billing modeProvisioned (5 read / 5 write capacity units, autoscaling 1–10 at 70% target)
StreamEnabled — NEW_AND_OLD_IMAGES
Point-in-time recoveryDisabled
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.
PropertyValue
Partition keyUserID (String)
Billing modePay per request
StreamDisabled
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.
PropertyValue
Partition keyUserID (String)
Sort keyInvoiceID (String)
Billing modePay per request
StreamEnabled — NEW_AND_OLD_IMAGES
Point-in-time recoveryEnabled
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.
Table nameCategory
FoodDeliveryInvoicesRestaurants and food delivery orders
ClothingInvoicesClothing and fashion purchases
TechnologyInvoicesElectronics and tech products
SubscriptionInvoicesStreaming services and memberships
GroceryInvoicesSupermarket purchases
MiscellaneousUtilityInvoicesUtility bills (electricity, water, internet)
MiscellaneousInvoicesOther retail purchases
TravelInvoicesTransportation invoices (flights, trains, buses)
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.
PropertyValue
Partition keyvendor_id (String)
Billing modePay per request
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):
rental-invoices-bucket/invoices/{user_id}/rental/{filename}.pdf
Example:
invoices/user_a1b2c3d4/rental/invoice_0001.pdf
Retail invoices (HTML):
rental-invoices-bucket/invoices/{user_id}/retail/{sub_type}/{vendor}_{date}_{hash}.html
The {sub_type} path segment is one of:
sub_typeDescription
food-deliveryRestaurant and food delivery orders
clothingClothing and fashion purchases
technologyElectronics and tech products
subscriptionsStreaming services and memberships
groceryGrocery store purchases
utilityUtility bills (electricity, water, etc.)
miscellaneousOther retail purchases
travelTransportation invoices (flights, trains, buses, etc.)
{user_id} is a UUID prefixed with user_, generated at signup. S3 event notifications:
FilterTrigger
Prefix invoices/, suffix .pdfInvokes parse_invoice Lambda
Prefix invoices/, suffix .htmlInvokes parse_retail_invoice Lambda

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.