The fifth milestone adds the second big part of the Kladde: public tenders. Public buyers in the EU publish their tenders in TED (Tenders Electronic Daily), and TED offers a search API that anyone can use without a key. In module 2.8 you built a client for it and a nightly import that reads for fixed CPV codes from the configuration. Now that becomes an import the office controls itself: Management decides what to search for, the import fetches only what’s new every night, it survives outages at TED, and everyone can see how the last run went.
The split from lesson 2.11.1, with the change recommended there in solution 3: The runs are recorded before the query needs the last successful run.
| Pull request | Branch | Brings | Where in this lesson |
|---|---|---|---|
| 1 | feature/m5-search-criteria |
CPV codes and countries, checked, saved, kept by management | Exercise 1 and “Pull request 1” |
| 2 | feature/m5-import-runs |
every run recorded, the last one visible, new and changed counted | “Pull request 2” |
| 3 | feature/m5-query-from-criteria |
the query from the criteria, from the last success on, all pages of the answer | “Pull request 3” |
| 4 | feature/m5-retry-run |
at 3 a.m. local time, retried up to three times after an error, the client doesn’t repeat a POST | Exercise 2 and “Pull request 4” |
Where the Kladde stands
After module 2.8 and milestone 4, the solutions have this:
TedClientin the projectKladde.Tedof its own is a typed client (lesson 2.8.1) withAllowAutoRedirect = falseand tests intests/Kladde.Ted.Testswith a fakeHttpMessageHandlerfor success, 500, redirect and broken JSON.TedQuerybuilds the query from aTenderSearch(CPV codes, countries, limit) fromKladde.Core.Tenders.- A background service imports the notices for the CPV codes and countries from the configuration (
Tenders:Import, lesson 2.8.2) every night. - The import is idempotent: A unique index on the publication number prevents duplicates (lesson 2.8.3). The standard resilience handler
doesn’t repeat a
POST(DisableForUnsafeHttpMethods). - At
/tendersthere’s a simple list of the imported tenders.
This lesson’s examples give TenderSearch a factory method with the rules for management’s input and leave out the limit, because the
import now reads all pages; TedQuery also gets the day of the last success. Change those two types from module 2.8 instead of putting new
ones next to them. If your files, classes or folders are named differently, keep your names and carry the steps over.