Skip to content

Add entities data layer (Base44-parity) - #1

Merged
7 commits merged into
mainfrom
entities-layer
Jul 16, 2026
Merged

7 commits merged into
mainfrom
entities-layer

Conversation

@HomemadeToast57

@HomemadeToast57 HomemadeToast57 commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

What

bool.entities.<table> — a data API over the gateway that mirrors Base44's entity surface one-to-one, so generated apps read/write data without ever touching Supabase, SQL, or credentials (and without needing a raw-SQL escape hatch).

const todos = await bool.entities.todos.list("-created_at", 20, 0, ["id","title"]);
await bool.entities.todos.create({ title: "hi" });
await bool.entities.todos.filter({ status: "active", count: { $gte: 10 }, $or: [{a:1},{b:2}] });
await bool.entities.todos.updateMany({ done: false }, { $set: { done: true } });
await bool.entities.todos.deleteMany({ archived: true });
await bool.entities.todos.importEntities(csvFile);

Op parity with Base44: list / filter / get (with sort/limit/skip/fields), create / bulkCreate / update / bulkUpdate / updateMany / delete / deleteMany, importEntities, subscribe. Return types match Base44 (DeleteResult/DeleteManyResult/UpdateManyResult/ImportResult).

Filter DSL: MongoDB-style $eq $ne $gt $gte $lt $lte $in $nin $exists $regex $all $not per field + $and/$or/$nor at the root + array shorthand + null → IS NULL. Maps to PostgREST through supabase-js.

Design notes:

  • Returns rows directly and throws on error (not {data,error}) — keeps app code plumbing-free, like Base44.
  • Dynamic Proxy keyed by table name — no per-entity codegen/files.
  • importEntities parses CSV client-sidebulkCreate — no new gateway endpoint / attack surface.
  • Additive & backward-compatible: bool.db / supabase / auth unchanged.

Known gaps (documented): updateMany $inc/$mul/$push/$pull is read-modify-write (not atomic under concurrent writers — RPC follow-up); $size omitted (not expressible over PostgREST).

Tests

Drive the entities layer through the real supabase-js builder and assert the PostgREST request produced (path, filter/sort/pagination/fields query params, bulk/upsert method+headers, read-modify-write $inc round-trip, CSV parse). 39 tests pass; typecheck + build clean.

Version / channel

0.2.0 surface, published to the next (canary) dist-tag as 0.2.0-next.1 for testing (production latest stays 0.1.1). Promote to latest once verified in a canary app.

🤖 Generated with Claude Code

HomemadeToast57 and others added 4 commits July 15, 2026 12:55
A Base44-style CRUD API over the gateway client so generated apps read/write
data without touching Supabase, SQL, or credentials:

  bool.entities.<table>.{list,filter,get,create,update,delete,subscribe}

- Dynamic Proxy keyed by table name; returns rows directly, throws on error.
- filter() maps scalar/null/array/operator queries to PostgREST; sort is a
  '-col' string; list/filter paginate via limit+offset.
- Additive and backward-compatible: bool.db / supabase / auth unchanged.
- Tests assert the real supabase-js -> PostgREST translation through the
  gateway (URL + query params), not a mocked builder.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rs, CSV import); v0.2.0-next.1

Brings bool.entities to one-to-one with Base44's entity surface so apps never
need a raw-SQL escape hatch:
- Methods: + bulkCreate, bulkUpdate (upsert), updateMany, deleteMany,
  importEntities (client-side CSV parse -> bulkCreate), + fields selection on
  list/filter. Base44-shaped return types (DeleteResult/UpdateManyResult/...).
- Filter DSL switched to Base44's MongoDB-style $-operators: $eq $ne $gt
  $gte $lt $lte $in $nin $exists $regex $all $not + root $and/$or/$nor.
- updateMany $set = one atomic PATCH; $inc/$mul/$push/$pull = read-modify-write
  (documented non-atomic; RPC follow-up). $size omitted (not expressible over
  PostgREST). importEntities parses CSV client-side — no gateway endpoint needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@HomemadeToast57 HomemadeToast57 changed the title Add entities data layer (bool.entities.X) Add entities data layer (Base44-parity) Jul 15, 2026
HomemadeToast57 and others added 3 commits July 15, 2026 14:28
…lback to RMW); v0.2.0-next.2

$inc/$mul now select target ids then call the per-schema bool_apply_numeric
function so the arithmetic is atomic in SQL. Falls back to read-modify-write on
PGRST202 (function not provisioned), so it's safe on any schema. $set/$unset
stay a single atomic PATCH; $push/$pull remain read-modify-write (documented).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…verage; v0.2.0-next.3

$nor was producing garbage (or=not.(...).undefined). Reimplemented via De
Morgan — NOR = AND of negated conditions — which is valid PostgREST. Caught by
adding a test that asserts the actual query string.

Test coverage expanded to 51 tests: $not, $nor, $and, $size-ignored, +sort,
limit cap, $mul RPC, $unset PATCH, mixed $set+$inc, $push/$pull
read-modify-write, plus the existing read/write/bulk/filter/import paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tities)

Change the EntitiesModule map from a `type` alias to an `interface` with a
string index signature, so a generated app can augment it per-entity via
`declare module "bool-sdk"` and get typed bool.entities.<name> (field names,
enum unions, value types) — caught at the app's `tsc -b` build. The index
signature keeps un-declared tables usable as EntityHandler<any>, so the
un-augmented SDK is unchanged. Runtime untouched.

v0.2.0-next.4 (canary).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@max-bader max-bader closed this pull request by merging all changes into main in f82df8f Jul 16, 2026
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.

2 participants