Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dev0302/nextjs-project-1/llms.txt

Use this file to discover all available pages before exploring further.

AnonMessage is built on the Next.js 14 App Router. Every page, API handler, and shared utility lives under src/, with route groups providing logical separation between authenticated pages, authentication flows, and public-facing profiles — all without affecting the URL structure.

Annotated Directory Tree

src/
├── app/
│   ├── (app)/                        # Route group: authenticated pages
│   │   ├── dashboard/
│   │   │   ├── page.tsx              # Main dashboard — view and manage messages
│   │   │   └── loading.tsx           # Suspense skeleton
│   │   └── u/
│   │       └── [username]/
│   │           └── page.tsx          # Public profile — send anonymous message
│   │
│   ├── (auth)/                       # Route group: authentication flows
│   │   ├── sign-in/
│   │   │   ├── page.tsx
│   │   │   └── loading.tsx
│   │   ├── sign-up/
│   │   │   ├── page.tsx
│   │   │   └── loading.tsx
│   │   └── verify-otp/
│   │       ├── page.tsx
│   │       └── loading.tsx
│   │
│   ├── api/                          # Co-located API routes
│   │   ├── accept-messages/route.ts  # GET + POST  — message acceptance toggle
│   │   ├── auth/[...nextauth]/route.ts  # NextAuth catch-all handler
│   │   ├── check-username-unique/route.ts  # GET  — username availability
│   │   ├── delete-message/route.tsx  # PATCH — remove a message by ID
│   │   ├── get-messages/route.ts     # GET  — aggregation pipeline for sorted messages
│   │   ├── send-message/route.ts     # POST — push anonymous message to user
│   │   ├── send-otp/route.ts         # POST — generate OTP and send via Brevo
│   │   ├── sign-up/route.ts          # POST — verify OTP + create user
│   │   └── suggest-messages/route.ts # GET  — AI-generated question suggestions (Gemini)
│   │
│   ├── lib/
│   │   ├── auth.ts                   # NextAuth AuthOptions config + callbacks
│   │   ├── dbConnect.ts              # Mongoose singleton connection
│   │   └── mailSender.ts             # Brevo transactional email client
│   │
│   ├── models/
│   │   ├── User.ts                   # IUser + Message Mongoose models
│   │   └── OTP.ts                    # IOTP model with TTL + pre-save email hook
│   │
│   ├── schemas/
│   │   ├── signUpSchema.ts           # Zod: username / email / password rules
│   │   ├── signInSchema.ts           # Zod: username + password
│   │   ├── messageSchema.ts          # Zod: content 10–300 chars
│   │   ├── acceptMessageSchema.ts    # Zod: boolean flag
│   │   └── verifySchema.ts           # Zod: 6-digit OTP code
│   │
│   ├── types/
│   │   ├── ApiResponse.ts            # Generic ApiResponse<T> interface
│   │   ├── user.ts                   # SafeUser — non-sensitive user subset
│   │   └── next-auth.d.ts            # NextAuth module augmentation
│   │
│   ├── layout.tsx                    # Root layout (html + body + AuthProvider)
│   ├── page.tsx                      # Landing page
│   └── loading.tsx                   # Root-level loading UI

├── components/
│   ├── ui/                           # shadcn/ui primitives
│   │   ├── alert-dialog.tsx
│   │   ├── avatar.tsx
│   │   ├── button.tsx
│   │   ├── input.tsx
│   │   ├── label.tsx
│   │   └── sonner.tsx
│   ├── navbar/
│   │   ├── Navbar.tsx
│   │   ├── NavbarAuthButtons.tsx
│   │   ├── NavbarMiddleLink.tsx
│   │   └── NavbarUserMenu.tsx
│   ├── MessageCard.tsx               # Displays a single anonymous message
│   ├── MessageGrid.tsx               # Grid layout for the message list
│   ├── MessageToogle.tsx             # Switch to enable/disable message acceptance
│   ├── CopyLink.tsx                  # Copy-to-clipboard for the public profile URL
│   ├── SendMessageProfile.tsx        # Form for sending a message on a public profile
│   ├── DeleteMessageButton.tsx       # Alert-dialog wrapper for delete confirmation
│   ├── RefreshButton.tsx             # Triggers re-fetch of messages
│   └── email-client-card.tsx         # Card shown after OTP is sent

├── context/
│   └── AuthProvider.tsx              # SessionProvider wrapper for NextAuth

├── lib/
│   └── utils.ts                      # Shared utilities (cn helper, etc.)

├── templates/
│   └── otpTemplate.ts                # HTML email template for OTP emails

└── middleware.ts                     # Edge middleware — route protection + redirects

Route Groups

Next.js treats any folder name wrapped in parentheses as a route group. The parentheses are stripped from the URL, so the folders exist purely for code organisation and to allow separate layouts.

(app) group

Contains dashboard/ and u/[username]/. Both pages share the same authenticated layout. The URL paths are /dashboard and /u/[username] — the (app) segment never appears in the browser.

(auth) group

Contains sign-in/, sign-up/, and verify-otp/. These three pages share an auth-focused layout. URL paths are /sign-in, /sign-up, and /verify-otp.
Because route group names are invisible to the router, you can have /dashboard (inside (app)) and /sign-in (inside (auth)) without any URL prefix from the group folders themselves.

API Routes

All API handlers live under src/app/api/. Each folder contains a route.ts (or route.tsx) file that exports named HTTP method functions.
RouteMethod(s)Purpose
/api/auth/[...nextauth]GET, POSTNextAuth catch-all — handles sign-in, sign-out, session, and callbacks
/api/sign-upPOSTVerifies OTP, hashes password with bcrypt, creates the user document
/api/send-otpPOSTGenerates a 6-digit OTP via otp-generator, creates an OTP document (pre-save hook emails it)
/api/check-username-uniqueGETAccepts ?username= query param, checks uniqueness against MongoDB
/api/accept-messagesGET, POSTGET returns isAcceptingMessages status; POST updates it
/api/send-messagePOSTPushes a new anonymous message onto the recipient user’s messages array
/api/get-messagesGETRuns a Mongoose aggregation pipeline ($match → $unwind → $sort → $group) and returns messages sorted by newest first
/api/delete-messagePATCHUses $pull to remove a specific message subdocument by _id
/api/suggest-messagesGETCalls Google Gemini (gemini-1.5-flash) with a few-shot prompt and returns three suggested questions separated by ||

Components

components/ui/

shadcn/ui primitives: Button, Input, Label, Avatar, AlertDialog, and Sonner (toast notifications). These are generated and owned by the project — not imported from an external package at runtime.

components/navbar/

Navbar is the shell; NavbarAuthButtons shows Sign In / Sign Up links for guests; NavbarUserMenu shows the logged-in avatar and sign-out option; NavbarMiddleLink renders nav links for authenticated users.

Feature components

MessageCard — renders content + delete button. MessageGrid — responsive grid. MessageToogle — shadcn Switch bound to the accept-messages toggle. CopyLink — copies the /u/[username] URL to clipboard. SendMessageProfile — anonymous message submission form on the public profile page.

Utility components

DeleteMessageButton — wraps AlertDialog to confirm deletion before calling PATCH /api/delete-message. RefreshButton — client component that triggers a router refresh or manual re-fetch. email-client-card — shown post-OTP to prompt the user to check their inbox.

Lib Utilities

1

auth.ts — NextAuth configuration

Exports NEXT_AUTH_CONFIG: AuthOptions, which defines a single CredentialsProvider. The authorize callback connects to MongoDB, looks up the user by email, and compares the password with bcrypt.compare. Two callbacks (jwt and session) copy _id, isVerified, isAcceptingMessages, and username into the JWT and then into the session object.
2

dbConnect.ts — Singleton Mongoose connection

Maintains a module-level connection object with an isConnected flag. If isConnected is truthy the function returns immediately, preventing duplicate connections during Next.js hot-module reloads. On failure it calls process.exit(1) to fail loudly at startup rather than silently later.
3

mailSender.ts — Brevo transactional email

Wraps an axios.post to the Brevo SMTP API (https://api.brevo.com/v3/smtp/email). Reads SENDER_EMAIL and BREVO_API_KEY from environment variables. Called by the OTP model’s pre-save hook — not directly by API routes.

Zod Validation Schemas

All form and API input validation is centralised in src/app/schemas/. Each schema is a named export so it can be reused in both client-side form hooks (react-hook-form + zodResolver) and server-side route handlers.
FileSchemaKey rules
signUpSchema.tssignUpSchemausername 2–20 chars, alphanumeric + underscores; email valid format; password min 3 chars
signInSchema.tssignInSchemausername string, password string (no extra constraints — auth logic handles failures)
messageSchema.tsmessageSchemacontent 10–300 characters
acceptMessageSchema.tsacceptMessageSchemaacceptMessage must be a boolean
verifySchema.tsverifySchemacode exactly 6 characters

Types

export interface ApiResponse<T = null> {
    success: boolean;
    message: string;
    data?: T;
}
T defaults to null, making data optional for responses that carry no payload (e.g., a simple success/failure acknowledgement).
export interface SafeUser {
    id: string;
    username: string;
    email: string;
    isVerified: boolean;
    isAcceptingMessages: boolean;
    messages: Message[];
}
Returned as the data field in sign-up and delete-message responses. The password field is intentionally excluded.
declare module "next-auth" {
    interface User {
        _id?: string;
        isVerified?: boolean;
        isAcceptingMessages?: boolean;
        username?: string;
    }

    interface Session {
        user: {
            _id?: string;
            isVerified?: boolean;
            isAcceptingMessages?: boolean;
            username?: string;
        } & DefaultSession['user']
    }
}

declare module "next-auth/jwt" {
    interface JWT {
        _id?: string;
        isVerified?: boolean;
        isAcceptingMessages?: boolean;
        username?: string;
    }
}
TypeScript declaration merging adds application-specific fields to NextAuth’s built-in User, Session, and JWT interfaces. The & DefaultSession['user'] intersection preserves the original name, email, and image fields.

Build docs developers (and LLMs) love