Architecture

Runtime layout, request flow, module lifecycle, and data boundaries.

Workbase is a single Next.js 16 application that serves admin pages, APIs, and in-app documentation from one codebase.

Runtime map

  • app/admin/**: authenticated admin interface
  • app/api/v1/**: versioned JSON API
  • app/api/storefront/**: storefront-facing APIs
  • app/api/admin/**: admin/module operation APIs
  • app/docs/**: documentation UI driven by MDX

Request flow

  1. proxy.ts runs before route handlers:
    • enforces admin auth redirects for /admin/*
    • applies CORS + per-identifier rate limiting for /api/v1/*
  2. Route handlers call resolveActor() to identify session/basic/bearer actor.
  3. Role checks run with ensureRole() or ensureSuperAdmin().
  4. Handlers return normalized envelopes via success() / failure().

Core layers

API layer (app/api/**)

  • Route handlers are thin orchestration boundaries.
  • Validation is primarily Zod-based in src/lib/validation/**.
  • Shared API helpers live in src/lib/api/**.

Domain/integration layer (src/lib/**)

  • Catalog, pricing, custom fields, file assets, and order helpers.
  • Auth/session logic for admin and storefront customers.
  • Integrations: MoySklad, OpenCart import settings, Yarvet settings.

Module layer (src/modules/**)

  • Optional features are registered in src/modules/registry.ts.
  • Module state is per company (ModuleState table).
  • Some modules include custom SQL migrations via lifecycle hooks.

Data layer (prisma/**)

  • PostgreSQL via Prisma.
  • Most business entities are scoped by companyId.
  • prisma/seed.ts seeds default company/admin/demo catalog data.

Authentication modes

resolveActor() supports:

  • NextAuth session (cookie)
  • Basic auth (Authorization: Basic ...)
  • Bearer API key (Authorization: Bearer ...)

For session-authenticated non-GET/HEAD API calls, CSRF tokens are required.

Storefront auth model

Storefront OTP auth uses:

  • EmailOtp table for one-time code verification
  • signed HTTP-only cookie wb_customer_session
  • two session states: pending_profile and customer

Upload and file asset model

/api/v1/upload stores files under UPLOAD_DIR/<companyId>/<group>/....

FileAsset records metadata and links uploads to entities (PRODUCT, CATEGORY, STOREFRONT_PAGE).

OpenAPI generation path

  • source: scripts/generate-openapi.ts
  • output: public/openapi.json
  • serve: /api/v1/openapi.json
  • UI: /api/v1/docs

The spec currently targets /api/v1/* endpoints.