# AvailEngine — Full AI Context

AvailEngine is a Booking Engine as a Service. It provides a REST API that lets developers add scheduling, reservations, and availability management to any application. One API handles any booking vertical: restaurants, salons, spas, clinics, med spas, photographers, beauty salons, hair salons, and more.

## Architecture
- **Stack**: FastAPI (Python) backend, React + Vite + Tailwind dashboard, Supabase (Postgres), Stripe (payments)
- **Multi-tenant**: Row-Level Security at the database layer isolates every business
- **Auth**: Dual-path — API keys (avail_live_/avail_test_ prefix, scoped) or Supabase JWT
- **Middleware**: Security headers → CORS → Idempotency → Rate limiting → Billing enforcement (402) → Usage tracking
- **Deployment**: Docker + docker-compose, runs on any VPS or cloud provider

## Domain Model
- **Business** (tenant): business_id, name, slug, type, subscription_status
- **Resource** (bookable unit): resource_id, name, type, capacity_min/max, section
- **Booking** (appointment): booking_id, status, date, time, capacity, customer_id, resource_id
- **Customer** (end client): customer_id, name, phone, email — deduplicated by phone per business
- **Service** (what's booked): service_id, name, duration_minutes, price_cents
- **Deposit** (payment): deposit_id, status (pending→held→captured/released), Stripe payment intent

## Booking Lifecycle
pending → confirmed → checked_in → completed
Terminal: cancelled, no_show

## API Endpoints

### Public
- GET /v1/availability/{business_id}?date=&capacity=&duration_minutes= — Real-time slot availability
- POST /v1/bookings/ — Create booking (returns stripe_client_secret if deposit required)
- GET /v1/public/hours/{business_id} — Operating hours
- GET /v1/public/business/{slug} — Resolve slug to business info
- GET /v1/public/blackout-dates/{business_id} — Closure dates
- GET /v1/public/services/{business_id} — Service catalog
- POST /v1/waitlist/{business_id} — Join waitlist
- POST /v1/auth/register — Business registration

### Staff/Management (requires write scope or JWT)
- GET /v1/manage/bookings — List; filters: booking_date, status, code
- POST /v1/manage/bookings/staff — Staff booking (confirmed, no deposit)
- PATCH /v1/manage/bookings/{id} — Update status, resource_id, capacity
- PATCH /v1/manage/bookings/{id}/notes — Save staff_notes
- POST /v1/manage/bookings/{id}/no-show — Capture deposit hold
- POST /v1/manage/bookings/{id}/release-hold — Release deposit hold
- GET /v1/manage/bookings/{id}/available-resources — Free resources for slot
- CRUD /v1/manage/resources — Resources
- CRUD /v1/manage/services — Services
- GET /v1/manage/customers?search= — Search by name, phone, email
- GET /v1/manage/customers/{id} — Profile + last 20 bookings + stats
- GET /v1/manage/stats?from_date=&to_date= — Bookings, revenue, rates, busy hours
- GET/PATCH /v1/manage/settings — Booking settings (interval, deposit amount)
- GET/PUT /v1/manage/hours — Operating hours (all 7 days)
- GET/DELETE /v1/manage/waitlist — Waitlist management
- GET /v1/manage/audit-logs — Staff action history
- GET /v1/manage/subscription — Current plan + status
- CRUD /v1/manage/blackout-dates — Closure dates
- POST/GET/DELETE /v1/manage/api-keys — API key management

### Developer (JWT, role: developer)
- POST /v1/auth/developer/register — Developer registration
- GET /v1/developer/me — Profile + owned businesses + subscription
- GET/POST /v1/developer/businesses — List/create businesses
- GET/DELETE /v1/developer/businesses/{id} — Business detail/deactivation
- GET /v1/developer/quickstart/{business_id} — cURL snippets
- POST /v1/developer/billing/checkout — Stripe Checkout
- POST /v1/developer/billing/portal — Stripe Customer Portal

### Webhooks
- POST /webhooks/stripe — Stripe events (payment_intent, checkout, subscription, invoice)
- X-AvailEngine-Signature: HMAC-SHA256 verification
- Events: booking.created, booking.confirmed, booking.checked_in, booking.completed, booking.cancelled, booking.no_show, deposit.paid, deposit.captured, deposit.released
- Retry: exponential backoff (5s, 30s, 5m, 30m, 2h)

## Pricing
| Tier | Price | Businesses | Bookings/mo | Webhooks | Google Calendar | Support |
|------|-------|-----------|-------------|----------|-----------------|---------|
| Starter | €9.99/mo | Up to 2 | 100 | 2 endpoints | — | Email 48h |
| Growth | €49.99/mo | Up to 5 | 1,000 | 5 endpoints | 1 connection | Email 24h |
| Scale | €99.99/mo | Up to 15 | 5,000 | 10 endpoints | 3 conn | Email 12h |
| Platform | €199.99/mo | Unlimited | Unlimited | Unlimited | Unlimited | Priority |

Free sandbox forever. No credit card required. Hard limits: API returns 402 at plan limit.

## Error Format
{ "error": { "code": "rate_limit_exceeded", "message": "Too many requests" } }

401 invalid_token | 402 payment_required | 403 insufficient_permissions | 403 missing_scope | 404 not_found | 409 conflict | 422 validation_error | 429 rate_limit_exceeded

## Pagination
Cursor-based. Response: { "items": [...], "next_cursor": "...", "has_more": true }
Use ?limit=50&cursor=<next_cursor>. Default 50, max 200.

## Idempotency
POST/PATCH accept Idempotency-Key header. Same key within 24h returns original response.
