Skip to Content
DocsSystem Architecture

System Architecture

The AnswerFlow is designed for high performance, scale, and extreme flexibility. It leverages the Server Components architecture from Next.js, along with a robust background processing pipeline.

Monorepo Workspace Structure

AnswerFlow is structured as a modern monorepo using Turborepo. This allows us to cleanly separate our frontend, background workers, and shared business logic.

  • biome.json
  • Caddyfile
  • commitlint.config.js
  • compose.prod.yaml
  • compose.yaml
  • CONTRIBUTING.md
  • lefthook.yaml
  • LICENSE
  • package.json
  • pnpm-lock.yaml
  • pnpm-workspace.yaml
  • README.md
  • turbo.json

Root Infrastructure

At the root of the repository, we maintain the configuration files that orchestrate the entire developer experience, CI/CD pipeline, and deployment strategy.

  • biome.json: Our master configuration for lightning-fast formatting and linting.
  • Caddyfile: Reverse proxy configuration for local development routing.
  • commitlint.config.js: Enforces the Conventional Commits standard (e.g., feat:, fix:) across the repository.
  • compose.prod.yaml: The secure, production-ready Docker architecture.
  • compose.yaml: The local Docker development environment (spins up MinIO, Postgres, and Redis).
  • CONTRIBUTING.md: Guidelines for contributing to the repository.
  • lefthook.yaml: Our Git hooks manager that automatically formats code and checks types before you commit or push.
  • LICENSE: The open-source license governing this project.
  • package.json: Root package configuration and scripts.
  • pnpm-lock.yaml: Exact dependency versions locked for reproducible builds.
  • pnpm-workspace.yaml: Defines the boundaries of our monorepo workspaces for the package manager.
  • README.md: Project overview and getting started instructions.
  • turbo.json: The Turborepo configuration that orchestrates our build pipelines and aggressive task caching.

Apps

  • web: The main Next.js application handling the AnswerFlow frontend and API routes.
  • docs: The Next.js documentation site (what you’re reading now).
  • worker: A dedicated Node.js background worker process for heavy asynchronous tasks.

Packages

  • constants: Constants used across the application.
  • db: The single source of truth for our Prisma schema and generated client.
  • email: Email Provider integrations.
  • emails: Email templates and layouts.
  • push-notification: Contains Push notification functionality created with firebase admin sdk.
  • queue: Queue adapter with BullMQ & Qstash integrations.
  • rate-limit: Rate Limiter with redis.
  • redis: Single source of truth for redis.
  • storage: Single source of truth for S3 storage.
  • types: TypeScript types and DTOs.
  • typescript-config: TypeScript base config for the project.
  • ui: UI Components.
  • utils: Utilities and helper functions.
  • validators: Zod schemas for validation.

Core Stack

  • Framework: Next.js App Router (React Server Components)
  • Database: PostgreSQL (interacted via Prisma ORM)
  • Auth: Better-Auth
  • Caching: Redis (ioredis)
  • Virtualization: React-Virtuoso
  • Fetching: TanStack Query
  • Styling: Tailwind CSS & Radix UI

Database Schema (Prisma)

AnswerFlow uses a relational database architecture managed by Prisma. Below is a high-level overview of our core data models, followed by the complete schema reference.

Core Architecture

  • User: Manages identity, credentials (via Better-Auth), profile details, reputation scores, and site roles.
  • Question & Answer: The core of the Q&A engine. Supports rich text, specific authors, tag relationships, and upvote/downvote tracking.
  • Vote: Tracks individual user votes (value: +1 or -1) polymorphically on Questions or Answers to dynamically calculate aggregate voteScores.
  • Notification: Stores real-time system alerts for users (e.g., “@username mentioned you”, “Someone answered your question”).

FieldTypeAttributes
idString@id @default(uuid())
nameString-
usernameString@unique @default(cuid())
displayUsernameString?Optional
emailString-
emailVerifiedBoolean@default(false)
imageString?Optional
bioString?Optional
websiteString?Optional
reputationInt@default(0)
createdAtDateTime@default(now())
updatedAtDateTime@updatedAt
accountsAccount[]Relation
questionsQuestion[]Relation
answersAnswer[]Relation
votesVote[]Relation
commentsComment[]Relation
bookmarksBookmark[]Relation
notificationsReceivedNotification[]Relation
notificationsSentNotification[]@relation("NotificationActor")
pushTokensPushToken[]Relation
notificationPreferencesNotificationPreferences?Relation

Caching Strategy

We utilize robust caching mechanisms to ensure pages remain snappy regardless of concurrent load:

  1. Next.js Full Route Cache: Static pages and basic routing are cached at the edge.
  2. TanStack Query: We use @tanstack/react-query to handle client-side pagination, fetching, and re-validation (like infinite-scrolling answers).

Background Worker Flow

To ensure the main Next.js web process stays lightning-fast, we offload heavy lifting (like compiling React email templates and sending Resend emails) to a background queue.

Because AnswerFlow is designed to be provider-agnostic, we support two completely different background worker architectures depending on how you want to deploy:

1. The VPS / Docker Route (BullMQ + Redis)

Perfect for self-hosters running traditional servers or Docker containers.

  1. Event Dispatch: The Next.js API pushes a job payload to the included Dockerized Redis container.
  2. Instant Response: Next.js immediately returns a 200 OK to the user so the UI feels instant.
  3. Dedicated Worker: Our separate apps/worker Node.js process continuously listens to Redis via BullMQ, picks up the job, and executes the heavy lifting in the background.

2. The Serverless Route (Upstash QStash)

Perfect for enterprise users deploying to Vercel, AWS, or Cloudflare.

  1. Event Dispatch: Instead of needing a persistent Redis container, the Next.js API pushes the job payload securely to Upstash QStash.
  2. Instant Response: Next.js returns a 200 OK to the user.
  3. Webhook Trigger: QStash acts as the reliable middleman and fires a secure HTTP POST request back to a dedicated Next.js webhook route (e.g., /api/webhooks/worker), executing the job dynamically on a serverless edge function.

This decoupling prevents third-party API latency from ever blocking the user experience, regardless of where you deploy!

Last updated on