Database
db.sb stores every record, Relationship and Event of a Startup, typed by its Nouns, with reads at any past moment and SQL analytics.
db.sb stores every Thing, Relationship and Event of a Startup, typed by its Nouns. It is the record: search, caches and files are projections rebuilt from it.
Read and write
Declaring a Noun gives it typed create, get, list, update and delete on every Interface. Every write runs as an Action attributed to its Worker. Leaseline declares a Lease Noun:
import { $ } from 'startup-builder'
const lease = await $.Lease.create({ unit: '4B', endsOn: '2027-01-31', rent: { amount: 1800, currency: 'USD' } })
const due = await $.Lease.list({ where: 'status = active and endsOn < 2027-03-01', sort: 'endsOn', limit: 50 })
const next = await $.Lease.list({ where: 'status = active', after: due.after })A list returns one page with a cursor and filters by any property or Relationship.
Relationships and find-or-create
A Relationship has a name from each end. Write it with Thing.relate, and read it from either side:
await $.Thing.relate({ thing: 'contact_7', predicate: 'rents', to: 'lease_1' })
const { thing, decision } = await $.Thing.resolve({ noun: 'contact', match: { email: 'ana@example.com' }, set: { name: 'Ana Costa' } })decision is found, created or held. Two matches write nothing and open a merge Task.
All or nothing
Writes inside one transaction commit together as one Action; a throw cancels every write in it.
await $.transaction(async (tx) => {
const lease = await tx.Lease.create({ unit: '4C', endsOn: '2027-06-30' })
await tx.Thing.relate({ thing: 'contact_9', predicate: 'rents', to: lease.$id })
})Past states and analytics
Nothing is overwritten. get with at returns a Thing as it stood, and @ does the same on the API: GET /leaseline.app/.
Every Action and Event also lands in an append-only analytics store, so a year of rows never slows a write:
npx startup-builder do Collection.query --json '{"query": "select date_trunc(month, endsOn) as month, count(*) from Lease group by month"}'Changing a Noun
A Noun changes only through a Change. Edit nouns/, and Change.review classifies the diff as additive or breaking.
A breaking Change opens a new Version, and pinned callers keep the old one. Rows that fail a type conversion are set aside, never dropped.
| Guarantee | Detail |
|---|---|
| Consistency | One writer per Startup; a read after a write sees it |
| Isolation | No query crosses Startups; each Customer's records sit in its Tenant |
| History | A delete hides a Thing and keeps its Events |
| Scale | About 1,000 writes a second per Startup; past that a Collection shards by key under the same ids |