Reference

SQL database

The managed relational database every Remy app ships with: typed tables, queries, batching, aggregates, and raw SQL.
import { db } from '@mindstudio-ai/agent';

Every Remy app ships with its own relational database, and the platform operates all of it. It is isolated per app, migrated on deploy, backed up continuously, and live from the first push. There are no connection strings to manage and no backups to schedule; that work belongs to the platform. What the SDK hands you is the set of verbs an app uses to read and write its data.

That set is complete but deliberately bounded. Because you do not operate this database yourself, the SDK gives you only what an app actually does to its own data: create, read, update, delete, aggregate, and an escape hatch to raw SQL for the rare query the typed API cannot express. The schema is the TypeScript interface you pass to db.defineTable, migrations are diffed and applied for you on deploy, and every row is typed the same from the table to the screen.

Two things shape how you write against it. First, every operation is a network round trip, not a local query, so the cost is round trips, not rows. db.batch collapses several reads and writes into one call, running the writes in order so later reads observe them. Prefer one batched call, or a query shaped to return exactly what a screen needs, over a loop that awaits each row. Second, a db.filter predicate compiles to a SQL WHERE clause, but only when every value it compares against is the row itself or a literal. When it references an input, the current user, or a foreign key gathered earlier, pass that through the bindings argument so the comparison runs in the database instead of pulling the table into memory.

Relationships are a modeling decision you make up front. Embed related data in a JSON column when it is always read and written with its parent; give it its own table, resolved with a second read, only when it is queried independently or grows without bound. There are no JOINs across tables; the SDK reads one table at a time. Every row also carries id, created_at, updated_at, and last_updated_by automatically, so you never declare or set them.

Product page
Data Model & Database
Typed, code-defined SQL, isolated per tenant and backed up.
goremy.ai/features/data-model
(opens goremy.ai in a new tab)
39 entries
Methods 34
db.filter
Return all rows matching a predicate. Use the bindings form so the predicate compiles to SQL instead of scanning every row.
db.aggregate
Grouped SQL aggregates (count/sum/avg/min/max/countDistinct) without fetching rows.
db.ago
A timestamp a given duration before now.
db.avg
Average a numeric column across matching rows, in SQL.
db.batch
Combine multiple reads and writes into a single round trip. Writes run in order; reads observe prior writes.
db.clear
Delete all rows in the table. Returns the count removed.
db.count
Count rows, optionally matching a predicate, as a SQL COUNT.
db.countDistinct
Count the distinct values of a column, in SQL.
db.days
n days expressed in milliseconds.
db.defineTable
Declare a typed table. The TypeScript interface is the schema: add a field and the column exists on next deploy.
db.every
Resolves to true if every row matches the predicate. Returns a Promise, not a Query, so it does not batch.
db.findOne
Return the first row matching a predicate, or null.
db.fromNow
A timestamp a given duration after now.
db.get
Fetch one row by id, or null when nothing matches.
db.groupBy
Group full rows by a key into a Map. Fetches every row.
db.hours
n hours expressed in milliseconds.
db.isEmpty
Resolves to true if the table holds no rows. Returns a Promise, not a Query, so it does not batch.
db.max
The full row holding the largest value of a column.
db.min
The full row holding the smallest value of a column.
db.minutes
n minutes expressed in milliseconds.
db.now
The current time as unix epoch milliseconds.
db.push
Insert one row or many. Returns the full row(s) with id and timestamps.
db.remove
Delete one row by id. Reports whether a row was removed.
db.removeAll
Delete every row matching a predicate, in one DELETE. Returns the count.
db.reverse
Flip a query's ordering to descending.
db.skip
Skip the first n rows (SQL OFFSET). Pairs with `take` for paging.
db.some
Resolves to true if any row matches the predicate.
db.sortBy
Order a query by a column. Chain `reverse` for descending.
db.sql
Read-only raw SQL escape hatch for joins, subqueries, and window functions the typed API can’t express.
db.sum
Total a numeric column across matching rows, in SQL.
db.take
Limit a query to the first n rows (SQL LIMIT).
db.toArray
Read every row in the table.
db.update
Update a row by id and return the updated row. Bumps updated_at automatically.
db.upsert
Insert or update on a declared unique constraint using SQLite ON CONFLICT.
Types 5