event-management
End-to-end management for NABIP events, covering registration, capacity, check-in, and analytics.
Install
mkdir -p .claude/skills/event-management && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/19063" && unzip -o skill.zip -d .claude/skills/event-management && rm skill.zipInstalls to .claude/skills/event-management
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Guides event lifecycle implementation including registration, capacity management, waitlists, QR code check-in, virtual/hybrid events, and post-event analytics for NABIP conferences, webinars, workshops, and networking events. Use when building event creation workflows, attendee management, or event performance tracking.Key capabilities
- →Create event registration workflows
- →Implement capacity and waitlist management for events
- →Build QR code check-in systems for attendees
- →Design virtual and hybrid event support
- →Implement multi-tier pricing for events
- →Generate post-event analytics and feedback
How it works
This skill guides the implementation of event lifecycle management, from registration to post-event analytics, by defining states, data models, and workflows. It supports various NABIP event types.
Inputs & outputs
When to use event-management
- →Setting up event registration
- →Managing waitlists
- →Implementing QR code check-ins
- →Running post-event analytics
About this skill
Event Management
Streamline event operations to improve attendee experience and drive measurable outcomes across in-person, virtual, and hybrid NABIP events.
When to Use
Activate this skill when:
- Creating event registration workflows
- Implementing capacity and waitlist management
- Building QR code check-in systems
- Designing virtual/hybrid event support
- Creating multi-tier pricing (early bird, member, non-member)
- Implementing post-event analytics and feedback
- Working on event calendar and scheduling
- Building event communication workflows (confirmations, reminders)
Event Types
NABIP Event Categories
- Conferences: Multi-day, large-scale events (500+ attendees)
- Webinars: Online-only educational sessions (100-300 attendees)
- Workshops: Hands-on training sessions (25-75 attendees)
- Networking: Social and professional connection events (50-200 attendees)
- Chapter Meetings: Local/state gatherings (15-50 attendees)
Event Lifecycle States
draft → published → registration_open → registration_closed → in_progress → completed → archived
State Transition Rules
- draft → published: Event details finalized, ready for announcement
- published → registration_open: Registration portal activated
- registration_open → registration_closed: Registration deadline reached OR capacity filled
- registration_closed → in_progress: Event start date/time reached
- in_progress → completed: Event end date/time reached
- completed → archived: Post-event tasks finished (30 days after completion)
Event Data Model
interface Event {
id: string
title: string
description: string
eventType: "conference" | "webinar" | "workshop" | "networking" | "chapter_meeting"
deliveryMode: "in_person" | "virtual" | "hybrid"
status: "draft" | "published" | "registration_open" | "registration_closed" | "in_progress" | "completed" | "archived"
// Scheduling
startDate: Date
endDate: Date
timezone: string
registrationOpenDate: Date
registrationCloseDate: Date
// Capacity
capacity: number
currentRegistrations: number
waitlistEnabled: boolean
waitlistCapacity?: number
// Location (for in-person/hybrid)
venueName?: string
venueAddress?: string
venueCity?: string
venueState?: string
venueZip?: string
// Virtual (for virtual/hybrid)
virtualPlatform?: "zoom" | "teams" | "webex" | "custom"
virtualMeetingUrl?: string
virtualAccessCode?: string
// Pricing
pricingTiers: EventPricingTier[]
// Organizer
organizerId: string
chapterId: string
// Metadata
createdAt: Date
updatedAt: Date
}
interface EventPricingTier {
id: string
eventId: string
name: string // "Early Bird", "Member", "Non-Member", "Student"
price: number
currency: string
validFrom?: Date
validUntil?: Date
memberTypesEligible?: string[] // ["national", "state", "local"]
maxQuantity?: number
}
interface EventRegistration {
id: string
eventId: string
memberId: string
status: "pending" | "confirmed" | "cancelled" | "waitlisted" | "attended" | "no_show"
pricingTierId: string
amountPaid: number
paymentStatus: "pending" | "completed" | "refunded" | "failed"
registrationDate: Date
cancellationDate?: Date
checkInTime?: Date
checkInMethod?: "qr_code" | "manual" | "self_service"
// Attendee info (for non-members)
guestName?: string
guestEmail?: string
guestPhone?: string
// Dietary/accessibility
dietaryRequirements?: string
accessibilityNeeds?: string
specialRequests?: string
}
Registration Workflow
Event Registration Process
async function registerForEvent(
eventId: string,
memberId: string,
pricingTierId: string,
additionalInfo?: {
dietaryRequirements?: string
accessibilityNeeds?: string
specialRequests?: string
}
) {
// Step 1: Validate event availability
const event = await getEvent(eventId)
if (event.status !== "registration_open") {
throw new Error("Registration is not currently open for this event")
}
// Step 2: Check capacity
if (event.currentRegistrations >= event.capacity) {
if (event.waitlistEnabled && event.waitlistCapacity) {
return addToWaitlist(eventId, memberId)
}
throw new Error("Event is at full capacity")
}
// Step 3: Validate pricing tier eligibility
const member = await getMember(memberId)
const pricingTier = event.pricingTiers.find(pt => pt.id === pricingTierId)
if (!pricingTier) {
throw new Error("Invalid pricing tier")
}
if (pricingTier.memberTypesEligible) {
if (!pricingTier.memberTypesEligible.includes(member.memberType)) {
throw new Error("You are not eligible for this pricing tier")
}
}
// Step 4: Check for duplicate registration
const existingRegistration = await db
.select()
.from(eventRegistrations)
.where(
and(
eq(eventRegistrations.eventId, eventId),
eq(eventRegistrations.memberId, memberId),
ne(eventRegistrations.status, "cancelled")
)
)
.limit(1)
if (existingRegistration.length > 0) {
throw new Error("You are already registered for this event")
}
// Step 5: Create registration record
const registration = await db
.insert(eventRegistrations)
.values({
eventId,
memberId,
pricingTierId,
status: "pending",
amountPaid: pricingTier.price,
paymentStatus: "pending",
registrationDate: new Date(),
...additionalInfo
})
.returning()
// Step 6: Process payment
const payment = await processEventPayment(
registration[0].id,
pricingTier.price,
memberId
)
if (!payment.success) {
// Mark registration as failed
await db
.update(eventRegistrations)
.set({ paymentStatus: "failed" })
.where(eq(eventRegistrations.id, registration[0].id))
throw new Error("Payment processing failed")
}
// Step 7: Confirm registration
await db
.update(eventRegistrations)
.set({
status: "confirmed",
paymentStatus: "completed"
})
.where(eq(eventRegistrations.id, registration[0].id))
// Step 8: Update event capacity
await db
.update(events)
.set({
currentRegistrations: sql`${events.currentRegistrations} + 1`
})
.where(eq(events.id, eventId))
// Step 9: Send confirmation email
await sendEventConfirmationEmail(member.email, {
eventTitle: event.title,
startDate: event.startDate,
location: event.deliveryMode === "in_person" ? event.venueName : "Virtual",
confirmationCode: registration[0].id,
amount: pricingTier.price
})
// Step 10: Add to calendar (generate .ics file)
const calendarInvite = generateCalendarInvite(event, registration[0])
await emailCalendarInvite(member.email, calendarInvite)
return registration[0]
}
Waitlist Management
async function addToWaitlist(eventId: string, memberId: string) {
const event = await getEvent(eventId)
if (!event.waitlistEnabled) {
throw new Error("Waitlist is not available for this event")
}
const waitlistCount = await db
.select({ count: sql`COUNT(*)` })
.from(eventRegistrations)
.where(
and(
eq(eventRegistrations.eventId, eventId),
eq(eventRegistrations.status, "waitlisted")
)
)
if (waitlistCount[0].count >= (event.waitlistCapacity || 0)) {
throw new Error("Waitlist is full")
}
const registration = await db
.insert(eventRegistrations)
.values({
eventId,
memberId,
status: "waitlisted",
registrationDate: new Date()
})
.returning()
await sendWaitlistEmail(memberId, event)
return registration[0]
}
async function promoteFromWaitlist(eventId: string, count: number = 1) {
// Get waitlisted registrations in order
const waitlisted = await db
.select()
.from(eventRegistrations)
.where(
and(
eq(eventRegistrations.eventId, eventId),
eq(eventRegistrations.status, "waitlisted")
)
)
.orderBy(asc(eventRegistrations.registrationDate))
.limit(count)
for (const registration of waitlisted) {
// Update status to pending (requires payment)
await db
.update(eventRegistrations)
.set({ status: "pending" })
.where(eq(eventRegistrations.id, registration.id))
// Send promotion email with payment link
const member = await getMember(registration.memberId)
await sendWaitlistPromotionEmail(member.email, {
eventId,
registrationId: registration.id,
paymentDeadline: new Date(Date.now() + 48 * 60 * 60 * 1000) // 48 hours
})
}
}
QR Code Check-In System
import { QRCodeSVG } from "qrcode.react"
// Generate unique QR code for each registration
function generateCheckInQR(registrationId: string): string {
const checkInData = {
registrationId,
timestamp: Date.now(),
signature: generateHMAC(registrationId) // Security verification
}
return JSON.stringify(checkInData)
}
// Render QR code in confirmation email
export function RegistrationQRCode({ registrationId }: { registrationId: string }) {
const qrData = generateCheckInQR(registrationId)
return (
<div className="flex flex-col items-center gap-4">
<QRCodeSVG
value={qrData}
size={200}
level="H"
includeMargin
/>
<p className="text-sm text-muted-foreground">
Show this QR code at event check-in
</p>
<p className="text-xs text-muted-foreground font-mono">
Confirmation: {registrationId.slice(0, 8).toUpperCase()}
</p>
</div>
)
}
// Check-in scanning endpoint
async function processCheckIn(scannedData: string) {
const checkInData = JSON.parse(scannedData)
// Verify signature
if (!verifyHMAC(checkInData.registrationId, checkInData.signature)) {
throw new Error("Invalid QR code")
}
// Verify registration exists
const registr
---
*Content truncated.*
When not to use it
- →When managing events outside of NABIP categories
- →When the event lifecycle does not fit the defined states
Limitations
- →Event types are limited to NABIP categories: Conferences, Webinars, Workshops, Networking, Chapter Meetings
- →Post-event tasks are finished 30 days after completion for archiving
- →Registration is not currently open for an event if its status is not `registration_open`
How it compares
This workflow provides a structured approach with defined event states and data models for NABIP events, unlike a generic event management system that may lack specific category support or state transitions.
Compared to similar skills
event-management side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| event-management (this skill) | 0 | 8mo | No flags | Intermediate |
| nextcloud-cli-deck | 0 | 3mo | Review | Intermediate |
| linear-core-workflow-b | 1 | 10d | Review | Intermediate |
| agency-studio-producer | 0 | 4mo | No flags | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
nextcloud-cli-deck
NicholaiVogel
Work with the Nextcloud Deck app through Nextcloud CLI. Use when an agent needs to list boards and cards, create boards or stacks, create or update cards, move cards, archive or delete cards safely, validate Deck availability, or perform dry-run protected project-board workflows with nxc.
linear-core-workflow-b
jeremylongshore
Project and cycle management workflows with Linear. Use when implementing sprint planning, managing projects and roadmaps, or organizing work into cycles. Trigger with phrases like "linear project", "linear cycle", "linear sprint", "linear roadmap", "linear planning", "organize linear work".
agency-studio-producer
iFrescoo
Senior strategic leader specializing in high-level creative and technical project orchestration, resource allocation, and multi-project portfolio management. Focused on aligning creative vision with business objectives while managing complex cross-functional initiatives and ensuring optimal studio o
slack-to-queue
eranto
>-
gtd
Gerstep
Autonomous task execution from GTD.md items. Use when processing GTD tasks, call prep, outreach, or podcast preparation.
trello
stelios12312312
How to manage Trello boards, lists, cards, labels, and comments via the Tesseract operator