BuzzTrip is built as a Turborepo monorepo housing two Next.js 15 applications — the main web app and an admin dashboard — backed by a single shared Convex real-time backend. Shared UI components, email templates, and TypeScript configurations are extracted into dedicated packages that both apps consume. This document describes how all those pieces fit together.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/jacobsamo/buzztrip/llms.txt
Use this file to discover all available pages before exploring further.
Technology Stack
Turborepo
Monorepo orchestration, task pipelines, and remote build caching. All
cross-package
build, dev, lint, and clean tasks are coordinated
through turbo.json.Bun (v1.3.1)
Package manager and JavaScript runtime. Used for all
install, run, and
script invocations across the monorepo.Next.js 15
React framework with App Router, server components, and server actions. Used
for both
apps/web and apps/admin.Convex
Real-time backend-as-a-service providing the database, type-safe queries and
mutations, real-time subscriptions, file storage, and HTTP action endpoints.
Clerk
User authentication and identity management. Handles sign-up, sign-in,
session JWTs, and user metadata. Integrated into Convex via webhooks.
Tailwind CSS v4
Utility-first CSS framework using the new CSS-first configuration approach
(no
tailwind.config.js). Configuration lives in CSS files directly.shadcn/ui (@buzztrip/ui)
Component library built on Radix UI primitives, distributed as the internal
@buzztrip/ui workspace package. Import components into any app from this
shared source.Zod + convex-helpers
Runtime validation for all Convex schemas.
zodToConvex() from
convex-helpers converts Zod schemas into Convex validators, keeping
type definitions as a single source of truth.TypeScript 5.9+
Strict typing throughout every app and package. Shared
tsconfig base
configurations live in packages/tsconfig/.Polar
Billing and subscription management for paid BuzzTrip plans.
Resend
Transactional email delivery. Email templates are React components in
packages/transactional/.Vercel
Deployment platform for both Next.js applications.
- Sentry — error monitoring and performance tracing (
NEXT_PUBLIC_SENTRY_DSN) - PostHog — product analytics and feature flags (
NEXT_PUBLIC_POSTHOG_KEY)
Data Flow
Every user interaction in the browser flows through the following path:preloadQuery / fetchQuery using the Convex Next.js adapter (convexNextjsOptions()), which forwards the Clerk JWT to Convex for authentication. Client components subscribe to live queries, receiving automatic real-time updates whenever the underlying data changes — no polling or manual cache invalidation required.
Backend Package Structure
All server-side logic lives inpackages/backend/convex/. The package is exported to both apps as @buzztrip/backend.
Key Patterns
Authenticated Functions
All user-facing Convex functions are wrapped withauthedQuery or authedMutation from convex/helpers.ts. These wrappers verify the Clerk JWT, look up the user record, and inject ctx.user — so individual functions never need to repeat auth boilerplate.
Zod Schemas as Single Source of Truth
Zod schemas inpackages/backend/zod-schemas/ drive both the Convex table schema (via zodToConvex) and runtime validation in queries and mutations. This keeps the database shape and validation logic in one place.
shared-schemas.ts make this ergonomic:
defaultSchema(zodObject)— wraps a Zod object with standard Convex system fields (_id,_creationTime) for read operationsinsertSchema(zodObject)— strips those system fields, producing a schema suitable for create and update operations
Role-Based Access Control
Map-level permissions are enforced viacanPerformAction(role, 'entity:action') in helpers/rbac.ts. Every map has associated map_users records that store a role for each collaborator. Before any mutating operation the role is fetched and passed through the RBAC check.
Authentication Flow
BuzzTrip uses Clerk for identity and Convex for data, with the following integration:JWT issuance
Clerk issues a signed JWT using the convex JWT template configured in
your Clerk dashboard. This token contains the user’s Clerk ID as the
subject claim.Token forwarding
In Next.js server components and route handlers,
convexNextjsOptions()
from @convex-dev/nextjs automatically reads the Clerk session and attaches
the JWT to every Convex request.Token validation
Convex validates the JWT on every query and mutation using the public key
configured in
convex/auth.config.ts. Requests with invalid or missing
tokens are rejected before reaching the handler.CLERK_WEBHOOK_SECRET) and validated using the svix library on every incoming request.
Monorepo Build Pipeline
Turborepo orchestrates all tasks through the pipeline defined inturbo.json. Key characteristics:
buildrespects the^builddependency order — packages build before the apps that consume themdevtasks run concurrently and persistently (no caching), so all three dev servers (web, admin, backend) start in parallel withbun devlintalso respects package dependency order (^lint)- All build outputs (
.next/**,dist/**) are cached by Turborepo;.next/cache/**is excluded from the cache to keep it lean