Start

Project Architecture

Understand the folder structure, design patterns, and how services, repositories, and routes connect in MoveFast.

MoveFast uses the Next.js App Router with a clean separation between frontend pages, API routes, and backend services. This page explains how everything fits together.

Folder Structure

text
src/
├── app/                    # Next.js App Router (pages + API routes)
│   ├── (main)/            # Public pages (landing, pricing, blog, auth, etc.)
│   ├── admin/             # Admin dashboard (protected)
│   ├── api/               # API route handlers
│   └── layout.tsx         # Root layout with providers
├── components/            # React components
│   ├── admin/             # Admin-specific components
│   ├── auth/              # Auth components (sign-in modal, forms)
│   ├── landing/           # Landing page sections
│   ├── ui/                # shadcn/ui primitives (button, card, dialog, etc.)
│   └── ...                # Feature-specific components
├── config/                # App configuration
│   ├── pricing.config.ts  # Pricing plans, currency, payment model
│   └── platform.config.ts # Platform access mode (open vs invite-only)
├── constants/             # Static values
│   ├── env.ts             # All environment variable names
│   ├── routes.ts          # Route path constants
│   ├── website.ts         # Brand name, URLs, support email
│   └── statusCode.ts      # HTTP status code constants
├── context/               # React context providers
│   └── AppContext.tsx      # Global user state + auth helpers
├── hooks/                 # Custom React hooks
│   ├── useCheckout.ts     # Payment checkout logic
│   ├── useSubscription.ts # Subscription management
│   ├── useUserProfile.ts  # Profile CRUD
│   └── ...
├── lib/                   # Core logic
│   ├── auth.ts            # NextAuth configuration
│   ├── auth/              # Auth utilities (page-auth, api-auth)
│   ├── backend/           # Backend services (see below)
│   ├── email/             # Email client + providers
│   ├── seo/               # Metadata helpers
│   ├── axios.ts           # Axios HTTP client
│   └── types/             # TypeScript type definitions
├── types/                 # Additional type definitions
└── utils/                 # Utility functions
    ├── errorHandling/     # ApiError, error handlers
    ├── pricing.ts         # Pricing display utilities
    └── ...

Backend Services Architecture

The src/lib/backend/ folder uses a layered pattern:

text
src/lib/backend/
├── auth/
│   ├── services/          # Business logic
│   │   ├── magicLink.service.ts
│   │   ├── platformAccess.service.ts
│   │   └── impersonation.service.ts
│   ├── repo/              # Data access (factory + implementations)
│   │   ├── magicLink.repository.ts      # Interface + factory
│   │   ├── mongo.magicLink.repository.ts
│   │   └── supabase.magicLink.repository.ts
│   └── adapters/          # Data mapping between DB and app types
├── user/
│   ├── services/
│   ├── repo/
│   └── adapters/
├── payment/
│   ├── services/
│   ├── repo/
│   └── adapters/
├── subscription/
│   ├── services/
│   ├── repo/
│   └── adapters/
├── waitingList/
│   ├── services/
│   ├── repo/
│   └── adapters/
├── invite/
│   ├── services/
│   ├── repo/
│   └── adapters/
├── payment-providers/
│   ├── providers/         # Stripe, Dodo, Polar implementations
│   └── adapters/          # Webhook event adapters
└── webhooks/
    └── webhook-coordinator.service.ts

The Repository Pattern

Every domain (user, payment, subscription, etc.) follows the same structure:

  1. Interface defines what operations are available (e.g., IUserRepository)
  2. Factory function picks the right implementation based on your variant
  3. Implementations handle the actual database calls (Mongo or Supabase)
  4. Adapters transform database records into app-level types
typescript
// repo/user.repository.ts (factory)
export const createUserRepository = (): IUserRepository => {
    return new MongoUserRepository(); // or SupabaseUserRepository in supabase variants
};

In single-provider variants, the factory is compiled to return only the selected implementation. No runtime switching happens.

How a Request Flows

Here is a typical API request flow:

text
Client (React) 
  → axios call to /api/payment/checkout
  → API route handler (src/app/api/payment/checkout/route.ts)
  → withAuth() middleware checks authentication + roles
  → validateBody() validates request with Zod schema
  → paymentService.initiateOneTimePayment() (business logic)
  → createPaymentProvider() factory returns Stripe/Dodo/Polar
  → provider.createOneTimePayment() calls external API
  → handleControllerResponse() returns standardized JSON

API Response Format

All API routes return a consistent shape:

json
{
  "success": true,
  "payload": { ... },
  "message": "Optional success message"
}

On errors:

json
{
  "success": false,
  "error": "Error message",
  "code": "OPTIONAL_ERROR_CODE"
}

Authentication Layers

MoveFast has two auth utilities depending on context:

  • checkAuth() (in src/lib/auth/page-auth.ts) is for Server Components and pages. It redirects users if they lack access.
  • withAuth() (in src/lib/auth/api-auth.ts) is for API routes. It returns 401/403 JSON responses if access is denied.

Both support: PUBLIC, AUTHENTICATED, role-based ({ roles: [UserRole.ADMIN] }), and custom predicate functions.

Error Handling

MoveFast uses a centralized error system:

  • ApiError is a custom error class with HTTP status code and optional error code
  • handleControllerError() catches errors in route handlers and returns proper HTTP responses
  • handleInternalServerError() is used inside services. It re-throws ApiError instances and wraps unexpected errors.

Validation

All API request bodies are validated with Zod schemas before reaching business logic:

typescript
const validatedData = await validateBody(req, CreateCheckoutSchema);

Schemas live in src/lib/zod-schemas/.

Key Configuration Files

FileWhat it controls
src/config/pricing.config.tsPlans, prices, currency, payment model
src/config/platform.config.tsAccess mode (open vs invite-only)
src/constants/website.tsBrand name, support email, social URLs
src/constants/env.tsAll environment variable names
src/constants/routes.tsFrontend route paths
src/lib/api-routes.tsAPI endpoint paths for the axios client