> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/azfar-imtiaz/PayPulse-Cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Lambda functions

> Complete reference for all 12 Lambda functions in PayPulse Cloud.

PayPulse Cloud uses 13 Lambda functions written in Python 3.12. They are organized into three groups: auth, users, and invoices.

## Function reference

| Function                     | Function name               | Trigger                            | Description                                                                                                                                                                                                     | Deployment          |
| ---------------------------- | --------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| Login                        | `login_user`                | API Gateway                        | Authenticates an existing user and returns a JWT access token.                                                                                                                                                  | Zip to S3           |
| Sign up                      | `signup_user`               | API Gateway                        | Registers a new user in PayPulse.                                                                                                                                                                               | Zip to S3           |
| Get user profile             | `get_user_profile`          | API Gateway                        | Returns the authenticated user's profile: name, email, creation date, and Gmail connection status.                                                                                                              | Zip to S3           |
| Store Gmail tokens           | `gmail_store_tokens`        | API Gateway                        | Persists OAuth 2.0 tokens received from the iOS app into AWS Secrets Manager for Gmail API access.                                                                                                              | Zip to S3           |
| Ingest all rental invoices   | `fetch_invoices`            | API Gateway                        | Fetches all rental invoice PDFs from the user's Gmail inbox and uploads them to S3.                                                                                                                             | Zip to S3           |
| Ingest latest rental invoice | `fetch_latest_invoice`      | EventBridge (weekday 08:30)        | Checks Gmail for the current month's rental invoice and uploads it to S3 if not already ingested.                                                                                                               | Zip to S3           |
| Ingest retail invoices       | `fetch_retail_invoices`     | API Gateway + EventBridge (weekly) | Fetches retail invoice HTML files from Gmail using VendorConfig-driven search. Supports custom date ranges.                                                                                                     | Zip to S3           |
| Parse invoice                | `parse_invoice`             | S3 (`s3:ObjectCreated` on `.pdf`)  | Downloads a newly uploaded rental invoice PDF, parses it with `HyresaviParser`, and writes the result to DynamoDB.                                                                                              | Docker image to ECR |
| Get invoices                 | `get_invoices`              | API Gateway                        | Returns rental or retail invoices for the authenticated user. Supports sub-type filtering, detail lookup by invoice ID, and invoice counts via query parameters.                                                | Zip to S3           |
| Get invoice                  | `get_rental_invoice`        | API Gateway                        | Returns full details for a single invoice by ID. Not currently used by the iOS app.                                                                                                                             | Zip to S3           |
| Delete user                  | `delete_user`               | API Gateway                        | Deletes all data for a given user from PayPulse Cloud.                                                                                                                                                          | Zip to S3           |
| Parse retail invoice         | `parse_retail_invoice`      | S3 (`s3:ObjectCreated` on `.html`) | Downloads a newly uploaded retail invoice HTML file, extracts structured data using the Gemini Flash API, and writes the result to the `RetailInvoices` base table and the corresponding category detail table. | Zip to S3           |
| Send invoice notification    | `send_invoice_notification` | DynamoDB stream (`RentalInvoices`) | Publishes an SNS notification (email + iOS push) whenever a new rental invoice record is inserted.                                                                                                              | Zip to S3           |

<Note>
  `get_rental_invoice` is deployed and reachable at `GET /v1/invoices/{type}/{invoice_id}` but is not currently called by the iOS app.
</Note>

## Lambda layers

Shared dependencies are distributed as Lambda layers so each function only packages its own logic.

### `utils-layer`

The common utilities layer contains all shared Python modules used across multiple functions:

| Module                    | Purpose                                                             |
| ------------------------- | ------------------------------------------------------------------- |
| `auth_utils.py`           | Request authentication helpers                                      |
| `dynamodb_utils.py`       | DynamoDB read/write helpers                                         |
| `jwt_utils.py`            | JWT token creation and validation                                   |
| `s3_utils.py`             | S3 download and upload helpers                                      |
| `secretsmanager_utils.py` | Secrets Manager access, including OAuth token storage and retrieval |
| `oauth_utils.py`          | OAuth 2.0 token validation and refresh logic                        |
| `gmail_api_utils.py`      | Gmail API service creation, email search, and attachment processing |
| `error_handling.py`       | Centralized error handling                                          |
| `responses.py`            | Standardized HTTP response builders                                 |
| `exceptions.py`           | Custom exception classes                                            |

To update the layer, regenerate `lambda_layers/common/utils_layer.zip` and run `terraform apply`.

### `pyjwt-layer`

Contains the [PyJWT](https://pyjwt.readthedocs.io/) package. Attached to functions that issue or validate JWT tokens.

### `bcrypt-layer`

Sourced from [Klayers](https://github.com/keithrozario/Klayers) — a community-maintained repository of pre-built Lambda layer ARNs. Attached to `signup_user` and `login_user` for password hashing.

### `google-api-layer`

Contains the Google API Python client library. Attached to functions that call the Gmail API (`fetch_invoices`, `fetch_latest_invoice`, `fetch_retail_invoices`, `gmail_store_tokens`).

### `gemini-parsers-layer`

Contains Google Gemini client libraries and per-category parser classes used by `parse_retail_invoice` for AI-assisted retail invoice parsing. Parsers are available for: food delivery, clothing, technology, subscriptions, grocery, utility, miscellaneous, and travel sub-types.

## Deployment methods

### Zip upload to S3

Most functions are packaged as ZIP archives and stored in the Lambda functions S3 bucket. Terraform reads the object version from S3 and updates the Lambda function when a new version is uploaded.

```hcl theme={null}
resource "aws_lambda_function" "fetch_latest_invoice" {
  s3_bucket         = var.lambda_bucket_id
  s3_key            = "fetch_latest_invoice.zip"
  s3_object_version = data.aws_s3_bucket_object.fetch_latest_invoice_zip.version_id
  ...
}
```

To redeploy a ZIP-based function:

1. Update the source code.
2. Rebuild the ZIP and upload it to the Lambda functions S3 bucket.
3. Run `terraform apply` — Terraform detects the new S3 object version and updates the function.

### Docker image to ECR (`parse_invoice` only)

`parse_invoice` uses a Docker image published to Amazon ECR. This is because its PDF parsing dependency (`HyresaviParser`) and its transitive requirements exceed the 250 MB unzipped Lambda limit.

```hcl theme={null}
resource "aws_lambda_function" "parse_invoice" {
  package_type = "Image"
  image_uri    = "<account_id>.dkr.ecr.<region>.amazonaws.com/wallenstam/invoice-parser:<tag>"
  timeout      = 60
  ...
}
```

To redeploy `parse_invoice`:

1. Build a new Docker image from `lambdas/invoices/parse_invoice/Dockerfile`.
2. Tag and push to ECR.
3. Update `image_uri` in `lambda_parse_invoice.tf` with the new tag.
4. Run `terraform apply`.

<Warning>
  The ECR image tag in `lambda_parse_invoice.tf` must be updated manually on every build. Forgetting this step means Terraform will not re-deploy the function.
</Warning>
