Case study · ale.business

AWS architecture for chat-driven bookkeeping with an LLM harness

Finance solutions for small businesses. Book expenses and send invoices by writing a chat message, with an LLM that proposes and deterministic code that decides.

Industry
Finance, bookkeeping
My role
Architecture, LLM harness, invoicing pipeline
Focus
Privacy, correctness, automation
Results
Automation
Bookkeeping from a chat message

Write what happened, attach the receipt. The harness turns it into a correct booking or asks back.

Correctness
Invoices sent correctly, automatically

Numbered, validated and archived before anything leaves the system.

Privacy
Financial data stays protected

EU region only, encrypted end to end, backed up and fully auditable.

The story

Bookkeeping is the part of running a business nobody wants to do. ale.business turns it into a conversation: write "paid 49 € for software" and attach the receipt, or ask for an invoice to a customer, and the system does the rest.

An LLM on its own is not good enough for finance. It can misread an amount, pick the wrong tax rate or invent an account. So I built a harness around it: Bedrock only returns a structured proposal, and Python code checks the schema, the double-entry balance, the tax rules and duplicates before anything is booked. Unclear cases go back to the user in the chat.

Invoices follow the same principle. Each one gets a gapless number, is validated for mandatory fields and totals, rendered as PDF and e-invoice, sent through SES and archived in S3 with Object Lock, so it can never be changed afterwards.

Because it is financial data, privacy shaped every decision: everything runs in the Frankfurt region, data is encrypted with KMS, backups are encrypted and stay in the EU, and CloudTrail records every access.

System architecture: Chat, finance API and LLM harness in one EU region
System architecture.
LLM harness: From a chat message to a correct booking
The LLM harness. The model never writes to the ledger directly.

Invoicing

An invoice is a legal document, so the pipeline treats it as one. If any check fails, nothing is sent and the user gets a concrete fix in the chat.

Invoice pipeline: Correct before it is sent, unchangeable after
Invoice pipeline, with the privacy and backup layer underneath.

Technology

Application
Nuxt, Vue
Nuxt, Vue
Nuxt, Vue
chat and web app
Python, FastAPI
Python, FastAPI
Python, FastAPI
finance API, LLM harness
Amazon EC2
Amazon EC2
app and harness servers
Amazon DynamoDB
Amazon DynamoDB
append-only ledger, invoice numbers
Amazon S3
Amazon S3
receipts, invoice archive with Object Lock
AI and automation
Amazon Bedrock
Amazon Bedrock
LLM and guardrails in the EU region
AWS Lambda
AWS Lambda
invoice worker
Amazon EventBridge
Amazon EventBridge
recurring invoices, reminders
Amazon SES
Amazon SES
invoice delivery
API Gateway
API Gateway
WebSocket chat
Security and privacy
Amazon Cognito
Amazon Cognito
login, MFA, roles
AWS IAM
AWS IAM
least-privilege roles
AWS KMS, Secrets Manager
AWS KMS, Secrets Manager
AWS KMS, Secrets Manager
encryption, credentials
Amazon VPC, CloudFront, WAF
Amazon VPC, CloudFront, WAF
Amazon VPC, CloudFront, WAF
Amazon VPC, CloudFront, WAF
private network, edge, protection
AWS Backup
AWS Backup
encrypted backups, EU only
Delivery and operations
Docker
Docker
containers
GitHub Actions
GitHub Actions
CI/CD
CloudWatch, CloudTrail
CloudWatch, CloudTrail
CloudWatch, CloudTrail
observability, audit trail
Core stack

Working on something similar?

Tell me what you run today and where it hurts. I will come back with how I would build it, and what I would leave alone.

Discuss your project