Skip to main content

System Architecture

KnowledgeCheckr is a modern SaaS platform built with Next.js 16 and React 19, designed to create and manage knowledge assessments with support for practice and examination modes.

Tech Stack Overview

Frontend

  • Framework: Next.js 16.0.7 with App Router
  • React: 19.1.0 with Server Components
  • TypeScript: Type-safe development
  • Styling: Tailwind CSS 4.1.18
  • UI Components:
    • Radix UI primitives for accessible components
    • HeroUI for specialized components
    • Framer Motion for animations
    • Lucide React for icons

Backend

  • Runtime: Node.js with Next.js API routes
  • Database: MySQL 2 (via mysql2 3.14.0)
  • ORM: Drizzle ORM 0.44.7
  • Authentication: Better Auth 1.2.5
  • Validation: Zod 3.24.2

State Management

  • Client State: Zustand 5.0.3
  • Server State: React Server Components
  • Forms: React Hook Form 7.55.0 with @hookform/resolvers

Internationalization

  • Library: next-international 1.3.1
  • Supported Locales: English (en), German (de)

Development & Testing

  • Testing: Cypress 15.7.0 (E2E and Component testing)
  • Code Coverage: @cypress/code-coverage
  • Linting: ESLint 9 with Next.js config
  • Formatting: Prettier 3.5.2
  • Git Hooks: Husky 8 with lint-staged

Monitoring & Logging

  • Error Tracking: Sentry (@sentry/nextjs 10.26.0)
  • Logging: Winston 3.19.0 with daily rotate file

Application Architecture

Directory Structure

workspace/source/
├── src/
│   ├── app/                    # Next.js App Router
│   │   ├── [locale]/          # Internationalized routes
│   │   └── api/               # API endpoints
│   ├── components/            # React components
│   ├── i18n/                  # Internationalization config
│   ├── lib/                   # Shared utilities
│   │   ├── auth/             # Authentication logic
│   │   ├── checks/           # Knowledge check utilities
│   │   ├── log/              # Logging configuration
│   │   └── Shared/           # Common utilities
│   └── schemas/              # Zod validation schemas
├── database/
│   ├── drizzle/              # Drizzle ORM schema & migrations
│   ├── knowledgeCheck/       # Check operations
│   ├── User/                 # User operations
│   ├── examination/          # Exam logic
│   ├── practice/             # Practice mode logic
│   ├── Database.ts           # Database connection
│   └── Pool.ts               # Connection pooling
└── config/                   # Configuration files

Design Patterns

Server-First Architecture

KnowledgeCheckr leverages Next.js Server Components for optimal performance:
  • Server Components handle data fetching
  • Client Components only where interactivity is needed
  • Server Actions for mutations
  • Streaming for progressive rendering

Database Layer

The application uses a layered database approach:
  1. Connection Layer (database/Pool.ts): Manages MySQL connection pooling
  2. ORM Layer (database/Database.ts): Drizzle ORM integration
  3. Repository Layer: Domain-specific database operations
// Example from database/Pool.ts
export default function createPool(): Pool {
  if (process.env.NODE_ENV === 'production') {
    pool = mysqlCreatePool(config)
  } else {
    if (!global.pool) {
      logger.info('Creating new database pool for development environment.')
      global.pool = mysqlCreatePool(config)
    }
    pool = global.pool
  }
  return pool
}
Connection Pooling Strategy:
  • Production: New pool per request
  • Development: Cached global pool to prevent “Too many connections” errors

Authentication Flow

Better Auth provides flexible authentication with multiple providers:
// From src/lib/auth/server.ts
export const auth = betterAuth({
  database: createPool(),
  emailAndPassword: {
    enabled: true,
    minPasswordLength: 8,
    autoSignIn: true,
  },
  socialProviders: {
    github: { clientId, clientSecret },
    google: { clientId, clientSecret },
  },
  plugins: [
    nextCookies(),
    anonymous(),
    genericOAuth(),
  ],
})

Internationalization Strategy

Next-international provides type-safe i18n:
  • Server-side: getI18n(), getScopedI18n(), getCurrentLocale()
  • Client-side: useI18n(), useScopedI18n(), useCurrentLocale()
  • URL strategy: rewriteDefault (hides default locale from URL)

Data Flow

Request Lifecycle

  1. Client Request → User accesses route
  2. Middleware → i18n middleware processes locale
  3. Server Component → Fetches data using Drizzle ORM
  4. Authentication Check → Better Auth validates session
  5. Data Transform → Zod validates and transforms data
  6. Response → Server Component renders or returns JSON

Knowledge Check Flow

User Relationships

  • Owner: Creates and manages knowledge checks
  • Collaborator: Can contribute to knowledge checks
  • Guest: Takes examinations and practice sessions
  • Anonymous: Temporary users (can be linked to accounts)

Deployment Architecture

Build Configuration

// From next.config.ts
const nextConfig: NextConfig = {
  experimental: {
    authInterrupts: true,
  },
  output: 'standalone',
  reactStrictMode: false,
  devIndicators: false,
}
Key Features:
  • Standalone output for containerization
  • Auth interrupts for Better Auth
  • Image optimization for avatars (GitHub, Google, ui-avatars.com)

Environment Management

Environment validation occurs at build time using src/lib/Shared/Env.ts:
npm run validateEnvironment

Database Migrations

Drizzle Kit manages schema migrations:
// drizzle.config.ts
export default defineConfig({
  out: './database/drizzle/migrations',
  schema: './database/drizzle/schema.ts',
  dialect: 'mysql',
  dbCredentials: { ... },
})

Performance Optimizations

Frontend

  • Code Splitting: Automatic with Next.js App Router
  • Image Optimization: Built-in Next.js image optimization
  • Font Optimization: Automatic font loading optimization
  • Bundle Analysis: Tree-shaking with ES modules

Database

  • Connection Pooling: Reused connections (limit: 10)
  • Query Optimization: Drizzle ORM generates efficient queries
  • Indexes: Strategic indexes on foreign keys and lookup fields

Caching Strategy

  • Static Generation: Pre-rendered pages where possible
  • Incremental Static Regeneration: For dynamic content
  • API Route Caching: Cached responses with revalidation

Security Considerations

Authentication

  • Session-based authentication via Better Auth
  • Secure cookie handling with httpOnly and secure flags
  • CSRF protection built into Better Auth
  • Rate limiting enabled in production

Database

  • Prepared statements via Drizzle ORM (SQL injection prevention)
  • Foreign key constraints for referential integrity
  • Cascade deletes for data consistency

API Security

  • Server-side validation with Zod schemas
  • Authentication checks on protected routes
  • IP address and user agent tracking for sessions

Monitoring & Observability

Error Tracking

Sentry integration for comprehensive error monitoring:
// Configured in next.config.ts
withSentryConfig(nextConfig, {
  tunnelRoute: '/monitoring',
  disableLogger: true,
  automaticVercelMonitors: true,
})

Logging

Winston logger with module-level logging:
const logger = _logger.createModuleLogger(
  '/' + import.meta.url.split('/').reverse().slice(0, 2).reverse().join('/')!
)
Features:
  • Daily rotating log files
  • Structured logging
  • Module-specific log contexts

Next Steps

Build docs developers (and LLMs) love