Web Applications

Fraud rules service for a card operations team

Built by Leandro Magbanua

A post-authorization rules service and review queue that lets a card operations team change fraud checks the same day instead of waiting for a release.

  • Builder email verified

    Verification

Type
Professional
Category
Web Applications
Published
Jul 26, 2026
Updated
Jul 26, 2026
Built withJavaSpring BootPostgreSQLRedis
TopicsFintechSecurity

About this project

The problem

The card fraud team's rules were hardcoded in a service owned by engineering, so reacting to a new fraud pattern meant writing a ticket, waiting for a sprint, and hoping the release train was on time — a loop of two to six weeks against adversaries who adjusted in days. Meanwhile their review queue was a shared mailbox fed by a report. The ask was a rules engine the fraud analysts could operate themselves, scoring transactions just after authorization and feeding a real queue.

My role

Senior backend developer and technical lead for the service, with two developers and a QA engineer, for about ten months. The fraud team's senior analyst was the closest thing to a product owner, and the best one I've worked with — she wrote acceptance criteria as actual fraud scenarios with card numbers and timelines, which QA turned into fixtures directly.

What I owned

I owned the rules engine core: the rule representation, versioning and approval workflow in PostgreSQL, the evaluation service that scored the post-authorization transaction stream, and the velocity counters in Redis that let rules ask questions like 'fourth transaction on this card in ten minutes'. The review queue backend was mine as well; another developer built the analyst-facing screens.

Technical & product decisions

Rules live as versioned data, every change carrying an author, an approver, and an activation window — the four-eyes approval was my addition, over some grumbling, and it took exactly one mistyped threshold caught at approval to become the feature the analysts defended most. The decision I'd defend hardest is keeping the service out of the authorization path entirely: we score within seconds after auth rather than blocking inside it, which meant a bad rule could flood the queue but never decline a legitimate card at a checkout counter. Every new rule also deploys in shadow mode first, logging what it would have flagged for a few days before it can go live — that habit killed several rules that looked precise on paper and would have flagged half of a payday weekend.

Constraints

The service consumed the transaction stream from a platform team that guarded its schemas closely, so every field we needed was a negotiation with their backlog — one enrichment we wanted took a quarter to arrive, and two rules shipped in a reduced form in the meantime. Data privacy rules meant analysts saw masked card numbers everywhere, which shaped the queue screens more than any design preference did. And the bank's change advisory board still reviewed our releases monthly even though rules now changed daily — explaining that distinction to auditors, twice, was its own small project.

Result & impact

Rule changes went from a release-cycle wait to same-day, with the analysts making about thirty changes in the first quarter unassisted — engineering stopped being in the loop at all, which was the point. Queue handling replaced the mailbox, so items now have state, an owner, and an outcome that feeds back into rule tuning. Shadow-mode statistics gave the team their first real false-positive measurements; one legacy rule inherited from the old hardcoded set turned out to flag 300 legitimate transactions for every confirmed fraud and was retired with honors.