Skip to content

Annotations Reference

Experimental

The DB integrations layer is experimental. APIs and annotations described in this section may change in future releases.

Complete reference for all @db.* annotations available in .as files. Generic annotations are provided by @atscript/db/plugin via dbPlugin() and work with every adapter. Adapter-specific annotations (PostgreSQL, MySQL, MongoDB) require the corresponding adapter plugin.

Tables & Columns

AnnotationApplies ToArgumentsDescription
@db.tableInterfacename? (string)Mark as database table (defaults to interface name)
@db.table.renamedInterfaceoldName (string)Previous table name for schema sync migration
@db.schemaInterfacename (string)Assign to a database schema/namespace
@db.columnFieldname (string)Override the physical column name
@db.column.renamedFieldoldName (string)Previous column name for schema sync migration
@db.column.collateFieldcollation (string)Portable collation: 'binary', 'nocase', or 'unicode'
@db.column.precisionFieldprecision (number), scale (number)Decimal precision/scale for DB storage (e.g., DECIMAL(10,2))
@db.column.dimensionFieldMark as dimension field — groupable in aggregate queries
@db.column.measureFieldMark as measure field — aggregatable (sum, avg, count, min, max). Numeric/decimal only
@db.jsonFieldStore as a single JSON column instead of flattening
@db.ignoreFieldExclude field from the database schema entirely
atscript
@db.table 'users'
@db.schema 'auth'
interface User {
  @db.column 'full_name'
  name: string

  @db.json
  preferences: Preferences

  @db.ignore
  computedField: string

  @db.column.collate 'nocase'
  username: string

  @db.column.precision 10, 2
  price: number
}

Defaults

AnnotationApplies ToArgumentsDescription
@db.defaultFieldvalue (string)Static default value
@db.default.incrementFieldstart? (number)Auto-incrementing integer (requires number type)
@db.default.uuidFieldRandom UUID string (requires string type)
@db.default.nowFieldCurrent timestamp (requires number or string type)
atscript
@db.table
interface Product {
  @meta.id
  @db.default.uuid
  id: string

  @db.default 'untitled'
  name: string

  @db.default.now
  createdAt: number
}

Indexes

AnnotationApplies ToArgumentsDescription
@db.index.plainFieldname? (string), sort? (string)Standard index, optional sort direction ('asc'/'desc')
@db.index.uniqueFieldname? (string)Unique constraint index
@db.index.fulltextFieldname? (string), weight? (number)Full-text search index with optional weight

Use the same index name on multiple fields to create a composite index.

atscript
@db.table
interface Article {
  @db.index.unique
  slug: string

  @db.index.plain 'date_idx', 'desc'
  publishedAt: number

  // Composite index across two fields
  @db.index.plain 'author_cat'
  authorId: string

  @db.index.plain 'author_cat'
  category: string

  @db.index.fulltext 'search', 3
  title: string

  @db.index.fulltext 'search', 1
  body: string
}
AnnotationApplies ToArgumentsDescription
@db.search.vectorFielddimensions (number), similarity? (string), indexName? (string)Vector search field
@db.search.vector.thresholdFieldvalue (number)Default minimum similarity threshold (0--1)
@db.search.filterFieldindexName (string)Pre-filter field for vector search

Similarity options: 'cosine' (default), 'euclidean', 'dotProduct'. Each adapter maps to its native vector type — see Text Search and Vector Search.

atscript
@db.table
interface Document {
  @db.search.vector 1536, 'cosine', 'doc_vec'
  @db.search.vector.threshold 0.7
  embedding: db.vector

  @db.search.filter 'doc_vec'
  category: string
}

Relations

AnnotationApplies ToArgumentsDescription
@db.rel.FKFieldalias? (string)Foreign key (field must use chain ref)
@db.rel.toFieldalias? (string)Forward navigation (N:1, FK on this table)
@db.rel.fromFieldalias? (string)Reverse navigation (1:N, FK on other table)
@db.rel.viaFieldjunction (ref)Many-to-many navigation through a junction table
@db.rel.onDeleteFieldaction (string)Referential action on parent delete
@db.rel.onUpdateFieldaction (string)Referential action on parent update
@db.rel.filterFieldcondition (expr)Static filter condition on navigation property
atscript
@db.table
interface Task {
  @db.rel.FK
  @db.rel.onDelete 'cascade'
  projectId: Project.id

  @db.rel.to
  project: Project

  @db.rel.from
  comments: Comment[]

  @db.rel.via TaskTag
  tags: Tag[]

  @db.rel.from
  @db.rel.filter `status = 'open'`
  openSubtasks: Task[]
}

Referential Action Values

For @db.rel.onDelete and @db.rel.onUpdate:

ActionDescription
'cascade'Propagate delete/update to related rows
'restrict'Prevent operation if related rows exist
'noAction'Database default behavior (no action)
'setNull'Set FK to null (field must be optional)
'setDefault'Set FK to default value (needs @db.default)

Views

AnnotationApplies ToArgumentsDescription
@db.viewInterfacename? (string)Mark as database view (defaults to interface name)
@db.view.forInterfaceentry (ref)Entry/primary table for a managed view
@db.view.joinsInterfacetarget (ref), condition (expr)Explicit join clause (repeatable)
@db.view.filterInterfacecondition (expr)View WHERE clause
@db.view.havingInterfacecondition (expr)Post-aggregation HAVING clause
@db.view.materializedInterfaceMark the view as materialized
@db.view.renamedInterfaceoldName (string)Previous view name for schema sync migration
atscript
@db.view
@db.view.for Task
@db.view.joins Project, `Project.id = Task.projectId`
@db.view.filter `Task.status = 'active'`
interface ActiveTaskView {
  taskName: Task.name
  projectName: Project.name
  dueDate: Task.dueDate
}

Aggregation

AnnotationApplies ToArgumentsDescription
@db.agg.sumFieldfield (string)SUM of a source column (numeric/decimal only)
@db.agg.avgFieldfield (string)AVG of a source column (numeric/decimal only)
@db.agg.countFieldfield? (string)COUNT — omit argument for COUNT(*), provide field name for non-null count
@db.agg.minFieldfield (string)MIN of a source column
@db.agg.maxFieldfield (string)MAX of a source column

Use aggregation annotations on view fields together with @db.column.dimension on grouping fields.

atscript
@db.view
@db.view.for Order
@db.view.having `totalRevenue > 100`
interface CategoryStats {
  @db.column.dimension
  category: Order.category

  @db.agg.sum 'amount'
  totalRevenue: number

  @db.agg.count
  orderCount: number

  @db.agg.avg 'amount'
  avgOrderValue: number
}

Schema Sync

AnnotationApplies ToArgumentsDescription
@db.sync.methodInterfacemethod (string)Sync strategy: 'drop' or 'recreate'
  • 'drop' — Drop and recreate the table on structural changes (lossy, data is deleted).
  • 'recreate' — Recreate with data preservation on structural changes.

Patch Behavior

AnnotationApplies ToArgumentsDescription
@db.patch.strategyFieldstrategy (string)'replace' (default) or 'merge'

Controls how nested objects are handled during PATCH/update operations. With 'replace', the entire nested object is overwritten. With 'merge', individual sub-fields are deep-merged.

PostgreSQL-Specific

These annotations require the @atscript/db-postgres plugin. See PostgreSQL adapter.

AnnotationApplies ToArgumentsDescription
@db.pg.typeFieldtype (string)Override native PG column type (e.g., CITEXT, INET, MACADDR)
@db.pg.schemaInterfaceschema (string)PostgreSQL schema (default: public)
@db.pg.collateInterface / Fieldcollation (string)Native PG collation (overrides portable @db.column.collate)
atscript
use '@atscript/db-postgres'

@db.table 'users'
@db.pg.schema 'auth'
interface User {
  @meta.id
  @db.default.uuid
  id: string

  @db.pg.type 'CITEXT'
  email: string

  @db.pg.collate 'tr-x-icu'
  name: string
}

MySQL-Specific

These annotations require the @atscript/db-mysql plugin. See MySQL adapter.

AnnotationApplies ToArgumentsDescription
@db.mysql.engineInterfaceengine (string)Storage engine (default: InnoDB)
@db.mysql.charsetInterface / Fieldcharset (string)Character set (default: utf8mb4)
@db.mysql.collateInterface / Fieldcollation (string)Native MySQL collation (overrides portable @db.column.collate)
@db.mysql.unsignedFieldUNSIGNED modifier for integer columns
@db.mysql.typeFieldtype (string)Override native MySQL column type (e.g., MEDIUMTEXT, TINYTEXT)
@db.mysql.onUpdateFieldexpression (string)ON UPDATE expression (e.g., CURRENT_TIMESTAMP)
atscript
use '@atscript/db-mysql'

@db.table 'events'
@db.mysql.engine 'InnoDB'
@db.mysql.charset 'utf8mb4'
interface Event {
  @meta.id
  @db.default.increment
  id: number

  @db.mysql.type 'MEDIUMTEXT'
  description: string

  @db.mysql.unsigned
  viewCount: number

  @db.default.now
  @db.mysql.onUpdate 'CURRENT_TIMESTAMP'
  updatedAt: number
}

MongoDB-Specific

These annotations require the @atscript/db-mongo plugin. See MongoDB adapter.

AnnotationApplies ToArgumentsDescription
@db.mongo.collectionInterfaceMark as MongoDB collection (auto-injects _id)
@db.mongo.cappedInterfacesize (number), max? (number)Capped collection with max byte size and optional doc limit
@db.mongo.search.dynamicInterfaceanalyzer? (string), fuzzy? (number)Dynamic Atlas Search index
@db.mongo.search.staticInterfaceanalyzer? (string), fuzzy? (number), indexName? (string)Named static Atlas Search index
@db.mongo.search.textFieldanalyzer? (string), indexName? (string)Include field in a search index
atscript
use '@atscript/db-mongo'

@db.table 'products'
@db.mongo.collection
@db.mongo.search.static 'lucene.english', 1, 'main_search'
interface Product {
  @meta.id
  _id: mongo.objectId

  @db.mongo.search.text 'lucene.english', 'main_search'
  name: string

  @db.search.vector 1536, 'cosine', 'vec_idx'
  embedding: number[]

  @db.search.filter 'vec_idx'
  category: string
}

Generic search annotations

@db.search.vector and @db.search.filter are generic annotations (not MongoDB-specific) and work across all adapters that support vector search. See the Search section above.

These are not @db.* annotations but are commonly used alongside the database layer.

AnnotationApplies ToArgumentsDescription
@meta.idFieldMark as primary key field (multiple fields form a composite key)
@expect.array.keyFieldArray element key field for patch matching
@expect.array.uniqueItemsFieldEnforce unique items in an array
atscript
@db.table
interface OrderLine {
  // Composite primary key
  @meta.id
  orderId: Order.id

  @meta.id
  productId: Product.id

  quantity: number
}

Released under the MIT License.