Skip to content
Mon–Fri · 09:00 — 12:00 New YorkReply within 1 business daycontact@ferwyn.com
FerwynContact
FerwynToggle navigation

Tender discovery platform

Continuous ingestion from dozens of public procurement sources, each with its own format, normalized into one dataset that can actually be searched and ranked.

Industry
Procurement
Scale
Dozens of public sources
Live since
2024 · ingesting daily
Delivered
2024

§ 01 — Problem

The tenders existed; finding them was the work

Public procurement notices are published, but each source publishes them its own way — its own fields, its own idea of a deadline, its own notion of what a category is. Finding the ones worth bidding on meant a person opening dozens of sites, reading past most of them, and hoping nothing closed while they were looking somewhere else.

The bottleneck was never access to the data. It was that no two sources described the same thing the same way, so nothing could be compared, filtered or ranked across them.

§ 02 — Constraints

What we could not change

  • Every source formats differently. Not a translation problem but a modelling one: the same field means different things in different places, and some sources omit entirely what others treat as mandatory.
  • Sources change without notice. Nobody is obliged to warn an integrator before altering a page or a feed. An ingester that assumes stability degrades silently, so ours had to detect that a source stopped making sense and say so rather than write nonsense into the dataset.
  • We do not control the upstream. No API contract, no test environment, no support channel. What we could do was reduce the blast radius of any one source breaking.
  • Freshness is the product. A tender found after its deadline is worthless, so ingestion had to keep running rather than run well once.

§ 03 — What we built

Ingestion, normalization, and one dataset to search

Continuous ingestion runs per source on a job queue, so one source failing does not stop the others and failures are visible rather than silent. Each source has its own adapter — the messy part stays at the edge — and everything past that point works on one normalized shape.

Normalization is where the value is: dates, categories, amounts and deadlines are mapped onto a single model, so the result is one dataset that can be searched, filtered and ranked instead of dozens that can only be read one at a time. The parsing and matching that carry the load run as separate services.

§ 04 — Outcome

Ingesting daily since 2024

The platform has been ingesting daily since 2024. Searching across sources takes one query rather than an afternoon, and a source that changes shape shows up as a failure to investigate instead of quietly missing tenders.

As with our other work, we are not quoting hit rates or win rates. Those belong to the client, and a number without its method attached is not evidence.

Stack

  • TypeScript
  • Node.js
  • BullMQ
  • Go
  • Rust

Have a system shaped like this one?

Send us the shape of the problem — what it has to do, what it must not break, and what is already in place. We will tell you whether we are the right team for it.

Start a project

We reply within 1 business day. No sales calls unless you ask for one.