Getting started
Project structure
How the Prolifto monorepo is organized and where code belongs.
Prolifto is a Turborepo with pnpm workspaces. The admin dashboard is the system of record: it owns the database, authentication, API, and background jobs. The storefront is a separate Next.js app that consumes the admin API.
Applications
| App | Directory | Port | Purpose |
|---|---|---|---|
| Admin | apps/admin | 3000 | Store management, oRPC API, auth, Inngest jobs, database access |
| Storefront | apps/storefront | 3001 | Customer catalog, cart, checkout, account, order tracking |
| Docs | apps/docs | 3002 | This documentation site (Fumadocs + MDX) |
| Desktop | apps/desktop | — | Electron wrapper for the admin dashboard |
| E2E | apps/e2e | 3100/3101 | Playwright tests and test data setup |
Shared packages
| Package | Responsibility |
|---|---|
@prolifto/db | Drizzle schema, database client, queries, migrations |
@prolifto/domain | Shared types, Zod schemas, enums, constants, business utilities |
@prolifto/auth | Better Auth configuration for admin and storefront |
@prolifto/env | Shared environment variable definitions and validation |
@prolifto/infrastructure | Email, SMS, WhatsApp, storage, and AI adapters |
@prolifto/payments | Stripe and cash-on-delivery payment providers, Polar webhooks |
@prolifto/pdf | Puppeteer-based invoices and receipts |
@prolifto/sdk | Typed HTTP client used by the storefront |
@prolifto/search | PostgreSQL and Upstash search providers |
@prolifto/telemetry | Structured logging (pino) |
@prolifto/ui | Shared UI components, hooks, and styles |
@prolifto/typescript-config | Shared TypeScript configuration |
How the pieces talk
Browser
├─ admin (3000)
│ ├─ Better Auth session
│ ├─ oRPC API (/api/orpc, /api/{orgSlug}/...)
│ ├─ PostgreSQL via @prolifto/db
│ └─ Inngest jobs (email, SMS, PDF, imports, search indexing)
│
└─ storefront (3001)
├─ Better Auth storefront session
├─ @prolifto/sdk → admin API with an API key
└─ cart, checkout, account pagesThe storefront never connects to the database directly for catalog operations.
It authenticates to the admin API with an API key scoped to one organization.
The ORGANIZATION_SLUG and API_KEY environment variables make that link.
Where code belongs
- Database tables and relations:
packages/db/src/schemas. - Shared API contracts and validation:
packages/domain/src/schemas. - Admin server logic:
apps/admin/modules/<module>/server. - Admin UI:
apps/admin/modules/<module>/uiand shared components inapps/admin/components. - Storefront UI and routes:
apps/storefront/appandapps/storefront/components. - Reusable primitives:
packages/ui.
Admin modules are vertical slices. A typical module has server/procedures.ts,
server/queries.ts, server/services, ui/views, and ui/components. The oRPC
router in apps/admin/orpc/routers.ts wires procedures into the API.
Boundaries to preserve
- Do not import admin-only server code into the storefront.
- Do not put shared business rules in either app; put them in
@prolifto/domain. - Do not add database access to the storefront unless there is a clear, documented reason.
- Keep public API behavior in
@prolifto/domainschemas so the SDK and admin agree on validation. - Background work belongs in Inngest functions under
apps/admin/inngest.