The original worked, which is exactly why it got rewritten.
It was a FastAPI service serving ISATEK’s product catalogue: item codes, variants, manufacturer
codes, prices, descriptions, supplier references. Then someone discovered that LibreOffice can call
a URL from a spreadsheet cell with WEBSERVICE(), and from that day the most important client of
this API was a quotation template that had been accumulating columns since 2019.
That changes the requirements. A browser can be told to reload; a spreadsheet cell cannot. The response has to be plain text, it has to be stable, and it has to be right, because a wrong price in a quotation is a customer conversation and a margin nobody notices for a month.
Meanwhile the business had already moved its ERP to Elixir. Two languages meant two deployments, two sets of conventions, and one more thing to remember on a bad morning. So the catalogue came across: Phoenix 1.8 and LiveView, same paths, same shapes.
What the API carries
The old surface is intact: search by field and query, list by field, single item, single attribute.
/one/ItemCode/:q/:attrib exists because a spreadsheet cell wants one value, not a document. A
/filter endpoint, a POST search for compound queries, and an OpenAPI description with Swagger and
Redoc pages, because the external contractors’ Python version had them and the spreadsheets were
built against what they documented.
What the rewrite bought
A browsing UI the spreadsheet never had: views by item code, variant name and manufacturer code, recent items, and a search that answers the question the old one could not — do we have this, from this supplier, at this price, and is it still current?
And a single deployment story. One language, one release, one place where the conventions live. The schema is one table, which is the correct size for a catalogue and a reminder of how much a rewrite can shrink when nobody is selling an architecture.
How the risk was contained
The response shape was frozen before the implementation changed. Every path a spreadsheet calls returns what it returned before, and the new UI was built on the same data rather than beside it.
That is slower than rewriting both at once. It is also the only version of this project that a quotation can survive.