Skip to content

Latest commit

Β 

History

History
967 lines (783 loc) Β· 29.7 KB

File metadata and controls

967 lines (783 loc) Β· 29.7 KB

πŸ“ ByteCode Blog Platform

A full-stack, production-ready blog application built with Next.js 16, featuring real-time interactions, rich text editing, and a comprehensive content management system.

Next.js TypeScript Prisma Tailwind CSS

πŸš€ Features

Core Functionality

  • πŸ“° Article Management - Create, edit, delete, and publish articles with rich text editor
  • πŸ” Advanced Search - Real-time search across articles with filtering capabilities
  • πŸ’¬ Comments System - Engage with readers through nested comments
  • ❀️ Like & Save - Interactive engagement with like/dislike and bookmark features
  • πŸ“Š Analytics Dashboard - Track article performance and user engagement
  • 🎨 Rich Text Editor - Powered by React Quill for professional content creation
  • πŸ–ΌοΈ Image Management - Cloudinary integration for optimized image uploads

User Experience

  • πŸ” Authentication - Secure user authentication via Clerk
  • πŸŒ“ Dark Mode - Seamless theme switching with next-themes
  • πŸ“± Responsive Design - Mobile-first approach with Tailwind CSS
  • ⚑ Performance - Optimized with Next.js 16 App Router and Server Components
  • β™Ώ Accessibility - Built with Radix UI primitives for WCAG compliance

πŸ› οΈ Tech Stack

Frontend

  • Framework: Next.js 16 (App Router)
  • Language: TypeScript 5
  • Styling: Tailwind CSS 4
  • UI Components: Radix UI, shadcn/ui
  • Rich Text: React Quill
  • Icons: Lucide React

Backend

  • Database: PostgreSQL
  • ORM: Prisma 5.22
  • Authentication: Clerk
  • File Storage: Cloudinary
  • Validation: Zod

DevOps & Tools

  • Package Manager: npm
  • Linting: ESLint 9
  • Type Checking: TypeScript
  • Database Seeding: tsx

πŸ“‹ Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js 18.x or higher
  • npm or yarn or pnpm
  • PostgreSQL database
  • Git

πŸ”§ Installation

1. Clone the repository

git clone <repository-url>
cd blog

2. Install dependencies

npm install

3. Environment Setup

Create a .env file in the root directory:

# Database
DATABASE_URL="postgresql://user:password@localhost:5432/blog_db"

# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

# Cloudinary
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret

4. Database Setup

# Generate Prisma Client
npx prisma generate

# Run migrations
npx prisma migrate dev

# Seed the database (optional)
npm run seed

5. Start Development Server

npm run dev

Visit http://localhost:3000 to see your application.

πŸ“ Project Structure

blog/
β”œβ”€β”€ actions/              # Server actions for data mutations
β”‚   β”œβ”€β”€ create-article.ts
β”‚   β”œβ”€β”€ edit-article.ts
β”‚   β”œβ”€β”€ delete-article.ts
β”‚   β”œβ”€β”€ like-dislike.ts
β”‚   β”œβ”€β”€ save-article.ts
β”‚   β”œβ”€β”€ create-comment.ts
β”‚   └── search.ts
β”œβ”€β”€ app/                  # Next.js App Router
β”‚   β”œβ”€β”€ (home)/          # Public home pages
β”‚   β”œβ”€β”€ about/           # About page
β”‚   β”œβ”€β”€ api/             # API routes
β”‚   β”œβ”€β”€ article/         # Article detail pages
β”‚   β”œβ”€β”€ dashboard/       # User dashboard
β”‚   └── layout.tsx       # Root layout
β”œβ”€β”€ components/          # React components
β”‚   β”œβ”€β”€ articles/        # Article-related components
β”‚   β”œβ”€β”€ comments/        # Comment components
β”‚   β”œβ”€β”€ dashboard/       # Dashboard components
β”‚   β”œβ”€β”€ home/            # Home page components
β”‚   └── ui/              # Reusable UI components
β”œβ”€β”€ hooks/               # Custom React hooks
β”œβ”€β”€ lib/                 # Utility functions
β”‚   β”œβ”€β”€ prisma.ts        # Prisma client
β”‚   β”œβ”€β”€ query/           # Database queries
β”‚   └── utils.ts         # Helper functions
β”œβ”€β”€ prisma/              # Database schema and migrations
β”‚   β”œβ”€β”€ schema.prisma
β”‚   └── seed.ts
└── public/              # Static assets

🎯 Available Scripts

# Development
npm run dev              # Start development server
npm run dev:turbo        # Start with Turbo mode

# Production
npm run build            # Build for production
npm run start            # Start production server

# Database
npm run seed             # Seed database with sample data
npx prisma studio        # Open Prisma Studio
npx prisma migrate dev   # Run migrations

# Code Quality
npm run lint             # Run ESLint

πŸ—„οΈ Database Schema

Models Overview

User Model

model User {
  id              String          @id @default(uuid())
  clearkUserId    String          @unique
  email           String          @unique
  name            String?
  imageURL        String?
  articles        Article[]
  Comment         Comment[]
  likes           Like[]
  savedArticles   SavedArticle[]
}
  • Stores user profile information
  • Linked to Clerk authentication
  • Manages user-generated content

Article Model

model Article {
  id             String          @id @default(uuid())
  title          String
  content        String
  category       String
  featuredImage  String
  authorId       String
  author         User            @relation(fields: [authorId], references: [id])
  comments       Comment[]
  likes          Like[]
  savedBy        SavedArticle[]
  createAt       DateTime        @default(now())
  updatedAt      DateTime        @updatedAt
}
  • Main content entity
  • Rich text content support
  • Automatic timestamps

Comment Model

model Comment {
  id         String   @id @default(uuid())
  userId     String
  user       User     @relation(fields: [userId], references: [id])
  articleId  String
  article    Article  @relation(fields: [articleId], references: [id])
  body       String
  createdAt  DateTime @default(now())
}
  • User comments on articles
  • Linked to both user and article

Like Model

model Like {
  id         String   @id @default(uuid())
  userId     String
  user       User     @relation(fields: [userId], references: [id])
  articleId  String
  article    Article  @relation(fields: [articleId], references: [id])
  createdAt  DateTime @default(now())
  @@unique([userId, articleId])
}
  • One like per user per article
  • Unique constraint prevents duplicates

SavedArticle Model

model SavedArticle {
  id         String   @id @default(uuid())
  userId     String
  user       User     @relation(fields: [userId], references: [id])
  articleId  String
  article    Article  @relation(fields: [articleId], references: [id])
  createdAt  DateTime @default(now())
  @@unique([userId, articleId])
}
  • Bookmark functionality
  • Unique constraint per user-article pair

Relationships

  • One-to-Many: User β†’ Articles, User β†’ Comments
  • Many-to-Many: Users ↔ Articles (via Likes and SavedArticles)
  • Cascade Deletes: Configured for data integrity

πŸ“‘ API Reference

Server Actions

Article Actions

Create Article

// actions/create-article.ts
createArticle(formData: FormData)
- Input: title, content, category, featuredImage
- Returns: Created article or error
- Auth: Required

Edit Article

// actions/edit-article.ts
editArticle(articleId: string, formData: FormData)
- Input: articleId, updated fields
- Returns: Updated article or error
- Auth: Required (must be author)

Delete Article

// actions/delete-article.ts
deleteArticle(articleId: string)
- Input: articleId
- Returns: Success or error
- Auth: Required (must be author)

Like/Dislike Article

// actions/like-dislike.ts
toggleLike(articleId: string)
- Input: articleId
- Returns: Updated like status
- Auth: Required

Save Article

// actions/save-article.ts
toggleSave(articleId: string)
- Input: articleId
- Returns: Updated save status
- Auth: Required

Search Articles

// actions/search.ts
searchArticles(query: string)
- Input: search query
- Returns: Matching articles
- Auth: Optional

Comment Actions

Create Comment

// actions/create-comment.ts
createComment(articleId: string, body: string)
- Input: articleId, comment body
- Returns: Created comment
- Auth: Required

Query Functions

Fetch Articles

// lib/query/fetch-articles.ts
- fetchAllArticles(): Get all published articles
- fetchArticleById(id): Get single article with relations
- fetchUserArticles(userId): Get articles by author
- fetchSavedArticles(userId): Get user's saved articles

🎨 Component Library

Article Components

  • ArticleCard - Display article preview
  • ArticleDetailPage - Full article view
  • CreateArticlePage - Article creation form
  • EditArticlePage - Article editing form
  • AllArticlePage - Article listing with filters
  • LikeButton - Interactive like/dislike button
  • ArticleSearchInput - Search functionality

Comment Components

  • CommentsList - Display all comments
  • CommentInput - Add new comment
  • CommentItem - Single comment display

Dashboard Components

  • BlogDashboard - Main

πŸ” Authentication Flow

  1. Users sign up/sign in via Clerk
  2. Clerk webhook creates user record in database
  3. User sessions managed by Clerk middleware
  4. Protected routes secured via middleware.ts

🎨 UI Components

Built with shadcn/ui and Radix UI for:

  • Accessible, keyboard-navigable interfaces
  • Consistent design system
  • Dark mode support
  • Responsive layouts

πŸš€ Deployment

Vercel (Recommended)

# Install Vercel CLI
npm i -g vercel

# Deploy
vercel

Environment Variables

Ensure all environment variables are configured in your deployment platform:

  • Database connection string
  • Clerk API keys
  • Cloudinary credentials

Database Migration

npx prisma migrate deploy

πŸ”„ Workflows

1. Development Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Development Lifecycle                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. Setup Environment
   β”œβ”€β”€ Clone repository
   β”œβ”€β”€ Install dependencies (npm install)
   β”œβ”€β”€ Configure .env file
   β”œβ”€β”€ Setup PostgreSQL database
   └── Run migrations (npx prisma migrate dev)

2. Local Development
   β”œβ”€β”€ Start dev server (npm run dev)
   β”œβ”€β”€ Access at http://localhost:3000
   β”œβ”€β”€ Hot reload enabled
   └── Prisma Studio for DB inspection (npx prisma studio)

3. Feature Development
   β”œβ”€β”€ Create feature branch (git checkout -b feature/name)
   β”œβ”€β”€ Implement changes
   β”œβ”€β”€ Test locally with seeded data
   β”œβ”€β”€ Check for type errors (TypeScript)
   └── Run linter (npm run lint)

4. Code Review & Merge
   β”œβ”€β”€ Commit changes (git commit -m "message")
   β”œβ”€β”€ Push to remote (git push origin feature/name)
   β”œβ”€β”€ Create Pull Request
   β”œβ”€β”€ Code review by team
   └── Merge to main branch

5. Deployment
   β”œβ”€β”€ Auto-deploy on merge (Vercel)
   β”œβ”€β”€ Run production migrations
   β”œβ”€β”€ Verify environment variables
   └── Monitor deployment logs

2. Content Creation Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Author Journey                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 1: Authentication
   └── Sign in/Sign up via Clerk
       β”œβ”€β”€ Email/Password
       β”œβ”€β”€ Google OAuth
       └── GitHub OAuth

Step 2: Dashboard Access
   └── Navigate to /dashboard
       β”œβ”€β”€ View recent articles
       β”œβ”€β”€ Check analytics
       └── Access saved articles

Step 3: Create Article
   └── Click "Create Article"
       β”œβ”€β”€ Enter title
       β”œβ”€β”€ Select category
       β”œβ”€β”€ Upload featured image (Cloudinary)
       └── Write content (Rich Text Editor)
           β”œβ”€β”€ Format text (bold, italic, headings)
           β”œβ”€β”€ Add links
           β”œβ”€β”€ Insert images
           └── Create lists

Step 4: Publish
   └── Submit article
       β”œβ”€β”€ Validation (Zod schema)
       β”œβ”€β”€ Save to database (Prisma)
       └── Redirect to article page

Step 5: Manage Content
   └── Article Management
       β”œβ”€β”€ Edit existing articles
       β”œβ”€β”€ Delete articles
       β”œβ”€β”€ View engagement metrics
       └── Respond to comments

3. Reader Engagement Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Reader Journey                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 1: Discovery
   └── Landing Page (/)
       β”œβ”€β”€ Browse featured articles
       β”œβ”€β”€ View top articles
       β”œβ”€β”€ Search by keyword
       └── Filter by category

Step 2: Read Article
   └── Article Detail Page (/article/[id])
       β”œβ”€β”€ Read full content
       β”œβ”€β”€ View author info
       β”œβ”€β”€ Check publish date
       └── See engagement stats

Step 3: Interact
   └── Engagement Options
       β”œβ”€β”€ Like/Dislike article
       β”œβ”€β”€ Save for later
       β”œβ”€β”€ Share article
       └── Leave comment

Step 4: Community
   └── Comments Section
       β”œβ”€β”€ Read other comments
       β”œβ”€β”€ Reply to comments
       β”œβ”€β”€ Engage in discussions
       └── Follow conversations

4. Database Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Data Flow                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

User Action β†’ Server Action β†’ Prisma ORM β†’ PostgreSQL

Example: Creating an Article
   1. User submits form
      └── /dashboard/article/create

   2. Server Action (create-article.ts)
      β”œβ”€β”€ Validate input (Zod)
      β”œβ”€β”€ Check authentication (Clerk)
      └── Process data

   3. Prisma Query
      β”œβ”€β”€ prisma.article.create()
      β”œβ”€β”€ Include relations (author)
      └── Return created article

   4. Database Update
      β”œβ”€β”€ Insert into Article table
      β”œβ”€β”€ Update foreign keys
      └── Commit transaction

   5. Response
      β”œβ”€β”€ Revalidate cache
      β”œβ”€β”€ Redirect to article
      └── Show success toast

5. Authentication Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Auth Flow (Clerk)                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. User Access
   └── Visit protected route
       └── middleware.ts checks auth

2. Not Authenticated
   └── Redirect to /sign-in
       β”œβ”€β”€ Show Clerk sign-in UI
       └── Multiple auth methods

3. Sign In/Sign Up
   └── Clerk handles authentication
       β”œβ”€β”€ Verify credentials
       β”œβ”€β”€ Create session
       └── Generate JWT token

4. Webhook (Optional)
   └── Clerk sends user.created event
       └── Create User in database
           β”œβ”€β”€ Store Clerk user ID
           β”œβ”€β”€ Save email & profile
           └── Initialize user data

5. Authenticated
   └── Access granted
       β”œβ”€β”€ Session stored in cookies
       β”œβ”€β”€ User data available
       └── Protected routes accessible

6. Image Upload Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Cloudinary Integration                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. User Selects Image
   └── File input in article form

2. Client-Side Upload
   └── next-cloudinary component
       β”œβ”€β”€ Validate file type/size
       β”œβ”€β”€ Show upload progress
       └── Generate preview

3. Cloudinary Processing
   └── Upload to cloud
       β”œβ”€β”€ Optimize image
       β”œβ”€β”€ Generate transformations
       β”œβ”€β”€ Create responsive URLs
       └── Return secure URL

4. Store URL
   └── Save to database
       β”œβ”€β”€ featuredImage field
       └── Associated with article

5. Display Image
   └── Render on frontend
       β”œβ”€β”€ Responsive images
       β”œβ”€β”€ Lazy loading
       └── Optimized delivery

7. Search Workflow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Search Implementation                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. User Input
   └── Search bar (header or article page)
       └── Type search query

2. Real-time Search
   └── Debounced input
       β”œβ”€β”€ Wait for user to stop typing
       └── Trigger search action

3. Server Action (search.ts)
   └── Query database
       β”œβ”€β”€ Search in title
       β”œβ”€β”€ Search in content
       β”œβ”€β”€ Search in category
       └── Filter by relevance

4. Prisma Query
   └── prisma.article.findMany()
       β”œβ”€β”€ WHERE clause with contains
       β”œβ”€β”€ Include author data
       └── Order by relevance

5. Display Results
   └── Update UI
       β”œβ”€β”€ Show matching articles
       β”œβ”€β”€ Highlight search terms
       β”œβ”€β”€ Show result count
       └── Handle no results

8. CI/CD Pipeline (Recommended)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Deployment Pipeline                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. Code Push
   └── git push origin main

2. Vercel Detection
   └── Webhook triggered
       └── Start build process

3. Build Phase
   β”œβ”€β”€ Install dependencies
   β”œβ”€β”€ Run TypeScript compilation
   β”œβ”€β”€ Run ESLint
   β”œβ”€β”€ Generate Prisma Client
   └── Build Next.js app (npm run build)

4. Database Migration
   └── npx prisma migrate deploy
       β”œβ”€β”€ Apply pending migrations
       └── Update production schema

5. Deployment
   β”œβ”€β”€ Deploy to Vercel edge network
   β”œβ”€β”€ Set environment variables
   β”œβ”€β”€ Configure domains
   └── Enable CDN

6. Post-Deployment
   β”œβ”€β”€ Run health checks
   β”œβ”€β”€ Monitor error logs
   β”œβ”€β”€ Verify functionality
   └── Notify team (optional)

πŸ—οΈ Architecture Overview

Application Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Client (Browser)                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚   Pages    β”‚  β”‚ Components β”‚  β”‚   Hooks    β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          ↕
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Next.js App Router                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚   Routes   β”‚  β”‚   Server   β”‚  β”‚    API     β”‚            β”‚
β”‚  β”‚            β”‚  β”‚  Actions   β”‚  β”‚   Routes   β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          ↕
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Business Logic                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚   Prisma   β”‚  β”‚    Zod     β”‚  β”‚   Utils    β”‚            β”‚
β”‚  β”‚    ORM     β”‚  β”‚ Validation β”‚  β”‚            β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          ↕
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   External Services                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚ PostgreSQL β”‚  β”‚   Clerk    β”‚  β”‚ Cloudinary β”‚            β”‚
β”‚  β”‚  Database  β”‚  β”‚    Auth    β”‚  β”‚   Images   β”‚            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Design Patterns

  • Server Components - Default rendering strategy for performance
  • Server Actions - Type-safe mutations without API routes
  • Optimistic Updates - Instant UI feedback before server confirmation
  • Middleware - Route protection and authentication checks
  • Component Composition - Reusable UI components with Radix UI
  • Type Safety - End-to-end TypeScript with Prisma and Zod

πŸ”’ Security Best Practices

Implemented Security Measures

  1. Authentication & Authorization

    • Clerk handles secure authentication
    • JWT tokens for session management
    • Protected routes via middleware
    • User-specific data access controls
  2. Data Validation

    • Zod schemas for input validation
    • Server-side validation on all mutations
    • SQL injection prevention via Prisma
    • XSS protection with React
  3. Environment Variables

    • Sensitive data in .env (not committed)
    • Different configs for dev/prod
    • Secure API key management
  4. Database Security

    • Parameterized queries via Prisma
    • Unique constraints on critical fields
    • Foreign key relationships enforced
    • Connection pooling for performance

πŸ§ͺ Testing Strategy (Recommended)

Unit Tests

# Install testing dependencies
npm install -D vitest @testing-library/react @testing-library/jest-dom

# Run tests
npm run test

Integration Tests

  • Test server actions with database
  • Mock Clerk authentication
  • Test Prisma queries

E2E Tests

# Install Playwright
npm install -D @playwright/test

# Run E2E tests
npx playwright test

πŸ“Š Performance Optimization

Implemented Optimizations

  1. Next.js Features

    • App Router for automatic code splitting
    • Server Components reduce client bundle
    • Image optimization with next/image
    • Font optimization with next/font
  2. Database

    • Prisma connection pooling
    • Indexed fields for fast queries
    • Efficient relations with include/select
  3. Caching

    • Next.js automatic caching
    • Revalidation strategies
    • Static generation where possible
  4. Assets

    • Cloudinary CDN for images
    • Responsive image delivery
    • Lazy loading components

πŸ› Troubleshooting

Common Issues

Database Connection Error

# Check DATABASE_URL in .env
# Ensure PostgreSQL is running
# Verify database exists
npx prisma db push

Clerk Authentication Issues

# Verify Clerk keys in .env
# Check middleware.ts configuration
# Ensure public routes are configured

Build Errors

# Clear Next.js cache
rm -rf .next

# Regenerate Prisma Client
npx prisma generate

# Rebuild
npm run build

Module Not Found

# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install

πŸ“ˆ Monitoring & Analytics

Recommended Tools

  • Vercel Analytics - Built-in performance monitoring
  • Sentry - Error tracking and monitoring
  • Prisma Pulse - Real-time database events
  • LogRocket - Session replay and debugging

πŸ”„ Version Control

Git Workflow

# Feature development
git checkout -b feature/new-feature
git add .
git commit -m "feat: add new feature"
git push origin feature/new-feature

# Bug fixes
git checkout -b fix/bug-description
git commit -m "fix: resolve bug description"

# Hotfix
git checkout -b hotfix/critical-issue
git commit -m "hotfix: critical issue fix"

Commit Convention

Follow Conventional Commits:

  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation changes
  • style: - Code style changes
  • refactor: - Code refactoring
  • test: - Test additions/changes
  • chore: - Build process or auxiliary tool changes

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository

    # Click "Fork" on GitHub
    git clone https://github.com/your-username/blog.git
  2. Create a feature branch

    git checkout -b feature/amazing-feature
  3. Make your changes

    • Follow code style guidelines
    • Add tests if applicable
    • Update documentation
  4. Commit your changes

    git commit -m 'feat: add amazing feature'
  5. Push to the branch

    git push origin feature/amazing-feature
  6. Open a Pull Request

    • Describe your changes
    • Link related issues
    • Wait for review

Code Style Guidelines

  • Use TypeScript for type safety
  • Follow ESLint rules
  • Use meaningful variable names
  • Add comments for complex logic
  • Keep components small and focused
  • Write reusable utility functions

πŸ“ License

This project is licensed under the MIT License.

πŸ™ Acknowledgments

πŸ“§ Contact

For questions or support, please open an issue on GitHub.


Built with ❀️ using Next.js and modern web technologies