Agent Skills: create-event-schema Skill

|

UncategorizedID: semicolon-devteam/semo/create-event-schema

Install this agent skill to your local

pnpm dlx add-skill https://github.com/semicolon-devteam/semo/tree/HEAD/semo-system/semo-skills/create-event-schema

Skill Files

Browse the full folder contents for create-event-schema.

Download Skill

Loading file tree…

semo-system/semo-skills/create-event-schema/SKILL.md

Skill Metadata

Name
create-event-schema
Description
|

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)
});

Reference