Prolifto
Developer guide

Architecture

How the admin, storefront, shared packages, and external services fit together.

Prolifto is a multi-tenant ecommerce platform built as a Turborepo. The admin dashboard is the system of record; the storefront is a separate application that consumes the admin API.

High-level view

                         ┌──────────────────────────────┐
                         │        PostgreSQL 17         │
                         │  organizations, catalog,     │
                         │  orders, invoices, auth      │
                         └──────────────▲───────────────┘
                                        │ Drizzle
             ┌──────────────────────────┴─────────────────────────┐
             │                     Admin app                      │
             │  Next.js 16 · Better Auth · oRPC · Inngest        │
             │  /api/orpc · /api/{orgSlug}/... · /api/openapi.json│
             └───────▲──────────────────────────────▲─────────────┘
                     │                              │
          session /  │                              │ ApiKey header
          oRPC       │                              │
     ┌───────────────┴──────────┐        ┌──────────┴─────────────┐
     │      Admin dashboard     │        │      Storefront        │
     │  Products · Orders ·     │        │  Catalog · Cart ·      │
     │  Inventory · Settings    │        │  Checkout · Account    │
     └──────────────────────────┘        └────────────────────────┘
                     │                              │
                     └──────────┬───────────────────┘
                                │
          ┌─────────────────────┼──────────────────────┐
          │                     │                      │
     ┌────▼────┐          ┌─────▼─────┐         ┌──────▼──────┐
     │ Mailpit │          │  Inngest  │         │  Storage    │
     │  SMTP   │          │   jobs    │         │ Cloudinary/ │
     └─────────┘          └───────────┘         │     S3      │
                                                 └─────────────┘

Applications

Admin (apps/admin)

  • Owns the database schema usage, authentication, oRPC API, and background jobs.
  • Serves the REST/OpenAPI surface under /api/{organizationSlug}/....
  • Exposes /api/openapi.json and an in-app Scalar reference.
  • Runs Inngest functions for email, SMS, WhatsApp, PDFs, imports, search indexing, and subscription renewals.
  • Uses module slices: modules/<name>/server, modules/<name>/ui, and shared components.

Storefront (apps/storefront)

  • Customer-facing catalog, cart, checkout, account, and order tracking.
  • Uses @prolifto/sdk with an API key scoped to one organization.
  • Has its own Better Auth tables and supports email/password, email OTP, and Google sign-in.
  • Resolves the organization from the request host for multi-tenant domains.
  • Does not read catalog tables directly for storefront operations.

Docs (apps/docs)

  • Fumadocs + MDX. Independent of the workspace packages.
  • Builds from committed content and a committed OpenAPI snapshot.
  • API pages are generated from the admin's OpenAPI spec.

Desktop (apps/desktop)

  • Electron wrapper that packages the built admin app.
  • Not a separate implementation; it ships the admin dashboard.

Shared packages

PackageRole
@prolifto/dbDrizzle schema, client, queries, migrations
@prolifto/domainTypes, enums, Zod schemas, business utilities
@prolifto/authAdmin and storefront Better Auth configuration
@prolifto/envShared env schema and validation helpers
@prolifto/infrastructureEmail, SMS, WhatsApp, storage, AI adapters
@prolifto/paymentsStripe and COD providers, Polar webhook verification
@prolifto/pdfInvoice and receipt PDF templates
@prolifto/sdkTyped HTTP client for the admin API
@prolifto/searchPostgreSQL and Upstash search providers
@prolifto/telemetryPino logger
@prolifto/uiShared components and styles

Multi-tenancy

An organization is a store. Every tenant-owned table carries an organizationId, and queries must scope by it.

  • Admin requests get the organization from the URL slug and the session's active organization.
  • API-key requests resolve the organization from the key's referenceId and verify it matches the slug in the path.
  • Storefront requests resolve the organization from the request host (custom domain or configured root domain).
  • Storefront customer accounts are scoped per organization, with scoped email identities so the same person can exist in multiple stores.

Request flow

Admin browser
  → Next.js route /api/{orgSlug}/...
  → oRPC OpenAPI handler
  → createORPCContext (session, org slug, db, search)
  → procedure (public / protected / org / apiKey)
  → permission middleware
  → service or query
  → Drizzle → PostgreSQL

Storefront requests follow the same path through the SDK:

Storefront server
  → @prolifto/sdk → /api/{orgSlug}/...
  → ApiKey header
  → oRPC procedure
  → same service/query layer

Payments

  • Cash on delivery is the default for the Algerian market.
  • Stripe handles card payments when STRIPE_ENABLED="true".
  • Polar handles platform subscription billing, not storefront checkout.

Payment confirmation sets the order's paid state, locks the invoice, creates a receipt, and records a transaction. See Payments.

Background work

Inngest runs asynchronous tasks so requests stay fast:

  • Order confirmation email, SMS, and WhatsApp messages.
  • Low-stock and out-of-stock notifications.
  • Invoice and receipt PDF generation.
  • Product CSV imports and search indexing.
  • Product description generation.
  • Subscription renewals and domain revalidation.

See Background jobs.

Data and file storage

  • PostgreSQL stores business data.
  • Cloudinary or S3-compatible storage stores product media, billboards, and generated PDFs.
  • Mailpit captures email locally; production uses SMTP.
  • Upstash is optional; search falls back to PostgreSQL.

Design boundaries

  • Shared business rules belong in @prolifto/domain.
  • Database access belongs in @prolifto/db and admin server modules.
  • The storefront must not import admin server code.
  • Public API contracts must remain stable for the SDK and external consumers.
  • Destructive operations should stay behind explicit permissions.

On this page