Akari Art is a full-stack AI image generation platform built on Next.js 15 with the App Router. It combines a React Server Component frontend, Next.js Route Handlers as its API layer, MongoDB (via Mongoose) for persistence, Cloudflare Workers AI (Flux-1-Schnell) for image synthesis, and Cloudinary for image hosting. Authentication is handled entirely by NextAuth.js using Google OAuth 2.0 with JWT sessions, meaning no session data is ever written to the database.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/nayalsaurav/Akari-Art/llms.txt
Use this file to discover all available pages before exploring further.
Application Layers
Frontend — Next.js App Router
Pages live under
app/ and are built with React Server Components where possible. Protected routes (/create, /community) are gated by middleware.ts using withAuth from NextAuth.js. Client-interactive surfaces (ImageGenerator.tsx, RenderPosts.tsx) are isolated into dedicated Client Components.API Routes — Next.js Route Handlers
Three Route Handler modules power the backend:
app/api/auth/[...nextauth]/route.ts handles the full OAuth flow, app/api/image-generation/route.ts proxies prompts to Cloudflare Workers AI and uploads results to Cloudinary, and app/api/post/route.ts provides GET (fetch all posts) and POST (create a post) operations against MongoDB.Database Layer — MongoDB + Mongoose
MongoDB Atlas stores two collections:
users and posts. Mongoose models (model/user.ts, model/post.ts) enforce schemas and TypeScript interfaces. The lib/database.ts module implements a global connection cache with maxPoolSize: 10 to safely share a single connection across serverless function invocations.External Services — Cloudflare AI + Cloudinary
User prompts are sent over HTTPS to the Cloudflare Workers AI REST API, which runs the
@cf/black-forest-labs/flux-1-schnell model and returns a base64-encoded PNG. That PNG is immediately uploaded to Cloudinary via the Node.js SDK, and the resulting secure_url is what gets stored and served — never the raw base64 payload.Image Generation Request Flow
Browser sends prompt
The
ImageGenerator client component collects the user’s text prompt and issues a POST /api/image-generation request with the JSON body { "prompt": "<user text>" }.Next.js Route Handler forwards to Cloudflare
app/api/image-generation/route.ts reads CLOUDFLARE_ID and CLOUDFLARE_API_KEY from environment variables, then calls:Authorization: Bearer {CLOUDFLARE_API_KEY} and { prompt } as the body.Cloudflare Workers AI generates the image
Flux-1-Schnell processes the prompt and returns
{ success: true, result: { image: "<base64 PNG>" } }. If success is false, the route handler immediately returns a 500 error to the client.Base64 image is uploaded to Cloudinary
The Route Handler calls
cloudinary.uploader.upload("data:image/png;base64,<base64>"). Cloudinary stores the image and returns a secure_url of the form https://res.cloudinary.com/....Cloudinary URL is returned to the browser
The Route Handler responds with
{ photo: photoUrl.secure_url } and HTTP 200. The client renders the image using Next.js <Image> (domain res.cloudinary.com is allow-listed in next.config.ts).Directory Structure
Key Design Decisions
App Router with Server Components for auth-protected pages Routes like/create and /community are protected at the middleware layer by withAuth — before any page component is even evaluated. The middleware.ts matcher covers every path except _next/static, _next/image, and favicon.ico, so no protected route can be reached without a valid JWT.
MongoDB connection pooling with global cache
In a serverless environment, each function invocation can create its own database connection, quickly exhausting the Atlas connection limit. lib/database.ts writes the Mongoose connection and its pending promise to global.mongoose, so warm invocations reuse the established connection. The maxPoolSize: 10 option caps concurrent connections per Node.js process.
Images stored in Cloudinary rather than inline
Storing raw base64 strings in MongoDB would bloat documents and make retrieval slow. Instead, every generated image is immediately pushed to Cloudinary; only the resulting https://res.cloudinary.com/... URL is saved in the posts collection. next.config.ts allow-lists res.cloudinary.com so Next.js <Image> can serve optimised variants.
JWT sessions for stateless auth
lib/auth.ts configures session: { strategy: "jwt" }. Session data is encoded in a signed cookie and never written to MongoDB. The jwt and session callbacks attach the MongoDB user _id to the token and surface it as session.user.id, making the ID available to client components and API routes without an extra database round-trip.