At Decasonic, 35+ apps and 350+ AI agents write into one shared Postgres schema through a gateway I built. The gateway checks keys, permissions and rate limits, logs every request and translates raw database errors into messages an app can act on. By every operational metric it was healthy.
And yet the views that depended on that data, like an action portal answering “what signals are about this company?”, came back thin or empty. The requests were arriving. The data was not doing its job.
Success codes measure delivery, not meaning
A 200 tells you the request was accepted. It says nothing about whether the row is linked to anything, whether a junction table was written, or whether the value in a UUID column is a UUID. When most of your write code is generated by AI builders, those are exactly the things that drift.
Five ways a successful write goes wrong
- Casing against CHECK constraints. About 400 failures, nearly all of them
'prod'sent where the schema expects'PROD'. - Plausible but wrong column names. About 30 failures from generated code guessing a name that sounds right.
- Missing junction writes. Zero rows in every junction table, so nothing could answer which signals belong to which company.
- Missing foreign keys. The agent on execution logs was filled on 0 of 1,021 rows. Contacts were linked to a company on 0 of 57.
- Bad types.
'test-123'and'[object Object]'shipped as UUIDs.
Fix it once, where it starts
The gateway onboards new apps by generating their integration code from the schema. When the very first integration hit foreign-key violations, the cause was the generator: it wasn’t passing relationship information into the prompt. I fixed it there, once, and every integration after it inherited the fix.
For the apps already live, I wrote a standard four-section fix prompt for each app and closed permission gaps in four of them.
Regressions happen on redeploy
The audit was not a one-time cleanup. One app lost 11 of its 15 table integrations in a single redeploy, and its writes still came back 200. Data health needs checking after every deploy, the same way tests do.
What I would do from day one
- Measure meaning, not status: foreign-key fill rates, junction row counts, and type validity per app.
- Enforce enums and casing at the gateway, and return an error that names the allowed values.
- Generate clients from a schema contract that carries human-written descriptions, so code knows a status column is a deal stage, not just a string.
- Run the health check after every redeploy, not once a quarter.
A gateway 200 tells you the request arrived. Only the data tells you whether it was worth sending.
Saad Al-Tamari