Files
esdp/serverless/README.md
2026-01-13 17:35:25 -08:00

172 lines
4.3 KiB
Markdown

# Serverless TypeScript Project
This folder contains AWS Lambda functions deployed via the Serverless Framework, written in TypeScript.
## Setup
This project is configured with TypeScript, ESLint, and Prettier independently from the main project.
### Prerequisites
- Node.js 22.x or higher
- npm or yarn
### Installation
```bash
npm install
```
## Development
### Available Scripts
- `npm run build` - Compile TypeScript to JavaScript
- `npm run type-check` - Run TypeScript type checking without emitting files
- `npm run lint` - Run ESLint on TypeScript files
- `npm run lint:fix` - Run ESLint with auto-fix
- `npm run format` - Format code with Prettier
- `npm run format:check` - Check if code is formatted correctly
### Project Structure
```
src/
handlers/ # Lambda function handlers
vehicleType.ts # Vehicle type lookup handler
scrub.ts # Estimate scrubbing handler
emsupload.ts # File upload presigned URL handler
lib/ # Shared library code
vehicleTypes/ # Vehicle type utilities
db.ts # Database utilities
```
## Deployment
The project uses `serverless-esbuild` for bundling TypeScript code for deployment.
```bash
# Deploy to dev stage
sls deploy --stage dev
# Deploy to production
sls deploy --stage prod
```
## RDS + Drizzle (Postgres)
This project provisions a **private** Postgres RDS instance and the networking needed for Lambdas to reach it.
### What gets created
Defined in `serverless.yml`:
- A dedicated VPC with 2 public subnets + 2 private subnets
- A NAT Gateway for private-subnet egress
- Security groups:
- Lambda SG (egress all)
- RDS SG (allows inbound `5432` only from the Lambda SG)
- An RDS Postgres instance:
- `DeletionProtection: true`
- `DeletionPolicy: Snapshot` / `UpdateReplacePolicy: Snapshot`
- `AutoMinorVersionUpgrade: true` (minor updates)
- Not publicly accessible
- An RDS Proxy in the same VPC (Lambdas connect to the proxy, proxy connects to RDS)
- A Secrets Manager secret for the RDS master user (generated password)
Note: RDS + NAT Gateway incur AWS costs.
### Drizzle files
- Schema: `src/db/schema/**/*.ts`
- Drizzle config: `drizzle.config.ts`
- Generated migrations (SQL): `drizzle/` (packaged for Lambda)
### Install deps
```bash
cd serverless
npm install
```
### Generate a migration (no DB connection required)
Drizzle can generate SQL migrations by diffing your schema files.
```bash
cd serverless
npm run db:generate
```
This writes SQL into `serverless/drizzle/`.
### Deploy the database
```bash
cd serverless
sls deploy --stage dev
```
RDS creation can take several minutes.
### Apply migrations (recommended: run inside AWS)
Because the RDS instance is in private subnets, it is not directly reachable from your laptop by default.
The repo includes an internal migration Lambda (`dbMigrate`) that runs in the same VPC as the database.
```bash
cd serverless
sls invoke -f dbMigrate --stage dev
```
### Sanity check connectivity
```bash
cd serverless
sls invoke -f dbPing --stage dev
```
### Local migrations (optional)
If you set up network access to the private RDS instance (e.g., via Client VPN or an SSM tunnel through a bastion host), you can run Drizzle migrations locally:
```bash
export DATABASE_URL='postgres://USER:PASSWORD@HOST:5432/esdp'
npm run db:migrate
```
### Deletion protection behavior
- `sls remove` will **not** be able to delete the DB instance while deletion protection is enabled.
- To intentionally remove it later, you must first disable deletion protection in `serverless.yml` and redeploy, then remove the stack.
### Stage-specific DB name
The Postgres database name comes from the stage param `db_name` in `serverless.yml` (e.g. `esdpdev`, `esdpalpha`, `esdpbeta`, `esdpprod`).
## Local Development
```bash
# Run serverless offline
sls dev
```
## Configuration
- **TypeScript**: Configured in `tsconfig.json`
- **ESLint**: Configured in `eslint.config.mjs` (ESM flat config)
- **Prettier**: Configured in `.prettierrc.json`
- **Serverless**: Configured in `serverless.yml`
## Code Quality
This project enforces:
- TypeScript strict mode
- ESLint rules for TypeScript
- Prettier formatting
- No unused variables or parameters (except those prefixed with `_`)
## Environment Variables
See `serverless.yml` for environment-specific configuration.