A decentralized scheduling platform built on the AT Protocol where availability is public data stored on Personal Data Servers (PDS), while private calendar sync remains client-side.
- Decentralized Identity: Sign in with your AT Protocol handle (no traditional email/password)
- Public Availability: Store your available time slots on your PDS
- Calendar Integration: Sync with Google Calendar (read-only) to block out busy times
- Smart Booking: Platform manages bookings while respecting your availability
- ICS Invites: Receive calendar invites via email
- Frontend: Astro (SSR + Islands for interactivity)
- Runtime: Bun (fallback to Node.js)
- Hosting: Cloudflare Pages + Workers
- Database: Drizzle ORM + D1
- Identity: AT Protocol OAuth
- Calendar: Google Calendar API (read-only)
/
├── src/
│ ├── pages/ # Astro pages and routes
│ │ ├── index.astro # Landing page
│ │ ├── dashboard.astro
│ │ ├── settings.astro
│ │ ├── auth/ # Authentication pages
│ │ ├── availability/# Availability management
│ │ ├── book/ # Public booking pages
│ │ └── api/ # API endpoints
│ ├── layouts/ # Page layouts
│ ├── components/ # Reusable components
│ ├── lib/ # Core library code
│ │ ├── atproto/ # AT Protocol integration
│ │ ├── auth/ # Authentication & sessions
│ │ └── db/ # Database schema
│ └── middleware/ # Astro middleware
├── public/ # Static assets
└── drizzle/ # Database migrations
- DEVELOPMENT.md - Local development setup and workflow
- ARCHITECTURE.md - System architecture and design decisions
- DEPLOYMENT.md - Production deployment guide for Cloudflare
- CONTRIBUTING.md - Guidelines for contributors
- Node.js 20+ or Bun 1.0+
- Cloudflare account (for deployment)
# Install dependencies
npm install
# or
bun install
# Set up environment variables
cp .env.example .env# AT Protocol OAuth
OAUTH_CLIENT_ID=your-client-id
OAUTH_CLIENT_SECRET=your-client-secret
OAUTH_REDIRECT_URI=http://localhost:4321/api/auth/callback
# Session Secret
JWT_SECRET=your-secret-key
# Cloudflare D1 (for local development)
CLOUDFLARE_ACCOUNT_ID=your-account-id
CLOUDFLARE_DATABASE_ID=your-database-id
CLOUDFLARE_D1_TOKEN=your-token
# Google Calendar (optional, for Phase 2)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret# Start development server
npm run dev
# or
bun run dev
# Build for production
npm run build
# or
bun run build
# Generate database migrations
npm run db:generate
# or
bun run db:generateVisit http://localhost:4321 to see the app.
- AT Protocol OAuth integration
- Session management
- Create/edit/delete availability slots
- Public profile view
- Basic availability UI
- Settings dashboard
- Profile customization
- Connected accounts management
- Notification preferences
- Data export & account deletion
- Google Calendar OAuth
- Encrypted token storage
- FreeBusy API integration
- Periodic sync worker
- Conflict detection
- Booking creation & management
- Host approval flow
- ICS file generation
- Email notifications
- In-app notifications
- Cancel bookings
- Reschedule requests
- Updated ICS files
- Recurring availability
- Team scheduling
- Discovery features
- Analytics
The application uses Cloudflare D1 (SQLite) with the following tables:
calendar_connections: Google Calendar OAuth tokensbusy_cache: Cached busy times from calendar syncbookings: Booking records (broker storage)notifications: User notificationsuser_settings: User preferences
Availability is stored on users' PDS using the collection:
social.schedule.availability
See src/lib/atproto/schema.ts for the full lexicon definition.
# Deploy to Cloudflare Pages
wrangler pages deploy dist
# Set up D1 database
wrangler d1 create atproto-cal
wrangler d1 execute atproto-cal --file=./drizzle/schema.sql- Sessions are managed via JWT tokens stored in HTTP-only cookies
- OAuth tokens are encrypted before storage
- All API endpoints validate authentication
- CSRF protection via state parameters
Contributions are welcome! This is an open-source project building on the AT Protocol.
MIT License - see LICENSE file for details
Built on the AT Protocol - a decentralized social networking protocol.
For issues and questions, please open an issue on GitHub.