Building calendar features turns into a mess fast. What starts as "just store some events" becomes Redis for caching, Kafka for real-time updates, and multiple services just to check if someone's free for a meeting.
You end up debugging why calendars aren't syncing instead of building the scheduling features users actually want.
Harper changes this. Everything runs in one process: database, cache, real-time updates, conflict detection. No network calls between services, no complex synchronization.
The Traditional Calendar Nightmare
Calendar systems get complex because of coordination between services. Your availability service needs to talk to your event service. Notifications need to sync with conflict detection. Time zones need to work across everything.
A simple "meeting time changed" notification becomes a distributed systems problem. Database updates, cache invalidation, real-time pushes, and hoping nothing fails halfway through.
Setting Up Your Calendar Schema
Harper uses GraphQL to define your data model and automatically generates REST endpoints:
type User @table @export {
id: ID @primaryKey
email: String @indexed
name: String
timezone: String
createdAt: String @createdTime
}
type Event @table @export {
id: ID @primaryKey
title: String @indexed
startTime: String @indexed
endTime: String @indexed
organizerId: ID @indexed
organizer: User @relationship(from: organizerId)
attendeeIds: [ID] @indexed
attendees: [User] @relationship(from: attendeeIds)
status: String @indexed
createdAt: String @createdTime
}
type Availability @table @export {
id: ID @primaryKey
userId: ID @indexed
dayOfWeek: Int @indexed
startTime: String @indexed
endTime: String @indexed
isAvailable: Boolean @indexed
}
The @export
directive creates REST endpoints at /User/
, /Event/
, and /Availability/
. The @relationship
directive handles joins automatically.
Simple Scheduling Operations
Create a meeting:
POST /Event/
Content-Type: application/json
{
"title": "Product Review",
"startTime": "2024-08-15T14:00:00Z",
"endTime": "2024-08-15T15:00:00Z",
"organizerId": "user123",
"attendeeIds": ["user456", "user789"]
}
Get someone's calendar:
GET /Event/?organizerId=user123&startTime=gte=2024-08-01&sort=startTime
Check for conflicts:
GET /Event/?attendeeIds=user123&startTime=lt=2024-08-15T15:00:00Z&endTime=gt=2024-08-15T14:00:00Z
Everything happens in the same process. No network latency, no coordination complexity.
Real-Time Updates
Harper has WebSockets built in:
ws://localhost:9926/Event/user123
When someone accepts a meeting, all attendees see the update instantly. No message brokers needed.
Time Zone Handling
Store everything in UTC, handle conversion at query time:
GET /Event/?organizerId=user123&timezone=America/New_York&startTime=gte=2024-08-15
No separate timezone service, no complex conversion logic.
Why This Works
Harper's single-process architecture eliminates the coordination problems that make calendar systems complex. You get faster response times, automatic conflict detection, and real-time sync without managing multiple services.
You focus on building scheduling features instead of debugging distributed systems.