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:
| Layer | Description |
|---|---|
| Browser | The user interface running in the browser, built with React 19 and Next.js App Router |
| Next.js Server | Server-side code handling API routes, authentication, and database queries via Prisma |
| External Services | Cloud 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 definitions2. 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 warmup3. 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:
- User clicks sign in - Initiates the OAuth flow
- NextAuth redirects - Browser is redirected to Azure AD login page
- User logs in - Enters Microsoft credentials
- Authorization code - Azure sends code back to NextAuth callback URL
- Token exchange - NextAuth exchanges the code for access and ID tokens
- User record - Prisma creates or updates the user in Turso database
- Session cookie - NextAuth sets an HTTP-only session cookie
- Dashboard - User is redirected to the dashboard
CRUD Operation Flow
How it works:
- React Component uses a hook like
useIdeas()to request data - React Query manages the request, caching, and loading states
- API Route handles the request at
/api/ideas - Prisma executes a type-safe query against Turso
- Turso DB returns the result rows
- JSON response is sent back to the client
- Cache update React Query updates its cache and re-renders the component
Real-time Calling Flow
How it works:
- Caller initiates - POST request creates a call record in Turso and returns a JWT token
- Callee polls - Every 3 seconds, the callee checks for incoming calls
- Call found - When a pending call is detected, the callee sees a notification
- Accept call - PATCH request updates the call status and returns a token for the callee
- Connect to LiveKit - Both users connect to the LiveKit room using their JWT tokens
- WebRTC streaming - LiveKit handles the peer-to-peer audio/video transmission
| Step | Who | Action |
|---|---|---|
| 1 | Caller | Creates call record, gets token |
| 2 | Callee | Polls and sees incoming call |
| 3 | Callee | Clicks Accept, gets token |
| 4 | Both | Connect to LiveKit room |
| 5 | Both | Exchange 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).
| Relationship | Meaning |
|---|---|
| USER → IDEA | One user creates many ideas |
| USER → GOAL | One user creates many goals |
| USER → TASK | One user creates many tasks |
| USER → CALL | One user can initiate many calls |
| IDEA → GOAL_IDEA | One idea can be linked to many goals (many-to-many via junction table) |
| GOAL → TASK | One goal can have many tasks |
| IDEA → TASK | One idea can have many tasks |
| IDEAS/GOALS/TASKS → COMMENT | Each entity can have many comments |
| USER → AUDIT_LOG | All 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
| Component | Implementation |
|---|---|
| Identity Provider | Azure AD (Microsoft Entra ID) |
| Auth Library | NextAuth.js v5 |
| Session Storage | Database (Prisma adapter) |
| Token Handling | HTTP-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:
- onMutate - Before the API call, immediately update the UI with the new idea
- onError - If the API call fails, rollback to the previous state
- onSettled - After success or failure, refetch to ensure consistency
Technology Summary
| Component | Technology | Purpose |
|---|---|---|
| Framework | Next.js 16 | Full-stack React framework |
| Language | TypeScript | Type safety |
| Styling | Tailwind CSS v4 | Utility-first CSS |
| UI Components | shadcn/ui + Radix | Accessible components |
| State Management | Zustand + React Query | Client and server state |
| Database | Turso (libSQL) | Cloud SQLite database |
| ORM | Prisma | Type-safe database access |
| Authentication | NextAuth.js v5 | OAuth with Azure AD |
| Real-time | LiveKit | Voice and video calling |
| Mind Maps | React Flow | Interactive node graphs |
| Drag & Drop | @dnd-kit | Kanban 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
| Property | Value |
|---|---|
| Version | 1.0 |
| Last Updated | December 2024 |
| Classification | Technical Documentation |