Ankit Singh

Home

Building Reviewly: A Modern Review Management Platform - Part 1

Published Jun 19, 2025

From Idea to Foundation

In this series, I’ll walk you through building Reviewly, a comprehensive review management platform that helps businesses collect, manage, and showcase authentic customer testimonials. This first post covers the foundation and initial setup.

The Vision

Reviewly aims to solve a common problem: businesses losing potential customers due to poor review management. The platform provides:

  • Review Collection: Easy-to-use widgets for collecting customer feedback
  • Review Management: Dashboard for managing and moderating reviews
  • Review Display: Beautiful widgets to showcase testimonials on websites
  • Analytics: Insights into review performance and customer sentiment

Tech Stack Decisions

After evaluating various options, I chose a modern, scalable stack:

  • Next.js 15 with App Router for the frontend and API routes
  • TypeScript for type safety and better developer experience
  • Prisma with PostgreSQL for database management
  • NextAuth.js for authentication
  • Tailwind CSS for styling
  • Vercel for deployment

Project Setup

1. Initial Next.js Setup

npx create-next-app@latest review-platform --typescript --tailwind --app --src-dir

This gave us a solid foundation with:

  • TypeScript configuration
  • Tailwind CSS setup
  • App Router structure
  • ESLint configuration

2. Database Schema Design

The heart of any application is its data model. I designed a comprehensive schema using Prisma:

model User {
  id        String   @id @default(cuid())
  email     String   @unique
  password  String?
  name      String?
  role      String   // 'admin', 'client'
  clients   Client[] @relation("UserClients")
  accounts  Account[]
  sessions  Session[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Client {
  id              String   @id @default(cuid())
  name            String
  domain          String
  brandingConfig  Json
  subscriptionTier String
  apiKeys         Json
  reviews         Review[]
  createdBy       User     @relation("UserClients", fields: [createdById], references: [id])
  createdById     String
  createdAt       DateTime @default(now())
  updatedAt       DateTime @updatedAt
}

model Review {
  id        String   @id @default(cuid())
  userId    String
  clientId  String
  rating    Int
  content   String
  mediaUrls Json?
  status    String
  client    Client   @relation(fields: [clientId], references: [id])
  media     Media[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

Key design decisions:

  • Multi-tenancy: Each client can have multiple reviews
  • Media support: Reviews can include images, videos, or documents
  • Audit trail: Complete logging of all actions
  • API key management: Secure access for integrations

3. Authentication Setup

NextAuth.js provides a robust authentication solution. I configured it with:

const authOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" },
        isSignUp: { label: "Sign Up", type: "hidden" },
        name: { label: "Name", type: "text", optional: true },
      },
      async authorize(credentials) {
        // Handle both sign-in and sign-up in one provider
        if (credentials.isSignUp === "true") {
          // Create new user
        } else {
          // Authenticate existing user
        }
      },
    }),
  ],
  session: { strategy: "jwt" as SessionStrategy },
  pages: {
    signIn: "/auth/signin",
    error: "/auth/error",
  },
};

This setup allows for:

  • Email/password authentication
  • User registration and login in one flow
  • Custom sign-in pages
  • JWT-based sessions

4. Landing Page Design

The landing page needed to be compelling and conversion-focused. I created a modern design with:

  • Gradient backgrounds with animated elements
  • Clear value proposition: “Transform customer feedback into growth”
  • Social proof elements
  • Strong CTAs for sign-up and sign-in
  • Responsive design for all devices
<h1 className="text-5xl sm:text-7xl font-extrabold mb-6 leading-tight">
  <span className="bg-gradient-to-r from-white via-slate-200 to-slate-300 bg-clip-text text-transparent">
    Transform customer
  </span>
  <br />
  <span className="bg-gradient-to-r from-violet-400 via-purple-400 to-cyan-400 bg-clip-text text-transparent">
    feedback into growth
  </span>
</h1>

5. Protected Routes

I implemented route protection using Next.js App Router and server components:

export default async function DashboardPage() {
  const session = await getServerSession(authOptions);
  if (!session) {
    redirect("/auth/signin");
  }

  return (
    <div>
      <h1>Dashboard</h1>
      <p>Signed in as {session.user?.email}</p>
      {/* Dashboard content */}
    </div>
  );
}

This ensures that:

  • Unauthenticated users are redirected to sign-in
  • Session data is available on the server
  • Routes are protected at the server level

Development Workflow

Code Quality Setup

I added several tools to maintain code quality:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": ["next lint"]
  },
  "scripts": {
    "prepare": "husky"
  }
}
  • Husky for git hooks
  • lint-staged for running linters on staged files
  • ESLint with Next.js rules
  • Prettier for code formatting

Database Migrations

Using Prisma migrations for database schema changes:

npx prisma migrate dev --name init
npx prisma generate

This ensures:

  • Version-controlled database schema
  • Type-safe database access
  • Easy deployment to production

Current Status

At this point, we have: ✅ Foundation: Next.js app with TypeScript and Tailwind
Database: Prisma schema with PostgreSQL
Authentication: NextAuth.js with custom sign-in/sign-up
Landing Page: Modern, conversion-focused design
Protected Routes: Server-side authentication
Code Quality: Linting and formatting setup

Next Steps

In the next post, I’ll cover:

  • Building the dashboard interface
  • Implementing review management features
  • Creating the widget system
  • Setting up API endpoints
  • Adding real-time features

The foundation is solid, and we’re ready to build the core features that will make Reviewly a powerful review management platform.


Stay tuned for Part 2, where we’ll dive into building the dashboard and review management system!