Falsafa
Frontend

Frontend Overview

Next.js 16 application powering Falsafa's user-facing features: auth, book discovery, chat with characters, payments, library management, and an admin panel.

Falsafa's frontend is a Next.js 16 application using the App Router. It is the user-facing half of the platform: it handles authentication, book browsing and purchasing, character chat, library management, and administration. It runs as a standalone Docker container on port 3000, sitting behind a Traefik reverse proxy that shares a network with the backend, Qdrant, Redis, and TypeSense.

Tech Stack

The frontend is a TypeScript monolith with a broad dependency surface:

  • Framework: Next.js 16 (App Router, React 19, server components, streaming SSR).
  • Auth: Supabase Auth with SSR cookie-based sessions. NextAuth.js stubs exist in the codebase but are unused.
  • Database: Supabase PostgreSQL accessed through the Supabase JavaScript client (SSR on the server, browser client on the client).
  • Storage: Supabase Storage exclusively. Two buckets: falsafa_public for cover images and avatars, falsafa_private for book files.
  • Payments: Stripe via Elements (CardElement) on the checkout page, with a webhook endpoint that adds purchased books to the user's library.
  • UI: shadcn/ui components (55+ primitives built on Radix UI), Tailwind CSS 4, lucide-react icons, Recharts for admin charts, sonner for toast notifications.
  • Container: Multi-stage node:20-alpine Docker build with Next.js standalone output.
  • Dev mode: A NEXT_PUBLIC_DEBUG_MODE flag that bypasses auth, Stripe, and certain Supabase checks for local development.

Architecture at a Glance

Every page in the frontend belongs to one of three tiers:

  • Public pages - homepage, category listings, book detail, auth forms, search, help. Served to anyone, no auth required.
  • Authenticated pages - library, wishlist, chat, settings, upload-book, notifications. Middleware redirects unauthenticated visitors to login.
  • Admin pages - a sub-application under /admin with its own layout, sidebar, and server-side role guard. Only users with role = 'admin' can access it.

Data flows are equally simple:

  • User actions (uploading a book, sending a chat message, purchasing) go through Next.js API routes. Those routes call Supabase directly, proxy to the Python backend, or call Stripe.
  • Chat is the only feature that goes to the backend. The frontend's /api/chat endpoint authenticates the user, loads session context, and proxies the SSE stream from POST /character/chat.
  • File uploads (book covers, book files, profile avatars) go to Supabase Storage. The backend never touches the frontend's storage bucket - it receives a signed URL when it needs to download a book file.

Design Decisions

  • Supabase-only storage. All files - book covers, book files, profile avatars, category images - live in Supabase Storage buckets. There is no S3 in the active architecture.
  • Service-role client for admin operations. DB queries that need to bypass Row-Level Security use a synchronous getAdminClient() factory that creates a Supabase client with the service-role key. This is used for all role checks, admin CRUD, and book upload pipeline steps.
  • Debug mode. NEXT_PUBLIC_DEBUG_MODE=true replaces the auth check with a mock admin user, replaces Stripe checkout with a fake session, and allows the frontend to run without Supabase env vars configured. It is a development escape hatch, not a production feature.
  • shadcn/ui component model. Every UI primitive is a local copy under components/ui/, customized with the project's Tailwind theme. No external component library is imported at runtime.
  • Trust boundary. The frontend owns auth and session management. The backend trusts user_id and book_id from the frontend because the frontend enforces authentication before those values reach the backend. Banning a user in the frontend prevents them from calling the backend at all.

Pages and Routes

The application exposes roughly thirty pages and forty API routes:

  • 7 public pages - /, /category, /category/[slug], /book/[id], /search, /auth/*, /help
  • 9 authenticated pages - /library, /wishlist, /chat, /chat/[id], /settings/*, /upload-book, /notifications, /checkout/[id]
  • 8 admin pages under /admin/ - dashboard, categories, books, users, comments, reports, notifications, settings
  • 40+ API routes under /api/ - books, categories, chat, library, wishlist, profile, notifications, payments, admin, files, media

All API routes are implemented as Next.js route handlers using the platform's standard NextRequest/NextResponse pattern.

On this page