Skip to content

Event Planning Backend Implementation

Backend implementation for event creation and management API endpoints.

Architecture

Events are managed through a layered architecture:

Client Request → Controller → Service → Repository → Database
                      ↓            ↓
                   Policy      Transaction

Layers

  • Controller (apps/server/app/controllers/events_controller.ts) - HTTP request handling, response formatting
  • Service (apps/server/app/services/event_service.ts) - Business logic and validation
  • Repository (apps/server/app/repositories/event_repository.ts) - Data access with transaction support
  • Policy (apps/server/app/policies/event_policy.ts) - Authorization rules
  • DTO (apps/server/app/dtos/event.ts) - Response serialization

Data Models

The event planning feature uses the following core models:

  • Event - Core event entity with organization ownership, status tracking, and flexible metadata for categories, guest counts, and budgets
  • Address - Polymorphic location data that can belong to Event, Vendor, or EventPersonnel entities
  • EventPlan - Event planning drafts and versions
  • EventBlock - Modular event components with polymorphic containers

For complete schema details, field definitions, metadata structure, and relationships, see:

Business Logic

Event Ownership & Organization Scope

  • Event ownership: Events belong to organizations, not individual users
    • All queries must be scoped to the active organization
    • Cross-organization access is prevented at the application layer
  • Collaborator access: Organization members can be added as EventCollaborators (future)
  • Personnel management: EventPersonnel are text entries (future)

Address Handling

  • Polymorphic relationship: Events can have one associated address
  • Transaction-safe: Address creation/updates happen within event transactions
  • Optional: Addresses are not required for event creation

For details on other event planning entities (EventPlan, EventBlock, Tasks, Vendors, Permissions), see the Event Planning Data Models documentation. These features are planned for future implementation.

API Endpoints

All event endpoints are nested under organization routes and require authentication.

Available Operations

  • POST /organizations/:organizationId/events - Create a new event with metadata and optional address
  • PATCH /organizations/:organizationId/events/:id - Update existing event (supports partial updates with metadata deep-merging)
  • GET /organizations/:organizationId/events/:id - Retrieve event details

For complete API documentation including request/response formats, metadata schemas, validation rules, deep-merge behavior, and usage examples, see:

Authorization

Authorization is handled by the EventPolicy class, which enforces organization-based access control.

Authorization Rules

All event operations check organization membership:

  1. Create Event - User must be a member of the target organization
  2. View Event - User must be a member of the organization that owns the event
  3. Update Event - User must be a member of the organization that owns the event

Organization Access Verification

Organization membership is verified by the OrganizationAuthorizationService:

Response Serialization

Event responses use a two-level DTO pattern:

  • Minimal DTO: Used for list views (id, name, description, organizationId)
  • Detailed DTO: Extends minimal with timestamps (createdAt, updatedAt)

Implementation: apps/server/app/dtos/event.ts

Validation

Validation Strategy

  • Required fields: Only name is required for event creation
  • Optional fields: description, targetDate, status, metadata, address
  • Metadata validation: Supports category, guestCount, budgetRange with nested validation
  • Address validation: Requires city, optional street address, state, postal code, country
  • Custom validators: Currency codes (ISO 4217), country codes (ISO 3166-1 alpha-2), postal codes

Default Values

  • status: BACKLOG
  • eventType: ONE_OFF
  • metadata.budgetRange.currency: CAD (when budgetRange is provided)

For complete validation schemas and field constraints, see:

Error Handling

The implementation uses the neverthrow Result pattern for explicit error handling.

Result Pattern

typescript
// Service layer returns Result
const result = await eventService.createEvent(organizationId, data)

// Controller handles both success and error cases
return result.match(
  (event) => response.created({ data: new EventDto(event).minimal }),
  (error) => {
    // Handle validation errors
    if (error instanceof errors.E_VALIDATION_ERROR) {
      return response.badRequest({ errors: error.messages })
    }
    // Handle other errors
    return response.internalServerError({ message: 'Failed to create event' })
  }
)

Error Types

  • E_VALIDATION_ERROR - VineJS validation failures
  • Error - Database errors, not found errors, etc.

Future Enhancements

The following features are planned but not yet implemented:

  • Role-based permissions (currently organization membership check only)
  • Event deletion endpoint
  • Event listing with pagination and filtering
  • Event search functionality
  • Recurring event instance management
  • And More..

For the current implementation status, see the actual code in:

  • apps/server/app/controllers/events_controller.ts
  • apps/server/app/services/event_service.ts
  • apps/server/app/repositories/event_repository.ts
  • apps/server/app/policies/event_policy.ts

Built with ❤️ by the Jubiloop team