Fraud intelligence
Aegis
A fraud investigation platform I designed, built, and shipped alone — from the detection rules to the WebGL that renders them.
A Brazilian betting operator needed its analysts to stop reconstructing player histories by hand. I built them the whole thing, with AI assistance: the investigation workflows, the detection engine, the API, the data pipelines, the security model, the deployment, and the WebGL view that renders 25,000 players at once. Aegis takes an analyst from a signal to the evidence behind it without leaving the screen.
- Role
- Software Developer
- Period
- April 2026–present
- State
- Deployed to production
- Source
- Private
The Aegis entry sequence — 9 seconds, silent
Every investigation started from scratch
An analyst who wanted to understand one suspicious account had to assemble it by hand. Identity and account data lived in the operational database. Deposits, withdrawals, bets, balances, and gameplay events accumulated in the analytical lakehouse. The story of a player existed, but only in pieces, across two systems that were never meant to be read together.
I also wanted the answer to survive scrutiny. A score on its own is useless to someone who has to justify freezing an account, so every finding Aegis produces names the rule that fired and shows the evidence that triggered it.
The path a request takes
Aegis is a static React application talking to a read-focused FastAPI service, and that service reads a curated PostgreSQL schema I designed for investigation. The lakehouse stays out of the request path entirely. That boundary buys a predictable read path and keeps access to sensitive evidence in one place I control.
Scheduled jobs move profiles, wallets, transactions, hourly balances, and visualization data from Databricks into PostgreSQL, then chain straight into detection scans every hour. Redis serves selected first reads: the jobs write it, the interface only reads it.
What a request touches
- Investigator UIReact single-page app, served as a static bundle
- FastAPI serviceRead-focused JSON API, and the only authorization authority
- Curated PostgreSQL schemaWhat the product reads for profiles, findings, and history
- Databricks lakehouseAnalytical source, read on a cache miss
- Redis cacheOptional, fronts the busiest reads
What keeps that data current
- Databricks lakehouseProfiles, wallets, transactions, and hourly balances
- Scheduled sync and detection jobsSync, then detection scans, chained hourly
- PostgreSQL and cache refreshJobs write; the interface only reads

01 — I made it a separate product
I could have bolted fraud screens onto a system that already existed, and nobody would have argued with me. I built Aegis as its own product instead: its own schema, its own API, its own deployment, its own release cycle.
Two things drove that. Fraud workflows change every time a new pattern shows up, and I wanted to ship those changes without touching anything else. And the evidence behind a finding — documents, transaction history — needs a tighter authorization model than the average internal user should ever inherit.
That decision handed me the entire security surface to own: sessions, CSRF protection, multi-factor authentication, Argon2 hashing, permissions, scoped job credentials, security auditing. I took it. The API is the single authorization authority.
02 — I stopped querying the lakehouse on every click
The event data lives in the lakehouse, and pointing the interface straight at it would have been the fastest route to a working dashboard. It would also have chained every step through a player timeline to warehouse latency and a billing meter.
So the data path splits. Scheduled jobs copy what the product needs into the curated schema, an hourly pipeline runs sync and then scan, and Redis absorbs the reads that repeat.
Aegis therefore reads recent data rather than live data, and I made that call deliberately. The behaviour I am detecting — structuring, velocity, repeated documents — develops over hours and days. Freshness I did not need was not worth the latency I would have paid for it.
03 — I followed the analyst's actual path
A dashboard tells you a number is high. That is where its job ends and the analyst's job starts, which is exactly the wrong place to stop. Aegis follows the path someone actually walks: a triage queue grouped by rule, opening into a player view that holds profile, balances, transactions, gameplay, open findings, and generated reports in one place.
Every finding carries its rule, category, confidence level, and the evidence that triggered it. Rules run in shadow mode by default and get promoted to live on purpose, never by accident. Findings an analyst is actively working sit in a browser-local worklist.
Then there is the Risk Constellation. I render the whole scored population as a GPU point field, with colour and brightness for risk and position to pull flagged players out of the crowd. It started as a question about whether 25,000 players could be legible at once. It turned out clusters and outliers are far easier to see than to query.


04 — I made an internal tool worth looking at
Internal tools look like internal tools because someone decided nobody would mind. I minded. Aegis got a shield-and-iris emblem, a dark console, and a cinematic entry sequence, and that identity holds from the first frame through to the investigation workspace.
I modelled and animated the emblem in Blender, exported it as FBX, assembled and lit the scene in Unreal Engine 5, rendered a 4K image sequence, and graded the film in DaVinci Resolve. That is not a normal thing to do for a fraud console. I wanted to find out whether I could.
None of it gets in the way of the work. The sequence plays once per session and fails open: if the media stalls, cannot play, or the user prefers reduced motion, the console is simply there.
What I built
Aegis is mine end to end. The product and interaction design. The React application, the FastAPI service, authentication, permissions. The PostgreSQL model, the lakehouse synchronization, the hourly pipeline, the detection rules, the scoring, the reports. The tests, the deployment, the WebGL Risk Constellation, and the identity film.
I work AI-native and I am not shy about it: agents accelerated scaffolding, refactoring, test generation, and review. Every architectural decision, every trade-off, and every judgment about whether something was actually good enough stayed mine.
What shipped
I shipped Aegis to production. Eight configurable rules across payment, gameplay, identity, and impact categories; shadow and live execution; scoring and explainable findings; alert triage; player investigation; a browser-local worklist; rule administration; geographic analysis; the Risk Constellation; security auditing; and reports exported as HTML, Markdown, or PDF.

What it is built with
React, Vite, and React Router deliver the interface. FastAPI exposes the read API. PostgreSQL owns the investigative model, Databricks stays the analytical source, and Redis backs selected cache-first reads. Opaque sessions, Argon2, TOTP, CSRF protection, and API-enforced permissions hold the security boundary.
Three.js and a Web Worker point decoder drive the Risk Constellation. deck.gl and MapLibre handle geographic analysis. WeasyPrint generates the reports. pytest and Jest cover backend and frontend paths. Blender, Unreal Engine 5, and DaVinci Resolve produced the identity film.