The Guides pipeline lets teachers upload a worksheet PDF and have the system automatically extract its questions, generate a step-by-step solution key for each one, and grade student photo submissions — all without leaving the Innova dashboard. Teachers retain full editorial control at every stage: extracted questions can be edited and re-classified, solution keys can be regenerated or hand-edited, and individual student responses can have their error tag overridden. The result is a zero-marking workflow that still produces structured, per-question error analytics.Documentation 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.
Pipeline Stages
Create guide
The teacher calls
POST /guides with a title and courseId. The server verifies course ownership via CourseTeacher, creates a Guide record with status: UPLOADED, and returns a presigned S3 PUT URL for the PDF together with the new guideId.Upload PDF
The teacher’s client PUTs the PDF file directly to S3 using the presigned URL. The file lands in the
innova-backend-serverless-{stage}-guides bucket at key guides/uploads/{uuid}.pdf. No server bandwidth is consumed.Ingest
The teacher calls
POST /guides/:id/ingest. The server transitions the guide to EXTRACTING and publishes a GuideIngestMessage to the SQS_GUIDE_INGEST_URL queue. The innova-ai-engine worker picks up the message, runs OCR + LLM extraction on the PDF, and creates GuideQuestion records — one per detected question — each with a statementLatex, sequence, and AI-classified subdomain.Review & approve
The guide transitions to
REVIEW. The teacher inspects each extracted question in the UI, edits any statementLatex, and confirms the subdomain classification with PATCH /guides/:id/questions/:qid. Confirming a subdomain sets topicSource: TEACHER and topicConfidence: 1.0, anchoring the question to the taxonomy for error analysis.Solution generation
On demand (or automatically after all questions are approved), the server enqueues a
SolutionGenMessage to SQS_SOLUTION_GEN_URL. The AI engine generates a canonical solution for each approved question: a JSON object with final_answer, points, ordered steps (each with a LaTeX expression and an optional checkpoint flag), and optional alt_paths. The guide moves to GENERATING_SOLUTIONS and then back to REVIEW (status SOLUTION_READY at the question level).Publish
The teacher calls
POST /guides/:id/publish. The server verifies all questions are APPROVED or EXCLUDED, then runs a database transaction that:- Creates an
Assignmentofkind: GUIDEwith oneAssignmentTargetper enrolled student. - Materializes an
Exerciserow for eachAPPROVEDquestion that has a confirmed topic. - Flips the guide to
PUBLISHEDand recordspublishedAt.
Student submission
Students call
POST /student/guides/:id/questions/:qid/submissions to get one or more presigned PUT URLs for their handwritten photo(s). They PUT the JPEG/PNG directly to the innova-submissions-{stage} S3 bucket.Photo upload & grading
The student calls
POST /student/submissions/:id/complete. The server enqueues a grading message to SQS_SUBMISSION_GRADE_URL. The AI engine transcribes the handwriting, aligns it against the canonical solution checkpoints, determines correctness, and creates an Attempt record with a errorTag assigned via the rule engine (or LLM fallback). The GuideSubmission status transitions to GRADED.Guide State Machine
The guide lifecycle is enforced byassertTransition in guide-state-machine.ts. Invalid transitions throw InvalidGuideTransitionError.
EXTRACTION_FAILED and GENERATION_FAILED are retryable: calling POST /guides/:id/ingest from either state re-queues the work. A guide can be ARCHIVED from any non-terminal state.
Scan-Page Mode
For handwritten worksheets where all questions are on one page, students can upload a single full-page photo instead of individual question photos:GET /student/guides/:id/scan-page-url— returns a presigned PUT URL targeting the submissions bucket.- Student PUTs the page image.
POST /student/guides/:id/scan-page— the server enqueues a scan-split job. The AI engine splits the page into per-question regions, creates oneGuideSubmissionper question, and grades each independently.
S3 Storage Layout
Two buckets, each with its own lifecycle policy:| Bucket pattern | Contents | Lifecycle |
|---|---|---|
innova-backend-serverless-{stage}-guides | Source PDFs (guides/uploads/*.pdf) | 1-year expiry |
innova-submissions-{stage} | Student handwriting photos | 30-day expiry |
S3_GUIDES_BUCKET and S3_SUBMISSIONS_BUCKET environment variables. The GuidesService raises a BadRequestException at startup if either variable is absent, ensuring misconfiguration is caught before any request is served.
Presigned URL TTLs are configurable via environment variables. The defaults are:
GUIDES_PRESIGNED_PUT_TTL—600seconds (10 min) for PDF uploadsGUIDES_PRESIGNED_GET_TTL—300seconds (5 min) for teacher preview URLsSUBMISSIONS_PRESIGNED_GET_TTL—300seconds (5 min) for student photo preview in the results drawer
GUIDES_PRESIGNED_PUT_TTL for slow network environments (e.g., rural schools with limited bandwidth).