Skip to main content

10 posts tagged with "typescript"

View All Tags

Direct Data API or Governed Business Query API? Supabase and TeaQL Solve Different Boundaries

· 10 min read
Philip Z
Architect

Supabase gives applications a direct Data API. TeaQL gives applications and AI agents a governed business query API.

The two ideas can produce a similar developer experience: a frontend composes a query instead of waiting for a backend team to add one more endpoint. But they place the public boundary at different layers of the system.

Supabase reflects a PostgreSQL schema into an API. TeaQL exposes capabilities from a shared business model and lets a trusted runtime decide how those capabilities are executed. That difference becomes important when an application has complex authorization, several backend languages, multiple data sources, or AI agents that need composition without database authority.

Build a Safe SQL Agent Without Giving the Model SQL Access

· 8 min read
TeaQL Team
Core Team

The fastest way to connect an AI agent to application data is often a generic SQL tool. Give the model a schema, accept a SQL string, run it, and return the rows.

That is also where a prototype can quietly become a production security and maintenance problem.

The model must understand physical table names, joins, nullable columns, tenant boundaries, authorization rules, and mutation policy. Database details become part of the prompt contract. A schema change can invalidate that contract, and a broadly capable SQL tool exposes much more authority than most business tasks require.

TeaQL takes a different approach:

Don't give your AI agent unrestricted SQL. Give it a typed business language.

The open-source @teaql/ai-sdk adapter converts an explicit allowlist of business capabilities into native Vercel AI SDK tools. The model sees operations such as findSchoolsMissingContact and updateSchoolContactPhone. The server keeps the TeaQL context, runtime resources, authorization state, credentials, and internal failures.

Who Are Active? Human and Non-human Predicates in Generated Query APIs

· 2 min read
TeaQL Team
Core Team

Generated query APIs contain language, not only identifiers. That makes a small grammatical choice part of the public contract.

For a collection of people, TeaQL uses whoAreActive(), not whoIsActive(). For an ordinary human attribute it uses whoseEmailIs(...). A non-human entity uses whichAreActive() and withCodeIs(...).

These forms sound related, but they solve different problems: whose expresses possession, while who are agrees with the plural result set.

Pluralization Is Not `name + s`: A Code Generator Maintenance Rule

· 2 min read
TeaQL Team
Core Team

One of the smallest code generator shortcuts creates one of the most persistent API defects:

plural = name + "s"

It works for order, which makes it look harmless. Then it produces order_statuss, categorys, persons, childs, and inventorys.

During TeaQL's six-language acceptance work, we found this assumption in Python and Go query templates and in a Rust diagnostic. The generated code compiled often enough for the mistake to survive until an entity ending in status exposed it.

252 Dynamic Queries Later: TeaQL's Six-Language Order Search Acceptance

· 3 min read
TeaQL Team
Core Team

On August 12 we published a persistence baseline across six TeaQL runtimes and a nine-database Java matrix. That was useful evidence, but it was not the complete Order Search Feature.

The next acceptance run closed that distinction. Java, Rust, Go, Python, .NET and TypeScript each executed the generated Order Search API against PostgreSQL, MySQL and SQLite: 18 of 18 core cells passed, representing 252 successful positive dynamic scenario executions.

Six Languages, One Query Meaning: Closing TeaQL API Parity Gaps

· 2 min read
TeaQL Team
Core Team

“Supports six languages” should mean more than producing six directories that compile. The same model must preserve the same query meaning, loaded-state behavior and governance boundaries in every generated API.

TeaQL recently used Java's generated Request API as the semantic reference and ran paired generation tests across Rust, Go, Python, .NET and TypeScript. The work exposed gaps that ordinary runtime unit tests had missed.

One Execution Argument: Why TeaQL Queries Receive Only UserContext

· 2 min read
TeaQL Team
Core Team

A generated TeaQL query has exactly one caller-supplied runtime dependency argument: UserContext.

await request.execute_for_list(ctx)

There is no second data-service, provider or connection argument. Those dependencies—together with tenant identity, authenticated user, permissions and policy—are installed when the trusted context is initialized and resolved from it during execution.

From ORM Claims to Executed Evidence: Six TeaQL Runtimes and a Nine-Database Java Matrix

· 4 min read
TeaQL Team
Core Team

TeaQL now has a dated, executed database baseline across six generated language runtimes: Java, Rust, Go, Python, C#/.NET, and TypeScript.

The headline result is Java's real nine-database matrix:

tests=9 failures=0 errors=0 skipped=0

The databases were PostgreSQL, MySQL, SQLite, Oracle, DB2, DM8 (Dameng), SAP HANA, SQL Server, and DuckDB.

That is meaningful only because these were not adapter-discovery tests. The generated domain APIs compiled and executed schema creation, graph persistence, reconnect queries, optimistic updates, and direct database checks.

TypeScript undefined Is Not a Query Plan

· 4 min read
Philip Z
Architect

TypeScript can describe optional data precisely at compile time, but JavaScript still has several runtime forms of absence: undefined, null, a missing object key, and an empty collection.

For database-backed models, a missing key has another possible meaning: the query did not select the field.

TeaQL's generated TypeScript E expressions preserve Value, Null, and NotLoaded so that undefined does not silently stand in for an incomplete query plan.