Innova Backend Serverless owns and provisions eight SQS queues (plus six DLQs) via CloudFormation resources inDocumentation 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.
serverless.yml. This backend stack is the source of truth for all queue infrastructure — the innova-ai-engine service consumes several of these queues but never creates them. Queue URLs are injected into every Lambda function’s environment at deploy time via Ref and Fn::GetAtt CloudFormation intrinsics, ensuring zero hard-coded ARNs or URLs in code.
Queue Overview
| Queue (logical name) | CloudFormation resource | Type | Visibility Timeout | Retention | DLQ | Consumer |
|---|---|---|---|---|---|---|
AttemptStreamQueue | attempt-stream.fifo | FIFO | 60 s | 24 h | — | telemetryWorker Lambda |
LlmClassifyQueue | llm-classify-queue | Standard | 360 s | 24 h | LlmClassifyDLQ (14 d, max 3) | llmClassifierWorker Lambda |
OcrQueue | ocr-queue | Standard | 60 s | 24 h | — | OCR adapter |
AttemptReprocessQueue | attempt-reprocess-queue | Standard | 60 s | 24 h | AttemptReprocessDLQ (14 d, max 5) | attemptReprocessWorker Lambda |
GuideIngestQueue | guide-ingest-queue | Standard | 900 s | 24 h | GuideIngestDLQ (14 d, max 3) | innova-ai-engine |
SolutionGenQueue | solution-generation-queue | Standard | 900 s | 24 h | SolutionGenDLQ (14 d, max 3) | innova-ai-engine |
SubmissionGradeQueue | submission-grade-queue | Standard | 180 s | 24 h | SubmissionGradeDLQ (14 d, max 3) | innova-ai-engine |
ExerciseGenerateQueue | exercise-generate-queue | Standard | 360 s | 24 h | ExerciseGenerateDLQ (14 d, max 3) | innova-ai-engine |
All queue names follow the pattern
innova-backend-serverless-{stage}-{queue-suffix}, e.g. innova-backend-serverless-prod-llm-classify-queue. The {stage} comes from --stage at deploy time (default dev).FIFO vs Standard
AttemptStreamQueue is the only FIFO queue. It uses FIFO semantics for two reasons:
- Ordering: Keystroke telemetry events for a given attempt must be processed in the order they were produced. FIFO queues guarantee exactly-once, in-order delivery per message group.
- Deduplication:
ContentBasedDeduplication: truemeans SQS hashes the message body and silently drops duplicates within the 5-minute deduplication window, preventing double-writes to MongoDB if the publisher retries.
- The processing logic for each queue is idempotent (upserts, deduplication by
attempt_idorupload_id), so at-least-once delivery is safe. - Standard queues offer substantially higher throughput and lower latency than FIFO queues — important for classification and guide pipelines that can burst significantly.
- The
LlmClassifyQueueuses a 60-secondmaximumBatchingWindowon its Lambda trigger, which benefits from Standard queue’s ability to accumulate messages quickly.
Message Schemas
Each queue has a typed message contract. All bodies contain only UUIDs and metadata — no PII, no student names or emails (COPPA compliance).attempt-stream.fifo — Telemetry Message
Published by the api Lambda immediately after each attempt is created and classified. The FIFO message group key is attemptId to preserve per-attempt ordering.
llm-classify-queue — LLM Classification Request
Published for every attempt the rule engine cannot classify synchronously.
llmClassifierWorker uses attemptId to fetch the full attempt context from Postgres before calling Claude.
guide-ingest-queue — Guide Ingest Request
Published by POST /guides once the teacher’s PDF is uploaded to S3. Consumed by innova-ai-engine’s guide ingest worker.
solution-generation-queue — Solution Generation Request
Enqueued after a guide’s questions are extracted and approved, requesting AI-generated step-by-step solution keys. A null guide_question_id means “regenerate all questions in this guide”.
submission-grade-queue — Submission Grading Request
Published when a student uploads a photo of their handwritten answer. The photo_keys array holds 1–3 S3 object keys for multi-page submissions.
exercise-generate-queue — On-Demand Exercise Generation
Published by POST /items/generate. The innova-ai-engine creates new Exercise rows targeting specific error codes.
attempt-reprocess-queue — OCR-to-Attempt Reprocess
Published by innova-ai-engine after grading a photo submission. This is the only queue where the AI engine is the producer and the backend is the consumer.
Dead Letter Queues
Messages that failmaxReceiveCount delivery attempts are automatically moved to the DLQ by SQS. All DLQs have a 14-day retention period to allow investigation and manual replay.
| DLQ | Source Queue | maxReceiveCount |
|---|---|---|
LlmClassifyDLQ | LlmClassifyQueue | 3 |
AttemptReprocessDLQ | AttemptReprocessQueue | 5 |
GuideIngestDLQ | GuideIngestQueue | 3 |
SolutionGenDLQ | SolutionGenQueue | 3 |
SubmissionGradeDLQ | SubmissionGradeQueue | 3 |
ExerciseGenerateDLQ | ExerciseGenerateQueue | 3 |
ApproximateNumberOfMessagesVisible metric. A non-zero value on any DLQ indicates a persistent processing failure and should trigger an alert. Billing killswitches (LLM_PAUSED, OCR_PAUSED) cause workers to stop processing and let messages accumulate in the DLQ intentionally when AI cost thresholds are hit.
Local Development
LocalStack emulates SQS and S3 athttp://localhost:4566. The docker-compose.yml starts LocalStack automatically alongside MongoDB.
.env point to LocalStack:
scripts/local-reprocess-consumer.ts which polls AttemptReprocessQueue on LocalStack and calls the AttemptReprocessWorker service directly.