Appearance
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 TransactionLayers
- 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 - Transformer (
apps/server/app/transformers/event_transformer.ts) - Response serialization - Event plan controller (
apps/server/app/controllers/event_plans_controller.ts) - Event-plan creation under an organization-scoped event - Event plan service (
apps/server/app/services/event_plan_service.ts) - Draft plan creation and duplicate-name validation - Event plan transformer (
apps/server/app/transformers/event_plan_transformer.ts) - Event-plan 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 schema; current API operations attach addresses to events
- 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
- Organization-scoped routes require membership in the route organization
- Create uses the route organization as the event owner
- Show and update load the requested event, then
EventPolicychecks membership in the organization stored on that event - Plan creation resolves the parent event within the route organization before applying the update policy
- Collaborator records: The schema and model exist; collaborator APIs and permission enforcement are planned
- Personnel records: The schema and model store text entries; personnel APIs and address links are planned
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 event planning entities (EventPlan, EventBlock, Tasks, Vendors, Permissions), see the Event Planning Data Models documentation. Event plan creation is implemented; additional plan operations and most sub-entity APIs are not yet implemented.
API Endpoints
All event endpoints are nested under organization routes and require authentication.
Available Operations
- POST
/organizations/:organizationId/events- Create a new event - PUT/PATCH
/organizations/:organizationId/events/:id- Partially update an existing event - GET
/organizations/:organizationId/events/:id- Retrieve event details - POST
/organizations/:organizationId/events/:eventId/plans- Create a new draft event plan
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:
- Create Event - User must be a member of the target organization
- View Event - User must be a member of the organization that owns the event
- Update Event - User must be a member of the organization that owns the event
- Create Event Plan - User must be able to update the parent event
Organization Access Verification
The route middleware verifies access to the organization path parameter. OrganizationAuthorizationService also supplies the membership checks used by EventPolicy.
Response Serialization
Event responses use EventTransformer with two representations:
toObject(): Used for list views and mutations (id, name, description, organizationId)forDetailed(): Extends toObject with timestamps (createdAt, updatedAt)
Implementation: apps/server/app/transformers/event_transformer.ts
Event plan creation responses use EventPlanTransformer.forDetailed() with id, eventId, name, description, state, createdAt, and updatedAt.
Validation
Controllers validate event and plan input with the domain validators before calling services. Complete accepted fields, enum values, defaults, and nested metadata/address rules are in the Events API reference. Recurrence fields exist in persistence but are not part of the current request contract.
Error Handling
The implementation uses neverthrow for explicit repository/service flow and self-handling app exceptions for consistent API/log output.
Result Pattern
typescript
// Service layer returns Result
const result = await eventService.createEvent(organizationId, data)
// Controller delegates error branches to the shared handler
if (result.isErr()) {
return handleAppError(result.error, ctx, {
fallback: {
message: 'Failed to create event',
logKey: 'events:create',
},
})
}Error Types
- VineJS validation errors - normalized to
422withinput.{field}.{rule}codes - RepositoryException - data-access failures with explicit API errors and backend-only log details
- ModelValidationException - domain/model validation failures with exposure-controlled field errors
- EventPlanValidationException - duplicate event-plan name and active-plan invariant failures
- EventPlanServiceException - service-owned event-plan creation failures that are not model validation errors
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 plan list/show/update/archive/activate endpoints
- Event search functionality
- Recurring event instance management
- APIs for blocks, tasks, budgets, collaborators, personnel, comments, and permissions
For the current implementation status, see the actual code in:
apps/server/app/controllers/events_controller.tsapps/server/app/services/event_service.tsapps/server/app/repositories/event_repository.tsapps/server/app/policies/event_policy.ts