Skip to content

feat(backend): generate typed SQL queries with bun-sqlgen - #204

Merged
ilbertt merged 5 commits into
mainfrom
feat/adopt-bun-sqlgen
Jun 25, 2026
Merged

feat(backend): generate typed SQL queries with bun-sqlgen#204
ilbertt merged 5 commits into
mainfrom
feat/adopt-bun-sqlgen

Conversation

@ilbertt

@ilbertt ilbertt commented Jun 24, 2026

Copy link
Copy Markdown
Member

Adopt @ilbertt/bun-sqlgen (v0.2.0) to type Bun.sql query results straight from the migrations, replacing hand-written Pick<> row shapes.

  • db/client.ts wraps the connection in withTypes(); the base Repository holds a TypedSQL.
  • Repositories tag queries by name (this.sql.ListApiKeys`...`) and pull row types from the generated QueryResults (queries.gen.d.ts).
  • sqlgen.config.ts (via defineConfig) strips the ParadeDB bm25 indexes the throwaway introspection DB can't run.
  • Migration 0015 documents the uuidv7-derived created_at columns with @notNull so they're typed non-nullable.
  • generate / check:sql-codegen scripts run the codegen; check:types gates on it being up to date.

🤖 Generated with Claude Code

ilbertt and others added 2 commits June 24, 2026 18:43
Adopt @ilbertt/bun-sqlgen to type Bun.sql query results against the
migrations. The base Repository now holds a TypedSQL, repositories tag
queries by name (this.sql.ListApiKeys`...`) and derive row types from the
generated QueryResults instead of hand-written Pick<> shapes.

sqlgen.config.ts strips the ParadeDB bm25 indexes the throwaway
introspection DB can't run, and migration 0015 adds @NotNull comments for
the uuidv7-derived created_at columns. The generate/check:sql-codegen
scripts run the codegen, and check:types gates on it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e ignore

The generated queries.gen.d.ts augments @ilbertt/bun-sqlgen's QueryResults
and TypedSQL via module augmentation, but it was only in the backend's own
tsconfig program. Packages that consume the Eden `App` type (backend-client,
dashboard, cli) compiled the repositories without the augmentation, so the
named query tags (this.sql.ListApiKeys, QueryResults['ListApiKeys'], …) did
not resolve and check:types failed there.

Reference the generated file from the public type entry (types.ts) so the
augmentation travels with `App` across the package boundary. Also ignore
*.gen.d.ts in Biome — the existing **/*.gen.ts override doesn't match the
.gen.d.ts suffix, so the generated output tripped codestyle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ilbertt
ilbertt marked this pull request as draft June 24, 2026 17:31
ilbertt and others added 3 commits June 25, 2026 14:51
bun-sqlgen now owns query result types, so the hand-maintained row mirror in
src/db/tables.ts is redundant. Source row types from QueryResults instead, tagging
the previously-generic search/get queries (SelectKnowledge, SearchKnowledgeFull,
SearchKnowledgePreview, GetRecord, SearchRecords) and annotating their json and
generated columns (@type / @NotNull). Query inputs become plain primitives;
created_by keeps its AuthUserId alias via a direct import. Bumps to @ilbertt/bun-sqlgen
^0.2.1 (deterministic output + exported result interfaces) and updates AGENTS.md to
describe the codegen workflow in place of the tables.ts convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ript

- Tag the transaction-internal queries (InsertKnowledge, KnowledgeExists,
  DeleteKnowledge, KnowledgeTypeExists, SelectExistingPeople/RecordIds,
  ReassignPersonDataSources/Records) so their row types are generated and
  verified instead of hand-asserted. The records ingest INSERT stays hand-typed:
  its dynamic CTE reads nango_records, which isn't in the introspection schema.
- Replace the four duplicated `@type participants Array<{…}>` literals with a
  single exported `Participant` type referenced via `import('#…')` — single
  source of truth, resolves across the package boundary (incl. the nango bundle).
- Rename `generate`/`check:sql-codegen` to `codegen:sql`/`codegen:sql:check` for
  clarity alongside the other codegens; update check:types and AGENTS.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
participant.ts sat loose among the *.repository.ts files. Its only consumer is
the generated db/queries.gen.d.ts, and it's a DB row-projection shape (where
tables.ts used to live), so db/types.ts is its natural home — and it keeps the
dependency flowing repositories → db instead of the generated db file importing
up into repositories. Matches the repo's `types.ts`-per-folder convention.
@ilbertt
ilbertt marked this pull request as ready for review June 25, 2026 13:41
@ilbertt
ilbertt merged commit 5b7905f into main Jun 25, 2026
5 checks passed
@ilbertt
ilbertt deleted the feat/adopt-bun-sqlgen branch June 25, 2026 13:41
ilbertt added a commit that referenced this pull request Jun 26, 2026
…205)

Bumps `@ilbertt/bun-sqlgen` to `^0.3.0`, which lets `withTypes` take the
query registry explicitly. The backend now types its client as
`TypedSQL<Queries>` and reads row types from the generated `Queries`
interface imported from `#db/queries.gen.d.ts`.

This drops the `/// <reference path="./db/queries.gen.d.ts" />` in
`backend/src/types.ts`. That reference existed only to drag the global
`QueryResults` module augmentation across the package boundary into the
consumers of the Eden `App` type (cli, dashboard), which compile the
repositories without otherwise pulling in the augmenting `.gen.d.ts`.
With the registry threaded through an ordinary `import type { Queries }`
edge, those row types now resolve in every consumer with no reference
directive.

Follow-up to #204. `check:all` and the full test suite pass across all
workspaces, including the cross-package consumers that previously needed
the reference.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant