Overview
DocuFlow AI automates the most tedious part of finance operations: turning a pile of invoices and receipts into clean, reviewed, structured data. A user uploads a PDF, JPG or PNG; the platform extracts the fields, normalizes them, and only asks a human to step in when the machine is not confident.
It was built by a five-person team as an internship project for the First Cloud AI Journey (FCAJ) program, and documented as a hands-on workshop so that anyone can rebuild the whole system step by step.
The problem
Manual invoice entry is slow and error-prone, but fully automatic extraction is risky: a wrong total or vendor name that slips through silently is worse than a slow process. The goal was a pipeline that is automatic by default, honest about its uncertainty, and auditable end to end.
Architecture
The system is a three-tier serverless design:
- Frontend – React 19 + TypeScript (Vite), served through CloudFront and deployed with Amplify Hosting.
- Orchestration – AWS Step Functions coordinating small Lambda microservices (Node.js 20.x, TypeScript).
- Data and AI – Amazon Textract for OCR, an external AI model to normalize the output, and DynamoDB for document metadata and extracted fields.
- Upload
- BrowserReact 19 · CloudFront · Amplify
- CognitoFinance user / admin roles
- Ingest
- S3Raw documents
- EventBridgeRoutes the upload event
- SQSAbsorbs bursts
- Orchestrate
- Step FunctionsOne state machine per document
- TextractExpense field extraction
- AI proxyNormalizes fields
- Outcome
- DynamoDBEXTRACTED: high confidence
- Review queueREVIEW_REQUIRED: low confidence
- Approval
- Finance userCorrects uncertain fields
- Approved recordAPPROVED
- Client
- Compute / service
- Data store
- Messaging / jobs
- External API
- Human step
CloudWatch, X-Ray, SNS/SES, KMS and Secrets Manager wrap the whole pipeline for observability, alerts and encryption.
Supporting services: API Gateway for the REST layer, Cognito for authentication and roles, CloudWatch and X-Ray for observability, SNS/SES for alerts, and KMS plus Secrets Manager for encryption and credentials.
How a document flows
Every document moves through an explicit state machine, which makes the UI, the alerts and the audit trail all speak the same language:
UPLOADED → QUEUED → PROCESSING → EXTRACTED / REVIEW_REQUIRED / FAILED → CORRECTED → APPROVED
- The browser uploads straight to S3 using a presigned URL, so large files never pass through a Lambda.
- The S3 event goes through EventBridge into an SQS queue, which decouples uploads from processing and absorbs bursts.
- A Lambda starts a Step Functions execution for each document.
- Textract analyzes the expense fields, then the AI proxy normalizes them into a consistent schema.
- Results below the confidence threshold land in a human review queue instead of being trusted blindly.
Key decisions
Human-in-the-loop by design. Low-confidence extractions are never auto-approved. Finance users correct the uncertain fields, and only then does the document become APPROVED. Administrators can see all records; regular users see their own.
Queue between ingestion and processing. EventBridge → SQS means a spike of uploads turns into a backlog rather than a failure, and failed items are visible instead of silently lost.
Infrastructure as code. The backend is described with AWS SAM, and the repository is a pnpm workspace with shared packages (shared-types for API contracts, shared-config for settings). Sharing the contract types between the frontend and the Lambda handlers keeps the two sides from drifting apart.
Security and cost from day one. Encryption with a KMS customer-managed key, secrets in Secrets Manager, IAM least privilege, audit logging, and AWS Budgets alerts are part of the foundation step of the workshop, not an afterthought.
My role
As project leader and integration owner, the job was less about a single component and more about making the parts fit: agreeing on the API contracts, wiring the frontend to API Gateway and Cognito, and making sure the ingestion pipeline, the workflow and the review flow behaved as one system. The team also turned the build into a seven-part workshop covering foundation setup, frontend deployment, the AI workflow, asynchronous ingestion, results and review, observability and governance, and end-to-end testing with cleanup.
What I took away
- Event-driven designs make failure modes visible, but only if every state is modelled explicitly.
- Confidence thresholds are a product decision as much as a technical one: they decide how much work lands on a human.
- Writing the workshop forced the architecture to be reproducible, which exposed hidden manual steps early.
