Why AI-generated software needs deterministic business APIs
AI coding tools can produce useful application code quickly. The problem is not speed. The problem is boundary control.
If an AI tool has to infer persistence behavior from scattered SQL, repositories, mapper XML, DTOs, and service conventions, it will eventually guess wrong.
TeaQL exists to make that boundary deterministic.
The Guessing Problem
When AI writes data-access code directly, it must infer:
- table names;
- column names;
- relation cardinality;
- tenant filters;
- permission rules;
- deleted-row semantics;
- transaction boundaries;
- pagination rules;
- response shape;
- database dialect differences.
Some of these guesses can pass a simple test and still be wrong in production.
The Business API Boundary
TeaQL generates APIs from the domain model. That means AI code can compose with named business methods instead of inventing storage behavior.
let orders = Q::orders()
.select_customer_with(Q::customers().select_name())
.select_line_item_list_with(Q::line_items().select_sku())
.which_statuses_are("PAID")
.page(1, 20)
.execute_for_list(&ctx)
.await?;
The model controls what fields and relations exist. The runtime controls how the query executes. The AI composes within those boundaries.
Deterministic Does Not Mean Rigid
A deterministic API can still be expressive:
- filters can be combined;
- relation loads can be nested;
- aggregates can be grouped;
- graph writes can save parent and child objects together;
- provider-specific behavior can be selected below the API.
The point is that the API surface is stable and reviewable.
Better Prompts
TeaQL also makes prompts smaller.
Instead of giving an AI tool the entire schema, SQL examples, repository conventions, and DTO rules, a team can provide a generated API guide:
Use TeaQL Q APIs for reads.
Use generated relation selectors.
Execute through UserContext.
Do not write raw SQL unless explicitly requested.
Use graph save for parent-child persistence.
That is a stronger contract than a long explanation of database structure.
Runtime Safety
The generated API is only half the story. Runtime boundaries matter too.
TeaQL keeps execution behind context and provider layers:
- Java uses
UserContextas the runtime boundary. - Rust uses
teaql_runtime::UserContext, repository registries, behavior hooks, and provider registration. - Database providers execute against PostgreSQL, MySQL, SQLite, rusqlite, or memory.
AI-generated application code should not own those decisions.
The Short Version
AI tools are fast at composition. They are unreliable at reconstructing business rules from infrastructure code.
TeaQL gives them deterministic business APIs to compose.
