Paid appointment booking for people whose time and expertise carry value.
Threecal lets a professional publish event-specific booking links, define weekly availability, collect invitee details, and route paid bookings through a connected payment provider.
The repository contains a working first version of the authentication, profile, scheduling, event type, public booking, provider payment, and platform billing flows.
The backend is the source of truth for available capabilities. Calendar synchronization, host booking management, booking status lookup, payment status lookup, and account recovery are not implemented because the current API does not expose those operations. The complete implementation state is recorded in MEMORY.md.
threecal/
├── frontend/ Next.js App Router client and public booking experience
├── backend/ FastAPI API, domain services, SQLAlchemy models, migrations
└── MEMORY.md Current feature inventory and missing-feature record
- Next.js 16 App Router and React 19
- TypeScript with strict checking
- TanStack Query for server state and mutations
- React Hook Form and Zod for form state and validation
- Framer Motion for marketing-page motion
- Feature-oriented modules under
frontend/features - Fetch API client with cookie credentials and structured API errors
- Python and FastAPI
- SQLAlchemy with SQLite initially
- Alembic migrations
- Pydantic v2 request and response validation
- HTTP-only cookie authentication using JWT
- Domain modules for auth, users, availability, event types, bookings, payments, billing, webhooks, and email
- Provider abstractions for email and doctor payment gateways
- BackgroundTasks for booking confirmation email delivery
cd backend
cp .env.example .env
uv sync
alembic upgrade head
uv run uvicorn app.main:app --reload --port 8000The default API is available at http://localhost:8000, with versioned routes under http://localhost:8000/api/v1.
cd frontend
pnpm install
cp .env.example .env.local
pnpm devThe frontend is available at http://localhost:3000. Set NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1 for local API access.
Frontend browser checkout integrations may also require:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYfor Stripe Payment Element checkoutNEXT_PUBLIC_RAZORPAY_KEY_IDfor Razorpay checkoutNEXT_PUBLIC_CASHFREE_MODE=sandboxorproductionfor Cashfree checkout
The backend must allow the frontend origin through CORS_ORIGINS, and cookie settings must be compatible with the deployed frontend and API domains.
/marketing landing page with role ticker and sign-up links/registeraccount creation/loginpassword login/onboardingrequired profile setup for accounts without a username/dashboardworkspace overview, public links, statistics, and platform billing/dashboard/profilepublic name, username, timezone, bio, and avatar URL editor/dashboard/event-typesevent type creation and full update editor/dashboard/availabilityweekly working hours and break editor/dashboard/paymentsdoctor payment-provider onboarding and platform billing/dashboard/billingDodo mandate checkout return destination and verification form/dashboard/bookingscapability notice for the missing host booking-list API/:username/:eventSlugpublic event page, slot picker, invitee form, and checkout
cd frontend
pnpm exec tsc --noEmit
pnpm lint
pnpm buildcd backend
uv run pytest -q- Apply migrations before deployment with
alembic upgrade head. - Run the idempotent monthly billing reconciler daily through Railway Cron with
python -m app.jobs.run_billing_cycle. - Keep
CREDENTIALS_ENCRYPTION_KEYstable and secret because doctor payment credentials are encrypted at rest. - Deploy the frontend to Vercel and the backend to Railway according to the project deployment target.
- SQLite is the initial database and is intended to use a Railway persistent volume with backups to Cloudflare R2; PostgreSQL is the planned later database.
Threecal is licensed under AGPL-3.0.
