create-event-schema Skill
π μμ€ν λ©μμ§: μ΄ Skillμ΄ νΈμΆλλ©΄ EventEnvelope μΈν°νμ΄μ€μ Zod μ€ν€λ§λ₯Ό μμ±ν©λλ€.
μ΄λ²€νΈ μ€ν€λ§ TypeScript νμ μμ±
Usage
skill:create-event-schema
Input
| νλΌλ―Έν° | νμ | μ€λͺ | |----------|------|------| | eventType | β | μ΄λ²€νΈ νμ (μ: job.failed) | | service | β | λ°μ μλΉμ€λͺ | | dataFields | β | νμ΄λ‘λ νλ μ μ |
Output
types/events/{domain}.event.ts
import { z } from 'zod';
// Event Envelope Base
export const EventMetadataSchema = z.object({
eventId: z.string().uuid(),
service: z.string(),
type: z.string(),
severity: z.enum(['info', 'warning', 'error', 'critical']),
occurredAt: z.string().datetime()
});
export const EventContextSchema = z.object({
env: z.enum(['development', 'staging', 'production']),
tenantId: z.string().optional(),
traceId: z.string().optional(),
resource: z.object({
type: z.string(),
id: z.string()
}).optional()
});
export const NotificationPolicySchema = z.object({
throttle: z.object({
maxPerHour: z.number(),
maxPerDay: z.number()
}).optional(),
retry: z.object({
maxAttempts: z.number(),
backoffMs: z.number()
}).optional()
});
export const EventNotificationSchema = z.object({
channels: z.array(z.string()),
targets: z.array(z.string()),
template: z.string().optional(),
policy: NotificationPolicySchema.optional()
});
// Service-Specific Event
export const {EventName}DataSchema = z.object({
// Define your payload fields here
{dataFields}
});
export const {EventName}EventSchema = z.object({
metadata: EventMetadataSchema,
context: EventContextSchema,
data: {EventName}DataSchema,
notification: EventNotificationSchema
});
// Type Exports
export type EventMetadata = z.infer<typeof EventMetadataSchema>;
export type EventContext = z.infer<typeof EventContextSchema>;
export type EventNotification = z.infer<typeof EventNotificationSchema>;
export type {EventName}Data = z.infer<typeof {EventName}DataSchema>;
export type {EventName}Event = z.infer<typeof {EventName}EventSchema>;
utils/event-factory.ts
import { v4 as uuidv4 } from 'uuid';
import type { EventMetadata, EventContext, EventNotification } from '../types/events';
interface CreateEventOptions<T> {
type: string;
service: string;
severity: EventMetadata['severity'];
data: T;
channels?: string[];
targets?: string[];
}
export function createEvent<T extends Record<string, unknown>>(
options: CreateEventOptions<T>
) {
const { type, service, severity, data, channels = ['slack'], targets = [] } = options;
return {
metadata: {
eventId: uuidv4(),
service,
type,
severity,
occurredAt: new Date().toISOString()
},
context: {
env: process.env.NODE_ENV as EventContext['env'] ?? 'development'
},
data,
notification: {
channels,
targets
}
};
}
Example
// μ¬μ© μμ
import { createEvent } from './utils/event-factory';
import type { JobFailedData } from './types/events/job.event';
const event = createEvent<JobFailedData>({
type: 'job.failed',
service: 'scheduler',
severity: 'error',
data: {
jobId: 'job-123',
jobName: 'daily-report',
error: 'Connection timeout'
},
channels: ['slack'],
targets: ['#_νμ
']
});
// ms-notifierλ‘ μ μ‘
await fetch('http://ms-notifier/api/events', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(event)
});