Skip to content

Tech Stack


Guiding principles

Jester is built on three principles.

Principle Details
Serverless No always-on servers; code runs only when needed, keeping cost and operational load down
Built on AWS Compose managed AWS services instead of running our own infrastructure
AI first Article and blog writing is delegated to Amazon Bedrock to reduce manual work

There is one more principle that matters specifically for using generative AI.

Let the machine do what machines are good at

Asking an AI to transcribe or cross-reference numbers produces mix-ups. So interpretation, matching and transcription are done in code, and the AI only writes the Japanese. Entrant names and payout amounts are filled in from the official data via placeholders, and the generated text is machine-checked against that data afterwards.


AI technology

Amazon Bedrock

Where the generative models run. Different models are used for different jobs.

Use Model Why
Race video / course image analysis Amazon Nova Pro Supports video input
Article and blog writing Claude Sonnet (falls back to Nova Pro when unset) Mostly Japanese text generation
Thumbnail moment selection Amazon Nova Pro Analyses the race video
Embeddings Titan Text Embeddings v2 Powers related-blog similarity search

LangGraph

A library for assembling AI as an agent โ€” a setup where the model decides "what to do next" and autonomously calls tools (e.g. race video analysis) until it reaches its goal, rather than following a fixed sequence.

Jester builds two agents: combined race analysis (video, course image and race result) and thumbnail moment selection. Article and blog writing is tool-less text processing, so it uses a single structured-output call rather than an agent.


Where code runs

AWS Lambda

AWS's mechanism for running small programs that start only when needed. No always-on server is required, so you pay only for what you use.

Jester currently has seven Lambdas.

Lambda Language Role
App Lambda (odds_poc_app) Python Web API serving the admin UI
article_generation Python Writes the 10-second race result summary with AI
article_builder TypeScript Renders the generated article data to HTML with React components and stores it
blog_generation Python Writes race recap / prediction blogs from scratch
blog_rewriter Python Rewrites past blog articles without changing their content
blog_builder TypeScript Pours the blog body into an article template, renders it and stores it
thumbnail_generation Python Extracts the frame at an AI-selected moment of the race video as a thumbnail

Amazon API Gateway

The front door for incoming web requests, which it forwards to the App Lambda.


Where data lives

Amazon DocumentDB

The database holding articles, blogs, race information and so on. It is MongoDB-compatible, so data can be stored in flexible JSON-like documents.

Amazon S3

The object store for large data: race videos, course images, uploaded media and generated thumbnails.

Amazon CloudFront

The S3 bucket is private, so CloudFront is the delivery front-end that lets browsers load images. Thumbnails are embedded into blog bodies as CloudFront URLs.


How the pieces talk to each other

Amazon SQS (message queues)

Rather than calling one another directly, Lambdas drop work into a queue โ€” like a mailbox for "please do this". When the App Lambda posts "generate this article", the article_generation Lambda picks it up. When generation finishes, the result goes into another mailbox (the article-builder queue) and the article_builder Lambda builds the HTML and stores it.

This gives us:

  • A burst of requests is absorbed and processed in order
  • Failed processing is retried automatically

Behaviour differs on the final attempt

Retries are capped. Jester cleans up records left mid-generation only when the final attempt fails (articles are kept as failed with a reason; blogs are deleted). Cleaning up on the first failure would prevent self-recovery from transient errors.

VPC (virtual private cloud)

A private area inside AWS. The database and the Lambdas live inside it, so they cannot be reached directly from outside.


Languages

Python

The backend is mostly Python 3.12 โ€” widely used for AI, data processing and web APIs, with a rich library ecosystem.

TypeScript / Node.js (article_builder and blog_builder)

Article and blog HTML is assembled from React components. blog_builder in particular bundles and renders the real components and real SCSS from the design repository (oddspark-static-pages). These two Lambdas are therefore written in TypeScript (Node.js 22).

Name Role
React / react-dom Turns components into an HTML string (renderToStaticMarkup)
zod Validates the shape of incoming messages
esbuild / sass Bundles components and styles into a single file at deploy time
mongodb Official driver for reading and writing DocumentDB

Main libraries

Name Role
FastAPI Web API framework (used by the App Lambda)
Pydantic / pydantic-settings Automatic type validation and environment variable management
Beanie / Motor Reading and writing DocumentDB from Python
LangGraph / langchain-aws Assembling AI as agents
boto3 Driving AWS services (S3 / SQS / Bedrock, โ€ฆ) from Python
Mangum Adapter that lets FastAPI run on Lambda
pyahocorasick Fast prohibited-word screening
ffmpeg / ffprobe Reading video duration and extracting a frame at a given moment

Quality tooling

Tool What it does
ruff Lints and formats Python code
mypy Catches type mismatches ahead of time
uv Manages and installs dependencies; the workspace ties all the apps together
mise Keeps everyone on the same Python version
ESLint / tsc Linting and type checking on the TypeScript side

These act as a safety net that prevents bugs, catching mistakes developers would otherwise miss.


Mini glossary

Term Meaning
Serverless Letting the cloud run and manage servers instead of doing it yourself
Lambda AWS's way of running small programs that start only when needed
Queue A "mailbox" that holds work until something is ready to process it
DLQ A dedicated queue where messages go after repeated processing failures
API The interface programs use to talk to each other
Database Storage for structured data (articles, race information, โ€ฆ)
Object storage Storage for large files such as images and videos
Library A collection of ready-made functionality
Framework The scaffolding an application is built on
Embedding A numeric representation of a text's meaning; comparing them finds similar articles
SSR Turning components into HTML on the server