{"openapi":"3.0.0","paths":{"/api/billing/checkout":{"post":{"operationId":"BillingController_createCheckout","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutDto"}}}},"responses":{"201":{"description":"Checkout session created"}},"summary":"Create a Stripe Checkout Session","tags":["Billing"]}},"/api/billing/portal":{"post":{"operationId":"BillingController_createPortal","parameters":[],"responses":{"201":{"description":"Portal session created"}},"summary":"Create a Billing Portal Session","tags":["Billing"]}},"/api/billing/transactions":{"get":{"operationId":"BillingController_listTransactions","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"type","required":false,"in":"query","description":"Filter by transaction type","schema":{"type":"string","enum":["SUBSCRIPTION","EVENT_UPGRADE","SMS_TOPUP"]}},{"name":"status","required":false,"in":"query","description":"Filter by status","schema":{"type":"string","enum":["COMPLETE","OPEN","EXPIRED"]}},{"name":"userId","required":false,"in":"query","description":"Filter by user ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Transactions fetched successfully"}},"summary":"List all transactions for the organization","tags":["Billing"]}},"/api/billing/webhooks":{"post":{"operationId":"BillingWebhookController_handleWebhook","parameters":[{"name":"stripe-signature","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Stripe Webhook Endpoint","tags":["Billing"]}},"/api/billing/usage":{"get":{"operationId":"UsageController_getUsageSummary","parameters":[],"responses":{"200":{"description":"Usage summary fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummaryResponseDto"}}}}},"summary":"Get organization usage summary for the current billing period","tags":["Billing / Usage"]}},"/api/billing/usage/events/{eventId}":{"get":{"operationId":"UsageController_getEventUsage","parameters":[{"name":"eventId","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Event usage fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventUsageSummaryDto"}}}}},"summary":"Get usage details for a specific event","tags":["Billing / Usage"]}},"/api/storage/upload-url":{"post":{"description":"Generates a presigned URL for uploading files directly to S3/MinIO. Client uploads directly to S3, then calls /storage/confirm to attach the file to a resource.","operationId":"StorageController_generateUploadUrl","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateUploadUrlDto"}}}},"responses":{"200":{"description":"Presigned upload URL generated successfully"},"400":{"description":"Invalid file type or size"},"401":{"description":"Not authenticated"}},"summary":"Generate presigned upload URL","tags":["Storage"]}},"/api/storage/confirm":{"post":{"description":"Confirms that a file has been uploaded to S3 and optionally attaches it to a resource (event invitation or greeting card design). Returns the permanent download URL.","operationId":"StorageController_confirmUpload","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmUploadDto"}}}},"responses":{"200":{"description":"Upload confirmed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmUploadResponseDto"}}}},"400":{"description":"Invalid key or resource"},"401":{"description":"Not authenticated"}},"summary":"Confirm file upload and attach to resource","tags":["Storage"]}},"/api/storage/delete":{"delete":{"description":"Deletes a file from S3/MinIO storage using its key.","operationId":"StorageController_deleteFile","parameters":[],"responses":{"200":{"description":"File deleted successfully"},"404":{"description":"File not found"}},"summary":"Delete a file from storage","tags":["Storage"]}},"/api/storage/download-url":{"get":{"description":"Generates a presigned URL for downloading a file.","operationId":"StorageController_getDownloadUrl","parameters":[{"name":"key","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Download URL generated"},"404":{"description":"File not found"}},"summary":"Get a presigned download URL","tags":["Storage"]}},"/api/events":{"post":{"description":"Creates a new event owned by the authenticated user. The event starts in DRAFT status with ESSENTIAL tier billing defaults.","operationId":"EventController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventDto"}}}},"responses":{"201":{"description":"Event created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleEventDto"}}}},"400":{"description":"Invalid input data"},"401":{"description":"Not authenticated"}},"summary":"Create a new event","tags":["Events"]},"get":{"description":"Returns a paginated list of events owned by the authenticated user. Supports search, filtering by type/status/date range, and sorting.","operationId":"EventController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"userId","required":false,"in":"query","description":"Filter events by user (host) ID. Only admins can use this parameter.","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"allEvents","required":false,"in":"query","description":"When true, retrieve events across all hosts in the organization. Requires events.read.all permission.","schema":{"example":true,"type":"boolean"}},{"name":"status","required":false,"in":"query","description":"Filter by event status","schema":{"example":"PUBLISHED","type":"string","enum":["DRAFT","PUBLISHED","AUTO_CLOSED","MANUALLY_CLOSED","DUPLICATE","CLONED"]}},{"name":"dateFrom","required":false,"in":"query","description":"Filter events on or after this date (ISO 8601)","schema":{"format":"date-time","example":"2026-01-01T00:00:00.000Z","type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"Filter events on or before this date (ISO 8601)","schema":{"format":"date-time","example":"2026-12-31T23:59:59.000Z","type":"string"}}],"responses":{"200":{"description":"Events fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllEventDto"}}}}},"summary":"List all events for the current user","tags":["Events"]}},"/api/events/{id}":{"get":{"description":"Returns detailed event information. Only the event owner can access this.","operationId":"EventController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Event fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleEventDto"}}}},"404":{"description":"Event not found"}},"summary":"Get a single event by ID","tags":["Events"]},"patch":{"description":"Updates an existing event. Only the event owner can update. Billing fields (tier, guestLimit, paymentStatus, smsCredits) cannot be changed via this endpoint.","operationId":"EventController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventDto"}}}},"responses":{"200":{"description":"Event updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleEventDto"}}}},"400":{"description":"Invalid input or status transition"},"404":{"description":"Event not found"}},"summary":"Update an event","tags":["Events"]},"delete":{"description":"Permanently deletes an event and all related data (guests, form fields, tokens). This action cannot be undone. Only the event owner can delete.","operationId":"EventController_delete","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Event deleted successfully"},"404":{"description":"Event not found"}},"summary":"Delete an event","tags":["Events"]}},"/api/events/public/{slug}":{"get":{"description":"Returns event details for the public-facing RSVP page. Only PUBLISHED events are accessible. No authentication required.","operationId":"EventController_findBySlug","parameters":[{"name":"slug","required":true,"in":"path","description":"Event slug (URL-friendly identifier)","schema":{"example":"sarah-and-john-wedding-abc123","type":"string"}}],"responses":{"200":{"description":"Event fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleEventDto"}}}},"404":{"description":"Event not found or not published"}},"summary":"Get a published event by slug (public RSVP page)","tags":["Events"]}},"/api/events/public/{slug}/rsvp":{"post":{"description":"Guest submits RSVP for a published event. No authentication required. Creates guest record with ATTENDING or DECLINED status.","operationId":"EventController_submitRsvp","parameters":[{"name":"slug","required":true,"in":"path","description":"Event slug","schema":{"example":"sarah-and-john-wedding-abc123","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitRsvpDto"}}}},"responses":{"201":{"description":"RSVP submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestRsvpResponseDto"}}}},"400":{"description":"RSVP deadline passed or at capacity"},"404":{"description":"Event not found"},"409":{"description":"Email already RSVPed for this event"}},"summary":"Submit RSVP (guest)","tags":["Events"]}},"/api/events/public/{slug}/rsvp/{token}":{"get":{"description":"Fetches the current RSVP state for a guest using their unique edit token. Returns guest data and form field responses. No authentication required.","operationId":"EventController_getRsvpByToken","parameters":[{"name":"slug","required":true,"in":"path","description":"Event slug","schema":{"example":"sarah-and-john-wedding-abc123","type":"string"}},{"name":"token","required":true,"in":"path","description":"Unique guest edit token","schema":{"example":"a1b2c3d4e5f6...","type":"string"}}],"responses":{"200":{"description":"RSVP fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestRsvpResponseDto"}}}},"400":{"description":"Token expired or revoked"},"404":{"description":"Invalid token or event not found"}},"summary":"Get current RSVP by edit token (guest)","tags":["Events"]},"patch":{"description":"Updates an existing RSVP using the unique edit token. Guests can change status, party size, and form field responses. No authentication required.","operationId":"EventController_updateRsvpByToken","parameters":[{"name":"slug","required":true,"in":"path","description":"Event slug","schema":{"example":"sarah-and-john-wedding-abc123","type":"string"}},{"name":"token","required":true,"in":"path","description":"Unique guest edit token","schema":{"example":"a1b2c3d4e5f6...","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRsvpDto"}}}},"responses":{"200":{"description":"RSVP updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuestRsvpResponseDto"}}}},"400":{"description":"RSVP deadline passed, token expired, or event closed"},"404":{"description":"Invalid token or event not found"}},"summary":"Update RSVP by edit token (guest)","tags":["Events"]}},"/api/events/{id}/guests":{"get":{"description":"Returns a paginated list of guests for the specified event. Supports search (name/email), filtering by status, and sorting.","operationId":"EventController_findAllGuests","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by RSVP status","schema":{"example":"ATTENDING","type":"string","enum":["PENDING","ATTENDING","DECLINED"]}}],"responses":{"200":{"description":"Guests fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllGuestsDto"}}}},"404":{"description":"Event not found"}},"summary":"List guests for an event","tags":["Events"]},"post":{"description":"Adds one or more guests to an existing event. Each guest receives a unique RSVP edit token. Validates guest limit and checks for duplicate emails within the event.","operationId":"EventController_addGuests","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddGuestsToEventDto"}}}},"responses":{"201":{"description":"Guests added successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllGuestsDto"}}}},"400":{"description":"Guest limit exceeded"},"404":{"description":"Event not found"},"409":{"description":"Duplicate email within event"}},"summary":"Add guests to an existing event","tags":["Events"]}},"/api/events/{id}/guests/export":{"get":{"description":"Exports the full guest list for an event as CSV or PDF. PDF includes event header, summary stats, and formatted guest table.","operationId":"EventController_exportGuests","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"format","required":true,"in":"query","description":"Export file format","schema":{"enum":["csv","pdf"],"type":"string"}}],"responses":{"200":{"description":"File exported successfully"},"404":{"description":"Event not found"}},"summary":"Export guest list","tags":["Events"]}},"/api/events/{id}/guests/{guestId}":{"get":{"description":"Returns detailed guest information including all form field responses.","operationId":"EventController_findOneGuest","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"guestId","required":true,"in":"path","description":"Guest ID","schema":{"example":"cmieqoaba0000iymt4fab9999","type":"string"}}],"responses":{"200":{"description":"Guest fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleGuestDto"}}}},"404":{"description":"Event or guest not found"}},"summary":"Get a single guest by ID","tags":["Events"]},"patch":{"description":"Host updates guest details (name, email, phone, status, party size) and/or custom form field responses. All fields are optional — send only what needs to change.","operationId":"EventController_updateGuest","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"guestId","required":true,"in":"path","description":"Guest ID","schema":{"example":"cmieqoaba0000iymt4fab9999","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateGuestByHostDto"}}}},"responses":{"200":{"description":"Guest updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleGuestDto"}}}},"400":{"description":"Validation error"},"404":{"description":"Event or guest not found"},"409":{"description":"Duplicate email within event"}},"summary":"Update a guest (host)","tags":["Events"]},"delete":{"description":"Permanently removes a guest and all related data (form responses, edit tokens) from the event. This action cannot be undone.","operationId":"EventController_deleteGuest","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"guestId","required":true,"in":"path","description":"Guest ID","schema":{"example":"cmieqoaba0000iymt4fab9999","type":"string"}}],"responses":{"200":{"description":"Guest removed successfully"},"404":{"description":"Event or guest not found"}},"summary":"Delete a guest","tags":["Events"]}},"/api/events/{id}/publish":{"post":{"description":"Transitions a DRAFT event to PUBLISHED status, making it accessible via the public RSVP page. Only DRAFT events can be published.","operationId":"EventController_publish","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Event published successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleEventDto"}}}},"400":{"description":"Event is not in DRAFT status"},"404":{"description":"Event not found"}},"summary":"Publish a draft event","tags":["Events"]}},"/api/events/{id}/close":{"post":{"description":"Transitions a PUBLISHED event to MANUALLY_CLOSED status, preventing further RSVPs. Only PUBLISHED events can be closed.","operationId":"EventController_close","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Event closed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleEventDto"}}}},"400":{"description":"Event is not in PUBLISHED status"},"404":{"description":"Event not found"}},"summary":"Manually close a published event","tags":["Events"]}},"/api/events/{id}/duplicate":{"post":{"description":"Creates a copy of an existing event with a new slug and DRAFT status. Copies event details and form fields, but NOT guests, tokens, or billing data.","operationId":"EventController_duplicate","parameters":[{"name":"id","required":true,"in":"path","description":"Source Event ID to duplicate","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"201":{"description":"Event duplicated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleEventDto"}}}},"404":{"description":"Source event not found"}},"summary":"Duplicate an existing event","tags":["Events"]}},"/api/events/{id}/send-invitation":{"post":{"description":"Queues RSVP invitation emails for all guests with PENDING status. Uses the outbox pattern for reliable delivery.","operationId":"EventController_sendInvitations","parameters":[{"name":"id","required":true,"in":"path","description":"Event ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Invitations queued successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendInvitationsResponseDto"}}}}},"summary":"Send invitation emails to all pending guests","tags":["Events"]}},"/api/audit":{"get":{"operationId":"AuditController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"entityType","required":false,"in":"query","description":"Filter by entity type (e.g., lead, note, booking)","schema":{"example":"lead","type":"string"}},{"name":"entityId","required":false,"in":"query","description":"Filter by specific entity ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"action","required":false,"in":"query","description":"Filter by action (e.g., leads.create, leads.status_change)","schema":{"example":"leads.create","type":"string"}},{"name":"actorUserId","required":false,"in":"query","description":"Filter by actor user ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"dateFrom","required":false,"in":"query","description":"Filter audit logs from this date","schema":{"example":"2024-01-01","type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"Filter audit logs to this date","schema":{"example":"2024-12-31","type":"string"}}],"responses":{"200":{"description":"Audit logs fetched successfully"}},"summary":"Get all audit logs (admin-only)","tags":["Audit"]}},"/api/audit/entity/{entityType}/{entityId}":{"get":{"operationId":"AuditController_findByEntity","parameters":[{"name":"entityType","required":true,"in":"path","description":"The type of entity (e.g., lead, note)","schema":{"example":"lead","type":"string"}},{"name":"entityId","required":true,"in":"path","description":"The ID of the entity","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Entity audit trail fetched successfully"}},"summary":"Get audit trail for a specific entity","tags":["Audit"]}},"/api/communications/config/twilio":{"get":{"operationId":"ConfigController_getTwilioConfig","parameters":[],"responses":{"200":{"description":"Twilio config retrieved"}},"summary":"Get Twilio configuration (masked)","tags":["Communication Config"]},"put":{"operationId":"ConfigController_saveTwilioConfig","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwilioConfigDto"}}}},"responses":{"200":{"description":"Twilio config saved"}},"summary":"Save Twilio configuration","tags":["Communication Config"]}},"/api/communications/config/smtp/test":{"get":{"operationId":"ConfigController_testSmtpConnection","parameters":[],"responses":{"200":{"description":"SMTP connection tested"}},"summary":"Test SMTP connection","tags":["Communication Config"]}},"/api/communications/config/smtp":{"get":{"operationId":"ConfigController_getSmtpConfig","parameters":[],"responses":{"200":{"description":"SMTP config retrieved"}},"summary":"Get SMTP configuration (masked)","tags":["Communication Config"]},"put":{"operationId":"ConfigController_saveSmtpConfig","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmtpConfigDto"}}}},"responses":{"200":{"description":"SMTP config saved"}},"summary":"Save SMTP configuration","tags":["Communication Config"]}},"/api/communications/config/status":{"get":{"operationId":"ConfigController_getProviderStatus","parameters":[],"responses":{"200":{"description":"Provider status retrieved"}},"summary":"Get provider status","tags":["Communication Config"]}},"/api/communications/templates":{"get":{"operationId":"TemplateController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"type","required":false,"in":"query","description":"Filter by channel type","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"status","required":false,"in":"query","description":"Filter by status","schema":{"type":"string","enum":["DRAFT","APPROVED","ARCHIVED"]}},{"name":"search","required":false,"in":"query","description":"Search by name or description","schema":{"type":"string"}}],"responses":{"200":{"description":"Templates retrieved"}},"summary":"Get all templates","tags":["Communication Templates"]},"post":{"operationId":"TemplateController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCommTemplateDto"}}}},"responses":{"201":{"description":"Template created"}},"summary":"Create a new template","tags":["Communication Templates"]}},"/api/communications/templates/placeholders":{"get":{"operationId":"TemplateController_getPlaceholders","parameters":[],"responses":{"200":{"description":"Placeholders retrieved"}},"summary":"Get available placeholders","tags":["Communication Templates"]}},"/api/communications/templates/{id}":{"get":{"operationId":"TemplateController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Template retrieved"}},"summary":"Get a single template","tags":["Communication Templates"]},"patch":{"operationId":"TemplateController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCommTemplateDto"}}}},"responses":{"200":{"description":"Template updated"}},"summary":"Update a template","tags":["Communication Templates"]}},"/api/communications/templates/{id}/approve":{"post":{"operationId":"TemplateController_approve","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Template approved"}},"summary":"Approve a template","tags":["Communication Templates"]}},"/api/communications/templates/{id}/archive":{"post":{"operationId":"TemplateController_archive","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Template archived"}},"summary":"Archive a template","tags":["Communication Templates"]}},"/api/communications/templates/{id}/new-version":{"post":{"operationId":"TemplateController_createNewVersion","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"201":{"description":"New version created"}},"summary":"Create a new version of a template","tags":["Communication Templates"]}},"/api/communications/templates/{id}/preview":{"post":{"operationId":"TemplateController_preview","parameters":[{"name":"id","required":true,"in":"path","description":"Template ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewTemplateDto"}}}},"responses":{"200":{"description":"Preview generated"}},"summary":"Preview a template with entity data","tags":["Communication Templates"]}},"/api/communications/sms":{"post":{"operationId":"CommController_sendSms","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendSmsDto"}}}},"responses":{"201":{"description":"SMS sent successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponseDto"}}}}},"summary":"Send an SMS message","tags":["Communications"]}},"/api/communications/email":{"post":{"operationId":"CommController_sendEmail","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendEmailDto"}}}},"responses":{"201":{"description":"Email sent successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponseDto"}}}}},"summary":"Send an email message","tags":["Communications"]}},"/api/communications/messages":{"get":{"operationId":"CommController_findMessages","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"direction","required":false,"in":"query","description":"Filter by direction","schema":{"type":"string","enum":["IN","OUT"]}},{"name":"status","required":false,"in":"query","description":"Filter by status","schema":{"type":"string","enum":["QUEUED","SENT","DELIVERED","FAILED","BOUNCED"]}},{"name":"channel","required":false,"in":"query","description":"Filter by channel","schema":{"type":"string","enum":["SMS","EMAIL"]}},{"name":"search","required":false,"in":"query","description":"Search in toAddress, subject, bodyText","schema":{"type":"string"}}],"responses":{"200":{"description":"Messages retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllMessagesDto"}}}}},"summary":"Get all messages with pagination","tags":["Communications"]}},"/api/communications/messages/{id}":{"get":{"operationId":"CommController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Message ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Message retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleMessageDto"}}}}},"summary":"Get a single message","tags":["Communications"]}},"/api/organizations":{"post":{"operationId":"OrganizationController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationDto"}}}},"responses":{"201":{"description":"Organization created successfully"},"403":{"description":"Forbidden - Super admin access required"},"409":{"description":"Conflict - Slug already exists"}},"summary":"Create a new organization","tags":["Organizations"]},"get":{"operationId":"OrganizationController_findAll","parameters":[{"name":"includeInactive","required":false,"in":"query","description":"Include inactive organizations in the response","schema":{"type":"boolean"}}],"responses":{"200":{"description":"List of organizations"}},"summary":"Get all organizations (public)","tags":["Organizations"]}},"/api/organizations/check-slug/{slug}":{"get":{"operationId":"OrganizationController_checkSlug","parameters":[{"name":"slug","required":true,"in":"path","description":"Organization slug to check","schema":{"example":"my-organization","type":"string"}}],"responses":{"200":{"description":"Slug availability status"}},"summary":"Check if a slug is available","tags":["Organizations"]}},"/api/organizations/by-slug/{slug}":{"get":{"operationId":"OrganizationController_findBySlug","parameters":[{"name":"slug","required":true,"in":"path","description":"Organization slug","schema":{"example":"my-organization","type":"string"}}],"responses":{"200":{"description":"Organization details"},"404":{"description":"Organization not found"}},"summary":"Get organization by slug (public)","tags":["Organizations"]}},"/api/organizations/{id}":{"get":{"operationId":"OrganizationController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Organization ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Organization details"},"404":{"description":"Organization not found"}},"summary":"Get organization by ID","tags":["Organizations"]},"patch":{"operationId":"OrganizationController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Organization ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationDto"}}}},"responses":{"200":{"description":"Organization updated successfully"},"403":{"description":"Forbidden - Super admin access required"},"404":{"description":"Organization not found"}},"summary":"Update an organization (Super Admin only)","tags":["Organizations"]},"delete":{"operationId":"OrganizationController_remove","parameters":[{"name":"id","required":true,"in":"path","description":"Organization ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Organization deleted successfully"},"403":{"description":"Forbidden - Super admin access required"},"404":{"description":"Organization not found"},"409":{"description":"Conflict - Organization has users"}},"summary":"Delete an organization (Super Admin only)","tags":["Organizations"]}},"/api/user-settings/reminders":{"get":{"operationId":"OrganizationSettingsController_getSettings","parameters":[],"responses":{"200":{"description":"Reminder settings fetched successfully"}},"summary":"Get current user reminder settings","tags":["User Settings"]},"patch":{"operationId":"OrganizationSettingsController_updateSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrgSettingsDto"}}}},"responses":{"200":{"description":"Reminder settings updated successfully"}},"summary":"Update current user reminder settings","tags":["User Settings"]}},"/api/greeting-cards":{"post":{"description":"Creates a new greeting card order in DRAFT status. The card starts at $19 base price and can be customized with design and recipients.","operationId":"GreetingCardController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGreetingCardDto"}}}},"responses":{"201":{"description":"Greeting card created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleGreetingCardDto"}}}},"400":{"description":"Invalid input data"},"401":{"description":"Not authenticated"}},"summary":"Create a new greeting card","tags":["Greeting Cards"]},"get":{"description":"Returns a paginated list of greeting cards for the authenticated user. Supports filtering by status and searching by title.","operationId":"GreetingCardController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (1-indexed)","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":10,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter by greeting card status","schema":{"type":"string","enum":["DRAFT","SCHEDULED","SENT","PARTIALLY_SENT","FAILED","CANCELED"]}},{"name":"search","required":false,"in":"query","description":"Search by title","schema":{"example":"Holiday","type":"string"}}],"responses":{"200":{"description":"Greeting cards fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllGreetingCardsDto"}}}}},"summary":"List all greeting cards","tags":["Greeting Cards"]}},"/api/greeting-cards/{id}":{"patch":{"description":"Updates greeting card title, design URL, drop shadow, or linked event. Can be updated while in DRAFT or SCHEDULED status.","operationId":"GreetingCardController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Greeting card ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateGreetingCardDto"}}}},"responses":{"200":{"description":"Greeting card updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleGreetingCardDto"}}}},"400":{"description":"Cannot update after sending"},"404":{"description":"Greeting card not found"}},"summary":"Update greeting card details","tags":["Greeting Cards"]},"get":{"description":"Returns full details of a single greeting card including recipients, SMS packs, and linked event information.","operationId":"GreetingCardController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Greeting card ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Greeting card fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleGreetingCardDto"}}}},"404":{"description":"Greeting card not found"}},"summary":"Get greeting card details","tags":["Greeting Cards"]},"delete":{"description":"Deletes a greeting card and all its recipients. Can only delete cards in DRAFT status.","operationId":"GreetingCardController_delete","parameters":[{"name":"id","required":true,"in":"path","description":"Greeting card ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Greeting card deleted successfully"},"400":{"description":"Cannot delete after processing"},"404":{"description":"Greeting card not found"}},"summary":"Delete greeting card","tags":["Greeting Cards"]}},"/api/greeting-cards/{id}/recipients":{"post":{"description":"Adds multiple recipients to the greeting card at once. Frontend handles CSV import and sends prepared recipient list. Each recipient needs name, channel (EMAIL/SMS), and appropriate contact info.","operationId":"GreetingCardController_addRecipients","parameters":[{"name":"id","required":true,"in":"path","description":"Greeting card ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRecipientsDto"}}}},"responses":{"200":{"description":"Recipients added successfully"},"400":{"description":"Invalid recipient data or card not in DRAFT status"},"404":{"description":"Greeting card not found"}},"summary":"Add recipients to greeting card","tags":["Greeting Cards"]}},"/api/greeting-cards/{id}/checkout":{"post":{"description":"Creates a Stripe checkout session for payment. Base price: $19 (includes up to 100 SMS). Additional SMS packs: $10 per 50 recipients. Returns checkout URL to redirect user to Stripe.","operationId":"GreetingCardController_createCheckout","parameters":[{"name":"id","required":true,"in":"path","description":"Greeting card ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutDto"}}}},"responses":{"200":{"description":"Checkout session created"},"400":{"description":"Missing design or recipients, or card already processed"},"404":{"description":"Greeting card not found"}},"summary":"Create Stripe checkout session","tags":["Greeting Cards"]}},"/api/greeting-cards/{id}/send":{"post":{"description":"Sends the greeting card to all recipients via email and SMS. Can be called from DRAFT or SCHEDULED status. Updates delivery status for tracking.","operationId":"GreetingCardController_send","parameters":[{"name":"id","required":true,"in":"path","description":"Greeting card ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Greeting card sent successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleGreetingCardDto"}}}},"400":{"description":"Card not in DRAFT or SCHEDULED status"},"404":{"description":"Greeting card not found"}},"summary":"Send greeting card to all recipients","tags":["Greeting Cards"]}},"/api/greeting-cards/{id}/deliveries":{"get":{"description":"Returns delivery tracking information for all recipients. Shows status (PENDING/SENT/DELIVERED/FAILED) and timestamps.","operationId":"GreetingCardController_getDeliveries","parameters":[{"name":"id","required":true,"in":"path","description":"Greeting card ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Deliveries fetched successfully","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GreetingCardDeliveryResponseDto"}}}}},"404":{"description":"Greeting card not found"}},"summary":"Get greeting card delivery status","tags":["Greeting Cards"]}},"/api/role":{"get":{"operationId":"RoleController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"name","required":false,"in":"query","description":"The name of the role","schema":{"example":"Admin","type":"string"}},{"name":"description","required":false,"in":"query","description":"The description of the role","schema":{"example":"Administrator role with full access","type":"string"}}],"responses":{"200":{"description":"Roles fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllRoleDto"}}}}},"summary":"Get all roles","tags":["Role"]},"post":{"operationId":"RoleController_createRole","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleDto"}}}},"responses":{"201":{"description":"Role created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleRoleDto"}}}}},"summary":"Create a new role","tags":["Role"]}},"/api/role/{id}":{"get":{"operationId":"RoleController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Role ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Role fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleRoleDto"}}}},"404":{"description":"Role not found"}},"summary":"Get a single role","tags":["Role"]},"patch":{"operationId":"RoleController_updateRole","parameters":[{"name":"id","required":true,"in":"path","description":"Role ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoleDto"}}}},"responses":{"200":{"description":"Role updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleRoleDto"}}}}},"summary":"Update a role","tags":["Role"]},"delete":{"operationId":"RoleController_deleteRole","parameters":[{"name":"id","required":true,"in":"path","description":"Role ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Role deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleRoleDto"}}}}},"summary":"Delete a role","tags":["Role"]}},"/api/role/{id}/permissions/add":{"post":{"operationId":"RoleController_addPermissionsToRole","parameters":[{"name":"id","required":true,"in":"path","description":"Role ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManageRolePermissionsDto"}}}},"responses":{"200":{"description":"Permissions added to role successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleRoleDto"}}}}},"summary":"Add permissions to a role","tags":["Role"]}},"/api/role/{id}/permissions/remove":{"post":{"operationId":"RoleController_removePermissionsFromRole","parameters":[{"name":"id","required":true,"in":"path","description":"Role ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManageRolePermissionsDto"}}}},"responses":{"200":{"description":"Permissions removed from role successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleRoleDto"}}}}},"summary":"Remove permissions from a role","tags":["Role"]}},"/api/permissions":{"get":{"operationId":"PermissionController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"name","required":false,"in":"query","description":"The name of the permission","schema":{"example":"leads.read","type":"string"}},{"name":"description","required":false,"in":"query","description":"The description of the permission","schema":{"example":"Permission to read leads","type":"string"}}],"responses":{"200":{"description":"Permissions fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllPermissionDto"}}}}},"summary":"Get all permissions","tags":["Permission"]}},"/api/permissions/{id}":{"get":{"operationId":"PermissionController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Permission ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Permission fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSinglePermissionDto"}}}},"404":{"description":"Permission not found"}},"summary":"Get a single permission","tags":["Permission"]}},"/api/user":{"get":{"operationId":"UserController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"name","required":false,"in":"query","description":"The name of the user","schema":{"example":"John Doe","type":"string"}},{"name":"email","required":false,"in":"query","description":"The email of the user","schema":{"example":"john@example.com","type":"string"}},{"name":"username","required":false,"in":"query","description":"The username of the user","schema":{"example":"johndoe","type":"string"}},{"name":"role","required":false,"in":"query","description":"Filter by role name","schema":{"example":"Admin","type":"string"}}],"responses":{"200":{"description":"Users fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllUserDto"}}}}},"summary":"Get all users","tags":["User"]},"post":{"operationId":"UserController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"201":{"description":"User created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleUserDto"}}}},"409":{"description":"User with this email already exists"}},"summary":"Create a new user","tags":["User"]}},"/api/user/{id}":{"get":{"operationId":"UserController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"User ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"User fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleUserDto"}}}},"404":{"description":"User not found"}},"summary":"Get a single user","tags":["User"]},"patch":{"operationId":"UserController_update","parameters":[{"name":"id","required":true,"in":"path","description":"User ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":"User updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleUserDto"}}}},"404":{"description":"User not found"}},"summary":"Update a user (name and image only)","tags":["User"]},"delete":{"operationId":"UserController_delete","parameters":[{"name":"id","required":true,"in":"path","description":"User ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"User deleted successfully"},"404":{"description":"User not found"}},"summary":"Delete a user and all related data","tags":["User"]}},"/api/user/{id}/roles":{"patch":{"operationId":"UserController_assignRoles","parameters":[{"name":"id","required":true,"in":"path","description":"User ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignRolesDto"}}}},"responses":{"200":{"description":"User roles updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleUserDto"}}}},"400":{"description":"Invalid role IDs"},"404":{"description":"User not found"}},"summary":"Assign roles to a user","tags":["User"]}},"/api/user/change-password":{"patch":{"operationId":"UserController_changePassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordDto"}}}},"responses":{"200":{"description":"Password changed successfully"},"400":{"description":"Invalid password change request"},"401":{"description":"Current password is incorrect"}},"summary":"Change current user password","tags":["User"]}},"/api/onboarding":{"get":{"description":"Returns the host onboarding state including profile completion, first event creation, and completed steps.","operationId":"OnboardingController_getState","parameters":[],"responses":{"200":{"description":"Onboarding state fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStateResponseDto"}}}},"404":{"description":"User not found"}},"summary":"Get current onboarding state","tags":["Onboarding"]}},"/api/onboarding/complete-step":{"post":{"description":"Marks a specific onboarding step as complete. The firstEvent step is auto-set when the host creates their first event.","operationId":"OnboardingController_completeStep","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteStepDto"}}}},"responses":{"200":{"description":"Step marked complete successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStateResponseDto"}}}},"400":{"description":"Invalid step"},"404":{"description":"User not found"}},"summary":"Mark onboarding step complete","tags":["Onboarding"]}},"/api/custom-category":{"get":{"operationId":"CustomCategoryController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"code","required":false,"in":"query","description":"The code of the custom category","schema":{"example":"rsvp_status","type":"string"}},{"name":"name","required":false,"in":"query","description":"The name of the custom category","schema":{"example":"RSVP Status","type":"string"}},{"name":"isSystem","required":false,"in":"query","description":"Whether this is a system category","schema":{"example":false,"type":"boolean"}}],"responses":{"200":{"description":"Custom categories fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAllCustomCategoryDto"}}}}},"summary":"Get all custom categories with pagination","tags":["Custom Category"]},"post":{"operationId":"CustomCategoryController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomCategoryDto"}}}},"responses":{"201":{"description":"Custom category created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleCustomCategoryDto"}}}}},"summary":"Create a new custom category","tags":["Custom Category"]}},"/api/custom-category/code/{code}":{"get":{"operationId":"CustomCategoryController_findOneByCode","parameters":[{"name":"code","required":true,"in":"path","description":"Category code","schema":{"example":"rsvp_status","type":"string"}}],"responses":{"200":{"description":"Custom category fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleCustomCategoryDto"}}}},"404":{"description":"Custom category not found"}},"summary":"Get a single custom category by code with all options","tags":["Custom Category"]}},"/api/custom-category/{id}":{"get":{"operationId":"CustomCategoryController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Category ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Custom category fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleCustomCategoryDto"}}}},"404":{"description":"Custom category not found"}},"summary":"Get a single custom category with all options","tags":["Custom Category"]},"patch":{"operationId":"CustomCategoryController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Category ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomCategoryDto"}}}},"responses":{"200":{"description":"Custom category updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetSingleCustomCategoryDto"}}}}},"summary":"Update a custom category","tags":["Custom Category"]},"delete":{"operationId":"CustomCategoryController_delete","parameters":[{"name":"id","required":true,"in":"path","description":"Category ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"responses":{"200":{"description":"Custom category deleted successfully"}},"summary":"Delete a custom category","tags":["Custom Category"]}},"/api/custom-category/{categoryId}/options":{"post":{"operationId":"CustomCategoryController_createOption","parameters":[{"name":"categoryId","required":true,"in":"path","description":"Category ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomCategoryOptionDto"}}}},"responses":{"201":{"description":"Custom category option created successfully"}},"summary":"Create a new option for a custom category","tags":["Custom Category"]}},"/api/custom-category/{categoryId}/options/{optionId}":{"patch":{"operationId":"CustomCategoryController_updateOption","parameters":[{"name":"categoryId","required":true,"in":"path","description":"Category ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"optionId","required":true,"in":"path","description":"Option ID","schema":{"example":"cmieqoaba0000iymt4fab0346","type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCustomCategoryOptionDto"}}}},"responses":{"200":{"description":"Custom category option updated successfully"}},"summary":"Update a custom category option","tags":["Custom Category"]},"delete":{"operationId":"CustomCategoryController_deleteOption","parameters":[{"name":"categoryId","required":true,"in":"path","description":"Category ID","schema":{"example":"cmieqoaba0000iymt4fab0345","type":"string"}},{"name":"optionId","required":true,"in":"path","description":"Option ID","schema":{"example":"cmieqoaba0000iymt4fab0346","type":"string"}}],"responses":{"200":{"description":"Custom category option deleted successfully"}},"summary":"Delete a custom category option","tags":["Custom Category"]}},"/api/ai-extract":{"post":{"description":"Upload a file (multipart/form-data) or provide an imageUrl (JSON body). Use mode=full to extract all event data, or mode=colors for just the colour palette.","operationId":"AiExtractController_extract","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Event poster/invitation image or PDF"},"imageUrl":{"type":"string","description":"URL of an online event image (alternative to file)"},"mode":{"type":"string","enum":["full","colors"],"default":"full","description":"Extraction mode"}}}},"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Event poster/invitation image or PDF"},"imageUrl":{"type":"string","description":"URL of an online event image (alternative to file)"},"mode":{"type":"string","enum":["full","colors"],"default":"full","description":"Extraction mode"}}}}}},"responses":{"200":{"description":"Successfully extracted event data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtractResponseDto"}}}},"400":{"description":"Bad request (no image, invalid file type)"},"429":{"description":"Rate limit exceeded"},"500":{"description":"AI processing error"}},"summary":"Extract event data or colours from an image/PDF","tags":["AI Extract"]}},"/api/health/live":{"get":{"operationId":"HealthController_liveness","parameters":[],"responses":{"200":{"description":"The Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"summary":"Liveness probe","tags":["Health"]}},"/api/health/ready":{"get":{"operationId":"HealthController_readiness","parameters":[],"responses":{"200":{"description":"The Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"summary":"Readiness probe","tags":["Health"]}},"/api/health/deep":{"get":{"operationId":"HealthController_deepCheck","parameters":[],"responses":{"200":{"description":"The Health Check is successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}},"503":{"description":"The Health Check is not successful","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"error"},"info":{"type":"object","example":{"database":{"status":"up"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"error":{"type":"object","example":{"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true},"nullable":true},"details":{"type":"object","example":{"database":{"status":"up"},"redis":{"status":"down","message":"Could not connect"}},"additionalProperties":{"type":"object","required":["status"],"properties":{"status":{"type":"string"}},"additionalProperties":true}}}}}}}},"summary":"Deep health check for debugging","tags":["Health"]}},"/api/schedules/jobs":{"get":{"operationId":"SchedulerController_getJobs","parameters":[],"responses":{"default":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScheduleJobResponseDto"}}}}}},"security":[{"bearer":[]}],"summary":"List all runnable scheduled jobs","tags":["Schedules"]}},"/api/schedules/trigger":{"post":{"operationId":"SchedulerController_triggerJob","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerScheduleDto"}}}},"responses":{"default":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleTriggerResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Manually trigger a scheduled job","tags":["Schedules"]}},"/api/dashboard/kpis":{"get":{"description":"Returns aggregated KPIs for the authenticated user including event counts, guest response aggregates, headcount, communication stats, recent events, and upcoming events.","operationId":"DashboardController_getKpis","parameters":[],"responses":{"200":{"description":"Dashboard KPIs fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetDashboardKpiDto"}}}}},"summary":"Get dashboard KPIs","tags":["Dashboard"]}},"/api/dashboard/admin-kpis":{"get":{"description":"Returns org-wide aggregated KPIs for admins including revenue, user stats, event stats, subscriptions, and recent activity.","operationId":"DashboardController_getAdminKpis","parameters":[],"responses":{"200":{"description":"Admin dashboard KPIs fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKpiResponseDto"}}}}},"summary":"Get admin dashboard KPIs","tags":["Dashboard"]}},"/api/support-tickets":{"post":{"operationId":"SupportTicketController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSupportTicketDto"}}}},"responses":{"201":{"description":"Support ticket created successfully"}},"summary":"Create a new support ticket","tags":["Support Tickets"]},"get":{"operationId":"SupportTicketController_findAll","parameters":[{"name":"page","required":false,"in":"query","description":"Page number","schema":{"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"default":10,"example":10,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Sort field","schema":{"example":"createdAt","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Sort order","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"search","required":false,"in":"query","description":"Search query","schema":{"example":"john","type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by ticket status","schema":{"example":"OPEN","type":"string","enum":["OPEN","IN_PROGRESS","RESOLVED","CLOSED"]}},{"name":"category","required":false,"in":"query","description":"Filter by ticket category","schema":{"example":"TECHNICAL","type":"string","enum":["BILLING","EVENTS","TECHNICAL","OTHER"]}},{"name":"priority","required":false,"in":"query","description":"Filter by ticket priority","schema":{"example":"NORMAL","type":"string","enum":["LOW","NORMAL","HIGH","URGENT"]}}],"responses":{"200":{"description":"Support tickets fetched successfully"}},"summary":"List support tickets","tags":["Support Tickets"]}},"/api/support-tickets/{id}":{"get":{"operationId":"SupportTicketController_findOne","parameters":[{"name":"id","required":true,"in":"path","description":"Support ticket ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Support ticket fetched successfully"},"404":{"description":"Support ticket not found"}},"summary":"Get a support ticket with messages","tags":["Support Tickets"]},"patch":{"operationId":"SupportTicketController_update","parameters":[{"name":"id","required":true,"in":"path","description":"Support ticket ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSupportTicketDto"}}}},"responses":{"200":{"description":"Support ticket updated successfully"},"404":{"description":"Support ticket not found"}},"summary":"Update a support ticket (admin only)","tags":["Support Tickets"]}},"/api/support-tickets/{id}/reply":{"post":{"operationId":"SupportTicketController_reply","parameters":[{"name":"id","required":true,"in":"path","description":"Support ticket ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplySupportTicketDto"}}}},"responses":{"201":{"description":"Reply sent successfully"},"404":{"description":"Support ticket not found"}},"summary":"Reply to a support ticket","tags":["Support Tickets"]}}},"info":{"title":"RSVPeasy API","description":"RSVPeasy documentation.\n\n## Authentication\n\nThis API uses session-based authentication with Bearer token support. Sessions are valid for 30 days and auto-refresh on activity.\n\n### Getting Started\n1. **Get an Organization ID** - Call `GET /api/organizations` to list available organizations\n2. **Sign Up/Sign In** - Use one of the authentication methods below\n3. **Use the token** - Include `Authorization: Bearer <session-token>` in requests\n\n### Email/Password Authentication\n- `POST /api/auth/sign-up/email` - Register with email/password\n- `POST /api/auth/sign-in/email` - Login with email/password\n\n### Email OTP (Passwordless)\n- `POST /api/auth/email-otp/send-verification-otp` - Send OTP to email (type: sign-in, email-verification, forget-password)\n- `POST /api/auth/sign-in/email-otp` - Sign in with email + OTP code\n- `POST /api/auth/email-otp/verify-email` - Verify email address with OTP\n- `POST /api/auth/email-otp/reset-password` - Reset password with OTP\n\n### Phone/SMS OTP (Passwordless)\n- `POST /api/auth/phone-number/send-otp` - Send OTP to phone number\n- `POST /api/auth/phone-number/verify` - Verify phone and sign in (auto-registers new users)\n- `POST /api/auth/phone-number/request-password-reset` - Request password reset via SMS\n- `POST /api/auth/phone-number/reset-password` - Reset password with SMS OTP\n\n### OAuth / Social Login\n- `GET /api/auth/sign-in/social?provider=google` - OAuth with Google\n\n### Session Management\n- `GET /api/auth/get-session` - Get current session and user info\n- `POST /api/auth/sign-out` - Logout and invalidate session\n- `GET /api/auth/list-sessions` - List all active sessions\n- `POST /api/auth/revoke-session` - Revoke a specific session\n\n### JWT Tokens (for service-to-service)\n- `GET /api/auth/token` - Get short-lived JWT from active session (15 min expiry)\n- `GET /api/auth/jwks` - Get public keys for JWT verification\n\n### Mobile Integration Notes\n- **Session lifetime**: 30 days, auto-extends on any API activity\n- **Silent refresh**: Sessions auto-refresh when `updateAge` (24h) is reached - no user action needed\n- **Secure storage**: Store session token in Keychain (iOS) / Keystore (Android)\n- **API calls**: Include `Authorization: Bearer <session-token>` header\n- **Session check**: On app launch, call `GET /api/auth/get-session` to verify token validity\n- **Rare expiration**: If session expires (30+ days inactive), use passwordless login:\n  - Email OTP: Send code to user's email, sign in without password\n  - SMS OTP: Send code to user's phone, sign in without password\n- **Biometric unlock**: Store session token behind biometric lock for seamless UX\n\n**Note:** All endpoints except auth and public organization routes require the `x-org-id` header.\n","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer-auth":{"scheme":"bearer","bearerFormat":"JWT","type":"http","name":"Authorization","description":"Enter your Bearer token","in":"header"},"x-org-id":{"type":"apiKey","in":"header","name":"x-org-id","description":"Organization ID (required for most endpoints)"}},"schemas":{"CreateCheckoutDto":{"type":"object","properties":{"additionalSmsPacks":{"type":"number","description":"Number of additional SMS packs to purchase (each pack = 50 SMS)","example":2,"minimum":0},"successUrl":{"type":"string","description":"Success URL to redirect after payment","example":"https://example.com/greeting-cards/success"},"cancelUrl":{"type":"string","description":"Cancel URL to redirect if payment is cancelled","example":"https://example.com/greeting-cards/cancel"}}},"UsageMetricDto":{"type":"object","properties":{"metric":{"type":"string","description":"Metric key","example":"EVENT_CREATED"},"used":{"type":"number","description":"Current usage count","example":3},"limit":{"type":"object","description":"Maximum allowed (null = unlimited)","example":10},"percentage":{"type":"object","description":"Usage percentage (0-100)","example":30}},"required":["metric","used"]},"SmsCreditSummaryDto":{"type":"object","properties":{"remaining":{"type":"number","description":"Total remaining SMS credits","example":200},"total":{"type":"number","description":"Total SMS credits allocated","example":250},"used":{"type":"number","description":"Used credits","example":50}},"required":["remaining","total","used"]},"UsageSummaryResponseDto":{"type":"object","properties":{"tierCode":{"type":"string","description":"Current billing tier code","example":"PREMIUM"},"tierName":{"type":"string","description":"Current billing tier name","example":"Premium"},"metrics":{"description":"Usage breakdown per metric","type":"array","items":{"$ref":"#/components/schemas/UsageMetricDto"}},"smsCredits":{"description":"SMS credit summary","allOf":[{"$ref":"#/components/schemas/SmsCreditSummaryDto"}]},"dailyEmailsSent":{"type":"number","description":"Daily emails sent today","example":42},"dailyEmailLimit":{"type":"number","description":"Daily email limit","example":500},"periodStart":{"type":"string","description":"Billing period start","example":"2026-03-01T00:00:00.000Z"},"periodEnd":{"type":"string","description":"Billing period end","example":"2026-03-31T23:59:59.999Z"}},"required":["tierCode","tierName","metrics","smsCredits","dailyEmailsSent","dailyEmailLimit","periodStart","periodEnd"]},"EventUsageSummaryDto":{"type":"object","properties":{"eventId":{"type":"string","description":"Event ID","example":"cmieqoaba0000iymt4fab0345"},"eventName":{"type":"string","description":"Event name","example":"Summer Gala"},"tier":{"type":"string","description":"Current tier","example":"PREMIUM"},"guestCount":{"type":"number","description":"Guest count","example":45},"guestLimit":{"type":"number","description":"Guest limit","example":250},"smsSentCount":{"type":"number","description":"SMS sent count","example":12},"emailSentCount":{"type":"number","description":"Email sent count","example":40},"invitationsSentCount":{"type":"number","description":"Invitations sent count","example":45},"remindersSentCount":{"type":"number","description":"Reminders sent count","example":5}},"required":["eventId","eventName","tier","guestCount","guestLimit","smsSentCount","emailSentCount","invitationsSentCount","remindersSentCount"]},"GenerateUploadUrlDto":{"type":"object","properties":{"uploadType":{"type":"string","enum":["event_invitation","greeting_card_design"],"description":"Type of file being uploaded"},"filename":{"type":"string","description":"Original filename","example":"invitation.jpg"},"contentType":{"type":"string","description":"MIME type","example":"image/jpeg"},"resourceId":{"type":"string","description":"Resource ID (eventId or cardId)"},"fileSize":{"type":"number","description":"File size in bytes for validation","example":1048576}},"required":["uploadType","filename","contentType"]},"ConfirmUploadDto":{"type":"object","properties":{"key":{"type":"string","description":"S3 key returned from upload URL generation"},"resourceId":{"type":"string","description":"Resource ID to attach the URL to (eventId or cardId)"},"uploadType":{"type":"string","description":"Upload type for resource validation"}},"required":["key"]},"ConfirmUploadResponseDto":{"type":"object","properties":{}},"CreateAccommodationDto":{"type":"object","properties":{"name":{"type":"string","description":"Name of the accommodation","example":"The Ritz-Carlton","minLength":1,"maxLength":300},"imageUrl":{"type":"string","description":"URL of the accommodation image (16:9 ratio preferred)","example":"https://cdn.rsvpeasy.com/accommodations/hotel.jpg"},"description":{"type":"string","description":"Short description of the accommodation","example":"A luxurious 5-star hotel just minutes from the venue","maxLength":2000},"bookingLink":{"type":"string","description":"URL for guests to book this accommodation","example":"https://www.marriott.com/reservation?groupCode=WEDDING"},"isVisible":{"type":"boolean","description":"Whether this accommodation is visible on the RSVP page","example":true,"default":true}},"required":["name"]},"CreateFormFieldDto":{"type":"object","properties":{"label":{"type":"string","description":"Display label for the form field","example":"Dietary restrictions","minLength":1,"maxLength":200},"placeholder":{"type":"string","description":"Placeholder text for the input","example":"e.g., Vegetarian, Gluten-free","maxLength":200},"helpText":{"type":"string","description":"Help text shown below the field","example":"Please let us know about any dietary requirements","maxLength":500},"fieldType":{"type":"string","description":"Type of the form field","enum":["TEXT","EMAIL","PHONE","NUMBER","BOOLEAN","DROPDOWN","DATE","TEXTAREA"],"example":"TEXT"},"isRequired":{"type":"boolean","description":"Whether this field is required","example":false,"default":false},"isActive":{"type":"boolean","description":"Whether this field is visible on the RSVP form","example":true,"default":true},"sortOrder":{"type":"number","description":"Sort order for display (lower = first)","example":0,"default":0},"options":{"description":"Dropdown options for DROPDOWN fields (stored inline as a JSON array)","example":["Vegetarian","Vegan"],"type":"array","items":{"type":"string"}}},"required":["label","fieldType"]},"CreateGuestDto":{"type":"object","properties":{"name":{"type":"string","description":"Guest full name","example":"Jane Smith","minLength":2,"maxLength":200},"email":{"type":"string","description":"Guest email address (optional — some hosts may only have phone)","example":"jane.smith@example.com"},"phone":{"type":"string","description":"Guest phone number","example":"+15551234567","maxLength":30},"addressee":{"type":"string","description":"Display name for the invitation (e.g., \"The Smith Family\")","example":"The Smith Family","maxLength":200},"partySize":{"type":"number","description":"Number of people in the party (maps to adultCount)","example":1,"default":1,"minimum":1,"maximum":50}},"required":["name"]},"CreateEventDto":{"type":"object","properties":{"name":{"type":"string","description":"Name of the event","example":"Sarah & John Wedding","minLength":2,"maxLength":200},"eventDate":{"format":"date-time","type":"string","description":"Date of the event (ISO 8601 format)","example":"2026-06-15T00:00:00.000Z"},"startTime":{"format":"date-time","type":"string","description":"Start time of the event (ISO 8601 format)","example":"2026-06-15T14:00:00.000Z"},"rsvpBy":{"format":"date-time","type":"string","description":"RSVP deadline (ISO 8601 format). Must be before eventDate.","example":"2026-06-01T23:59:59.000Z"},"locationName":{"type":"string","description":"Name of the event location/venue","example":"The Grand Ballroom","minLength":2,"maxLength":300},"slug":{"type":"string","description":"Custom URL slug for the event. Must be lowercase alphanumeric with hyphens. If omitted, a slug is auto-generated from the event name.","example":"sarah-and-john-wedding","maxLength":100},"address":{"type":"string","description":"Full address of the event location","example":"123 Main St, New York, NY 10001","maxLength":500},"hostMessage":{"type":"string","description":"Personal message from the host displayed on the RSVP page","example":"We are thrilled to invite you to celebrate our special day with us!","maxLength":5000},"invitationUrl":{"type":"string","description":"URL to the uploaded invitation image/media (S3/CDN URL)","example":"https://cdn.rsvpeasy.com/invitations/my-invite.jpg"},"backgroundColor":{"type":"string","description":"Background color for the RSVP page (hex code)","example":"#FFFFFF","maxLength":20},"textColor":{"type":"string","description":"Text color for the RSVP page (hex code)","example":"#333333","maxLength":20},"accentColor":{"type":"string","description":"Accent color for buttons and highlights (hex code)","example":"#D4AF37","maxLength":20},"fontFamily":{"type":"string","description":"Font family for the RSVP page","example":"Playfair Display","maxLength":100},"showAnimation":{"type":"boolean","description":"Whether to show entrance animation on the RSVP page","example":false,"default":false},"isDropShadowRequired":{"type":"boolean","description":"Whether to apply a drop shadow to the invitation image","example":false,"default":false},"acceptResponseText":{"type":"string","description":"Custom text shown when guest accepts the invitation","example":"We're so glad you can make it!","maxLength":500},"declineResponseText":{"type":"string","description":"Custom text shown when guest declines the invitation","example":"We'll miss you!","maxLength":500},"headerFont":{"type":"string","description":"Header font name (e.g. display font)","example":"Playfair Display","maxLength":100},"bodyFont":{"type":"string","description":"Body font name (e.g. body text font)","example":"Open Sans","maxLength":100},"headerFontFamily":{"type":"string","description":"Header font family for the RSVP page","example":"Playfair Display, serif","maxLength":150},"bodyFontFamily":{"type":"string","description":"Body font family for the RSVP page","example":"Open Sans, sans-serif","maxLength":150},"headerSize":{"type":"string","description":"Header font size (e.g. \"24px\", \"1.5rem\")","example":"24px","maxLength":20},"bodySize":{"type":"string","description":"Body font size (e.g. \"16px\", \"1rem\")","example":"16px","maxLength":20},"buttonTextColor":{"type":"string","description":"Button text color (hex code)","example":"#FFFFFF","maxLength":20},"buttonBorderColor":{"type":"string","description":"Button border color (hex code)","example":"#D4AF37","maxLength":20},"buttonBorderRadius":{"type":"string","description":"Button border radius (e.g. \"8px\", \"0.5rem\")","example":"8px","maxLength":20},"buttonBgColor":{"type":"string","description":"Button background color (hex code)","example":"#D4AF37","maxLength":20},"headerTextColor":{"type":"string","description":"Header text color (hex code)","example":"#333333","maxLength":20},"accommodations":{"description":"List of accommodation options for this event","type":"array","items":{"$ref":"#/components/schemas/CreateAccommodationDto"}},"formFields":{"description":"Custom form fields for the RSVP page. Controls show/hide and required/optional per field.","type":"array","items":{"$ref":"#/components/schemas/CreateFormFieldDto"}},"guests":{"description":"Pre-loaded guest list. Each guest gets a unique RSVP token on creation. Frontend can populate this from manual entry, CSV import, or phone contacts.","type":"array","items":{"$ref":"#/components/schemas/CreateGuestDto"}},"registryLinkName":{"type":"string","description":"Display name for the registry link","example":"Our Wedding Registry","maxLength":300},"registryUrl":{"type":"string","description":"URL to the gift registry (https:// is added if no protocol is provided)","example":"https://www.zola.com/registry/sarahandjohn2026"}},"required":["name","eventDate","startTime","rsvpBy","locationName"]},"EventHostDto":{"type":"object","properties":{"id":{"type":"string","description":"Host user ID"},"name":{"type":"string","description":"Host display name"},"email":{"type":"string","description":"Host email address"},"image":{"type":"string","description":"Host avatar URL"}},"required":["id","email"]},"AccommodationResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Accommodation ID","example":"cmieqoaba0000iymt4fab9999"},"name":{"type":"string","description":"Accommodation name","example":"The Ritz-Carlton"},"imageUrl":{"type":"string","description":"Image URL (16:9 preferred)"},"description":{"type":"string","description":"Short description"},"bookingLink":{"type":"string","description":"Booking link URL"},"isVisible":{"type":"boolean","description":"Whether visible on RSVP page","example":true},"createdAt":{"format":"date-time","type":"string","description":"When the record was created"},"updatedAt":{"format":"date-time","type":"string","description":"When the record was last updated"}},"required":["id","name","isVisible","createdAt","updatedAt"]},"FormFieldResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Form field ID","example":"cmieqoaba0000iymt4fab9999"},"label":{"type":"string","description":"Display label","example":"Dietary restrictions"},"placeholder":{"type":"string","description":"Placeholder text"},"helpText":{"type":"string","description":"Help text shown below the field"},"fieldType":{"type":"string","description":"Field type","example":"TEXT"},"isRequired":{"type":"boolean","description":"Whether the field is required","example":false},"isActive":{"type":"boolean","description":"Whether the field is visible on the RSVP form","example":true},"sortOrder":{"type":"number","description":"Sort order for display","example":0},"options":{"description":"Dropdown options for DROPDOWN fields (inline JSON array)","example":["Vegetarian","Vegan","Gluten-free"],"type":"array","items":{"type":"string"}}},"required":["id","label","fieldType","isRequired","isActive","sortOrder"]},"GuestFieldResponseDto":{"type":"object","properties":{"fieldId":{"type":"string","description":"Form field ID","example":"cmieqoaba0000iymt4fab9999"},"label":{"type":"string","description":"Field label","example":"Dietary restrictions"},"fieldType":{"type":"string","description":"Field type","example":"TEXT"},"value":{"type":"object","description":"Response value","example":"Vegetarian"}},"required":["fieldId","label","fieldType","value"]},"AdditionalGuestResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Additional guest ID","example":"cmieqoaba0000iymt4fab0456"},"name":{"type":"string","description":"Additional guest full name","example":"Mia Smith"},"ageType":{"type":"string","description":"Additional guest age type","example":"ADULT"},"dietaryRestrictions":{"type":"string","description":"Additional guest dietary restrictions","example":"Vegetarian"}},"required":["id","name","ageType"]},"GuestRsvpResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Guest ID","example":"cmieqoaba0000iymt4fab0345"},"name":{"type":"string","description":"Guest name","example":"Jane Smith"},"email":{"type":"string","description":"Guest email","example":"jane.smith@example.com"},"status":{"type":"string","description":"RSVP status","example":"ATTENDING"},"adultCount":{"type":"number","description":"Number of adults","example":1},"childCount":{"type":"number","description":"Number of children","example":0},"addressee":{"type":"string","description":"Display name for the invitation (e.g., \"The Smith Family\")","example":"The Smith Family"},"phone":{"type":"string","description":"Guest phone number","example":"+15551234567"},"editToken":{"type":"string","description":"Token for guest to edit RSVP later (if generated)"},"responses":{"description":"Form field responses (returned when fetching RSVP by token)","type":"array","items":{"$ref":"#/components/schemas/GuestFieldResponseDto"}},"formFields":{"description":"Active form fields for this event (returned when fetching RSVP by token)","type":"array","items":{"type":"string"}},"additionalGuests":{"description":"Additional guests attached to this RSVP","type":"array","items":{"$ref":"#/components/schemas/AdditionalGuestResponseDto"}}},"required":["id","name","email","status","adultCount","childCount"]},"EventResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique event identifier","example":"cmieqoaba0000iymt4fab0345"},"orgId":{"type":"string","description":"Organization ID this event belongs to","example":"cmieqoaba0000iymt4fab1234"},"userId":{"type":"string","description":"User ID of the event host/owner","example":"cmieqoaba0000iymt4fab5678"},"host":{"description":"Host/owner details (present when viewing all events)","allOf":[{"$ref":"#/components/schemas/EventHostDto"}]},"slug":{"type":"string","description":"URL-friendly unique slug","example":"sarah-and-john-wedding-abc123"},"status":{"type":"string","description":"Current event status","example":"DRAFT"},"name":{"type":"string","description":"Name of the event","example":"Sarah & John Wedding"},"eventDate":{"format":"date-time","type":"string","description":"Date of the event","example":"2026-06-15T00:00:00.000Z"},"startTime":{"format":"date-time","type":"string","description":"Start time of the event","example":"2026-06-15T14:00:00.000Z"},"rsvpBy":{"format":"date-time","type":"string","description":"RSVP deadline","example":"2026-06-01T23:59:59.000Z"},"locationName":{"type":"string","description":"Name of the event venue","example":"The Grand Ballroom"},"address":{"type":"string","description":"Full address of the event venue","example":"123 Main St, New York, NY 10001"},"hostMessage":{"type":"string","description":"Personal message from the host","example":"We are thrilled to invite you to celebrate with us!"},"invitationUrl":{"type":"string","description":"URL of the uploaded invitation"},"backgroundColor":{"type":"string","description":"Background color (hex)","example":"#FFFFFF"},"textColor":{"type":"string","description":"Text color (hex)","example":"#333333"},"accentColor":{"type":"string","description":"Accent color (hex)","example":"#D4AF37"},"fontFamily":{"type":"string","description":"Font family","example":"Playfair Display"},"showAnimation":{"type":"boolean","description":"Show animation on RSVP page","example":false},"isDropShadowRequired":{"type":"boolean","description":"Whether drop shadow is applied to the invitation image","example":false},"acceptResponseText":{"type":"string","description":"Text shown when guest accepts","example":"We're so glad you can make it!"},"declineResponseText":{"type":"string","description":"Text shown when guest declines","example":"We'll miss you!"},"headerFont":{"type":"string","description":"Header font name","example":"Playfair Display"},"bodyFont":{"type":"string","description":"Body font name","example":"Open Sans"},"headerFontFamily":{"type":"string","description":"Header font family","example":"Playfair Display, serif"},"bodyFontFamily":{"type":"string","description":"Body font family","example":"Open Sans, sans-serif"},"headerSize":{"type":"string","description":"Header font size","example":"24px"},"bodySize":{"type":"string","description":"Body font size","example":"16px"},"buttonTextColor":{"type":"string","description":"Button text color (hex)","example":"#FFFFFF"},"buttonBorderColor":{"type":"string","description":"Button border color (hex)","example":"#D4AF37"},"buttonBorderRadius":{"type":"string","description":"Button border radius","example":"8px"},"buttonBgColor":{"type":"string","description":"Button background color (hex)","example":"#D4AF37"},"headerTextColor":{"type":"string","description":"Header text color (hex)","example":"#333333"},"accommodations":{"description":"List of accommodation options","type":"array","items":{"$ref":"#/components/schemas/AccommodationResponseDto"}},"formFields":{"description":"Custom RSVP form fields (show/hide, required/optional)","type":"array","items":{"$ref":"#/components/schemas/FormFieldResponseDto"}},"qrCodeUrl":{"type":"string","description":"S3/CDN URL of the event QR code image"},"registryLinkName":{"type":"string","description":"Display name for the registry link","example":"Our Wedding Registry"},"registryUrl":{"type":"string","description":"Gift registry URL"},"guests":{"description":"Pre-loaded guest list with edit tokens (only returned on creation when guests were uploaded)","type":"array","items":{"$ref":"#/components/schemas/GuestRsvpResponseDto"}},"tier":{"type":"string","description":"Current plan tier for this event","example":"ESSENTIAL"},"guestLimit":{"type":"number","description":"Maximum number of guests allowed","example":50},"paymentStatus":{"type":"string","description":"Payment status for this event","example":"FREE"},"smsInvitesRemaining":{"type":"number","description":"Remaining SMS invite credits","example":0},"smsRemindersRemaining":{"type":"number","description":"Remaining SMS reminder credits","example":0},"totalGuests":{"type":"number","description":"Total number of guests (when included by host fetches)","example":3},"attendingGuests":{"type":"number","description":"Number of guests attending","example":18},"declinedGuests":{"type":"number","description":"Number of guests who declined","example":3},"pendingGuests":{"type":"number","description":"Number of guests pending response","example":4},"createdAt":{"format":"date-time","type":"string","description":"When the event was created","example":"2026-01-15T10:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"When the event was last updated","example":"2026-01-15T10:00:00.000Z"}},"required":["id","orgId","userId","slug","status","name","eventDate","startTime","rsvpBy","locationName","showAnimation","isDropShadowRequired","tier","guestLimit","paymentStatus","smsInvitesRemaining","smsRemindersRemaining","createdAt","updatedAt"]},"GetSingleEventDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"description":"Event object","allOf":[{"$ref":"#/components/schemas/EventResponseDto"}]}},"required":["success","statusCode","message","timestamp","data"]},"GetAllEventDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"description":"Array of event objects","type":"array","items":{"$ref":"#/components/schemas/EventResponseDto"}},"meta":{"type":"object","description":"Pagination metadata","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":10},"total":{"type":"number","example":50},"totalPages":{"type":"number","example":5},"hasNext":{"type":"boolean","example":true},"hasPrev":{"type":"boolean","example":false}}}},"required":["success","statusCode","message","timestamp","data","meta"]},"AdditionalGuestDetailDto":{"type":"object","properties":{"name":{"type":"string","description":"Additional guest full name","example":"Mia Smith","minLength":2,"maxLength":200},"ageType":{"type":"string","description":"Additional guest age type","enum":["ADULT","CHILD"],"example":"ADULT"},"dietaryRestrictions":{"type":"string","description":"Additional guest dietary restrictions","example":"Vegetarian","maxLength":300}},"required":["name","ageType"]},"SubmitRsvpDto":{"type":"object","properties":{"name":{"type":"string","description":"Guest full name","example":"Jane Smith","minLength":2,"maxLength":200},"email":{"type":"string","description":"Guest email address","example":"jane.smith@example.com"},"phone":{"type":"string","description":"Guest phone number","example":"+15551234567","maxLength":30},"status":{"type":"string","description":"RSVP status","enum":["PENDING","ATTENDING","DECLINED"],"example":"ATTENDING"},"adultCount":{"type":"number","description":"Number of adults attending (including guest). Use 0 when status is DECLINED.","example":1,"default":1,"minimum":0,"maximum":20},"childCount":{"type":"number","description":"Number of children attending","example":0,"default":0,"minimum":0,"maximum":20},"addressee":{"type":"string","description":"Display name for the invitation (e.g., \"The Smith Family\")","example":"The Smith Family","maxLength":200},"responses":{"description":"Responses to custom form fields","type":"array","items":{"$ref":"#/components/schemas/FormFieldResponseDto"}},"additionalGuests":{"description":"Additional guests and their details (name, age type, dietary restrictions)","type":"array","items":{"$ref":"#/components/schemas/AdditionalGuestDetailDto"}}},"required":["name","email","status"]},"UpdateRsvpDto":{"type":"object","properties":{"status":{"type":"string","description":"Updated RSVP status","enum":["PENDING","ATTENDING","DECLINED"],"example":"ATTENDING"},"adultCount":{"type":"number","description":"Updated number of adults attending (including guest)","example":2,"minimum":1,"maximum":20},"childCount":{"type":"number","description":"Updated number of children attending","example":1,"minimum":0,"maximum":20},"addressee":{"type":"string","description":"Display name for the invitation (e.g., \"The Smith Family\")","example":"The Smith Family"},"responses":{"description":"Updated responses to custom form fields","type":"array","items":{"$ref":"#/components/schemas/FormFieldResponseDto"}},"additionalGuests":{"description":"Updated additional guests (full replacement list: create, update, remove)","type":"array","items":{"$ref":"#/components/schemas/AdditionalGuestDetailDto"}}}},"GuestListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Guest ID","example":"cmieqoaba0000iymt4fab0345"},"name":{"type":"string","description":"Guest name","example":"Jane Smith"},"email":{"type":"string","description":"Guest email","example":"jane.smith@example.com"},"phone":{"type":"string","description":"Guest phone number","example":"+1234567890"},"status":{"type":"string","description":"RSVP status","example":"ATTENDING"},"adultCount":{"type":"number","description":"Number of adults","example":1},"childCount":{"type":"number","description":"Number of children","example":0},"addressee":{"type":"string","description":"Display name for the invitation (e.g., \"The Smith Family\")","example":"The Smith Family"},"responses":{"description":"Form field responses","type":"array","items":{"$ref":"#/components/schemas/GuestFieldResponseDto"}},"additionalGuests":{"description":"Additional guests attached to this RSVP","type":"array","items":{"$ref":"#/components/schemas/AdditionalGuestResponseDto"}}},"required":["id","name","email","status","adultCount","childCount"]},"GetAllGuestsDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"description":"Array of guest objects","type":"array","items":{"$ref":"#/components/schemas/GuestListItemDto"}},"meta":{"type":"object","description":"Pagination metadata","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":10},"total":{"type":"number","example":50},"totalPages":{"type":"number","example":5},"hasNext":{"type":"boolean","example":true},"hasPrev":{"type":"boolean","example":false}}},"guestCounts":{"type":"object","description":"Guest count summary for the event","properties":{"total":{"type":"number","example":25},"attending":{"type":"number","example":18},"declined":{"type":"number","example":3},"pending":{"type":"number","example":4}}}},"required":["success","statusCode","message","timestamp","data","meta","guestCounts"]},"GuestDetailResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Guest ID","example":"cmieqoaba0000iymt4fab0345"},"name":{"type":"string","description":"Guest name","example":"Jane Smith"},"email":{"type":"string","description":"Guest email","example":"jane.smith@example.com"},"phone":{"type":"string","description":"Guest phone number","example":"+1234567890"},"status":{"type":"string","description":"RSVP status","example":"ATTENDING"},"adultCount":{"type":"number","description":"Number of adults","example":1},"childCount":{"type":"number","description":"Number of children","example":0},"addressee":{"type":"string","description":"Display name for the invitation (e.g., \"The Smith Family\")","example":"The Smith Family"},"responses":{"description":"Form field responses","type":"array","items":{"$ref":"#/components/schemas/GuestFieldResponseDto"}},"additionalGuests":{"description":"Additional guests attached to this RSVP","type":"array","items":{"$ref":"#/components/schemas/AdditionalGuestResponseDto"}}},"required":["id","name","email","status","adultCount","childCount"]},"GetSingleGuestDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"description":"Guest detail object","allOf":[{"$ref":"#/components/schemas/GuestDetailResponseDto"}]}},"required":["success","statusCode","message","timestamp","data"]},"UpdateGuestByHostDto":{"type":"object","properties":{"name":{"type":"string","description":"Guest full name","example":"Jane Smith"},"email":{"type":"string","description":"Guest email address (must be unique per event)","example":"jane.smith@example.com"},"phone":{"type":"object","description":"Guest phone number","example":"+15551234567","maxLength":30},"addressee":{"type":"object","description":"Display name for the invitation (e.g., \"The Smith Family\")","example":"The Smith Family"},"status":{"type":"string","description":"RSVP status","enum":["PENDING","ATTENDING","DECLINED"],"example":"ATTENDING"},"adultCount":{"type":"number","description":"Number of adults (0 when declined)","example":2,"minimum":0,"maximum":20},"childCount":{"type":"number","description":"Number of children","example":1,"minimum":0,"maximum":20},"responses":{"description":"Responses to custom form fields (upsert by fieldId; omitted fields are left unchanged)","type":"array","items":{"$ref":"#/components/schemas/FormFieldResponseDto"}},"additionalGuests":{"description":"Additional guests (full replacement — all existing additional guests are removed and replaced with this list). Omit to leave unchanged.","type":"array","items":{"$ref":"#/components/schemas/AdditionalGuestDetailDto"}}}},"AddGuestsToEventDto":{"type":"object","properties":{"guests":{"description":"Array of guests to add to the event","type":"array","items":{"$ref":"#/components/schemas/CreateGuestDto"}}},"required":["guests"]},"UpdateAccommodationItemDto":{"type":"object","properties":{"name":{"type":"string","description":"Name of the accommodation","example":"The Ritz-Carlton","minLength":1,"maxLength":300},"imageUrl":{"type":"string","description":"URL of the accommodation image (16:9 ratio preferred)","example":"https://cdn.rsvpeasy.com/accommodations/hotel.jpg"},"description":{"type":"string","description":"Short description of the accommodation","example":"A luxurious 5-star hotel just minutes from the venue","maxLength":2000},"bookingLink":{"type":"string","description":"URL for guests to book this accommodation","example":"https://www.marriott.com/reservation?groupCode=WEDDING"},"isVisible":{"type":"boolean","description":"Whether this accommodation is visible on the RSVP page","example":true,"default":true},"id":{"type":"string","description":"ID of an existing accommodation record. Omit for new entries.","example":"cmieqoaba0000iymt4fab9999"}},"required":["name"]},"UpdateFormFieldItemDto":{"type":"object","properties":{"label":{"type":"string","description":"Display label for the form field","example":"Dietary restrictions","minLength":1,"maxLength":200},"placeholder":{"type":"string","description":"Placeholder text for the input","example":"e.g., Vegetarian, Gluten-free","maxLength":200},"helpText":{"type":"string","description":"Help text shown below the field","example":"Please let us know about any dietary requirements","maxLength":500},"fieldType":{"type":"string","description":"Type of the form field","enum":["TEXT","EMAIL","PHONE","NUMBER","BOOLEAN","DROPDOWN","DATE","TEXTAREA"],"example":"TEXT"},"isRequired":{"type":"boolean","description":"Whether this field is required","example":false,"default":false},"isActive":{"type":"boolean","description":"Whether this field is visible on the RSVP form","example":true,"default":true},"sortOrder":{"type":"number","description":"Sort order for display (lower = first)","example":0,"default":0},"options":{"description":"Dropdown options for DROPDOWN fields (stored inline as a JSON array)","example":["Vegetarian","Vegan"],"type":"array","items":{"type":"string"}},"id":{"type":"string","description":"ID of an existing form field record. Omit for new entries.","example":"cmieqoaba0000iymt4fab9999"}},"required":["label","fieldType"]},"UpdateEventDto":{"type":"object","properties":{"name":{"type":"string","description":"Name of the event","example":"Sarah & John Wedding","minLength":2,"maxLength":200},"eventDate":{"format":"date-time","type":"string","description":"Date of the event (ISO 8601 format)","example":"2026-06-15T00:00:00.000Z"},"startTime":{"format":"date-time","type":"string","description":"Start time of the event (ISO 8601 format)","example":"2026-06-15T14:00:00.000Z"},"rsvpBy":{"format":"date-time","type":"string","description":"RSVP deadline (ISO 8601 format). Must be before eventDate.","example":"2026-06-01T23:59:59.000Z"},"locationName":{"type":"string","description":"Name of the event location/venue","example":"The Grand Ballroom","minLength":2,"maxLength":300},"slug":{"type":"string","description":"Custom URL slug for the event. Must be lowercase alphanumeric with hyphens. If omitted, a slug is auto-generated from the event name.","example":"sarah-and-john-wedding","maxLength":100},"address":{"type":"string","description":"Full address of the event location","example":"123 Main St, New York, NY 10001","maxLength":500},"hostMessage":{"type":"string","description":"Personal message from the host displayed on the RSVP page","example":"We are thrilled to invite you to celebrate our special day with us!","maxLength":5000},"invitationUrl":{"type":"string","description":"URL to the uploaded invitation image/media (S3/CDN URL)","example":"https://cdn.rsvpeasy.com/invitations/my-invite.jpg"},"backgroundColor":{"type":"string","description":"Background color for the RSVP page (hex code)","example":"#FFFFFF","maxLength":20},"textColor":{"type":"string","description":"Text color for the RSVP page (hex code)","example":"#333333","maxLength":20},"accentColor":{"type":"string","description":"Accent color for buttons and highlights (hex code)","example":"#D4AF37","maxLength":20},"fontFamily":{"type":"string","description":"Font family for the RSVP page","example":"Playfair Display","maxLength":100},"showAnimation":{"type":"boolean","description":"Whether to show entrance animation on the RSVP page","example":false,"default":false},"isDropShadowRequired":{"type":"boolean","description":"Whether to apply a drop shadow to the invitation image","example":false,"default":false},"acceptResponseText":{"type":"string","description":"Custom text shown when guest accepts the invitation","example":"We're so glad you can make it!","maxLength":500},"declineResponseText":{"type":"string","description":"Custom text shown when guest declines the invitation","example":"We'll miss you!","maxLength":500},"headerFont":{"type":"string","description":"Header font name (e.g. display font)","example":"Playfair Display","maxLength":100},"bodyFont":{"type":"string","description":"Body font name (e.g. body text font)","example":"Open Sans","maxLength":100},"headerFontFamily":{"type":"string","description":"Header font family for the RSVP page","example":"Playfair Display, serif","maxLength":150},"bodyFontFamily":{"type":"string","description":"Body font family for the RSVP page","example":"Open Sans, sans-serif","maxLength":150},"headerSize":{"type":"string","description":"Header font size (e.g. \"24px\", \"1.5rem\")","example":"24px","maxLength":20},"bodySize":{"type":"string","description":"Body font size (e.g. \"16px\", \"1rem\")","example":"16px","maxLength":20},"buttonTextColor":{"type":"string","description":"Button text color (hex code)","example":"#FFFFFF","maxLength":20},"buttonBorderColor":{"type":"string","description":"Button border color (hex code)","example":"#D4AF37","maxLength":20},"buttonBorderRadius":{"type":"string","description":"Button border radius (e.g. \"8px\", \"0.5rem\")","example":"8px","maxLength":20},"buttonBgColor":{"type":"string","description":"Button background color (hex code)","example":"#D4AF37","maxLength":20},"headerTextColor":{"type":"string","description":"Header text color (hex code)","example":"#333333","maxLength":20},"accommodations":{"description":"List of accommodation options. Items with an `id` update existing records; items without `id` create new ones. All existing accommodations not in this array will be deleted.","type":"array","items":{"$ref":"#/components/schemas/UpdateAccommodationItemDto"}},"formFields":{"description":"List of form fields. Replaces all existing form fields. Any existing GuestResponse data for custom fields will be removed when form fields are replaced.","type":"array","items":{"$ref":"#/components/schemas/UpdateFormFieldItemDto"}},"guests":{"description":"Pre-loaded guest list. Each guest gets a unique RSVP token on creation. Frontend can populate this from manual entry, CSV import, or phone contacts.","type":"array","items":{"$ref":"#/components/schemas/CreateGuestDto"}},"registryLinkName":{"type":"string","description":"Display name for the registry link","example":"Our Wedding Registry","maxLength":300},"registryUrl":{"type":"string","description":"URL to the gift registry (https:// is added if no protocol is provided)","example":"https://www.zola.com/registry/sarahandjohn2026"},"status":{"type":"string","description":"Event status. Allowed transitions: DRAFT → PUBLISHED, PUBLISHED → MANUALLY_CLOSED.","enum":["DRAFT","PUBLISHED","AUTO_CLOSED","MANUALLY_CLOSED","DUPLICATE","CLONED"],"example":"PUBLISHED"}}},"SendInvitationsResponseDto":{"type":"object","properties":{"message":{"type":"string","description":"Result message","example":"Successfully queued 5 invitations."},"count":{"type":"number","description":"Number of invitations queued","example":5}},"required":["message","count"]},"TwilioConfigDto":{"type":"object","properties":{"accountSid":{"type":"string","description":"Twilio Account SID"},"authToken":{"type":"string","description":"Twilio Auth Token"},"messagingServiceSid":{"type":"string","description":"Twilio Messaging Service SID"},"fromNumber":{"type":"string","description":"Twilio phone number (E.164 format, e.g. +61412345678)"}},"required":["accountSid","authToken","fromNumber"]},"SmtpConfigDto":{"type":"object","properties":{"host":{"type":"string","description":"SMTP host"},"port":{"type":"number","description":"SMTP port"},"secure":{"type":"boolean","description":"Use TLS/SSL"},"user":{"type":"string","description":"SMTP username"},"pass":{"type":"string","description":"SMTP password"},"fromEmail":{"type":"string","description":"From email address"},"fromName":{"type":"string","description":"From display name"},"replyTo":{"type":"string","description":"Reply-to email address"}},"required":["host","port","secure","user","pass","fromEmail","fromName"]},"CreateCommTemplateDto":{"type":"object","properties":{"type":{"type":"string","enum":["SMS","EMAIL"],"description":"Template channel type (SMS or EMAIL)"},"name":{"type":"string","description":"Unique template name within the organization"},"description":{"type":"string","description":"Template description"},"tags":{"description":"Tags for categorization","type":"array","items":{"type":"string"}},"subjectTemplate":{"type":"string","description":"Subject template - email only (LiquidJS syntax)"},"bodyTemplate":{"type":"string","description":"Body template (LiquidJS syntax)"},"bodyHtmlTemplate":{"type":"string","description":"HTML body template - email only (LiquidJS syntax)"},"greeting":{"type":"string","description":"Header greeting text, e.g. \"You're Invited!\"","example":"You're Invited!"},"customMessage":{"type":"string","description":"Custom body message from the host","example":"We would love for you to join us for this special occasion."},"buttonLabel":{"type":"string","description":"CTA button label, e.g. \"RSVP Now\"","example":"RSVP Now"}},"required":["type","name","bodyTemplate"]},"UpdateCommTemplateDto":{"type":"object","properties":{"name":{"type":"string","description":"Template name"},"description":{"type":"string","description":"Template description"},"tags":{"description":"Tags for categorization","type":"array","items":{"type":"string"}},"subjectTemplate":{"type":"string","description":"Subject template - email only"},"bodyTemplate":{"type":"string","description":"Body template"},"bodyHtmlTemplate":{"type":"string","description":"HTML body template - email only"},"greeting":{"type":"string","description":"Header greeting text, e.g. \"You're Invited!\""},"customMessage":{"type":"string","description":"Custom body message from the host"},"buttonLabel":{"type":"string","description":"CTA button label, e.g. \"RSVP Now\""}}},"PreviewTemplateDto":{"type":"object","properties":{"entityType":{"type":"string","description":"Entity type (event or guest)"},"entityId":{"type":"string","description":"Entity ID for context data"},"eventId":{"type":"string","description":"Event ID to use for context data"},"guestId":{"type":"string","description":"Guest ID to use for context data"}}},"SendSmsDto":{"type":"object","properties":{"to":{"type":"string","description":"Recipient phone number (any format, will be normalized to +61)"},"body":{"type":"string","description":"SMS message body"},"templateId":{"type":"string","description":"Template ID to render body from"},"eventId":{"type":"string","description":"Event ID for template context"},"guestId":{"type":"string","description":"Guest ID for template context"}},"required":["to","body"]},"MessageResponseDto":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"channel":{"type":"string"},"direction":{"type":"string"},"fromAddress":{"type":"string"},"toAddress":{"type":"string"},"subject":{"type":"string"},"bodyText":{"type":"string"},"bodyHtml":{"type":"string"},"provider":{"type":"string"},"providerMessageId":{"type":"string"},"status":{"type":"string"},"errorCode":{"type":"string"},"errorMessage":{"type":"string"},"sentAt":{"format":"date-time","type":"string"},"deliveredAt":{"format":"date-time","type":"string"},"templateId":{"type":"string"},"segmentCount":{"type":"number"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","orgId","channel","direction","fromAddress","toAddress","bodyText","status","createdAt","updatedAt"]},"SendEmailDto":{"type":"object","properties":{"to":{"type":"string","description":"Recipient email address"},"subject":{"type":"string","description":"Email subject line"},"bodyText":{"type":"string","description":"Plain text body"},"bodyHtml":{"type":"string","description":"HTML body"},"templateId":{"type":"string","description":"Template ID to render content from"},"eventId":{"type":"string","description":"Event ID for template context"},"guestId":{"type":"string","description":"Guest ID for template context"},"cc":{"description":"CC recipients","type":"array","items":{"type":"string"}},"bcc":{"description":"BCC recipients","type":"array","items":{"type":"string"}},"replyTo":{"type":"string","description":"Reply-To address"}},"required":["to","subject","bodyText"]},"GetAllMessagesDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MessageResponseDto"}}},"required":["data"]},"GetSingleMessageDto":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MessageResponseDto"}},"required":["data"]},"CreateOrganizationDto":{"type":"object","properties":{"name":{"type":"string","description":"Organization name","example":"Acme Corporation"},"slug":{"type":"string","description":"Unique URL-friendly slug","example":"acme-corp","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"description":{"type":"string","description":"Organization description","example":"A leading tech company"}},"required":["name","slug"]},"UpdateOrganizationDto":{"type":"object","properties":{"name":{"type":"string","description":"Organization name","example":"Acme Corporation"},"description":{"type":"string","description":"Organization description","example":"A leading tech company"},"isActive":{"type":"boolean","description":"Whether the organization is active","example":true}}},"UpdateOrgSettingsDto":{"type":"object","properties":{"emailRsvpReminderEnabled":{"type":"boolean","description":"Enable RSVP reminder emails","example":true},"emailEventReminderEnabled":{"type":"boolean","description":"Enable event reminder emails","example":true},"smsRsvpReminderEnabled":{"type":"boolean","description":"Enable RSVP reminder SMS","example":false},"smsEventReminderEnabled":{"type":"boolean","description":"Enable event reminder SMS","example":false}}},"CreateGreetingCardDto":{"type":"object","properties":{"title":{"type":"string","description":"Optional title for the greeting card","example":"Holiday Season Greetings","maxLength":200},"designUrl":{"type":"string","description":"URL of the greeting card design image","example":"https://example.com/designs/holiday-card.jpg"},"isDropShadowRequired":{"type":"boolean","description":"Whether to apply a drop shadow to the greeting card design","example":false,"default":false},"eventId":{"type":"string","description":"Optional event ID to link this greeting card to an existing event","example":"evt_abc123"}}},"GreetingCardDeliveryResponseDto":{"type":"object","properties":{"id":{"type":"string"},"orderId":{"type":"string"},"recipientName":{"type":"string"},"recipientEmail":{"type":"string"},"recipientPhone":{"type":"string"},"channel":{"type":"string","enum":["EMAIL","SMS"]},"status":{"type":"string","enum":["PENDING","SENT","DELIVERED","FAILED","CANCELED"]},"sentAt":{"format":"date-time","type":"string"},"deliveredAt":{"format":"date-time","type":"string"}},"required":["id","orderId","recipientName","channel","status"]},"GreetingCardSmsPackResponseDto":{"type":"object","properties":{"id":{"type":"string"},"quantity":{"type":"number"},"amount":{"type":"number"}},"required":["id","quantity","amount"]},"GreetingCardResponseDto":{"type":"object","properties":{"id":{"type":"string"},"orgId":{"type":"string"},"userId":{"type":"string"},"eventId":{"type":"string"},"status":{"type":"string","enum":["DRAFT","SCHEDULED","SENT","PARTIALLY_SENT","FAILED","CANCELED"]},"title":{"type":"string"},"designUrl":{"type":"string"},"isDropShadowRequired":{"type":"boolean","description":"Whether drop shadow is applied to the design","example":false},"totalRecipients":{"type":"number"},"smsRecipients":{"type":"number"},"emailRecipients":{"type":"number"},"price":{"type":"object"},"currency":{"type":"string"},"stripePriceId":{"type":"string"},"stripeInvoiceId":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/GreetingCardDeliveryResponseDto"}},"smsPacks":{"type":"array","items":{"$ref":"#/components/schemas/GreetingCardSmsPackResponseDto"}}},"required":["id","orgId","userId","status","isDropShadowRequired","totalRecipients","smsRecipients","emailRecipients","price","currency","createdAt","updatedAt"]},"GetSingleGreetingCardDto":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GreetingCardResponseDto"}},"required":["data"]},"UpdateGreetingCardDto":{"type":"object","properties":{"title":{"type":"string","description":"Title for the greeting card","example":"Holiday Season Greetings","maxLength":200},"designUrl":{"type":"string","description":"URL of the greeting card design image","example":"https://example.com/designs/holiday-card.jpg"},"isDropShadowRequired":{"type":"boolean","description":"Whether to apply a drop shadow to the greeting card design","example":false},"eventId":{"type":"string","description":"Optional event ID to link this greeting card to","example":"evt_abc123"}}},"RecipientDto":{"type":"object","properties":{"recipientName":{"type":"string","description":"Name of the recipient","example":"John Doe"},"recipientEmail":{"type":"string","description":"Email address of the recipient (required if channel is EMAIL)","example":"john@example.com"},"recipientPhone":{"type":"string","description":"Phone number of the recipient (required if channel is SMS)","example":"+15551234567"},"channel":{"type":"string","description":"Delivery channel for the greeting card","enum":["EMAIL","SMS"],"example":"EMAIL"}},"required":["recipientName","recipientEmail","recipientPhone","channel"]},"AddRecipientsDto":{"type":"object","properties":{"recipients":{"description":"Array of recipients to add to the greeting card","minItems":1,"type":"array","items":{"$ref":"#/components/schemas/RecipientDto"}}},"required":["recipients"]},"GetAllGreetingCardsDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GreetingCardResponseDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totalPages":{"type":"number"}},"required":["data","total","page","limit","totalPages"]},"RoleResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"The id of the role","example":"123e4567-e89b-12d3-a456-426614174000"},"orgId":{"type":"string","description":"The organization ID of the role","example":"123e4567-e89b-12d3-a456-426614174000"},"name":{"type":"string","description":"The name of the role","example":"Admin"},"description":{"type":"object","description":"The description of the role","example":"Administrator role with full access","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"The created at date of the role","example":"2021-01-01T00:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"The updated at date of the role","example":"2021-01-01T00:00:00.000Z"},"permissionCount":{"type":"number","description":"The number of permissions assigned to this role","example":12}},"required":["id","orgId","name","description","createdAt","updatedAt","permissionCount"]},"GetAllRoleDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"type":"array","items":{"$ref":"#/components/schemas/RoleResponseDto"}},"meta":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":10},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":10},"hasNext":{"type":"boolean","example":true},"hasPrev":{"type":"boolean","example":false}}}},"required":["success","statusCode","message","timestamp","data","meta"]},"CreateRoleDto":{"type":"object","properties":{"name":{"type":"string","description":"The name of the role","example":"Admin"},"description":{"type":"string","description":"The description of the role","example":"Administrator role with full access"}},"required":["name"]},"PermissionResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"The id of the permission","example":"123e4567-e89b-12d3-a456-426614174000"},"orgId":{"type":"string","description":"The organization ID of the permission","example":"123e4567-e89b-12d3-a456-426614174000"},"name":{"type":"string","description":"The name of the permission","example":"leads.read"},"description":{"type":"object","description":"The description of the permission","example":"Permission to read leads","nullable":true}},"required":["id","orgId","name","description"]},"RoleWithPermissionsResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"The id of the role","example":"123e4567-e89b-12d3-a456-426614174000"},"orgId":{"type":"string","description":"The organization ID of the role","example":"123e4567-e89b-12d3-a456-426614174000"},"name":{"type":"string","description":"The name of the role","example":"Admin"},"description":{"type":"object","description":"The description of the role","example":"Administrator role with full access","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"The created at date of the role","example":"2021-01-01T00:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"The updated at date of the role","example":"2021-01-01T00:00:00.000Z"},"permissionCount":{"type":"number","description":"The number of permissions assigned to this role","example":12},"permissions":{"description":"The permissions associated with this role","example":[{"id":"123e4567-e89b-12d3-a456-426614174000","orgId":"123e4567-e89b-12d3-a456-426614174000","name":"leads.read","description":"Permission to read leads"}],"type":"array","items":{"$ref":"#/components/schemas/PermissionResponseDto"}}},"required":["id","orgId","name","description","createdAt","updatedAt","permissionCount","permissions"]},"GetSingleRoleDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"$ref":"#/components/schemas/RoleWithPermissionsResponseDto"}},"required":["success","statusCode","message","timestamp","data"]},"UpdateRoleDto":{"type":"object","properties":{"name":{"type":"string","description":"The name of the role","example":"Admin"},"description":{"type":"string","description":"The description of the role","example":"Administrator role with full access"}}},"ManageRolePermissionsDto":{"type":"object","properties":{"permissionIds":{"description":"Array of permission IDs to add or remove from the role","example":["123e4567-e89b-12d3-a456-426614174000","223e4567-e89b-12d3-a456-426614174001"],"type":"array","items":{"type":"string"}}},"required":["permissionIds"]},"GetAllPermissionDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"type":"array","items":{"$ref":"#/components/schemas/PermissionResponseDto"}},"meta":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":10},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":10},"hasNext":{"type":"boolean","example":true},"hasPrev":{"type":"boolean","example":false}}}},"required":["success","statusCode","message","timestamp","data","meta"]},"GetSinglePermissionDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"$ref":"#/components/schemas/PermissionResponseDto"}},"required":["success","statusCode","message","timestamp","data"]},"UserWithRoleResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"The id of the user","example":"123e4567-e89b-12d3-a456-426614174000"},"orgId":{"type":"string","description":"The organization ID of the user","example":"123e4567-e89b-12d3-a456-426614174000"},"username":{"type":"object","description":"The username of the user","example":"johndoe","nullable":true},"name":{"type":"object","description":"The name of the user","example":"John Doe","nullable":true},"email":{"type":"string","description":"The email of the user","example":"john@example.com"},"emailVerified":{"type":"boolean","description":"Email verification status","example":true},"image":{"type":"object","description":"User profile image","example":"https://example.com/image.jpg","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"User creation date","example":"2024-01-01T00:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"User last update date","example":"2024-01-01T00:00:00.000Z"},"onboardingStatus":{"type":"string","description":"User onboarding status","enum":["PENDING","ACTIVE","SUSPENDED"],"example":"ACTIVE"},"accountType":{"type":"string","description":"User account type","enum":["ADMIN","HOST"],"example":"HOST"},"roles":{"description":"The roles associated with this user","example":[{"id":"123e4567-e89b-12d3-a456-426614174000","orgId":"123e4567-e89b-12d3-a456-426614174000","name":"Admin","description":"Administrator role with full access"}],"type":"array","items":{"$ref":"#/components/schemas/RoleResponseDto"}},"eventCount":{"type":"number","description":"Number of events created by this user","example":5},"planName":{"type":"object","description":"Name of the subscription plan","example":"Premium","nullable":true},"planCode":{"type":"object","description":"Code of the subscription plan","example":"PREMIUM","nullable":true}},"required":["id","orgId","username","name","email","emailVerified","image","createdAt","updatedAt","onboardingStatus","accountType","roles","eventCount","planName","planCode"]},"GetAllUserDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"type":"array","items":{"$ref":"#/components/schemas/UserWithRoleResponseDto"}},"meta":{"type":"object","properties":{"page":{"type":"number","example":1},"limit":{"type":"number","example":10},"total":{"type":"number","example":100},"totalPages":{"type":"number","example":10},"hasNext":{"type":"boolean","example":true},"hasPrev":{"type":"boolean","example":false}}}},"required":["success","statusCode","message","timestamp","data","meta"]},"GetSingleUserDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"$ref":"#/components/schemas/UserWithRoleResponseDto"}},"required":["success","statusCode","message","timestamp","data"]},"CreateUserDto":{"type":"object","properties":{"name":{"type":"string","description":"The name of the user","example":"John Doe"},"email":{"type":"string","description":"The email of the user","example":"john@example.com"},"password":{"type":"string","description":"The password for the user account","example":"SecurePassword123!","minLength":8},"username":{"type":"string","description":"The username of the user","example":"johndoe"},"image":{"type":"string","description":"User profile image URL","example":"https://example.com/image.jpg"}},"required":["name","email","password"]},"AssignRolesDto":{"type":"object","properties":{"roleIds":{"description":"Array of role IDs to assign to the user","example":["role-id-1","role-id-2"],"type":"array","items":{"type":"string"}}},"required":["roleIds"]},"ChangePasswordDto":{"type":"object","properties":{"currentPassword":{"type":"string","description":"Current account password","example":"old-password-123"},"newPassword":{"type":"string","description":"New account password (minimum 6 characters)","example":"new-password-123"}},"required":["currentPassword","newPassword"]},"UpdateUserDto":{"type":"object","properties":{"name":{"type":"string","description":"The name of the user","example":"John Doe"},"image":{"type":"string","description":"User profile image URL","example":"https://example.com/image.jpg"}}},"OnboardingStateResponseDto":{"type":"object","properties":{"profileCompleted":{"type":"boolean","description":"Whether the host has completed their profile","example":false},"hasCreatedFirstEvent":{"type":"boolean","description":"Whether the host has created their first event","example":false},"hasCompletedOnboarding":{"type":"boolean","description":"Whether the host has completed all onboarding steps","example":false},"completedSteps":{"description":"List of completed step identifiers","example":["profile"],"type":"array","items":{"type":"string"}}},"required":["profileCompleted","hasCreatedFirstEvent","hasCompletedOnboarding","completedSteps"]},"CompleteStepDto":{"type":"object","properties":{"step":{"type":"string","description":"The onboarding step to mark as complete","enum":["profile","firstEvent"],"example":"profile"}},"required":["step"]},"CustomCategoryResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"The id of the custom category","example":"123e4567-e89b-12d3-a456-426614174000"},"orgId":{"type":"string","description":"The organization ID of the custom category","example":"123e4567-e89b-12d3-a456-426614174000"},"code":{"type":"string","description":"The code of the custom category","example":"rsvp_status"},"name":{"type":"string","description":"The name of the custom category","example":"RSVP Status"},"description":{"type":"object","description":"The description of the custom category","example":"RSVP status options for events","nullable":true},"isSystem":{"type":"boolean","description":"Whether this is a system category","example":false},"createdAt":{"format":"date-time","type":"string","description":"The created at timestamp of the custom category","example":"2025-11-19T10:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"The updated at timestamp of the custom category","example":"2025-11-19T10:00:00.000Z"},"icon":{"type":"object","description":"The icon for the custom category","example":"user","nullable":true}},"required":["id","orgId","code","name","description","isSystem","createdAt","updatedAt","icon"]},"PaginationMeta":{"type":"object","properties":{}},"GetAllCustomCategoryDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"type":"array","items":{"$ref":"#/components/schemas/CustomCategoryResponseDto"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["success","statusCode","message","timestamp","data","meta"]},"CreateCustomCategoryDto":{"type":"object","properties":{"code":{"type":"string","description":"The code of the custom category","example":"rsvp_status"},"name":{"type":"string","description":"The name of the custom category","example":"RSVP Status"},"description":{"type":"string","description":"The description of the custom category","example":"RSVP status options for events"},"isSystem":{"type":"boolean","description":"Whether this is a system category (cannot be deleted)","example":false,"default":false},"icon":{"type":"string","description":"The icon for the custom category","example":"user"}},"required":["code","name"]},"CustomCategoryOptionResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"The id of the custom category option","example":"123e4567-e89b-12d3-a456-426614174000"},"categoryId":{"type":"string","description":"The id of the custom category","example":"123e4567-e89b-12d3-a456-426614174000"},"optionName":{"type":"string","description":"The name of the custom category option","example":"Attending"},"optionValue":{"type":"string","description":"The value of the custom category option","example":"attending"},"sortOrder":{"type":"number","description":"The sort order of the custom category option","example":1},"isActive":{"type":"boolean","description":"Whether this option is active","example":true},"colorHex":{"type":"object","description":"The color hex code for this option","example":"#FF5733","nullable":true},"icon":{"type":"object","description":"The icon for this option","example":"user","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"The created at timestamp","example":"2025-11-19T10:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"The updated at timestamp","example":"2025-11-19T10:00:00.000Z"}},"required":["id","categoryId","optionName","optionValue","sortOrder","isActive","colorHex","icon","createdAt","updatedAt"]},"CustomCategoryWithOptionsResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"The id of the custom category","example":"123e4567-e89b-12d3-a456-426614174000"},"orgId":{"type":"string","description":"The organization ID of the custom category","example":"123e4567-e89b-12d3-a456-426614174000"},"code":{"type":"string","description":"The code of the custom category","example":"rsvp_status"},"name":{"type":"string","description":"The name of the custom category","example":"RSVP Status"},"description":{"type":"object","description":"The description of the custom category","example":"RSVP status options for events","nullable":true},"isSystem":{"type":"boolean","description":"Whether this is a system category","example":false},"createdAt":{"format":"date-time","type":"string","description":"The created at timestamp of the custom category","example":"2025-11-19T10:00:00.000Z"},"updatedAt":{"format":"date-time","type":"string","description":"The updated at timestamp of the custom category","example":"2025-11-19T10:00:00.000Z"},"icon":{"type":"object","description":"The icon for the custom category","example":"user","nullable":true},"options":{"description":"The options of the custom category","type":"array","items":{"$ref":"#/components/schemas/CustomCategoryOptionResponseDto"}}},"required":["id","orgId","code","name","description","isSystem","createdAt","updatedAt","icon","options"]},"GetSingleCustomCategoryDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"$ref":"#/components/schemas/CustomCategoryWithOptionsResponseDto"}},"required":["success","statusCode","message","timestamp","data"]},"UpdateCustomCategoryDto":{"type":"object","properties":{"code":{"type":"string","description":"The code of the custom category","example":"rsvp_status"},"name":{"type":"string","description":"The name of the custom category","example":"RSVP Status"},"description":{"type":"string","description":"The description of the custom category","example":"RSVP status options for events"},"isSystem":{"type":"boolean","description":"Whether this is a system category (cannot be deleted)","example":false}}},"CreateCustomCategoryOptionDto":{"type":"object","properties":{"optionName":{"type":"string","description":"The name of the option","example":"Attending"},"optionValue":{"type":"string","description":"The value of the option","example":"attending"},"sortOrder":{"type":"number","description":"The sort order of the option","example":1},"isActive":{"type":"boolean","description":"Whether this option is active","example":true,"default":true},"colorHex":{"type":"string","description":"The color hex code for this option","example":"#FF5733"},"icon":{"type":"string","description":"The icon for this option","example":"user"}},"required":["optionName","optionValue","sortOrder"]},"UpdateCustomCategoryOptionDto":{"type":"object","properties":{"optionName":{"type":"string","description":"The name of the option","example":"Attending"},"optionValue":{"type":"string","description":"The value of the option","example":"attending"},"sortOrder":{"type":"number","description":"The sort order of the option","example":1},"isActive":{"type":"boolean","description":"Whether this option is active","example":true},"colorHex":{"type":"string","description":"The color hex code for this option","example":"#FF5733"},"icon":{"type":"string","description":"The icon for this option","example":"user"}}},"ExtractResponseDto":{"type":"object","properties":{"data":{"type":"object","description":"Extracted event data"},"confidence":{"type":"number","description":"Confidence score from 0 to 1","example":0.85},"mode":{"type":"string","description":"Extraction mode that was used","example":"full"}},"required":["data","confidence","mode"]},"ScheduleJobResponseDto":{"type":"object","properties":{"jobName":{"type":"string"},"cronExpression":{"type":"string"},"description":{"type":"string"},"manualTriggerEnabled":{"type":"boolean"}},"required":["jobName","cronExpression","description","manualTriggerEnabled"]},"TriggerScheduleDto":{"type":"object","properties":{"jobName":{"type":"string","description":"The name of the job to trigger","enum":["outbox.process","outbox.cleanup","event.reminders.process","event.event-reminders.process","billing.sms-credits.expire"],"example":"outbox.process"}},"required":["jobName"]},"ScheduleTriggerResponseDto":{"type":"object","properties":{"jobName":{"type":"string"},"startedAt":{"format":"date-time","type":"string"},"finishedAt":{"format":"date-time","type":"string"},"durationMs":{"type":"number"},"status":{"type":"string","enum":["success","skipped","failed"]},"result":{"type":"object"},"error":{"type":"string"}},"required":["jobName","startedAt","finishedAt","durationMs","status"]},"EventCountsDto":{"type":"object","properties":{"total":{"type":"number","example":12,"description":"Total events created"},"published":{"type":"number","example":5,"description":"Currently published events"},"draft":{"type":"number","example":3,"description":"Events in draft status"},"closed":{"type":"number","example":4,"description":"Closed events (auto + manual)"},"newThisMonth":{"type":"number","example":2,"description":"New events created this month"},"publishedChangeThisWeek":{"type":"number","example":1,"description":"Net published event change compared to last week"}},"required":["total","published","draft","closed","newThisMonth","publishedChangeThisWeek"]},"GuestAggregatesDto":{"type":"object","properties":{"total":{"type":"number","example":150,"description":"Total guests across all events"},"attending":{"type":"number","example":90,"description":"Guests who accepted"},"declined":{"type":"number","example":20,"description":"Guests who declined"},"pending":{"type":"number","example":40,"description":"Guests who have not responded"},"responseRate":{"type":"number","example":73,"description":"Percentage of guests who responded"},"responseRateChange":{"type":"number","example":12,"description":"Change in response rate compared to last week, in percentage points"}},"required":["total","attending","declined","pending","responseRate","responseRateChange"]},"HeadcountDto":{"type":"object","properties":{"totalAdults":{"type":"number","example":120,"description":"Total attending adults"},"totalChildren":{"type":"number","example":15,"description":"Total attending children"},"totalHeadcount":{"type":"number","example":135,"description":"Total headcount (adults + children)"}},"required":["totalAdults","totalChildren","totalHeadcount"]},"CommunicationStatsDto":{"type":"object","properties":{"smsSent":{"type":"number","example":50,"description":"Total SMS messages sent"},"emailsSent":{"type":"number","example":200,"description":"Total emails sent"},"invitationsSent":{"type":"number","example":150,"description":"Total invitations sent"},"remindersSent":{"type":"number","example":80,"description":"Total reminders sent"}},"required":["smsSent","emailsSent","invitationsSent","remindersSent"]},"RecentEventDto":{"type":"object","properties":{"id":{"type":"string","example":"cmieqoaba0000iymt4fab0345"},"name":{"type":"string","example":"Sarah & John Wedding"},"slug":{"type":"string","example":"sarah-john-wedding-abc123"},"status":{"type":"string","example":"PUBLISHED"},"eventDate":{"type":"object","example":"2026-06-15T00:00:00.000Z","nullable":true},"locationName":{"type":"object","example":"Grand Ballroom","nullable":true},"tier":{"type":"string","example":"ESSENTIAL"},"createdAt":{"format":"date-time","type":"string","example":"2026-04-01T10:00:00.000Z"},"guestCount":{"type":"number","example":45}},"required":["id","name","slug","status","eventDate","locationName","tier","createdAt","guestCount"]},"UpcomingEventDto":{"type":"object","properties":{"id":{"type":"string","example":"cmieqoaba0000iymt4fab0345"},"name":{"type":"string","example":"Sarah & John Wedding"},"slug":{"type":"string","example":"sarah-john-wedding-abc123"},"eventDate":{"type":"object","example":"2026-06-15T00:00:00.000Z","nullable":true},"locationName":{"type":"object","example":"Grand Ballroom","nullable":true},"rsvpBy":{"type":"object","example":"2026-06-01T00:00:00.000Z","nullable":true},"attendingCount":{"type":"number","example":30}},"required":["id","name","slug","eventDate","locationName","rsvpBy","attendingCount"]},"DashboardKpiDto":{"type":"object","properties":{"events":{"$ref":"#/components/schemas/EventCountsDto"},"guests":{"$ref":"#/components/schemas/GuestAggregatesDto"},"headcount":{"$ref":"#/components/schemas/HeadcountDto"},"communications":{"$ref":"#/components/schemas/CommunicationStatsDto"},"recentEvents":{"description":"Last 5 events created","type":"array","items":{"$ref":"#/components/schemas/RecentEventDto"}},"upcomingEvents":{"description":"Next 5 upcoming published events","type":"array","items":{"$ref":"#/components/schemas/UpcomingEventDto"}}},"required":["events","guests","headcount","communications","recentEvents","upcomingEvents"]},"GetDashboardKpiDto":{"type":"object","properties":{"success":{"type":"boolean","example":true,"description":"Indicates if the request was successful"},"statusCode":{"type":"number","example":200,"description":"HTTP status code"},"message":{"type":"string","example":"Operation completed successfully","description":"Response message"},"timestamp":{"type":"string","example":"2025-11-19T10:00:00.000Z","description":"Response timestamp"},"data":{"$ref":"#/components/schemas/DashboardKpiDto"}},"required":["success","statusCode","message","timestamp","data"]},"AdminRevenueDto":{"type":"object","properties":{"total":{"type":"number","example":15800},"subscriptions":{"type":"number","example":7900},"eventUpgrades":{"type":"number","example":6900},"smsTopups":{"type":"number","example":1000},"currency":{"type":"string","example":"usd"}},"required":["total","subscriptions","eventUpgrades","smsTopups","currency"]},"AdminUserStatsDto":{"type":"object","properties":{"total":{"type":"number","example":25},"admins":{"type":"number","example":2},"hosts":{"type":"number","example":23},"newThisMonth":{"type":"number","example":5}},"required":["total","admins","hosts","newThisMonth"]},"AdminEventStatsDto":{"type":"object","properties":{"total":{"type":"number","example":40},"published":{"type":"number","example":25},"draft":{"type":"number","example":10},"closed":{"type":"number","example":5}},"required":["total","published","draft","closed"]},"AdminSubscriptionStatsDto":{"type":"object","properties":{"active":{"type":"number","example":8},"canceled":{"type":"number","example":2},"total":{"type":"number","example":10}},"required":["active","canceled","total"]},"AdminGuestStatsDto":{"type":"object","properties":{"total":{"type":"number","example":500},"attending":{"type":"number","example":300},"declined":{"type":"number","example":50},"pending":{"type":"number","example":150},"responseRate":{"type":"number","example":70}},"required":["total","attending","declined","pending","responseRate"]},"RecentSignupDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"object"},"email":{"type":"string"},"accountType":{"type":"string"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","name","email","accountType","createdAt"]},"RecentTransactionDto":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"amount":{"type":"object"},"currency":{"type":"object"},"status":{"type":"string"},"userName":{"type":"object"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","type","amount","currency","status","userName","createdAt"]},"AdminKpiResponseDto":{"type":"object","properties":{"revenue":{"$ref":"#/components/schemas/AdminRevenueDto"},"users":{"$ref":"#/components/schemas/AdminUserStatsDto"},"events":{"$ref":"#/components/schemas/AdminEventStatsDto"},"subscriptions":{"$ref":"#/components/schemas/AdminSubscriptionStatsDto"},"guests":{"$ref":"#/components/schemas/AdminGuestStatsDto"},"recentSignups":{"type":"array","items":{"$ref":"#/components/schemas/RecentSignupDto"}},"recentTransactions":{"type":"array","items":{"$ref":"#/components/schemas/RecentTransactionDto"}}},"required":["revenue","users","events","subscriptions","guests","recentSignups","recentTransactions"]},"CreateSupportTicketDto":{"type":"object","properties":{"subject":{"type":"string","description":"The subject of the support ticket","example":"Cannot publish my event"},"category":{"type":"string","description":"The category of the support ticket","enum":["BILLING","EVENTS","TECHNICAL","OTHER"],"example":"TECHNICAL"},"message":{"type":"string","description":"The initial message for the support ticket","example":"I am trying to publish my event but the button is not working."},"priority":{"type":"string","description":"The priority of the support ticket","enum":["LOW","NORMAL","HIGH","URGENT"],"example":"NORMAL","default":"NORMAL"}},"required":["subject","category","message"]},"ReplySupportTicketDto":{"type":"object","properties":{"body":{"type":"string","description":"The reply message body","example":"Thank you for reaching out. We are looking into this."}},"required":["body"]},"UpdateSupportTicketDto":{"type":"object","properties":{"status":{"type":"string","description":"The status of the support ticket","enum":["OPEN","IN_PROGRESS","RESOLVED","CLOSED"],"example":"IN_PROGRESS"},"priority":{"type":"string","description":"The priority of the support ticket","enum":["LOW","NORMAL","HIGH","URGENT"],"example":"HIGH"}}}}},"security":[{"bearer-auth":[],"x-org-id":[]}]}