Production runs on AWS Lambda + API Gateway, deployed via Serverless Framework 3 with esbuild bundling toDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/vruizz22/innova-backend-serverless/llms.txt
Use this file to discover all available pages before exploring further.
nodejs20.x. The custom domain api.superprofes.app is mapped to the API Gateway regional endpoint via serverless-domain-manager. The service lives in the us-east-1 region and is the infrastructure authority for all SQS queues and S3 buckets in the platform — any dependent service (innova-ai-engine, client apps) must be deployed after this backend.
Deployment Mechanism
Serverless Framework readsserverless.yml and deploys one CloudFormation stack containing six Lambda functions, all SQS queues, all S3 buckets, and the custom domain mapping. esbuild bundles each handler independently, tree-shaking unused modules and preserving NestJS decorator metadata via a custom plugin (esbuild-decorators.cjs).
The six Lambda functions deployed:
| Function | Handler | Trigger | Purpose |
|---|---|---|---|
api | src/lambda.handler | API Gateway (ANY) | Main NestJS HTTP application |
telemetryWorker | src/infrastructure/workers/telemetry-persister.handler | SQS FIFO (batch 10) | Persists attempt events to MongoDB |
llmClassifierWorker | src/infrastructure/workers/llm-classifier.handler | SQS Standard (batch 20) | Routes unclassified errors to Claude |
ocrWorker | src/infrastructure/workers/ocr-worker.handler | S3 ObjectCreated | Transcribes student photo uploads via Gemini |
alertGenerator | src/infrastructure/workers/alert-generator.handler | EventBridge rate(1 hour) | Generates teacher alerts on a schedule |
attemptReprocessWorker | src/infrastructure/workers/attempt-reprocess.handler | SQS Standard (batch 10) | Creates Attempt records from graded submissions |
innova-ai-engine consumes. The required deploy order when provisioning a new environment is: backend → ai-engine → clients.
Manual Deploy
Use this procedure for a one-off manual deploy or when bootstrapping a new stage. CI/CD (below) performs exactly these same steps automatically on every merge tomain.
Build the project
Compile TypeScript via NestJS CLI. This validates types and produces the
dist/ output that esbuild ingests.Run pending database migrations
Apply any unapplied Prisma migrations to the production Postgres database. This step is safe to run repeatedly — Prisma tracks applied migrations in the
_prisma_migrations table.Deploy to AWS via Serverless Framework
Package, upload, and deploy all Lambda functions plus CloudFormation resources. The
--stage flag controls the resource name suffix and the NODE_ENV value injected into every function.CI/CD
Three GitHub Actions workflows automate the quality gate and deployment pipeline:| Workflow | Trigger | Action |
|---|---|---|
ci.yml | Pull request opened or updated | Runs TypeScript type-check, ESLint, unit tests, and coverage gate (≥ 75%) |
deploy.yml | Push to main (after CI passes) | Runs pnpm build → prisma migrate deploy → serverless deploy --stage prod |
seed-prod.yml | Manual workflow dispatch only | Seeds demo auth users in production via Supabase Admin REST API |
deploy.yml and seed-prod.yml are stored as GitHub Actions repository secrets and injected as environment variables at runtime. No secrets are baked into the repository.
Production Configuration Notes
These settings are easy to misconfigure and each one has a significant operational impact:-
DATABASE_URLmust use the Supabase transaction pooler. The backend uses Prisma with the@prisma/adapter-pgserverless adapter. In Lambda, each cold start opens a new TCP connection. Without the transaction pooler (:6543) and the?pgbouncer=true&connection_limit=1flags, Postgres will hit its connection limit under modest load. See the Environment Variables reference for the exact URL format. -
CORS_ORIGINSmust list browser origins only. The CORS policy applies to requests made from a browser. Theinnova-ai-engineservice runs as Lambda functions — they call this API server-to-server and never send a preflight request. Do not addai.superprofes.apptoCORS_ORIGINS. -
All secrets live in GitHub Actions repository secrets. The following secrets must be configured before
deploy.ymlcan run:SUPABASE_URL,SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY,DATABASE_URL,MONGODB_URI,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION,ANTHROPIC_API_KEY,GEMINI_API_KEY,RESEND_API_KEY,RESEND_FROM_EMAIL,PUBLIC_API_URL,PUBLIC_APP_URL,SEED_DEMO_PASSWORD. -
AWS account and region. All resources are deployed to region
us-east-1. The AWS IAM user used by CI must have permissions to manage CloudFormation, Lambda, SQS, S3, and API Gateway in that region.
Release Flow
The project follows a Gitflow-style branching model. The release process after a sprint is complete:- Open a release PR from
develop→mainand get it reviewed - Merge the PR —
deploy.ymltriggers automatically and deploys to production - Verify the deployment with
curl https://api.superprofes.app/health - Back-merge
main→developto keep the branches in sync - Create a GitHub release and tag on
maindocumenting the changes (see../docs/DEPLOY_RUNBOOK.md§5–6)
Environment Stages
Theserverless.yml accepts a --stage parameter that controls the names of every resource created. This makes it possible to maintain completely isolated dev and prod environments within the same AWS account.
| Resource | dev name | prod name |
|---|---|---|
| SQS attempt-stream | innova-backend-serverless-dev-attempt-stream.fifo | innova-backend-serverless-prod-attempt-stream.fifo |
| S3 guides bucket | innova-backend-serverless-dev-guides | innova-backend-serverless-prod-guides |
| S3 submissions bucket | innova-submissions-dev | innova-submissions-prod |
Outputs section of serverless.yml) export queue ARNs prefixed with the stage name so that innova-ai-engine can import them regardless of which stage is being deployed:
| Export name | Value |
|---|---|
innova-{stage}-LlmClassifyQueueArn | ARN of the LLM classification queue |
innova-{stage}-GuideIngestQueueArn | ARN of the guide-ingest queue |
innova-{stage}-SolutionGenQueueArn | ARN of the solution-generation queue |
innova-{stage}-SubmissionGradeQueueArn | ARN of the submission-grading queue |
innova-{stage}-AttemptReprocessQueueArn | ARN of the attempt-reprocess queue |
innova-{stage}-ExerciseGenerateQueueArn | ARN of the exercise-generation queue |