Tech Stack
Next.js 16, Supabase (Auth / DB / Storage), Stripe, shadcn/ui, and the tooling choices that shape the frontend.
The frontend is a Next.js 16 TypeScript application. Every other choice - auth provider, database, storage backend, payment processor - is a deliberate integration with an external service rather than a pluggable abstraction.
Framework
- Next.js 16 with the App Router. Pages are server components by default; interactivity is added via
'use client'boundaries. - React 19 with server components, streaming SSR, and the new React compiler.
- TypeScript 5.7 in strict mode.
- Build output: Next.js
standalonemode produces a self-contained deployable with onlynode_modulesand the compiled application.
Authentication
- Supabase Auth with SSR cookie management (
@supabase/ssr). The middleware refreshes sessions on every request. The server helper (auth.ts) verifies cookies and enriches the user object with role and status from theprofilesanduser_rolestables. - No NextAuth.js. The
auth.config.tsandauth.tsfiles export empty stubs for backward compatibility; all actual auth flows go through the Supabase client.
Database
- Supabase PostgreSQL accessed through two client factories:
getSupabaseServer()- SSR-aware client that reads/writes cookies for authenticated user queries.getAdminClient()- synchronous service-role client that bypasses RLS for privileged operations.supabase(browser) - lazy-initialized proxy client for client-side queries.
- Schema: ~15 tables covering users, books, categories, characters, chat sessions, messages, preferences, purchases, library, wishlist, notifications, reports, settings.
Storage
- Supabase Storage is the sole file store. Two buckets:
falsafa_public- cover images, profile avatars, category images (publicly readable URLs).falsafa_private- book files (private, accessed via signed URLs).
- File validation (MIME type, size limits) is per-purpose and configurable via environment variables.
- Signed URLs for the backend expire after one hour.
Payments
- Stripe Elements (
CardElement) for PCI-compliant card input on the checkout page. - PaymentIntents for server-side payment processing.
- Webhooks via
POST /api/payments/webhookwith signature verification. Oncheckout.session.completed, the purchased book is added touser_library. - No subscription billing; all purchases are one-time.
UI Components
- shadcn/ui component library - 55+ primitives built on Radix UI (
@radix-ui/*packages). Every component is a local copy undercomponents/ui/and is customized with the project's Tailwind theme. - Tailwind CSS 4 with
tw-animate-cssfor animations. - lucide-react for icons.
- Recharts for admin dashboard charts.
- sonner for toast notifications.
- next-themes for dark/light mode (used by the
<ThemeProvider>layout component).
Custom Components
A small set of domain-specific components live outside ui/:
BookCard- book cover card with two variants (default 2:3 aspect ratio, compact 1:1 for grids).CategoryCard- square card with cover image or gradient fallback.CharacterAvatar- circular avatar with name and description.AppLayout- responsive shell with sidebar (desktop) / bottom-tab-bar (mobile).
Container
The Dockerfile uses a three-stage build:
deps-node:20-alpine, installs dependencies with pnpm.builder- compiles the application viapnpm build.runner-node:20-alpine, copies.next/standaloneoutput, runs asnextjsuser on port 3000.
The production image listens on 0.0.0.0:3000 and runs node server.js.
Development
pnpm devstarts the Next.js dev server on port 3000.NEXT_PUBLIC_DEBUG_MODE=trueenables mock auth and mock Stripe so the frontend runs without external services.- Tailwind CSS 4 uses the new CSS-first configuration (no
tailwind.config.js).
High-Level Design
Architecture overview of Falsafa's frontend: how auth, storage, chat, payments, and the API layer fit together.
Auth Flow
Three-layer auth architecture: edge middleware, server-side helper, client-side context. Supabase Auth with SSR cookies, role-based access, blocked-user enforcement, and debug mode bypass.