Data EngineeringML/AIProductOps

Live at licitapr.com

LicitaPR Inteligencia

Thirty-four government sources that don't talk to each other, unified into one procurement-intelligence product that looks ahead instead of back.

~1.37Mgovernment contracts ingested from 34 sources
422K → ~345Kvendors resolved to entities (Splink + deterministic)
7procurement categories in the live product
Nightlydata-quality checks and integrity-checked snapshots

Thirty-four government sources that don’t talk to each other, unified into one procurement-intelligence product that looks ahead instead of back.

Vendor-facing intelligence built on Puerto Rico public data. It answers the questions a bidder actually has. What can I bid on? What does this work pay? Which contracts expire next (the re-bid), and who holds them?

Problem

Public procurement data in Puerto Rico exists, but it’s spread across 34 separate government sources that don’t interoperate. What’s there only looks backward. Watchdog and transparency tools tell you what already happened. A vendor deciding where to spend bid-prep effort needs the opposite. They need to know what’s coming up for re-bid, what the work pays, and who they’d be bidding against.

The expiring-contract radar is the wedge. It’s re-bid intelligence: which contracts come up next and who holds them. That’s the part people will pay for.

Build

The product

A multi-category, searchable site spanning seven procurement categories. Per category, vendors get a clear free-vs-paid line:

  • Open RFPs: free
  • Award pricing: paid
  • ★ Expiring-contract radar: paid (the wedge)
  • Competitor leaderboard: paid

On top of that sit firm and agency drill-down dossiers and server-rendered charts. A server-side paywall enforces the free/paid boundary with no view-source leak. The visual identity is institutional on purpose. Public Sans with a Newsreader serif, tabular figures, semantic color. It reads like an intelligence product, not a dark-terminal cliché.

Data engineering (acquisition)

Thirty-four Puerto Rico government sources scraped, structured, cross-linked, and quality-monitored:

  • ~1.37M contracts ingested from the Contralor registry.
  • 50K+ legislative measures toward the full record since 1985, with GPU-OCR’d bill text.
  • 440K+ campaign-finance donations across 125K+ donors. The finding that 98.8% of donation dollars come from individuals drove the schema design.
  • ~1,700 RFPs, plus a corporate-registry crawler feeding entity resolution.

The crawlers hold up against messy public sources. They’re resumable and idempotent, and a supervisor auto-restarts jobs.

Entity resolution

A corporate-registry crawler feeds Splink + deterministic entity resolution, collapsing 422K vendor records to ~345K resolved entities with confidence scores attached. The framing stays strict. The system maps public records and flags patterns for review. It never accuses. A tempting fraud thesis got tested hard and did not survive, so I killed it instead of shipping it.

Engineering quality and honest data

  • A standalone data-quality monitor and integrity-checked nightly snapshots.
  • A release-gating QA harness on the product surface.
  • Honest-data discipline. A completeness audit caught ~80K silently-missing measures. I re-crawled them instead of serving partial data.

Architecture and ops

A clean security boundary keeps the internal warehouse separate from anything public:

  • Internal 1.29 GB warehouse → nightly ETL → a small, indexed product.sqlite.
  • A read-only public Flask app serves only the slimmed product database, behind a cloudflared tunnel.
  • Result: instant indexed lookups for users, with the working data never exposed.

Numbers

  • ~1.37M government contracts ingested from 34 sources
  • 422K → ~345K vendors resolved to entities (Splink + deterministic)
  • 440K+ campaign-finance donations across 125K+ donors
  • 50K+ legislative measures toward the full record since 1985
  • 7-category live procurement-intelligence product
  • Release-gating QA harness · standalone data-quality monitor
  • ~80K silently-missing measures caught by a completeness audit and re-crawled

Stack

Python · Flask · SQLite (WAL) · Splink · Patchright · httpx/selectolax · EasyOCR (GPU) · cloudflared

Stack

PythonFlaskSQLite (WAL)SplinkPatchrighthttpx/selectolaxEasyOCR (GPU)cloudflared

← All work

Have data? Let’s make it think.

Available for consulting engagements through Vizlogic, and open to senior data, analytics and AI engineering roles — remote, U.S.