Building block · Database
A serverless, typed database, reachable over one API.
Declare a schema in one place (fields, validation, indexing) and get a validated, versioned data store immediately. No cluster to provision, no capacity to plan for.
The alternative
What you'd otherwise build.
A serverless database on its own isn't new. What usually comes with it is a second set of problems.
- Provision it yourself. Stand up DynamoDB, Firestore, or Postgres, and plan capacity before you know your real load.
- Hand-write validation. Every field, every type, every required check, in application code instead of a declaration.
- Build your own concurrency handling. Optimistic locking, version numbers, conflict detection: normally a library you bolt on, not something the store gives you.
- Wire up your own indexes. Exact, range, and prefix lookups, each one a separate thing to configure and keep working as fields change.
- Hand-write authorization checks. A permission check in every handler or service method: the actual enforcement, not just a note in a schema doc. Multiply by every new caller you add.
- Build an audit trail from scratch. Track who changed what and when, protect the history from tampering, and add read-access logging yourself if you ever need to show who saw something, not just who changed it.
What's actually different
One file declares what it looks like, and who can touch it.
Search is a schema property
Full-text, semantic, hybrid, or none: declared with your fields, not bolted on after. See the search building block for the mode details.
Scales like a managed store should
No capacity to provision or replan as you grow. Steady performance from a thousand records to many millions, continuously backed up in production.
schemas:
- typeName: task
indexMode: HYBRID # HYBRID | SEMANTIC | TEXT | NONE
fields:
- { fieldId: title, fieldType: string, required: true, searchable: true }
- { fieldId: status, fieldType: string, required: true }
lookupFields: [status]
accessProfile:
# least privilege is the authoring default: no records:d unless you ask
allowedActions: [records:r, records:c, records:u, search:r]The schema and the access profile sit in the same declaration. There's nothing else to cross-reference to know what a caller can do with this data. In a blueprint, accessProfile grants the blueprint's own service-principal key directly (or via roleIds referencing a declared role); assigning a role to an arbitrary principal later is a separate call, covered on the access-control page.
Isolate your own clients, orgs, or anything else
Give a caller access to exactly one client, one org, or any other axis your product needs. It can never read or write outside that boundary, no matter what the call itself says: leave the scope off and the request is rejected outright, not silently widened. Org and client are two reserved names, registered the same way as anything else you define.
// clientId is the id of a client entity you already created.
const { token } = await client.auth.mintToken({
scope: {
allowedActions: ['records:r', 'records:c'],
dataScope: { 'scope:client': [clientId] },
},
});
const scoped = new VectrosClient({ token, environment: 'production' });
// Every read through it must name that same boundary, or it's rejected outright:
const theirRecords = await scoped.records.listRecords({
type: 'case_note',
scope: 'client:' + clientId,
});
// A write through it must state ownership too, or it's refused the same way:
await scoped.records.createRecord({
body: {
typeName: 'case_note',
payload: { summary: 'Intake call, follow-up scheduled' },
scopes: ['client:' + clientId],
},
});See the full access-control mechanics: roles, credentials, audit →
See it in a real app
Fork the RAVV reference app.
The only reference app that ships with a real front end. Its blueprint declares the schema and the access profile side by side, the same shape as the example above, running against production-grade data.
Read: the RAVV stack →Declare it once, and it's validated, versioned, access-controlled, and exactly as searchable as you told it to be. This is one of five building blocks Vectros is built from.
See how it all fits together on the platform page.