How nazmul-nhb/next-portfolio works
1. Overall shape
- This is a Next.js App Router application with a strong split between:
- public-facing content pages,
- a rich admin dashboard,
- a large set of self-contained productivity tools,
- and a shared REST-style API layer under src/app/api.
- Most business logic is concentrated in src/lib, while pages and route handlers stay thin and delegate to those shared modules.
2. Primary runtime boundaries
- The app runs as a server-rendered Next.js site with mixed server/client components.
- Interactive areas such as the admin console, editors, chat, and tools are mostly client components.
- Cross-cutting providers in src/providers handle auth, TanStack Query, and theme state across the UI.
3. Public site subsystem
- The landing page lives in src/app/(home) and is composed from section components like hero, skills, projects, testimonials, blogs, and career highlights.
- Content pages for about, projects, blogs, resume, contact, messages, settings, and users all follow the same pattern: a route-level page plus focused feature components.
- These pages typically read from the API or DB-backed server data, then render with shared UI primitives from src/components.
4. Content management subsystem
- The repo models several content domains: blogs, projects, skills, experiences, education, testimonials, categories, tags, users, and messages.
- Each domain has:
- a schema in src/lib/drizzle/schema,
- validation in src/lib/zod-schema,
- API routes under src/app/api/...,
- and admin UI under src/app/admin/....
- This creates a clear flow: form/UI → validated request → API route → Drizzle/Postgres.
5. Admin dashboard
- src/app/admin is the operational center for CRUD and sorting workflows.
- It contains dedicated sections for blogs, categories, education, experience, projects, skills, testimonials, messages, and users.
- Client components such as AdminBlogsClient, ProjectsClient, and SortableSkillCard imply heavy client-side interaction for tables, dialogs, drag-and-drop ordering, and editing flows.
6. Database layer
- Persistence is built on Drizzle ORM with a PostgreSQL database, likely Neon as described in the README.
- drizzle.config.ts, migrations/, and src/lib/drizzle/schema/* define the schema/migration boundary.
- The database appears to be the system of record for:
- user accounts,
- blog content and metadata,
- project/career records,
- messaging/conversations,
- polls,
- and expense-manager data.
- The migration history suggests the schema evolved incrementally and is managed explicitly rather than being generated at runtime.
7. Authentication and user identity
- Authentication is handled through NextAuth v5 in src/lib/auth.ts and src/app/api/auth/[...nextauth].
- The app supports credentials and Google OAuth.
- User-aware APIs like users/me, users/search, users/admin, and messaging endpoints indicate a central identity model shared across public and admin features.
- There is also a login/register/error/force-signout flow under src/app/auth.
8. Messaging subsystem
- Messaging is implemented as a database-backed conversation system rather than WebSockets.
- The UI under src/app/messages uses conversation lists and chat area components, while API routes under src/app/api/messages/* expose conversations, unread counts, and message-by-conversation access.
- The README notes the “almost real-time” behavior: the client likely polls for updates via TanStack Query or custom hooks.
- This makes messaging a distinct subsystem with a polling-driven data flow: client poll → API → DB → refreshed conversation state.
9. Media, uploads, and external services
- Cloudinary is the media backend for uploads and image management, with route support in src/app/api/uploads.
- Nodemailer is used for email notifications, most visibly around contact and perhaps auth-related workflows.
- The resume feature also references an externally hosted PDF URL, so the app combines local generated views with remote document delivery.
- These integrations are abstracted under src/lib/actions/cloudinary.ts, src/lib/email, and related helpers.
10. Blog/editor and publishing workflow
- Blog creation/editing is handled through a richer editor stack, with Tiptap-based editor support mentioned in the README and components under src/components/misc/blog-editor.tsx.
- Blog routes include list/detail pages, personal posts, create/edit flows, admin management, reactions, and comments.
- This subsystem is a good example of the app’s layering:
- content editing in the client,
- validation in Zod,
- persistence through API routes and Drizzle,
- and presentation via public blog pages plus social/SEO helpers.
11. Tools subsystem
- src/app/tools is effectively a mini product suite inside the portfolio.
- Tools are mostly independent pages with local UI and a small shared shell (Navigate, PoweredBy, TitleWithShare).
- Some tools are pure client-side utilities, while others call dedicated APIs under src/app/api/tools/*.
- Notable data-heavy tools include:
- expense manager,
- crowd polls,
- npm package lookup,
- and utilities that may rely on browser storage or local computation.
12. Tool-specific persistence and state
- Some tools use more than transient UI state:
- crowd polls has dedicated poll, vote, and analytics endpoints,
- expense manager has entries, loans, payments, summary, and currency routes,
- and some utilities reference src/lib/tools/indexed-db.ts, indicating browser-side persistence for selected features.
- src/lib/store contains Zustand stores for reusable interactive state, likely used by messaging and UI bubbles.
- This means the tools area is not just static calculators; it mixes local computation, client persistence, and DB-backed feature tools.
13. Shared component and design system
- src/components/ui is the base design system, combining shadcn-style primitives and Radix UI components.
- Higher-level shared components in src/components/forms, src/components/nav, and src/components/misc support reuse across the app.
- These shared components are the main architectural boundary for consistency: feature pages are assembled from them rather than implementing bespoke UI each time.
14. API and service conventions
- API routes are organized by domain and generally mirror the UI sections one-for-one.
- src/lib/actions provides request/response helpers and shared server-side utilities, which keeps route handlers standardized.
- Zod schemas in src/lib/zod-schema and typed interfaces in src/types enforce a contract between UI, API, and DB.
- The result is a fairly strict vertical slice architecture: feature page → component → API route → service/helper → DB/external service.
15. SEO and platform concerns
- The app has dedicated support for OpenGraph images, robots.ts, and sitemap.ts.
- This suggests the public content areas are treated as indexed, shareable products rather than internal tooling.
- Next.js image/metadata routes are used as part of the rendering layer, not as separate services.
16. What to draw in an architecture diagram
- The most important boxes are:
- Next.js App Router UI with public pages, admin, auth, messages, tools,
- API routes grouped by domain,
- Shared libs for auth, Drizzle, email, uploads, validation, and utility tools,
- PostgreSQL/Neon as the main datastore,
- Cloudinary, Google OAuth/NextAuth, and email as external dependencies.
- The key flows are:
- content CRUD from admin/public forms to DB,
- blog/contact/message interactions through APIs,
- tool-specific fetches and polling,
- and media/auth integration through external providers.
Main entry points: lib Shared Lib · app App Router · api API Routes · components Shared Components
Components 19
Next.js UI
App Router pages and route-level feature UIs
- App Router · Server-rendered application shell with mixed server/client routes
src/app - Home · Landing page and public content sections
src/app/(home) - Content Pages · About, projects, blogs, resume, contact, settings, and users pages
src/app - Admin Console · CRUD and sorting workspace for content domains
src/app/admin - Auth UI · Login, register, error, and forced sign-out flows
src/app/auth - Messaging UI · Conversation list and chat views for user messaging
src/app/messages - Tools Hub · Standalone productivity tools and their local shells
src/app/tools
API Layer
Route handlers grouped by domain
- API Routes · Thin route handlers that expose domain APIs
src/app/api - Content APIs · Blogs, projects, categories, tags, comments, resume, contact, and users endpoints
src/app/api - Messaging APIs · Conversation, unread, and message retrieval/update endpoints
src/app/api/messages - Tool APIs · Expense manager, polls, npm lookup, and upload endpoints
src/app/api/tools - Auth APIs · NextAuth, registration, and OTP routes
src/app/api/auth
Shared Logic
Reusable server and client logic
- Shared Lib · Server helpers, validation, auth, email, uploads, and utility modules
src/lib - Drizzle Schema · Database tables and migrations for blogs, careers, users, messages, polls, skills, testimonials, and expenses
src/lib/drizzle/schema - Zod Schemas · Request and domain validation contracts shared across UI and APIs
src/lib/zod-schema
Shared Components
Cross-feature UI building blocks
- Shared Components · Reusable forms, nav, misc helpers, and base UI primitives
src/components
Platform
Providers and external systems
- Providers · Auth, query, and theme context for the app
src/providers - PostgreSQL · Primary persistent store, likely Neon-backed
- External Services · Cloudinary, Google OAuth, email delivery, and NextAuth providers
Connections 24
- App Router → Home: renders · App Router composes public landing content
- App Router → Content Pages: routes · Public pages share the same application shell
- App Router → Admin Console: hosts · Admin dashboard is a major UI boundary
- App Router → Auth UI: hosts · Authentication pages live in the app router
- App Router → Messaging UI: hosts · Messaging is a first-class interactive section
- App Router → Tools Hub: hosts · Tool pages are implemented as a mini product suite
- Home → Shared Components: uses · Landing sections are assembled from reusable UI
- Content Pages → Shared Components: uses · Content pages rely on shared forms, nav, and primitives
- Admin Console → Shared Components: uses · Dashboard CRUD screens use shared tables, dialogs, and forms
- Messaging UI → Providers: uses · Chat state depends on auth and query context
- Tools Hub → Providers: uses · Tools reuse query/theme/auth context where needed
- API Routes → Content APIs: organizes · Domain route handlers are grouped under the API layer
- API Routes → Messaging APIs: organizes · Messaging endpoints are a dedicated API slice
- API Routes → Tool APIs: organizes · Tool-specific services are exposed through routes
- API Routes → Auth APIs: organizes · Authentication flows are served through API routes
- Content APIs → Shared Lib: delegates · Handlers validate, normalize, and persist through shared services
- Messaging APIs → Shared Lib: delegates · Conversation logic is implemented in shared server modules
- Tool APIs → Shared Lib: delegates · Tool endpoints reuse common helpers and specialized utilities
- Auth APIs → Shared Lib: delegates · Auth routes rely on the shared auth and email layer
- Shared Lib → Zod Schemas: validates · Zod schemas define the input contract for features
- Shared Lib → Drizzle Schema: persists · Drizzle models define application storage
- Drizzle Schema → PostgreSQL: stores · Migrations and schema target the relational database
- Shared Lib → External Services: integrates · Uploads, OAuth, and email are abstracted behind helpers
- Providers → Shared Components: supplies · Global UI state and context feed reusable components