Skip to main content

Models

Models define your data entities. Each JSON file in config/models/ is one model.

Basic example

config/models/User.json
{
"name": "User",
"fields": {
"email": "string",
"name": "string",
"createdAt": "date_now"
}
}

id is always implicit — it's generated as a UUID.

Field types

The TypeScript type is always the same regardless of ORM or database. The generated ORM column type depends on the chosen ORM and database.

TypeTypeScriptDrizzle — SQLiteDrizzle — PostgreSQLDrizzle — MySQLPrisma (all databases)Notes
stringstringtexttextvarchar(255)String
numbernumberintegerintegerintInt
booleanbooleaninteger (0/1)booleanbooleanBoolean
dateDateinteger (epoch ms)timestamptimestampDateTime
date_nowDateinteger + .now()timestamp + .now()timestamp + .now()DateTime @default(now())Auto-set on create
uuidstringtext + randomUUID()uuid + .defaultRandom()varchar(36) + randomUUID()String @default(uuid())Auto-generated UUID
ModelNameModelNameFK text / integer columnFK uuid columnFK varchar(36) columnFK relationReferences another model

Full field definition

You can use a shorthand string or a full field object:

{
"name": "Article",
"fields": {
"title": "string",
"body": {
"type": "string",
"required": false
},
"published": {
"type": "boolean",
"default": false
},
"authorId": {
"type": "string",
"unique": false
}
}
}

Relations

{
"name": "Article",
"fields": {
"author": {
"type": "User",
"relation": {
"model": "User",
"type": "one-to-many"
}
}
}
}

Relation generation

When you declare a relation, Codabra automatically generates both sides of the relation. For example:

config/models/Article.json
{
"name": "Article",
"fields": {
"title": "string",
"author": {
"type": "User",
"relation": { "model": "User", "type": "one-to-many" }
}
}
}
src/drizzle/schema.ts
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";

export const articles = sqliteTable("articles", {
id: text("id")
.primaryKey()
.$defaultFn(() => crypto.randomUUID()),
title: text("title").notNull(),
authorId: text("authorId"), // FK to users
});

export const users = sqliteTable("users", {
id: text("id")
.primaryKey()
.$defaultFn(() => crypto.randomUUID()),
email: text("email").notNull(),
name: text("name").notNull(),
createdAt: integer("createdAt")
.$defaultFn(() => Date.now())
.notNull(),
});

Supported relation types: one-to-one, one-to-many, many-to-many.

Generated output

For each model Codabra generates:

  • apps/web/src/types/<ModelName>.ts — TypeScript interface (with relation imports)
  • ORM schema file (aggregated, all models):
    • Drizzle: apps/web/drizzle/schema.ts
    • Prisma: apps/web/prisma/schema.prisma
  • ORM client singleton:
    • Drizzle: apps/web/src/lib/db.ts
    • Prisma: apps/web/src/lib/prisma.ts