← All work
Deployed technical projectFinancial services · Payments risk

A governed fraud-risk validation register that publishes all 1,852,394 allowlisted simulated events for bounded analytical queries while keeping identity-like fields, model scores, and payment actions out of the public system.

Payments Fraud Risk Data Platform

The business question

Which measured fraud-risk policy best uses a fixed analyst queue, and can the decision be audited against every approved simulated event?

The answer

Retain the ordinary logistic baseline. It outperforms the class-weighted challenger on ranking, fixed-capacity recall, and probability error, and the complete 1,852,394-row allowlisted register is publicly queryable for audit.

Demonstrated value

Retain the ordinary logistic baseline for the measured 1% review queue. It reaches 0.160 PR-AUC and 51.3% recall while the class-weighted challenger performs worse on ranking, recall, and probability error.

My role

Data Engineering

Built a governed PostgreSQL pipeline over 1,852,394 simulated payment events with deterministic ingestion, prior-row-only features, zero duplicate IDs, and a compact seven-column publication store containing every approved row.
Primary stakeholder

A fraud-risk analyst or data-platform reviewer assessing offline model evidence, review capacity, and publication controls.

Context and stakes

The decision context behind the system.

The ordinary logistic baseline is the stronger measured review policy. On the 555,719-event later partition it reaches 0.160 PR-AUC, 51.3% recall at a fixed 1% review rate, and a 0.004 Brier score. The class-weighted challenger falls to 0.112 PR-AUC, 45.4% recall, and a 0.077 Brier score. The dashboard makes that disposition auditable against all 1,852,394 allowlisted simulated events without presenting a live payment score or action.

A fraud-risk analyst can inspect the complete 1,852,394-row simulated event register, filter and page through bounded public records, compare baseline and challenger evidence, and see exactly why the ordinary logistic policy is retained for a fixed 1% review queue.

Approach

A bounded approach shaped by the published constraints.

Retain the ordinary logistic baseline. It outperforms the class-weighted challenger on ranking, fixed-capacity recall, and probability error, and the complete 1,852,394-row allowlisted register is publicly queryable for audit.

Design constraints

  • The source is simulated and covers January 2019 through December 2020.
  • Evidence comes from one chronological holdout without confidence intervals.
  • The challenger is a class-weighted configuration of the same model family, not a distinct algorithm.
  • Calibration is uneven, so scores are not reliable payment probabilities.

Decision journey

The system moves through an inspectable sequence.

Each stage below comes from the published project manifest.

  1. Stage

    Validate approved simulated source

    Schema, license, ordering, null, and label checks reject an invalid source before any row enters governed storage.

  2. Stage

    Load events and prior-row

    Deterministic event IDs make repeated loads idempotent, while SQL window frames stop before the current event to prevent leakage.

  3. Stage

    Compare baseline and challenger

    Both logistic policies use the same six approved inputs and the same later holdout, so ranking, recall, and Brier comparisons remain like-for-like.

  4. Stage

    Normalize the complete public

    Dictionary encoding and integer amounts retain all 1,852,394 allowlisted rows and supporting indexes in a measured 286 MB database.

  5. Stage

    Serve bounded read-only event

    Parameterized filters, stable cursors, a 100-row ceiling, and a least-privilege role keep anonymous event queries bounded.

  6. Stage

    Present the decision, capacity,

    The server-rendered interface connects the model disposition, event queries, analyst capacity, data boundary, and explicit unavailable states.

Interactive architecture

The published architecture, made interactive.

The product separates governed development data from public analytical data. Local validation locks the approved source and loads deterministic events into PostgreSQL. Window frames end one row before the current event, creating point-in-time merchant and category history without current-label leakage. Both logistic policies share those inputs and a chronological holdout. Publication then normalizes every event into a compact seven-column store whose read-only role cannot access the wider development tables. FastAPI enforces parameterized filters, cursor pagination, and a 100-row ceiling, while Next.js exposes the decision, event evidence, monitoring, and explicit unavailable states.

Drag to pan · use controls to zoom · select any stage
100%
feedsfeedsfeedsfeedsfeedsStage 1Source validation rejects schemaPythonStage 2Governed PostgreSQL load buildsPostgreSQLStage 3Chronological evaluation compares baselinescikit-learnStage 4Compact Supabase store retainsSupabaseStage 5FastAPI enforces cursor paginationFastAPIStage 6Next.js register exposes decisions,Next.js
Read the architecture as text
  1. Source validation rejects schemaStage 1 · Python

    Schema, license, ordering, null, and label checks reject an invalid source before any row enters governed storage.

  2. Governed PostgreSQL load buildsStage 2 · PostgreSQL

    Deterministic event IDs make repeated loads idempotent, while SQL window frames stop before the current event to prevent leakage.

  3. Chronological evaluation compares baselineStage 3 · scikit-learn

    Both logistic policies use the same six approved inputs and the same later holdout, so ranking, recall, and Brier comparisons remain like-for-like.

  4. Compact Supabase store retainsStage 4 · Supabase

    Dictionary encoding and integer amounts retain all 1,852,394 allowlisted rows and supporting indexes in a measured 286 MB database.

  5. FastAPI enforces cursor paginationStage 5 · FastAPI

    Parameterized filters, stable cursors, a 100-row ceiling, and a least-privilege role keep anonymous event queries bounded.

  6. Next.js register exposes decisions,Stage 6 · Next.js

    The server-rendered interface connects the model disposition, event queries, analyst capacity, data boundary, and explicit unavailable states.

Technology used
PythonPostgreSQLscikit-learnSupabaseFastAPINext.jsTypeScriptRenderVercel

Pivotal decisions

Technology choices recorded with their trade-offs.

These choices are derived from the project’s published decision record.

Decision

Use Prior-row PostgreSQL window features within the published boundary

Historical merchant and category behavior is computed at the event timestamp without using the current event or label.

Constraints
  • Publishing every simulated row improves auditability but requires bounded pages, indexed filters, and abuse controls.
  • The compact 286 MB public store fits the current free database tier with measured headroom but has no production capacity guarantee.
  • The governed 2,266 MB development database remains local because features and lineage fields are outside the public boundary.
Alternatives
  • Precompute features in an unversioned dataframe
Criteria
Fit for the stated scope · Inspectable evidence · Explicit operating boundary
Selected
Prior-row PostgreSQL window features
Why
Historical merchant and category behavior is computed at the event timestamp without using the current event or label.
Trade-off
The SQL contract is explicit and reproducible but the wider governed database remains local.
What supported it
1,852,394 Public simulated events: Every approved source row is represented through seven allowlisted analytical fields.
Revisit when
Add gateway rate limits, connection pooling, request telemetry, and service objectives before materially higher public traffic.
Decision

Use Chronological baseline and challenger evaluation within the published boundary

A later source partition tests the policies against future simulated events and keeps the comparison capacity-aware.

Constraints
  • Publishing every simulated row improves auditability but requires bounded pages, indexed filters, and abuse controls.
  • The compact 286 MB public store fits the current free database tier with measured headroom but has no production capacity guarantee.
  • The governed 2,266 MB development database remains local because features and lineage fields are outside the public boundary.
Alternatives
  • Random split or highest single metric
Criteria
Fit for the stated scope · Inspectable evidence · Explicit operating boundary
Selected
Chronological baseline and challenger evaluation
Why
A later source partition tests the policies against future simulated events and keeps the comparison capacity-aware.
Trade-off
One chronological holdout is more realistic than a random split but does not quantify variance.
What supported it
0.160 PR-AUC Retained baseline ranking quality: The class-weighted challenger reaches 0.112 on the same 555,719-event chronological holdout.
Revisit when
Move batch validation and evaluation into scheduled immutable jobs only after defining freshness, retry, retention, and alert ownership.
Decision

Use Normalized compact public store within the published boundary

Dictionary encoding and integer amounts fit all approved rows plus indexes inside the existing free database tier.

Constraints
  • Publishing every simulated row improves auditability but requires bounded pages, indexed filters, and abuse controls.
  • The compact 286 MB public store fits the current free database tier with measured headroom but has no production capacity guarantee.
  • The governed 2,266 MB development database remains local because features and lineage fields are outside the public boundary.
Alternatives
  • Publish the 2,266 MB governed development schema
Criteria
Fit for the stated scope · Inspectable evidence · Explicit operating boundary
Selected
Normalized compact public store
Why
Dictionary encoding and integer amounts fit all approved rows plus indexes inside the existing free database tier.
Trade-off
The compact store removes features and lineage detail from public queries by design.
What supported it
51.3% Fraud-label recall at 1% review: The measured queue contains 5,557 events; the challenger reaches 45.4% recall at the same capacity.
Revisit when
Add new chronological windows, confidence intervals, threshold sweeps, and delayed-label monitoring before revisiting the model policy.
Decision

Use FastAPI cursor pagination within the published boundary

Stable indexed cursors and a fixed 100-row ceiling keep anonymous full-row access bounded.

Constraints
  • Publishing every simulated row improves auditability but requires bounded pages, indexed filters, and abuse controls.
  • The compact 286 MB public store fits the current free database tier with measured headroom but has no production capacity guarantee.
  • The governed 2,266 MB development database remains local because features and lineage fields are outside the public boundary.
Alternatives
  • Unbounded downloads or offset pagination
Criteria
Fit for the stated scope · Inspectable evidence · Explicit operating boundary
Selected
FastAPI cursor pagination
Why
Stable indexed cursors and a fixed 100-row ceiling keep anonymous full-row access bounded.
Trade-off
Visitors query the complete population incrementally rather than downloading it in one response.
What supported it
286 MB Hosted full-row publication store: All rows, dictionaries, and query indexes remain inside the existing 500 MB free database tier.
Revisit when
Move beyond the free 500 MB database tier only with a new capacity review, cost approval, backup plan, and teardown condition.

Results and evaluation

Measured results within the disclosed evaluation boundary.

1,852,394Public simulated events
Method
Remote count reconciliation, source totals, schema inspection, and privilege checks.
Meaning
The public register is complete within its disclosed field boundary.
Limitation
The source is simulated and covers January 2019 through December 2020.

Limitations and next steps

Useful evidence, bounded claims.

What this does not prove

  • The source is simulated and covers January 2019 through December 2020.
  • Evidence comes from one chronological holdout without confidence intervals.
  • The challenger is a class-weighted configuration of the same model family, not a distinct algorithm.
  • Calibration is uneven, so scores are not reliable payment probabilities.
  • No fairness analysis, threshold sweep, delayed-label feedback loop, or production drift study is claimed.
  • No live scoring, approval, decline, or automated payment action exists.
  • Free-tier services may cold-start, pause, or reach capacity and have no uptime guarantee.

What I would do next

  1. Add gateway rate limits, connection pooling, request telemetry, and service objectives before materially higher public traffic.
  2. Move batch validation and evaluation into scheduled immutable jobs only after defining freshness, retry, retention, and alert ownership.
  3. Add new chronological windows, confidence intervals, threshold sweeps, and delayed-label monitoring before revisiting the model policy.
  4. Move beyond the free 500 MB database tier only with a new capacity review, cost approval, backup plan, and teardown condition.

This public demonstration uses simulated 2019 to 2020 payment events. It is not a production fraud system, does not score a live payment, and does not make an approval, decline, or other payment decision.

Explore the rest of the work