Three legacy systems, one question
A read-only layer over Firebird and MS SQL exposing named queries as JSON. The user does not need to know which system holds the data.
- Client
- wholesale and retail operator with in-house ERP
- Status
- Production · 2026
- Outcome
- A business question is asked once, without knowing which system holds the data.
- Source databases are reachable for reading only; writing through the layer is impossible.
- New queries are added by configuration at runtime, without touching any client.
- Stack
- GoFirebird 2.5MS SQL ServerPowerShell and ODBCWindows ServiceJSON manifests
The problem
A company with a long history typically runs three or four systems that do not understand each other: stock and ordering on Firebird, a central database on MS SQL, and finance in a separate package. Answering a simple business question — which orders have no matching delivery, for instance — requires a person who knows where to look and has access to all three.
At the same time these databases must not be touched. They are in production, they are old, and their vendors either no longer exist or do not support changes.
What was built
A layer that sits in front of every source and exposes named queries as JSON over HTTP. The client knows nothing about the database, needs no driver, and cannot send its own SQL — it sees only the list of questions it is permitted to ask.
The decisive choice is that connections are opened in read-only transactions. This is not a convention or a permission that can be changed; writing through this layer is simply impossible. That is the only kind of guarantee anyone accepts when the data is production legacy data.
In front of Firebird there is a separate service written in Go using a pure-Go driver, so it deploys as a single binary with no client libraries to install — which on older Windows servers is the difference between "done within the hour" and "cannot be done". Queries are defined in a configuration file that reloads at runtime.
Why this matters for AI
The layer was built for conventional reporting, but it turned out to be exactly the interface a language model needs. The model is not given database access; it is given a list of questions it can ask, and structured answers. It cannot invent a query, cannot change anything, and cannot reach data that was not exposed to it.
Named queries are safe but not universal. A question with no prepared query behind it does not get answered and a human has to add one. That is a deliberate trade: less flexibility in exchange for certainty that nobody reaches where they should not.
Result
The layer runs in production with recorded sources and checksums of generated artefacts, so it is always traceable where a specific number came from.