-
-
Twenty-four fictional tenders ranked by the current company-specific evaluation.
-
A tender detail separates final score, eligibility, and evidence coverage.
-
Continuous factors show their value, curve, points, and plain-language explanation.
-
A stable twenty-tender calibration set records score and eligibility agreement separately.
-
The active matching configuration is immutable, hashed, and previewable before a new version is activated.
-
Contract expirations are derived only from sufficient source facts, with the rule and unavailable cases kept visible.
Inspiration
I manage road maintenance and green management contracts for a living, so I watch small companies chase public work every week. The routine is always the same: five portals open at once, deadlines copied into a spreadsheet by hand, and the one question that matters still unanswered, "is this tender actually right for us?" A generic keyword alert never answers that. It cannot weigh territory, equipment, qualifications, timing, and the gaps you would have to close before the deadline. I wanted a tool that gives an honest answer, and shows its reasoning.
What it does
Radar Gare collects tender notices from TED and Italian public data sources, normalizes them into a single tenant-scoped record, keeps the source provenance, and removes duplicates. Then evaluation_v1 scores each tender on four explainable levels: L0 for hard exclusions, L1 for eligibility (full, bridgeable, presumed, or blocked), L2 for seven continuous fit factors, and L3 for evidence, gaps, suggested instruments, and disclaimers. It also imports historical awards, derives contract expirations only when the source dates are unambiguous, and produces an auditable morning digest. It ranks and explains. It never signs or submits a bid.
How I built it
I started with a written domain brief and not a single line of application code. From the first commit on July 14 I worked with Codex, powered by GPT-5.6, building the FastAPI, PostgreSQL, and React product one milestone at a time. Codex took a lot of weight off the mechanical work: migrations, API contracts, source adapters, frontend views, regression tests. GPT-5.6 was most useful when I had to turn messy source behavior and procurement rules into explicit models and edge cases.
The decisions that define the product stayed mine. Deterministic scoring instead of asking an LLM to do arithmetic. Strict tenant isolation from the first schema. Append-only evaluations, so nothing gets silently rewritten. Immutable configurations. And null when a value is unknown, never an invented capacity to make a row look complete.
Challenges I ran into
Most of the pain lived at the source boundaries. TED rejected a sort direction that looked perfectly valid on paper. One Italian source only exposes its data through an undocumented interface behind a dynamic map. The large open-data archives sit behind a WAF, so the downloader had to slow down and behave: paced requests, resumable ranges, ZIP validation, checksums, cache revalidation. And in the matching logic I kept fighting the temptation to let a metadata guess quietly become a fact.
Accomplishments that I'm proud of
The local acceptance run evaluated all 734 tenders on current snapshots, with no stale projections left hanging around. The historical importer persisted 5,947 awards and derived 1,292 inspectable schedules, and left 4,655 incomplete cases explicitly marked as unavailable instead of faking them. The repository reached 273 passing backend tests and 90 passing frontend tests. What I'm most proud of is that every result carries its own trail: source payload, run report, configuration hash, evidence coverage, and the reasons behind the score.
What I learned
The biggest lesson: uncertainty is a product state, not missing polish. A score only becomes useful when the person reading it can tell apart what was observed, what was presumed, and what still needs work. I also learned how to get the most out of Codex, which is narrow milestones with executable acceptance criteria, followed by me reviewing every domain assumption by hand. It moves fast, but the judgment about what is correct in this domain still has to be mine.
What's next
Next is human review of the 20-tender golden set, scoring fit and eligibility separately. After that I want cited extraction straight from the tender documents, so verified requirements can replace the metadata presumptions. Further out there is bid planning. Through all of it Radar Gare keeps the same boundary: it prepares and explains the decision, it does not sign or submit the bid for you.
Built With
- alembic
- anac-open-data
- argon2
- codex
- docker
- fastapi
- gpt-5.6
- jwt
- mantine
- openai
- postgresql
- procrastinate
- pydantic
- pytest
- python
- react
- sqlalchemy
- structlog
- tanstack-query
- tanstack-router
- ted-api
- typescript
- vite
- vitest
Log in or sign up for Devpost to join the conversation.