Architecture
API Routes (Remix v2)
Following Remix v2 dot notation conventions:
app/routes/ ├── api.booking.tsx // Main booking endpoint for CRUD operations ├── api.booking.$id.tsx // Get or delete booking by ID ├── api.booking.type.$type.tsx // Get bookings by type ├── api.booking.email.$email.tsx // Get bookings by email ├── api.booking.org.$org.tsx // Get bookings by organization ├── api.booking.user.$userId.tsx // Get bookings by user ID
Database Schema (D1)
CREATE TABLE bookings ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, email TEXT NOT NULL, type TEXT NOT NULL, status TEXT NOT NULL, org TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, deleted_at DATETIME DEFAULT NULL ); CREATE INDEX idx_bookings_type ON bookings (type) WHERE deleted_at IS NULL; CREATE INDEX idx_bookings_email ON bookings (email) WHERE deleted_at IS NULL; CREATE INDEX idx_bookings_user_id ON bookings (user_id) WHERE deleted_at IS NULL; CREATE INDEX idx_bookings_org ON bookings (org) WHERE deleted_at IS NULL;
Storage Strategy
Core Data (D1)
D1 stores only the essential fields needed for filtering and listing bookings:
- id (primary key)
- user_id (who made the booking)
- email (contact information)
- type (booking category)
- status (booking state)
- org (organization/company)
- timestamps
Extended Data (KV)
KV store contains the complete booking objects including all extended fields specific to each booking type:
- Key format: Direct booking ID
- Value: Complete JSON booking object
- No TTL (stored until explicitly deleted)
Supported Booking Types
The system supports a wide range of booking types, each with specialized fields:
Appointment
For scheduling meetings and consultations:
- Virtual or in-person options
- Participant management
- Agenda and materials
- Reminders and notifications
Event
For conferences, webinars, and gatherings:
- Multi-day scheduling
- Speaker and presenter management
- Venue details and capacity
- Registration and attendance tracking
Rental
For equipment, vehicles, and space rentals:
- Rental period management
- Insurance and liability documentation
- Delivery and pickup options
- Additional equipment add-ons
Transportation
For airport shuttles, corporate travel, and transportation services:
- Multiple passenger support
- Pickup and dropoff locations
- Vehicle type and features
- Flight information integration
Medical
For healthcare appointments:
- Patient information and insurance
- Provider credentials and specialties
- Telehealth options
- Billing and preauthorization
Class/Workshop
For educational sessions and workshops:
- Instructor information
- Course materials and prerequisites
- Multi-session scheduling
- Capacity and enrollment tracking
API Routes Overview
All API routes follow RESTful conventions using the Remix v2 Resource Routes pattern.
Main Booking API (api.booking.tsx)
/api/bookingCreate a new booking of any type
/api/bookingUpdate an existing booking
/api/booking?id={bookingId}Soft delete a booking via deleted_at timestamp
Get By ID (api.booking.$id.tsx)
/api/booking/{bookingId}Retrieve a specific booking by ID
Get By Type (api.booking.type.$type.tsx)
/api/booking/type/{bookingType}Retrieve all bookings of a specific type
Get By Email (api.booking.email.$email.tsx)
/api/booking/email/{email}Retrieve all bookings associated with a specific email address
Get By Organization (api.booking.org.$org.tsx)
/api/booking/org/{organization}Retrieve all bookings for a specific organization or company
Get By User ID (api.booking.user.$userId.tsx)
/api/booking/user/{userId}Retrieve all bookings made by a specific user
API Usage Examples
Creating Different Booking Types
// Create an appointment booking
const response = await fetch('/api/booking', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
// Core fields (stored in D1)
type: "appointment",
userId: "user123",
email: "user@example.com",
org: "acme-corp.com",
status: "confirmed",
// Extended fields (stored in KV)
title: "Quarterly Review Meeting",
description: "Discussion of Q1 results and Q2 planning",
date: "2025-04-15",
startTime: "2025-04-15T14:00:00Z",
endTime: "2025-04-15T15:30:00Z",
location: {
name: "HQ Conference Room 3",
address: "123 Business Park",
city: "San Francisco",
state: "CA",
zipCode: "94103"
},
virtual: true,
meetingLink: "https://meet.example.com/123-456-789"
})
});Retrieving Bookings
// Get bookings by organization
const orgBookings = await fetch('/api/booking/org/acme-corp.com');
// Get bookings by user ID
const userBookings = await fetch('/api/booking/user/user123');
// Get bookings by type
const medicalBookings = await fetch('/api/booking/type/medical');
// Get specific booking by ID
const booking = await fetch('/api/booking/booking123-456');Technical Stack
- Remix v2
- Cloudflare D1 (Database)
- Cloudflare KV (Caching)
- TypeScript
- Resource Routes for API
- Tailwind CSS
Testing
End-to-end testing scripts are available for all booking types:
- ✓test.py
- ✓test_appointment.py
- ✓test_event.py
- ✓test_rental.py
- ✓test_transportation.py
- ✓test_medical.py
- ✓test_class.py