Data / Thai procurement
Where this started
The first idea was simple: make procurement records easier to search and summarize. In practice, the first questions were about the dataset itself: which mode is this, which resource did it come from, and how much can we honestly say about it?
What I tried
- Keep synthetic mode as an easy local demo instead of mixing it with the official snapshot.
- Normalize and deduplicate the DGA/data.go.th snapshot while preserving record-level metadata.
- Show source links and dataset status alongside search, dashboards, and assistant answers.
The rough shape of it
- 1
CSV / public source → source and mapping checks
- 2
Normalize → deduplicate → keep record-level metadata
- 3
Search / analytics / assistant → link answers back to the source
The wording had to change
Once the official data path existed, I stopped calling it “Thai procurement data” without a qualifier. It comes from one resource part and contains 250 records. Making that boundary visible matters as much as the search screen.

What came out of it
The official snapshot contains 250 unique project IDs covering 4 October 2024 to 29 September 2025. The report records 250/250 valid rows and 250 unchanged rows on the second import. Retrieval results from four labeled queries are bounded-fixture results, not production accuracy.

What's still missing
- The snapshot comes from one resource part, so it is not complete or representative of Thai procurement.
- It is not real-time, and the source may change after the retrieval date.
- The hosted demo remains synthetic in the repository documentation until it is migrated and verified separately.
What I'd change today
- Put dataset status on the first screen before adding more assistant features.
- Build a harder evaluation set and have a person review relevance.
- Keep official, sampled, and synthetic as separate labels in every component from day one.
Source and demo
The repository has the complete setup, tests, and implementation details.