Publishing Services
Use the @Publish decorator to expose any TypeScript class as a remote service. The namespace you pass to @Publish combined with the class name forms the service identifier that callers use to reach it.
Basic Example
import { Publish, Version } from '@kinotic-ai/core'
@Version('1.0.0')
@Publish('com.example')
class GreetingService {
hello(name: string): string {
return `Hello, ${name}!`
}
add(a: number, b: number): number {
return a + b
}
}
This registers the service as com.example.GreetingService at version 1.0.0. Every public method on the class becomes a remotely callable operation.
Decorators
@Publish(namespace)
Marks a class for publication. The full service identifier becomes namespace.ClassName.
@Version(version)
Sets the semantic version for the service in X.Y.Z format. Callers can pin to a specific version when resolving the service.
@Scope
A property decorator that designates a field as the scope identifier. Scope narrows which service instance handles a request, which is useful for multi-tenant or per-device services.
import { Publish, Scope } from '@kinotic-ai/core'
@Publish('com.example')
class DeviceService {
@Scope
deviceId: string
constructor(deviceId: string) {
this.deviceId = deviceId
}
getStatus(): string {
return `Status for device ${this.deviceId}`
}
}
When a caller targets a specific scope (e.g., device-42), the platform routes the request to the instance whose deviceId matches.
@Context()
A parameter decorator that injects the request context into a method. The context carries information about the caller, such as the authenticated participant.
import { Publish, Context } from '@kinotic-ai/core'
@Publish('com.example')
class AuditService {
logAction(action: string, @Context() ctx: any): void {
console.log(`${ctx.participant.id} performed ${action}`)
}
}
The @Context() parameter is invisible to callers. They do not pass it as an argument; the platform injects it automatically.
@AbacPolicy(expression)
Enforces attribute-based access control before the method is invoked. The expression can reference properties of the caller (participant) and the method arguments. Multiple @AbacPolicy decorators on the same method are combined with AND semantics -- all policies must pass.
import { Publish, AbacPolicy } from '@kinotic-ai/core'
@Publish('com.example')
class OrderService {
@AbacPolicy("participant.roles contains 'finance' and order.amount < 50000")
placeOrder(order: Order): void {
// Only reached if caller has 'finance' role AND order under 50k
}
}
If any policy expression evaluates to false, the platform rejects the call before it reaches the service.