Calendar
Multi-calendar event scheduling with audience-based access control
Overview
The Calendar feature provides a comprehensive event scheduling and management system supporting multiple calendars with color-coding, audience-based access control, and full CRUD operations. It enables organizations to manage events across different calendars, departments, and user groups with granular permission controls.
Key Features
Multiple Calendars
- Color-Coded Calendars: Organize events with 12+ color options
- Unlimited Calendars: Create as many calendars as needed
- Calendar Naming: Unique calendar names per tenant
- Audience Filtering: Restrict calendar visibility based on user audiences
Event Management
- Create Events: Schedule events with date, time, and details
- Recurring Events: Support for repeating events (implementation in CalendarEvent model)
- Calendar Association: Events linked to specific calendars
- Full CRUD Operations: Create, read, update, and delete events
- Event Validation: Prevent calendar deletion if events exist
Access Control
- Audience-Based Visibility: Show/hide calendars based on user audience membership
- Admin-Only Management: Calendar creation restricted to admins
- Department Integration: Optional department-based calendar organization
- User Tracking: Track calendar creators and last modifiers
Database Models
Calendar Model
model Calendar {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenantId String
tenant Tenant @relation(fields: [tenantId], references: [id])
createdByUserId String?
createdByUser User? @relation("createdByUser", fields: [createdByUserId], references: [id])
lastModifiedByUserId String?
lastModifiedByUser User? @relation("modifiedByUser", fields: [lastModifiedByUserId], references: [id])
name String
color String @default("blue")
events CalendarEvent[]
audience Audience[]
}CalendarEvent Model
model CalendarEvent {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenantId String
tenant Tenant @relation(fields: [tenantId], references: [id])
calendarId String
calendar Calendar @relation(fields: [calendarId], references: [id])
title String
description String?
startDate DateTime
endDate DateTime
location String?
allDay Boolean @default(false)
recurrence String? // JSON for recurring event rules
}Routes
Admin Routes
/app/{tenant}/settings/calendars- Manage calendars (create, edit, delete)
Calendar management features:
- Table view with color indicators
- Calendar creation dialog
- Edit calendar details
- Delete calendars (only if no events exist)
- Audience assignment
Calendar Configuration
Default Colors
Available calendar colors using Tailwind color system:
- Blue (default)
- Red
- Green
- Yellow
- Purple
- Pink
- Indigo
- Orange
- Teal
- Cyan
- Lime
- Emerald
Color Implementation
const DEFAULT_CALENDAR_COLOR = "blue";
// Color display in UI
<span
className="size-2 rounded-full"
style={{
"--event-color": `var(--color-${item.color}-400)`,
backgroundColor: "var(--event-color)"
} as React.CSSProperties}
></span>Access Control
Audience-Based Filtering
Calendars can be restricted to specific audiences:
const filterableProperties: FilterablePropertyDto[] = [];
// Calendars are filtered by user's audience membership
// Users only see calendars they have access to via audiencePermission Requirements
- View Calendars: All authenticated users with
calendarfeature access - Manage Calendars: Admin users only (
adminOnly: true) - Create Events: Users with calendar access
- Delete Calendar: Admin only, and only if no events exist
Calendar Operations
Creating a Calendar
await createCalendar({
tenantId,
createdByUserId: userId,
name,
color,
audienceIds,
});Validation:
- Unique calendar name per tenant
- Color defaults to blue if not specified
- Creator tracked in
createdByUserId
Updating a Calendar
await updateCalendar({
id,
tenantId,
data: {
name,
color,
lastModifiedByUserId: userId,
audienceIds,
},
});Deleting a Calendar
const countEvents = await db.calendarEvent.count({ where: { calendarId: id } });
if (countEvents > 0) {
return { error: "Calendar has events. Please delete events first." };
}
await deleteCalendar({ id, tenantId });Best Practices
- Color Consistency: Use consistent color schemes across related calendars
- Naming Conventions: Use clear, descriptive calendar names
- Audience Setup: Configure audiences before assigning to calendars
- Event Cleanup: Delete all events before deleting a calendar
- Access Control: Regularly review audience assignments for calendars
- Department Alignment: Align calendars with organizational departments when applicable
Common Operations
Create a Calendar
- Navigate to
/app/{tenant}/settings/calendars - Click "+ Add" button
- Enter calendar name
- Select calendar color
- Assign audiences (optional)
- Click "Save"
Edit Calendar Details
- Click on a calendar in the table
- Update name, color, or audience assignments
- Click "Save"
- Changes tracked with
lastModifiedByUserId
Delete a Calendar
- Ensure calendar has no events
- Click dropdown menu next to calendar
- Select "Delete"
- Confirm deletion
- Calendar permanently removed
Assign Audiences
- Open calendar edit dialog
- Select audiences from dropdown
- Save changes
- Calendar now visible only to selected audience members
Integration Points
- Audiences: Audience-based calendar visibility and access control
- Departments: Optional department-based calendar organization
- Events: CalendarEvent model for storing scheduled events
- Users: Track calendar creators and modifiers
- Tenants: Multi-tenant isolation for calendar data

