Skip to Content
WebForge Web - Architecture Overview

Forge Web - Architecture Overview

Executive Summary

Forge Web is a modern Next.js 16 application providing idea-to-execution tracking with visual mind mapping, goal management, task boards, and real-time collaboration features. It runs in any modern browser and connects to Turso (libSQL) for cloud data storage.


System Architecture

High-Level Architecture Diagram

How it works:

LayerDescription
BrowserThe user interface running in the browser, built with React 19 and Next.js App Router
Next.js ServerServer-side code handling API routes, authentication, and database queries via Prisma
External ServicesCloud services: Turso for data, Azure AD for authentication, LiveKit for voice/video

The data flows: User interacts with React → Browser sends fetch requests to API Routes → Next.js queries Turso via Prisma → Response flows back to update the UI.


Component Overview

1. Frontend Layer (React/Next.js)

Technology Stack:

  • Next.js 16 with App Router
  • React 19 with TypeScript
  • Tailwind CSS v4 for styling
  • shadcn/ui + Radix UI components
  • React Query for server state
  • Zustand for client state
  • React Flow for mind maps
  • Framer Motion for animations
  • @dnd-kit for drag-and-drop

Key Directories:

src/ ├── app/ # Next.js App Router │ ├── (auth)/ # Authentication pages │ ├── api/ # API routes │ └── dashboard/ # Main application ├── components/ # React components │ ├── ui/ # shadcn/ui primitives │ ├── dashboard/ # Dashboard components │ ├── calling/ # LiveKit voice/video │ ├── ideas/ # Ideas module │ ├── goals/ # Goals module │ ├── tasks/ # Tasks/Kanban module │ ├── mindmap/ # React Flow mind maps │ └── shared/ # Shared components ├── hooks/ # Custom React hooks ├── stores/ # Zustand state stores ├── lib/ # Utilities and configs └── types/ # TypeScript definitions

2. API Layer (Next.js API Routes)

API Routes Structure:

src/app/api/ ├── auth/[...nextauth]/ # NextAuth.js handlers ├── ideas/ # Ideas CRUD ├── goals/ # Goals CRUD ├── tasks/ # Tasks CRUD ├── comments/ # Comments CRUD ├── activity/ # Activity feed ├── users/ # User management ├── livekit/ # Voice/video calling │ ├── call/ # Call management │ └── token/ # Token generation ├── mindmaps/ # Mind map data ├── search/ # Global search └── warmup/ # Database warmup

3. Data Layer (Prisma + Turso)

Database Configuration:

  • Turso (libSQL) - SQLite-compatible cloud database
  • Prisma ORM for type-safe queries
  • Multi-tenant architecture via tenantId

Prisma Schema Models:

model User { id String @id @default(cuid()) email String @unique name String? image String? tenantId String? ideas Idea[] goals Goal[] tasks Task[] comments Comment[] } model Idea { id String @id @default(cuid()) title String description String? status String @default("draft") priority String @default("medium") authorId String author User @relation(fields: [authorId]) goals GoalIdea[] tasks Task[] comments Comment[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Goal { id String @id @default(cuid()) title String description String? status String @default("not_started") priority String @default("medium") progress Int @default(0) dueDate DateTime? authorId String author User @relation(fields: [authorId]) ideas GoalIdea[] tasks Task[] comments Comment[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Task { id String @id @default(cuid()) title String description String? status String @default("backlog") priority String @default("medium") dueDate DateTime? orderIndex Int @default(0) goalId String? ideaId String? authorId String author User @relation(fields: [authorId]) goal Goal? @relation(fields: [goalId]) idea Idea? @relation(fields: [ideaId]) comments Comment[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }

Data Flow Architecture

Authentication Flow

How it works:

  1. User clicks sign in - Initiates the OAuth flow
  2. NextAuth redirects - Browser is redirected to Azure AD login page
  3. User logs in - Enters Microsoft credentials
  4. Authorization code - Azure sends code back to NextAuth callback URL
  5. Token exchange - NextAuth exchanges the code for access and ID tokens
  6. User record - Prisma creates or updates the user in Turso database
  7. Session cookie - NextAuth sets an HTTP-only session cookie
  8. Dashboard - User is redirected to the dashboard

CRUD Operation Flow

How it works:

  1. React Component uses a hook like useIdeas() to request data
  2. React Query manages the request, caching, and loading states
  3. API Route handles the request at /api/ideas
  4. Prisma executes a type-safe query against Turso
  5. Turso DB returns the result rows
  6. JSON response is sent back to the client
  7. Cache update React Query updates its cache and re-renders the component

Real-time Calling Flow

How it works:

  1. Caller initiates - POST request creates a call record in Turso and returns a JWT token
  2. Callee polls - Every 3 seconds, the callee checks for incoming calls
  3. Call found - When a pending call is detected, the callee sees a notification
  4. Accept call - PATCH request updates the call status and returns a token for the callee
  5. Connect to LiveKit - Both users connect to the LiveKit room using their JWT tokens
  6. WebRTC streaming - LiveKit handles the peer-to-peer audio/video transmission
StepWhoAction
1CallerCreates call record, gets token
2CalleePolls and sees incoming call
3CalleeClicks Accept, gets token
4BothConnect to LiveKit room
5BothExchange audio/video via WebRTC

Database Schema

Entity Relationship Diagram

How to read this diagram:

The lines show relationships between database tables. ||--o{ means “one-to-many” (one record on the left relates to many records on the right).

RelationshipMeaning
USER → IDEAOne user creates many ideas
USER → GOALOne user creates many goals
USER → TASKOne user creates many tasks
USER → CALLOne user can initiate many calls
IDEA → GOAL_IDEAOne idea can be linked to many goals (many-to-many via junction table)
GOAL → TASKOne goal can have many tasks
IDEA → TASKOne idea can have many tasks
IDEAS/GOALS/TASKS → COMMENTEach entity can have many comments
USER → AUDIT_LOGAll user actions generate audit log entries

Multi-Tenancy

All queries are scoped by tenantId from the authenticated user’s Azure AD tenant:

// lib/db.ts export async function getIdeasForTenant(tenantId: string) { return prisma.idea.findMany({ where: { author: { tenantId: tenantId } } }); }

This ensures users from one Microsoft 365 tenant cannot see data from another tenant.


Security Architecture

Authentication

ComponentImplementation
Identity ProviderAzure AD (Microsoft Entra ID)
Auth LibraryNextAuth.js v5
Session StorageDatabase (Prisma adapter)
Token HandlingHTTP-only cookies

Middleware Protection

// middleware.ts export { auth as middleware } from "@/lib/auth"; export const config = { matcher: [ "/((?!api/auth|_next/static|_next/image|favicon.ico).*)", ], };

How it works: The middleware runs on every request and checks if the user is authenticated. Unauthenticated users are redirected to the sign-in page.

API Route Protection

// app/api/ideas/route.ts import { auth } from "@/lib/auth"; export async function GET() { const session = await auth(); if (!session?.user) { return Response.json({ error: "Unauthorized" }, { status: 401 }); } // Fetch ideas for user's tenant }

How it works: Each API route checks the session before processing. If no valid session exists, a 401 Unauthorized response is returned.


Performance Optimizations

React Compiler

Next.js 16 includes the React Compiler for automatic optimizations:

// next.config.ts const nextConfig = { experimental: { reactCompiler: true, }, };

How it works: The React Compiler automatically memoizes components and hooks, eliminating the need for manual useMemo and useCallback in most cases.

React Query Caching

// hooks/use-ideas.ts export function useIdeas() { return useQuery({ queryKey: ["ideas"], queryFn: fetchIdeas, staleTime: 5 * 60 * 1000, // 5 minutes gcTime: 30 * 60 * 1000, // 30 minutes }); }

How it works:

  • staleTime - Data is considered fresh for 5 minutes (no refetching)
  • gcTime - Unused data is garbage collected after 30 minutes

Optimistic Updates

export function useCreateIdea() { const queryClient = useQueryClient(); return useMutation({ mutationFn: createIdea, onMutate: async (newIdea) => { await queryClient.cancelQueries({ queryKey: ["ideas"] }); const previous = queryClient.getQueryData(["ideas"]); queryClient.setQueryData(["ideas"], (old) => [...old, newIdea]); return { previous }; }, onError: (err, newIdea, context) => { queryClient.setQueryData(["ideas"], context.previous); }, onSettled: () => { queryClient.invalidateQueries({ queryKey: ["ideas"] }); }, }); }

How it works:

  1. onMutate - Before the API call, immediately update the UI with the new idea
  2. onError - If the API call fails, rollback to the previous state
  3. onSettled - After success or failure, refetch to ensure consistency

Technology Summary

ComponentTechnologyPurpose
FrameworkNext.js 16Full-stack React framework
LanguageTypeScriptType safety
StylingTailwind CSS v4Utility-first CSS
UI Componentsshadcn/ui + RadixAccessible components
State ManagementZustand + React QueryClient and server state
DatabaseTurso (libSQL)Cloud SQLite database
ORMPrismaType-safe database access
AuthenticationNextAuth.js v5OAuth with Azure AD
Real-timeLiveKitVoice and video calling
Mind MapsReact FlowInteractive node graphs
Drag & Drop@dnd-kitKanban board interactions

Environment Variables

# Authentication AUTH_SECRET="your-auth-secret" AUTH_MICROSOFT_ENTRA_ID_ID="azure-client-id" AUTH_MICROSOFT_ENTRA_ID_SECRET="azure-client-secret" AUTH_MICROSOFT_ENTRA_ID_ISSUER="https://login.microsoftonline.com/tenant-id/v2.0" # Database TURSO_DATABASE_URL="libsql://your-db.turso.io" TURSO_AUTH_TOKEN="your-turso-token" # LiveKit (optional) LIVEKIT_URL="wss://your-app.livekit.cloud" LIVEKIT_API_KEY="your-api-key" LIVEKIT_API_SECRET="your-api-secret" # Application NEXT_PUBLIC_APP_URL="https://your-domain.com"

Document Information

PropertyValue
Version1.0
Last UpdatedDecember 2024
ClassificationTechnical Documentation
Last updated on