OS Trading Engine
Technical Documentation
Frontend
App Router Structure

App Router Structure

Nexgent uses Next.js 15 with the App Router for server-side rendering, routing, and layouts.

Directory Structure

      • layout.tsx
      • layout.tsx
        • page.tsx
    • layout.tsx
    • page.tsx
    • globals.css

  • Route Groups

    Next.js route groups (folders in parentheses) organize routes without affecting the URL structure.

    Auth Routes (auth)

    Authentication pages with a minimal layout (no sidebar):

    RouteFileDescription
    /login(auth)/login/page.tsxLogin form
    /register(auth)/register/page.tsxRegistration form

    Dashboard Routes (dashboard)

    Protected pages with the full dashboard layout (sidebar, header):

    RouteFileDescription
    /dashboarddashboard/page.tsxDashboard home (redirects to general)
    /dashboard/generaldashboard/general/page.tsxMain dashboard with positions
    /dashboard/agent-profiledashboard/agent-profile/page.tsxAgent trading configuration
    /dashboard/performance-overviewdashboard/performance-overview/page.tsxPerformance charts and metrics
    /dashboard/trade-signalsdashboard/trade-signals/page.tsxSignal history
    /dashboard/transactionsdashboard/transactions/page.tsxTransaction history
    /dashboard/walletdashboard/wallet/page.tsxWallet management
    /dashboard/integrationsdashboard/integrations/page.tsxAPI keys and integrations

    Layouts

    Root Layout (app/layout.tsx)

    The root layout wraps the entire application with providers:

    // app/layout.tsx
    import { AppProviders } from '@/shared/providers';
    import { Toaster } from '@/shared/components/ui/toaster';
     
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en" className="dark">
          <body className="font-sans">
            <AppProviders>{children}</AppProviders>
            <Toaster />
          </body>
        </html>
      );
    }

    Dashboard Layout (app/(dashboard)/layout.tsx)

    The dashboard layout provides the sidebar and requires authentication:

    // app/(dashboard)/layout.tsx
    'use client';
     
    import { useSession } from 'next-auth/react';
    import { redirect } from 'next/navigation';
    import { SidebarProvider, SidebarInset } from '@/shared/components/ui/sidebar';
    import { AppSidebar } from '@/shared/components/layout/app-sidebar';
    import { Providers } from '@/shared/contexts/providers';
     
    export default function DashboardLayout({ children }: { children: React.ReactNode }) {
      const { status } = useSession();
      
      if (status === 'unauthenticated') {
        redirect('/login');
      }
      
      if (status === 'loading') {
        return <LoadingScreen />;
      }
      
      return (
        <Providers>
          <SidebarProvider>
            <AppSidebar />
            <SidebarInset>
              {children}
            </SidebarInset>
          </SidebarProvider>
        </Providers>
      );
    }

    The dashboard layout uses Providers from contexts (agent selection, currency, trading mode) which are separate from AppProviders (NextAuth, React Query) at the root.


    Page Pattern

    Pages are thin wrappers that compose feature components:

    // app/(dashboard)/dashboard/general/page.tsx
    import { LivePositionsTable } from '@/features/positions';
    import { RecentTradesTable } from '@/features/trades';
    import { SystemHealthCard } from '@/features/system-health';
     
    export default function GeneralPage() {
      return (
        <div className="flex flex-col gap-6 p-6">
          <h1 className="text-2xl font-bold">Dashboard</h1>
          
          <div className="grid gap-6">
            <LivePositionsTable />
            <RecentTradesTable />
            <SystemHealthCard />
          </div>
        </div>
      );
    }

    API Routes

    NextAuth.js uses an API route for authentication callbacks:

    // app/api/auth/[...nextauth]/route.ts
    import NextAuth from 'next-auth';
    import { authConfig } from '@/infrastructure/auth/auth-config';
     
    const handler = NextAuth(authConfig);
     
    export { handler as GET, handler as POST };

    Middleware

    Next.js middleware protects routes and handles redirects:

    // src/middleware.ts
    import { withAuth } from 'next-auth/middleware';
     
    export default withAuth({
      pages: {
        signIn: '/login',
      },
    });
     
    export const config = {
      matcher: ['/dashboard/:path*'],
    };

    Static vs Dynamic

    RenderingUsage
    StaticLanding page, auth pages
    DynamicDashboard pages (require session)

    Dashboard pages are client components ('use client') because they depend on:

    • Session state (authentication)
    • WebSocket connections (real-time updates)
    • Client-side contexts (agent selection)