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_publicfor cover images and avatars,falsafa_privatefor 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-alpineDocker build with Next.js standalone output. - Dev mode: A
NEXT_PUBLIC_DEBUG_MODEflag 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
/adminwith its own layout, sidebar, and server-side role guard. Only users withrole = '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/chatendpoint authenticates the user, loads session context, and proxies the SSE stream fromPOST /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=truereplaces 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_idandbook_idfrom 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.