Why I Built This
Hacom Holdings receives bid documents (HSDT) from several bidders for each tender. Checking them against the tender appendices — every item, code, unit, quantity and requirement — and then comparing bidders was manual spreadsheet work: slow, error-prone and hard to audit. During my internship (July – September 2026) I built the "Trung tâm kiểm tra hồ sơ" that does this, and I owned it from front to back.
How It Works
The user uploads the tender appendices (Phụ lục 01 / 02) and one or more bidders' Excel files. The backend parses them with python-calamine, maps every sheet to one normalised schema and runs the checks:
- Appendix ↔ HSDT: items, codes, units, quantities and requirements must match the appendix; mismatches are flagged with configurable warning levels.
- Bidder comparison: with two or more files, prices are compared side by side across bidders.
- HSMT ↔ HSDT: compliance of the bid against the tender invitation requirements.
- Version comparison: old vs new price offers from the same bidder.
- Clarification tracking: pairs the owner's clarification requests with bidder responses.
- Document checklist: completeness of the submitted file set.
- PDF-scan → Excel: converts scanned PDFs or images into spreadsheets so they can go through the same checks.
- AI price estimation: reference pricing for MEP materials.
The frontend is plain HTML, CSS and JavaScript talking to a FastAPI backend over a REST API.
Key Decisions
- python-calamine for Excel. Tender files are large and inconsistently formatted; calamine parsed them several times faster than the usual Python options and handled the edge cases we hit.
- Normalise first, check second. Mapping every file into one schema before running checks kept the rule logic simple and let new modules (version diff, checklist) reuse the same data.
- FastAPI + a dependency-free front end. The company wanted something easy to deploy and maintain after the internship ended, so I avoided heavy frameworks on both sides.
What I Learned
This was my first time shipping software for real business users. Requirements changed as people used the tool — the module list above grew from one check into eight — and I learned to build in small increments, demo often, and keep the data model flexible enough to absorb those changes.
