包含 classes/exams/homework/grades/attendance/scheduling 域、outbox、iam-consumer、redis 配置等完整实现
62 lines
1.5 KiB
TypeScript
62 lines
1.5 KiB
TypeScript
import { randomUUID } from "node:crypto";
|
||
|
||
/**
|
||
* Outbox 事件构建器
|
||
*
|
||
* 所有事件 payload 必须包含(events.proto 仲裁 §2.1):
|
||
* - event_id: UUID(幂等消费)
|
||
* - occurred_at: 业务时间戳(ms epoch)
|
||
* - schema_version: 默认 "v1"
|
||
* - metadata: { traceId, userId }
|
||
*/
|
||
|
||
export interface EventMetadata {
|
||
schema_version: string;
|
||
trace_id: string;
|
||
user_id: string;
|
||
}
|
||
|
||
export interface OutboxEvent<T = Record<string, unknown>> {
|
||
event_id: string;
|
||
aggregate_id: string;
|
||
event_type: string;
|
||
occurred_at: number;
|
||
payload: T;
|
||
metadata: EventMetadata;
|
||
}
|
||
|
||
export interface BuildEventInput {
|
||
aggregateId: string;
|
||
eventType: string;
|
||
payload: Record<string, unknown>;
|
||
userId?: string;
|
||
traceId?: string;
|
||
schemaVersion?: string;
|
||
}
|
||
|
||
/**
|
||
* 构建标准 Outbox 事件(含 event_id / occurred_at / schema_version / metadata)。
|
||
* 返回的对象可直接 JSON.stringify 作为 outbox.payload 存储。
|
||
*/
|
||
export function buildEvent(input: BuildEventInput): OutboxEvent {
|
||
return {
|
||
event_id: randomUUID(),
|
||
aggregate_id: input.aggregateId,
|
||
event_type: input.eventType,
|
||
occurred_at: Date.now(),
|
||
payload: input.payload,
|
||
metadata: {
|
||
schema_version: input.schemaVersion ?? "v1",
|
||
trace_id: input.traceId ?? "unknown",
|
||
user_id: input.userId ?? "system",
|
||
},
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 将 OutboxEvent 序列化为 JSON 字符串(用于 outbox.payload 列)。
|
||
*/
|
||
export function serializeEvent(event: OutboxEvent): string {
|
||
return JSON.stringify(event);
|
||
}
|