create-event-handlers — RabbitMQ event publishers create-event-handlers, castiel2, community, RabbitMQ event publishers, ide skills, tenant-only context, event naming convention, create-event-handlers install, Claude Code, Cursor, Windsurf

v1.0.0
GitHub

About this Skill

Perfect for Event-Driven Architecture Agents needing RabbitMQ event publishers and consumers integration. create-event-handlers is a skill that sets up RabbitMQ event publishers and consumers, following a specific event naming convention and tenant-only context.

Features

Sets up RabbitMQ event publishers and consumers following ModuleImplementationGuide.md Section 9
Follows a specific event naming convention: {domain}.{entity}.{action}
Supports tenant-only context using tenantId
Excludes organizationId from event payloads and createBaseEvent
Adheres to guidelines outlined in ModuleImplementationGuide.md Section 9.1
Generates events in the format of user.created, auth.login.success, and notification.email.sent

# Core Topics

Edgame2 Edgame2
[0]
[0]
Updated: 3/8/2026

Agent Capability Analysis

The create-event-handlers skill by Edgame2 is an open-source community AI agent skill for Claude Code and other IDE workflows, helping agents execute tasks with better context, repeatability, and domain-specific guidance. Optimized for RabbitMQ event publishers, tenant-only context, event naming convention.

Ideal Agent Persona

Perfect for Event-Driven Architecture Agents needing RabbitMQ event publishers and consumers integration.

Core Value

Empowers agents to handle events with tenant-only context using RabbitMQ, following the ModuleImplementationGuide.md Section 9, and adhering to a strict event naming convention format: {domain}.{entity}.{action}, enabling seamless interaction with event-driven systems via RabbitMQ event publishers and consumers.

Capabilities Granted for create-event-handlers

Setting up RabbitMQ event publishers for tenant-specific events
Creating event consumers for handling actions like user.created or auth.login.success
Implementing event-driven architectures with tenant-only context

! Prerequisites & Limits

  • Requires RabbitMQ setup and configuration
  • Adheres to specific event naming convention
  • Tenant-only context, excluding organizationId
Labs Demo

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

create-event-handlers

Discover how to set up RabbitMQ event publishers and consumers with create-event-handlers. Learn the best practices for event naming conventions and...

SKILL.md
Readonly

Create Event Handlers

Sets up RabbitMQ event publishers and consumers following ModuleImplementationGuide.md Section 9.

Tenant-only: Events use tenantId only for tenant context. Do not include organizationId in event payloads or in createBaseEvent; use tenantId only.

Event Naming Convention

Reference: ModuleImplementationGuide.md Section 9.1

Format: {domain}.{entity}.{action}

Correct:

  • user.created
  • auth.login.success
  • notification.email.sent
  • secret.rotated

Wrong:

  • userCreated
  • loginSuccess
  • emailSent

Standard Actions:

  • created, updated, deleted
  • started, completed, failed
  • sent, received, expired, rotated

Event Structure

Reference: ModuleImplementationGuide.md Section 9.2

typescript
1interface DomainEvent<T = unknown> { 2 // Identity 3 id: string; // Unique event ID (UUID) 4 type: string; // Event type (domain.entity.action) 5 6 // Metadata 7 timestamp: string; // ISO 8601 8 version: string; // Event schema version 9 source: string; // Module that emitted 10 correlationId?: string; // Request correlation 11 12 // Context 13 tenantId: string; // Tenant context (required; all users and data are scoped by tenant) 14 userId?: string; // Actor 15 16 // Payload 17 data: T; // Event-specific data 18}

Event Publisher

Reference: containers/auth/src/events/publishers/AuthEventPublisher.ts

src/events/publishers/[Module]EventPublisher.ts

typescript
1import { randomUUID } from 'crypto'; 2import { EventPublisher, getChannel, closeConnection } from '@coder/shared'; 3import { log } from '../../utils/logger'; 4import { getConfig } from '../../config'; 5 6let publisher: EventPublisher | null = null; 7 8export async function initializeEventPublisher(): Promise<void> { 9 if (publisher) return; 10 11 const config = getConfig(); 12 if (!config.rabbitmq?.url) { 13 log.warn('RabbitMQ URL not configured, events will not be published'); 14 return; 15 } 16 17 try { 18 await getChannel(); 19 publisher = new EventPublisher(config.rabbitmq.exchange || 'coder_events'); 20 log.info('Event publisher initialized', { exchange: config.rabbitmq.exchange }); 21 } catch (error: any) { 22 log.error('Failed to initialize event publisher', error); 23 } 24} 25 26export async function closeEventPublisher(): Promise<void> { 27 try { 28 await closeConnection(); 29 publisher = null; 30 } catch (error: any) { 31 log.error('Error closing event publisher', error); 32 } 33} 34 35function getPublisher(): EventPublisher | null { 36 if (!publisher) { 37 const config = getConfig(); 38 publisher = new EventPublisher(config.rabbitmq.exchange || 'coder_events'); 39 } 40 return publisher; 41} 42 43export function createBaseEvent( 44 type: string, 45 userId?: string, 46 tenantId?: string, 47 correlationId?: string, 48 data?: any 49) { 50 return { 51 id: randomUUID(), 52 type, 53 timestamp: new Date().toISOString(), 54 version: '1.0', 55 source: '[module-name]', 56 correlationId, 57 tenantId, 58 userId, 59 data: data || {}, 60 }; 61} 62 63export async function publishEvent(event: any, routingKey?: string): Promise<void> { 64 const pub = getPublisher(); 65 if (!pub) { 66 log.warn('Event publisher not initialized, skipping event', { type: event.type }); 67 return; 68 } 69 70 try { 71 await pub.publish(routingKey || event.type, event); 72 log.debug('Event published', { type: event.type, id: event.id }); 73 } catch (error: any) { 74 log.error('Failed to publish event', error, { type: event.type }); 75 } 76}

Usage in Services

typescript
1import { publishEvent, createBaseEvent } from '../events/publishers/ModuleEventPublisher'; 2 3// Publish event (tenantId for tenant context) 4const event = createBaseEvent( 5 'resource.created', 6 userId, 7 tenantId, 8 correlationId, 9 { 10 resourceId: resource.id, 11 name: resource.name, 12 } 13); 14 15await publishEvent(event);

Event Consumer

Reference: ModuleImplementationGuide.md Section 9.4

src/events/consumers/[Resource]Consumer.ts

typescript
1import { EventConsumer } from '@coder/shared'; 2import { log } from '../../utils/logger'; 3import { getConfig } from '../../config'; 4 5let consumer: EventConsumer | null = null; 6 7export async function initializeEventConsumer(): Promise<void> { 8 if (consumer) return; 9 10 const config = getConfig(); 11 if (!config.rabbitmq?.url) { 12 log.warn('RabbitMQ URL not configured, events will not be consumed'); 13 return; 14 } 15 16 try { 17 consumer = new EventConsumer({ 18 queue: config.rabbitmq.queue || '[module-name]_service', 19 exchange: config.rabbitmq.exchange || 'coder_events', 20 bindings: config.rabbitmq.bindings || [], 21 }); 22 23 // Register handlers 24 consumer.on('other.resource.created', handleResourceCreated); 25 consumer.on('other.resource.updated', handleResourceUpdated); 26 27 await consumer.start(); 28 log.info('Event consumer initialized', { queue: config.rabbitmq.queue }); 29 } catch (error: any) { 30 log.error('Failed to initialize event consumer', error); 31 } 32} 33 34async function handleResourceCreated(event: any): Promise<void> { 35 log.info('Resource created event received', { resourceId: event.data.resourceId }); 36 // Handle the event 37} 38 39async function handleResourceUpdated(event: any): Promise<void> { 40 log.info('Resource updated event received', { resourceId: event.data.resourceId }); 41 // Handle the event 42} 43 44export async function closeEventConsumer(): Promise<void> { 45 try { 46 if (consumer) { 47 await consumer.stop(); 48 consumer = null; 49 } 50 } catch (error: any) { 51 log.error('Error closing event consumer', error); 52 } 53}

Event Documentation

Reference: ModuleImplementationGuide.md Section 9.5

logs-events.md (if events are logged)

Create in module root if module publishes events that get logged:

markdown
1# [Module Name] - Logs Events 2 3## Published Events 4 5### {domain}.{entity}.{action} 6 7**Description**: When this event is triggered. 8 9**Triggered When**: 10- Condition 1 11- Condition 2 12 13**Event Type**: `{domain}.{entity}.{action}` 14 15**Event Schema**: 16 17\`\`\`json 18{ 19 "$schema": "http://json-schema.org/draft-07/schema#", 20 "type": "object", 21 "required": ["id", "type", "timestamp", "version", "source", "data"], 22 "properties": { 23 "id": { "type": "string", "format": "uuid" }, 24 "type": { "type": "string" }, 25 "timestamp": { "type": "string", "format": "date-time" }, 26 "version": { "type": "string" }, 27 "source": { "type": "string" }, 28 "tenantId": { "type": "string", "format": "uuid" }, 29 "userId": { "type": "string", "format": "uuid" }, 30 "data": { 31 "type": "object", 32 "properties": { 33 "resourceId": { "type": "string" } 34 } 35 } 36 } 37} 38\`\`\`

notifications-events.md (if events trigger notifications)

Create in module root if module publishes events that trigger notifications.

Configuration

Add to config/default.yaml:

yaml
1rabbitmq: 2 url: ${RABBITMQ_URL} 3 exchange: coder_events 4 queue: [module-name]_service 5 bindings: 6 - "other.resource.created" 7 - "other.resource.updated"

Checklist

  • Event publisher created following pattern
  • Event consumer created (if consuming events)
  • Events follow naming convention: {domain}.{entity}.{action}
  • Events include all required fields (id, type, version, timestamp, source, data)
  • Events include tenantId when applicable (tenantId only; no organizationId in events)
  • RabbitMQ only; no Azure Service Bus
  • logs-events.md created (if events are logged)
  • notifications-events.md created (if events trigger notifications)
  • RabbitMQ config added to default.yaml

FAQ & Installation Steps

These questions and steps mirror the structured data on this page for better search understanding.

? Frequently Asked Questions

What is create-event-handlers?

Perfect for Event-Driven Architecture Agents needing RabbitMQ event publishers and consumers integration. create-event-handlers is a skill that sets up RabbitMQ event publishers and consumers, following a specific event naming convention and tenant-only context.

How do I install create-event-handlers?

Run the command: npx killer-skills add Edgame2/castiel2. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.

What are the use cases for create-event-handlers?

Key use cases include: Setting up RabbitMQ event publishers for tenant-specific events, Creating event consumers for handling actions like user.created or auth.login.success, Implementing event-driven architectures with tenant-only context.

Which IDEs are compatible with create-event-handlers?

This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.

Are there any limitations for create-event-handlers?

Requires RabbitMQ setup and configuration. Adheres to specific event naming convention. Tenant-only context, excluding organizationId.

How To Install

  1. 1. Open your terminal

    Open the terminal or command line in your project directory.

  2. 2. Run the install command

    Run: npx killer-skills add Edgame2/castiel2. The CLI will automatically detect your IDE or AI agent and configure the skill.

  3. 3. Start using the skill

    The skill is now active. Your AI agent can use create-event-handlers immediately in the current project.

Related Skills

Looking for an alternative to create-event-handlers or another community skill for your workflow? Explore these related open-source skills.

View All

widget-generator

Logo of f
f

f.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete privacy.

149.6k
0
AI

flags

Logo of vercel
vercel

flags is a Next.js feature management skill that enables developers to efficiently add or modify framework feature flags, streamlining React application development.

138.4k
0
Browser

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
AI

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
AI