Vianova
Five years of APIs, data and AI for cities and mobility operators
Vianova collects mobility data from shared-mobility operators and other partners, then gives operators and cities, in places like Munich, Dublin, Malmö and West Sussex, dashboards, maps, reports and an API to explore it. I joined in 2021. Today I'm Lead Backend Engineer, and I'm the largest contributor to its backend. Here is what that means.
The query API
Customers ask for their data as typed JSON, and the API compiles it to Snowflake SQL. A colleague wrote the first endpoint. I built the query language on top of it, and I've been its main developer ever since.
- Filters, aggregations, computed fields, joins, pivots, custom metrics and geospatial operations
- Raw points snapped onto roads, areas or H3 cells
- Customer files turned into queryable, map-ready datasets, with dashboards created automatically
- About 80% of the commits on this code, and 83% of the lines still there today
AI in the product
Since September 2024, you can type a question in plain language. Claude writes the query, the API validates it, and it can become a chart. I built this from the first commit, and I still maintain it.
- Tested like code: CI fails if query generation drops below 85%, or suggested prompts below 90%
- Explanations of a generated query, and suggested prompts for each dataset
- One interface over Anthropic, Bedrock and OpenAI, now behind nine use cases
- PowerPoint reports built from a dashboard, with AI-written analysis in several languages, from prototype to production in five months
- AI dataset categorization, from hackathon idea to default on upload in a month
When production pushes back
Real clients and real data find what tests don't. These are the ones I'm happiest about.
- Year-long queries didn't fit the 29-second API timeout. Routing them to a daily rollup cut about 40M rows to about 1.7M, with no change for callers
- One slow client could freeze the API for everyone. I traced it to cached routes blocking the event loop, fixed it, and added request deadlines and query cancellation
- A live traffic-data pipeline ran on a colleague's laptop. I moved it to scheduled cloud jobs with alerts, five weeks before a vendor deadline
- Pydantic v1 to v2 across the backend in about four weeks: 217 files, with the API contract unchanged
Data
The data reaches the API through a dbt project of 483 models, and I've been its top committer since 2022.
- Brought unit testing to the project in 2022, and wrote about 42% of today's unit tests
- Rebuilt regulation compliance history so each hour belongs to the rule version in force, checked against 176,000 production version pairs
- Built the first dbt pipeline into the stream serving table, then made it safe: partial data can't overwrite full days, and empty merges fail loudly
- Automated 30-day deletion of citizen report photos and comments, backups included, with a test that fails if anything is left
How I work now
Six automations run every weekday, in Paradev. They triage new tickets, start a Claude Code session in its own worktree for each ticket I label, check what shipped, and draft my stand-up. The thinking stays with me. By my estimate, agents now write over 80% of my code.
A small, clear fix
Slack message or alert›triage investigates›I pick the route›the agent fixes it›I review the diff›MR, CI, review, deploy›I read the closing note›QA sweep checks prod›I close itSomething that needs thinking
ticket labelled›session opens›agent grills me›I answer every round›spec›I confirm the test seams›slices›I approve the breakdown›3 builders in parallel, test-first›MR, CI, review, deployAgents propose, I apply
Triage can read and comment. It has no permission to change a ticket.
Safe to run twice
A stopped ship step checks the live state, then resumes where it stopped.
Parallel, with a cap
Three builders at once. More just thrashes the laptop.
The plan-to-build chain is adapted from Matt Pocock's skills. The automations around it are mine.
Under it
- Python
- FastAPI
- Snowflake
- dbt
- PostgreSQL
- Redis
- AWS Lambda
- App Runner
- Cognito
- Pulumi
- GitLab CI
- Streamlit
- Claude
- Claude Code
- Paradev