Records
SemitraRecord is the D1-backed model layer.
It keeps persistence, queries, associations, lifecycle hooks, and attachment behavior inside one runtime-aware abstraction.
Example record
Section titled “Example record”import { s } from "@semitra/cli";import ApplicationRecord from "./application_record.ts";
export default class Post extends ApplicationRecord { static table = "posts";
static schema = s.object({ title: s.string().min(3), content: s.string().optional() });
static { this.hasOneAttached("cover"); }}The example app sets these application defaults:
import { SemitraRecord } from "@semitra/cli";
export default class ApplicationRecord extends SemitraRecord { static database = "DB"; static tenancy = "tenant";}What records provide
Section titled “What records provide”- schema-backed attributes
- CRUD helpers
- query chaining
- associations
- validations
- lifecycle hooks
- attachment helpers
- tenant-aware context
Query shape
Section titled “Query shape”Common record entry points include:
all()find(id)findBy(criteria)where(criteria)whereIn(attribute, values)orderBy({ createdAt: "desc" })limit(count)includes("association")
Semitra prefers structured ordering over raw SQL string order clauses.
A typical request-time record flow looks like this:
const Posts = this.model(Post);
const recentPosts = await Posts.all() .orderBy({ createdAt: "desc" }) .limit(10);
const post = Posts.build({ title: input.post.title, content: input.post.content});
if (await post.save()) { await post.attachment("cover").attach(coverBytes, { filename: "cover.png", contentType: "image/png" });}That keeps D1 persistence, validation, and attachment ownership in the record layer while still using storage for the binary body.
Hooks and side effects
Section titled “Hooks and side effects”Records support lifecycle hooks such as:
beforeValidateafterValidatebeforeSaveafterSavebeforeCreateafterCreatebeforeUpdateafterUpdatebeforeDestroyafterDestroyafterCommit
Jobs can also be dispatched from record events when side effects belong to the state transition itself.
Attachments
Section titled “Attachments”Attachments are part of the record layer but backed by storage adapters.
Semitra supports:
- named attachments
- metadata persistence
- tenant-aware storage prefixes
- object access through
SemitraStorage
This keeps upload semantics close to the record that owns the file, while still leaving storage concerns in the storage subsystem.