API Workflows
This page covers the development workflows for the HonoX backend API — running it locally, working with auth, and managing the OpenAPI spec.
Local development
# Generate Prisma client first
pnpm --filter=@kubuli/database db:generate
# Start the API dev server
pnpm dev --filter=apiIf a Laravel migration changed the shared schema, apply it from apps/admin, then sync Prisma with prisma db pull and rerun db:generate. Do not run prisma migrate from packages/database.
The API runs at http://localhost:3001.
Authentication model
The API implements two auth surfaces:
| Surface | Purpose |
|---|---|
/api/v1/auth/* | Public JWT contract — registration, login, guest sessions, refresh |
/api/auth/* | Better Auth session and social provider workflows |
Protected routes accept either a bearer JWT (Authorization: Bearer <token>) or a valid Better Auth session cookie. The shared auth middleware is in apps/api/app/lib/.
Key auth endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/auth/register | POST | Email registration |
/api/v1/auth/login | POST | Email login → JWT |
/api/v1/auth/guest | POST | Anonymous session token |
/api/v1/auth/refresh | POST | Rotate JWT |
/api/v1/auth/phone/send-otp | POST | Phone OTP request |
/api/v1/auth/phone/verify-otp | POST | Phone OTP verify → JWT |
/api/v1/me | GET / PATCH | Current user profile |
→ Full contracts: Authentication · Registration
Project structure
apps/api/
├── app/
│ ├── server.ts # App entry point
│ ├── lib/ # Auth, validation, storage, utilities
│ └── routes/
│ ├── _404.ts
│ ├── _error.ts
│ └── api/
│ ├── index.ts # /api/health
│ └── v1/
│ ├── admin/ # Admin-facing photo helpers
│ ├── app/ # App config and onboarding payloads
│ ├── auth/ # JWT auth endpoints
│ ├── culture/ # Stories and topics
│ ├── map/ # Map and POI endpoints
│ ├── me/ # Current-user profile and preferences
│ ├── tours/ # Tour generation and stop workflows
│ ├── users/ # Handle/profile helpers
│ ├── categories.ts
│ ├── favorites.ts
│ ├── feed.ts
│ ├── openapi.ts
│ ├── places.ts
│ ├── reviews.ts
│ └── search.ts
├── vite.config.ts
└── tsconfig.jsonOpenAPI spec
The API ships a generated OpenAPI 3.1 spec via GET /api/v1/openapi. The TypeScript source is at apps/api/app/lib/openapi-spec.ts.
Export the spec as a static artifact:
pnpm --filter=@kubuli/api openapi:exportThis writes to apps/api/docs/openapi.json. Commit this file whenever you add or change endpoints — the docs site and any tooling that consumes the spec picks it up from here.
Testing
# Run all API tests
pnpm test --filter=api
# Watch mode
pnpm test --filter=api -- --watch
# Run OpenAPI validation tests specifically
pnpm --filter=@kubuli/api test -- app/lib/openapi-spec.test.ts app/routes/api/v1/openapi.test.tsCoverage reports live in apps/api/coverage/.
Adding a new endpoint
- Create the route file under
app/routes/api/v1/following the existing pattern. - Add the endpoint to
app/lib/openapi-spec.ts. - Write a test in the adjacent
*.test.tsfile. - Run
pnpm --filter=@kubuli/api openapi:exportto update the generated spec. - Update
apps/docs/api/if this is a user-facing endpoint family.