Decorators Reference
Entity Decorators
These decorators are imported from @kinotic-ai/persistence.
@Entity(multiTenancyType?, entityType?)
Marks a class as a Kinotic entity. Required for any class that should be persisted and managed by the entity service system.
import { Entity, MultiTenancyType, EntityType } from '@kinotic-ai/persistence'
@Entity()
export class Product {
// ...
}
@Entity(MultiTenancyType.SHARED)
export class TenantProduct {
// ...
}
@Entity(MultiTenancyType.NONE, EntityType.DATA_STREAM)
export class SensorReading {
// ...
}
Parameters:
multiTenancyType—MultiTenancyType.NONE(default),MultiTenancyType.SHARED, orMultiTenancyType.DEDICATEDentityType—EntityType.TABLE(default) orEntityType.DATA_STREAM
@EntityServiceDecorators(config)
Configures per-operation decorators for the entity service. Used to apply ABAC policies, role checks, or other decorators to specific CRUD operations.
import { Entity, EntityServiceDecorators, $AbacPolicy } from '@kinotic-ai/persistence'
@EntityServiceDecorators({
allRead: [
$AbacPolicy("entity.ownerId == participant.id")
],
allDelete: [
$AbacPolicy("participant.roles contains 'admin'")
]
})
@Entity()
export class Document {
// ...
}
Operation groups: allCreate, allRead, allUpdate, allDelete
Individual operations: save, bulkSave, findById, findByIds, findAll, search, count, countByQuery, update, bulkUpdate, deleteById, deleteByQuery
ID Decorators
@AutoGeneratedId
Marks a field as a server-generated ID. The field type must be string | null since the ID is null before the entity is saved.
import { Entity, AutoGeneratedId } from '@kinotic-ai/persistence'
@Entity()
export class Product {
@AutoGeneratedId
id: string | null = null
}
@Id
Marks a field as a manually-assigned ID. The field type is string since the caller is responsible for providing the value.
import { Entity, Id } from '@kinotic-ai/persistence'
@Entity()
export class Product {
@Id
sku: string = ''
}
Field Decorators
@NotNull
Marks a field as required. The persistence layer will reject entities where this field is missing or null.
import { Entity, AutoGeneratedId, NotNull } from '@kinotic-ai/persistence'
@Entity()
export class Product {
@AutoGeneratedId
id: string | null = null
@NotNull
name: string = ''
}
@Text
Enables full-text search indexing on a string field. By default, string fields are indexed as keywords (exact match only). Adding @Text enables tokenized search.
import { Entity, AutoGeneratedId, Text } from '@kinotic-ai/persistence'
@Entity()
export class Article {
@AutoGeneratedId
id: string | null = null
@Text
body: string = ''
}
@Precision(PrecisionType)
Sets the numeric precision for a number field. Controls how the value is stored in Elasticsearch.
import { Entity, AutoGeneratedId, Precision, PrecisionType } from '@kinotic-ai/persistence'
@Entity()
export class Measurement {
@AutoGeneratedId
id: string | null = null
@Precision(PrecisionType.DOUBLE)
value: number = 0
@Precision(PrecisionType.LONG)
timestamp: number = 0
}
Precision types: PrecisionType.INT, PrecisionType.SHORT, PrecisionType.LONG, PrecisionType.FLOAT, PrecisionType.DOUBLE
@NotIndexed
Excludes a field from Elasticsearch indexing. The field is still stored and returned in queries, but cannot be searched or filtered on.
import { Entity, AutoGeneratedId, NotIndexed } from '@kinotic-ai/persistence'
@Entity()
export class Document {
@AutoGeneratedId
id: string | null = null
@NotIndexed
rawData: string = ''
}
@Flattened
Uses Elasticsearch flattened mapping for an object field. All values in the object are indexed as keywords, enabling filtering without the overhead of dynamic field mappings.
import { Entity, AutoGeneratedId, Flattened } from '@kinotic-ai/persistence'
@Entity()
export class Event {
@AutoGeneratedId
id: string | null = null
@Flattened
metadata: Record<string, string> = {}
}
@Nested
Uses Elasticsearch nested mapping for an array of objects. Preserves the relationship between fields within each object, enabling accurate queries across object boundaries.
import { Entity, AutoGeneratedId, Nested } from '@kinotic-ai/persistence'
@Entity()
export class Order {
@AutoGeneratedId
id: string | null = null
@Nested
lineItems: LineItem[] = []
}
Relationship
@Discriminator(propertyName)
Marks a field as a polymorphic type discriminator. Used when a field can contain different types and the system needs to determine the concrete type during deserialization.
import { Entity, AutoGeneratedId, Discriminator } from '@kinotic-ai/persistence'
@Entity()
export class Notification {
@AutoGeneratedId
id: string | null = null
@Discriminator('type')
payload: EmailPayload | SmsPayload | null = null
}
Parameters:
propertyName— The name of the property within the object that identifies its type
Multi-tenancy
@TenantId
Marks a field as the tenant identifier. Used with MultiTenancyType.SHARED entities to partition data by tenant.
import { Entity, AutoGeneratedId, TenantId, MultiTenancyType } from '@kinotic-ai/persistence'
@Entity(MultiTenancyType.SHARED)
export class Invoice {
@AutoGeneratedId
id: string | null = null
@TenantId
tenantId: string = ''
}
Versioning
@Version
Enables optimistic locking for the entity. The field type must be string | null. The persistence layer uses this field to detect concurrent modifications.
import { Entity, AutoGeneratedId, Version } from '@kinotic-ai/persistence'
@Entity()
export class Product {
@AutoGeneratedId
id: string | null = null
@Version
version: string | null = null
name: string = ''
}
Time Series
@TimeReference
Marks a field as the time reference for data stream entities. Used with EntityType.DATA_STREAM to identify the timestamp field.
import { Entity, AutoGeneratedId, TimeReference, EntityType } from '@kinotic-ai/persistence'
@Entity(undefined, EntityType.DATA_STREAM)
export class SensorReading {
@AutoGeneratedId
id: string | null = null
@TimeReference
timestamp: Date = new Date()
value: number = 0
}
Query
@Query(statement)
Defines a named query on an entity service method. The statement uses the Kinotic query syntax.
import { Entity, AutoGeneratedId, Query } from '@kinotic-ai/persistence'
@Entity()
export class Product {
@AutoGeneratedId
id: string | null = null
name: string = ''
category: string = ''
@Query("category == ?0")
static findByCategory: (category: string) => Promise<Product[]>
}
Entity Service Policy Decorators
These factory functions create decorator instances for use within @EntityServiceDecorators. They are imported from @kinotic-ai/persistence.
$AbacPolicy(expression)
Creates an ABAC policy decorator for entity operations. The expression uses the ABAC expression language.
import { $AbacPolicy } from '@kinotic-ai/persistence'
$AbacPolicy("entity.ownerId == participant.id")
$AbacPolicy("participant.roles contains 'admin'")
$Policy(policies)
Creates a policy decorator with a matrix of policy rules.
import { $Policy } from '@kinotic-ai/persistence'
$Policy([['admin', 'editor'], ['manager']])
$Role(roles)
Creates a role-based access decorator for entity operations.
import { $Role } from '@kinotic-ai/persistence'
$Role(['admin', 'editor'])
Service Decorators
These decorators are imported from @kinotic-ai/core.
@Publish(namespace, name?)
Publishes a class as a remotely accessible service. The service becomes available to clients via the RPC gateway.
import { Publish } from '@kinotic-ai/core'
@Publish('com.example')
class UserService {
async findUser(id: string): Promise<User> {
// ...
}
}
@Publish('com.example', 'CustomName')
class MyService {
// Published as com.example.CustomName
}
Parameters:
namespace— The service namespace (e.g.,'com.example')name— Optional custom service name. Defaults to the class name.
@Version(version)
Sets the semantic version for a published service. Enables versioned service routing.
import { Publish, Version } from '@kinotic-ai/core'
@Publish('com.example')
@Version('2.0.0')
class UserService {
// ...
}
@Scope
Marks a property as the scope for service routing. Used for multi-tenant service resolution.
import { Publish, Scope } from '@kinotic-ai/core'
@Publish('com.example')
class TenantService {
@Scope
tenantId: string = ''
}
@Context()
Injects request context into a method parameter. The parameter receives metadata about the current request.
import { Publish, Context } from '@kinotic-ai/core'
@Publish('com.example')
class AuditService {
async logAction(action: string, @Context() context: any): Promise<void> {
// context contains request metadata
}
}
@AbacPolicy(expression)
Enforces an ABAC policy on a published service method. The policy is evaluated at the gateway before the method is invoked.
import { Publish, AbacPolicy } from '@kinotic-ai/core'
@Publish('com.example')
class AdminService {
@AbacPolicy("participant.roles contains 'admin'")
async deleteAllData(): Promise<void> {
// Only reachable by callers with the 'admin' role
}
}
See Access Control for detailed policy documentation.