Interfaces
This document provides a comprehensive reference of all TypeScript interfaces used in the MBC CQRS Serverless framework.
Core Interfaces
Command Interfaces
CommandInputModel
The primary interface for creating new commands. Used when publishing new entities.
export interface CommandInputModel {
pk: string // Partition key (e.g., "ORDER#tenant001")
sk: string // Sort key with version (e.g., "ORDER#ORD001#v0")
id: string // Unique identifier (e.g., UUID)
code: string // Business code (e.g., "ORD001")
name: string // Display name
version: number // Version number for optimistic locking
tenantCode: string // Tenant identifier
type: string // Entity type (e.g., "ORDER")
isDeleted?: boolean // Soft delete flag
seq?: number // Sequence number (auto-generated)
ttl?: number // Time-to-live timestamp (Unix epoch)
attributes?: Record<string, any> // Custom domain attributes
}
Usage Example:
const orderInput: CommandInputModel = {
pk: 'ORDER#tenant001',
sk: 'ORDER#ORD001#v0',
id: crypto.randomUUID(),
code: 'ORD001',
name: 'Customer Order',
version: 1,
tenantCode: 'tenant001',
type: 'ORDER',
attributes: {
customerId: 'CUST001',
totalAmount: 1500,
status: 'pending',
},
};
CommandPartialInputModel
Used for partial updates. Only pk, sk, and version are required.
export interface CommandPartialInputModel extends Partial<CommandInputModel> {
pk: string // Required: Partition key
sk: string // Required: Sort key
version: number // Required: Current version for optimistic locking
}
Usage Example:
const partialUpdate: CommandPartialInputModel = {
pk: 'ORDER#tenant001',
sk: 'ORDER#ORD001',
version: 2, // Must match current version
name: 'Updated Order Name',
attributes: {
status: 'confirmed',
},
};
ICommandOptions
Options passed to command publishing methods.
export interface ICommandOptions {
source?: string // Source identifier for tracking
requestId?: string // Request ID for tracing
invokeContext: IInvoke // Required: Invocation context
}
Usage Example:
const options: ICommandOptions = {
source: 'order-service',
requestId: context.awsRequestId,
invokeContext: {
userContext: getUserContext(event),
tenantCode: 'tenant001',
},
};
Key Interfaces
DetailKey
Represents the primary key for DynamoDB items.
export interface DetailKey {
pk: string // Partition key
sk: string // Sort key
}
SearchKey
Extended key interface for search operations with optional tenant filtering.
export interface SearchKey extends DetailKey {
tenantCode?: string // Optional tenant filter
}
Context Interfaces
IInvoke
Invocation context containing Lambda/Express event and context.
export interface IInvoke {
event?: IInvokeEvent // Request event (headers, requestContext, etc.)
context?: IInvokeContext // Lambda context (requestId, functionName, etc.)
}
UserContext
User context class extracted from authentication token.
export class UserContext {
userId: string // Cognito user ID (from JWT sub claim)
tenantRole: string // User's role within the tenant
tenantCode: string // Current tenant code
}
Usage Example:
import { getUserContext, IInvoke } from '@mbc-cqrs-serverless/core';
// Extract user context from IInvoke or ExecutionContext
const userContext = getUserContext(invokeContext);
console.log(userContext.userId); // '92ca4f68-9ac6-4080-9ae2-2f02a86206a4'
console.log(userContext.tenantCode); // 'tenant001'
console.log(userContext.tenantRole); // 'admin'
Data Interfaces
Entity Interfaces
IDataEntity
Base interface for data entities (read model).
export interface IDataEntity {
pk: string
sk: string
id: string
code: string
name: string
version: number
tenantCode: string
type: string
isDeleted: boolean
createdAt: string // ISO 8601 timestamp
createdBy: string // User ID
createdIp?: string // Client IP
updatedAt: string // ISO 8601 timestamp
updatedBy: string // User ID
updatedIp?: string // Client IP
attributes?: Record<string, any>
}
ICommandEntity
Interface for command entities (write model).
export interface ICommandEntity extends IDataEntity {
cpk: string // Command partition key
csk: string // Command sort key (includes version)
seq: number // Sequence number
}
List Response Interfaces
DataListEntity
Paginated list response for data queries.
export class DataListEntity {
items: DataEntity[] // Array of entities
total?: number // Total count (if available)
lastSk?: string // Pagination cursor (last sort key)
}
Usage Example:
const result = await dataService.listItemsByPk('ORDER#tenant001', {
limit: 20,
startFromSk: previousLastSk,
});
// Pagination
if (result.lastSk) {
// More items available - use result.lastSk for next page
}
Service Interfaces
Query Options
ListOptions
Options for list queries.
export interface ListOptions {
limit?: number // Maximum items to return
scanIndexForward?: boolean // Sort order (true = ascending)
startFromSk?: string // Pagination cursor (start from this sort key)
filter?: FilterExpression // Additional filters
}
SearchOptions
Options for search operations with full-text search.
export interface SearchOptions extends ListOptions {
query?: string // Full-text search query
fields?: string[] // Fields to search
sort?: SortOptions // Sort configuration
}
Sync Handler Interfaces
IDataSyncHandler
Interface for implementing data synchronization handlers. Handles both forward (up) and rollback (down) operations.
export interface IDataSyncHandler<TExecuteResult = any, TRollbackResult = any> {
readonly type?: string // Optional type identifier
/**
* Upgrade/sync data when a command is executed
*/
up(cmd: CommandModel): Promise<TExecuteResult>
/**
* Rollback/undo data when a command needs to be reverted
*/
down(cmd: CommandModel): Promise<TRollbackResult>
}
Implementation Example:
@Injectable()
export class OrderRdsSyncHandler implements IDataSyncHandler {
readonly type = 'ORDER';
constructor(private readonly prisma: PrismaService) {}
async up(cmd: CommandModel): Promise<void> {
if (cmd.isDeleted) {
await this.prisma.order.delete({
where: { id: cmd.id },
});
} else {
await this.prisma.order.upsert({
where: { id: cmd.id },
create: this.toRdsModel(cmd),
update: this.toRdsModel(cmd),
});
}
}
async down(cmd: CommandModel): Promise<void> {
// Rollback logic - restore previous state
await this.prisma.order.delete({
where: { id: cmd.id },
});
}
private toRdsModel(cmd: CommandModel) {
return {
id: cmd.id,
code: cmd.code,
name: cmd.name,
...cmd.attributes,
};
}
}
Notification Interfaces
EmailNotification
Configuration for sending email notifications.
export interface EmailNotification {
fromAddr?: string // Sender address (uses default if not specified)
toAddrs: string[] // Required: Recipient addresses
ccAddrs?: string[] // CC addresses
bccAddrs?: string[] // BCC addresses
subject: string // Required: Email subject
body: string // Required: HTML body content
replyToAddrs?: string[] // Reply-to addresses
attachments?: Attachment[] // File attachments
}
export interface Attachment {
filename: string // Attachment filename
content: Buffer // File content as Buffer
contentType?: string // MIME type (e.g., 'application/pdf')
}
Usage Example:
await emailService.sendEmail({
toAddrs: ['user@example.com'],
subject: 'Order Confirmation',
body: `<h1>Order Confirmed</h1><p>Your order ${orderCode} has been confirmed.</p>`,
});
Module Configuration Interfaces
CommandModuleOptions
Configuration options for CommandModule.
export interface CommandModuleOptions {
tableName: string // DynamoDB table name
dataSyncHandlers?: Type<IDataSyncHandler>[] // Custom sync handlers
skipError?: boolean // Skip errors from previous command versions
disableDefaultHandler?: boolean // Disable the default data sync handler
}
Usage Example:
@Module({
imports: [
CommandModule.register({
tableName: 'order',
dataSyncHandlers: [OrderRdsSyncHandler],
disableDefaultHandler: false,
}),
],
})
export class OrderModule {}
SequencesModuleOptions
Configuration options for SequenceModule.
export interface SequencesModuleOptions {
enableController?: boolean // Enable or disable default sequence controller
}
Event Interfaces
StepFunctionEvent
Event structure from AWS Step Functions.
export interface StepFunctionEvent {
taskToken: string // Step Functions callback token
input: Record<string, any> // Input data from state machine
executionId: string // State machine execution ID
}
S3Event
S3 event structure for file processing.
export interface S3EventRecord {
s3: {
bucket: { name: string }
object: { key: string; size: number }
}
eventName: string // e.g., "ObjectCreated:Put"
}
Error Interfaces
AppException
Base exception interface for application errors.
export interface AppException {
statusCode: number // HTTP status code
message: string // Error message
code?: string // Error code for client handling
details?: any // Additional error details
}
Type Utilities
Common Type Helpers
// Partial type that requires specific keys
type RequiredPick<T, K extends keyof T> = Partial<T> & Pick<T, K>;
// Deep partial type
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
// Entity without audit fields
type EntityInput<T> = Omit<T, 'createdAt' | 'createdBy' | 'updatedAt' | 'updatedBy'>;
See Also
- Command Service - Using commands with these interfaces
- Data Service - Querying data with these interfaces
- Entity Patterns - Designing entities
- Error Catalog - Error handling