Skip to content

kesanglama7/FullStack_Boiler_Template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fullstack Starter Boilerplate

A production-ready fullstack starter boilerplate built with:

  • Backend: NestJS, PostgreSQL, Prisma, JWT Auth, RBAC, Swagger
  • Frontend: Next.js App Router, TypeScript, Bun, shadcn/ui, Tailwind CSS, TanStack Query, Zustand, Axios
  • Database: PostgreSQL via Docker Compose
  • Auth: Access token + refresh token with secure cookie flow
  • Roles: SUPER_ADMIN, ADMIN, USER

Project Structure

fullstack-starter/
├── backend/
│   ├── prisma/
│   │   ├── schema.prisma
│   │   └── seed.ts
│   ├── src
│   │   ├── common/
│   │   │   ├── decorators/
│   │   │   ├── filters/
│   │   │   ├── guards/
│   │   │   ├── interceptors/
│   │   │   └── types/
│   │   ├── config/
│   │   ├── database/
│   │   ├── modules/
│   │   │   ├── admin/
│   │   │   ├── auth/
│   │   │   └── users/
│   │   ├── swagger/
│   │   ├── app.module.ts
│   │   └── main.ts
│   ├── .env.example
│   └── package.json
│
├── frontend/
│   ├── app/
│   │   │
│   │   ├── (marketing)/
│   │   ├── admin/
│   │   ├── user/
│   │   ├── forbidden/
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   └── providers.tsx
│   ├── components/
│   │   ├── layout/
│   │   └── ui/
│   ├── constants/
│   ├── features/
│   │   ├── auth/
│   │   └── users/
│   ├── lib/
│   └── types/
│   ├── .env.example
│   └── package.json
│
├── docker-compose.yml
├── .gitignore
└── README.md

Main Features

Backend

  • NestJS modular architecture
  • PostgreSQL database using Docker
  • Prisma ORM
  • JWT authentication
  • Access token returned to frontend
  • Refresh token stored in httpOnly cookie
  • Global JWT guard
  • @Public() decorator for public routes
  • Role-based access control with @Roles()
  • Roles:
    • SUPER_ADMIN
    • ADMIN
    • USER
  • User management module
  • Admin dashboard module
  • Swagger API documentation
  • Global validation pipe
  • Global response interceptor
  • Global exception filter

Frontend

  • Next.js App Router
  • Bun as package manager
  • Feature-based architecture
  • shadcn/ui components
  • shadcn Sidebar layout
  • Tailwind CSS
  • TanStack Query
  • Axios API client
  • Zustand auth store
  • React Hook Form + Zod
  • Role-based route redirects
  • Separate route areas:
    • Marketing/Auth
    • User portal
    • Admin portal

Route Structure

Marketing / Auth Routes

/                  Landing page
/login             Login page
/register          Register page
/forgot-password   Forgot password page
/otp               OTP page

User Routes

/user/dashboard
/user/profile
/user/settings

Only normal USER accounts should access this area.

Admin Routes

/admin/dashboard
/admin/users
/admin/settings

Both SUPER_ADMIN and ADMIN can access the admin area.

Some actions are only visible/available to SUPER_ADMIN.


Role Behavior

SUPER_ADMIN
- Access admin dashboard
- View users
- Update user roles
- Activate/deactivate users
- Access super-admin-only UI/actions

ADMIN
- Access admin dashboard
- View users
- Cannot update user roles
- Cannot activate/deactivate users

USER
- Access user dashboard
- Access own profile/settings
- Cannot access admin area

Test Credentials

These accounts can be seeded for local testing.

Super Admin

Email: superadmin@example.com
Password: 123456789
Role: SUPER_ADMIN

Admin

Email: admin@example.com
Password: 123456789
Role: ADMIN

User

Email: user@example.com
Password: 1223456789
Role: USER

Prerequisites

Make sure you have installed:

  • Node.js
  • Docker
  • Docker Compose
  • Bun
  • npm

Backend uses npm in this starter.

Frontend uses Bun.


Environment Variables

Backend

Create:

backend/.env

Use this example:

NODE_ENV=development
PORT=4000

DATABASE_URL="postgresql://starter_user:starter_password@localhost:5432/starter_db?schema=public"

FRONTEND_URL="http://localhost:3000"

JWT_ACCESS_SECRET="replace-with-strong-access-secret"
JWT_REFRESH_SECRET="replace-with-strong-refresh-secret"

JWT_ACCESS_EXPIRES_IN="15m"
JWT_REFRESH_EXPIRES_IN="7d"

COOKIE_DOMAIN="localhost"

Frontend

Create:

frontend/.env.local

Use this example:

NEXT_PUBLIC_APP_NAME="Fullstack Starter"
NEXT_PUBLIC_API_URL="http://localhost:4000/api/v1"
NEXT_PUBLIC_APP_URL="http://localhost:3000"

Local Development Setup

1. Start PostgreSQL

From the project root:

docker compose up -d

This starts PostgreSQL at:

localhost:5432

2. Install Backend Dependencies

cd backend
npm install

3. Run Prisma Migration

npx prisma migrate dev --name init

This will:

1. Create database tables
2. Generate Prisma Client

4. Seed Database

npx prisma db seed

Or:

npm run db:seed

This creates the test users.

5. Start Backend

npm run dev

Backend runs at:

http://localhost:4000

Swagger docs:

http://localhost:4000/api/docs

Health check:

http://localhost:4000/api/v1/health

6. Install Frontend Dependencies

Open a new terminal:

cd frontend
bun install

7. Start Frontend

bun dev

Frontend runs at:

http://localhost:3000

Common Commands

Backend

cd backend

Run development server:

npm run dev

Build:

npm run build

Generate Prisma Client:

npx prisma generate

Create migration:

npx prisma migrate dev --name migration_name

Open Prisma Studio:

npx prisma studio

Seed database:

npx prisma db seed

Reset local database:

npx prisma migrate reset

Frontend

cd frontend

Run development server:

bun dev

Build:

bun run build

Type check:

bun run type-check

Add a package:

bun add package-name

Add shadcn component:

bunx shadcn@latest add component-name

Authentication Flow

Login

Frontend calls:

POST /api/v1/auth/login

Backend returns:

user
accessToken

The refresh token is stored in an httpOnly cookie.

Access Token

The frontend stores the access token in Zustand and attaches it to requests:

Authorization: Bearer ACCESS_TOKEN

Refresh Token

When an API request returns 401, Axios tries:

POST /api/v1/auth/refresh

If the refresh token cookie is valid, the backend returns a new access token.

Logout

Frontend calls:

POST /api/v1/auth/logout

Backend revokes the current refresh session and clears the cookie.


Backend API Overview

Auth

POST /api/v1/auth/register
POST /api/v1/auth/login
POST /api/v1/auth/refresh
POST /api/v1/auth/logout
POST /api/v1/auth/logout-all
GET  /api/v1/auth/me

Users

GET   /api/v1/users/me
PATCH /api/v1/users/me

GET   /api/v1/users
GET   /api/v1/users/:id
PATCH /api/v1/users/:id/role
PATCH /api/v1/users/:id/status

Admin

GET /api/v1/admin/overview
GET /api/v1/admin/stats

Frontend Architecture

The frontend follows a feature-based structure.

features/auth/
├── components/
├── hooks/
├── schemas/
├── services/
├── stores/
└── types.ts
features/users/
├── components/
├── hooks/
├── services/
└── types.ts

Important Rule

Reusable UI primitives go in:

components/ui/

Feature-specific logic goes in:

features/{feature-name}/

Route-specific components go inside:

app/.../_components/

This avoids creating a large global component folder.


Layout Architecture

Marketing Layout

Used for:

/
/login
/register
/forgot-password
/otp

Folder:

app/(marketing)/

User Layout

Used for:

/user/*

Folder:

app/user/

Uses:

components/layout/user/

Admin Layout

Used for:

/admin/*

Folder:

app/admin/

Uses:

components/layout/admin/

The admin layout uses shadcn Sidebar components:

SidebarProvider
Sidebar
SidebarHeader
SidebarContent
SidebarGroup
SidebarMenu
SidebarMenuItem
SidebarFooter
SidebarRail
SidebarInset
SidebarTrigger

Route Protection

Frontend route protection uses:

proxy.ts

The proxy protects:

/user/*
/admin/*

It checks a frontend-readable auth flag cookie:

starter_auth

This is only for redirect UX.

Real security is always enforced by the backend using JWT guards and RBAC.


Backend Security

Backend routes are protected globally by JwtAuthGuard.

Public routes use:

@Public()

Role-protected routes use:

@Roles(Role.SUPER_ADMIN)

or:

@Roles(Role.SUPER_ADMIN, Role.ADMIN)

Example:

@UseGuards(RolesGuard)
@Roles(Role.SUPER_ADMIN)
@Patch(':id/role')
updateRole() {
  // Only SUPER_ADMIN can access
}

Prisma Models

Main models:

User
Session

Main enum:

Role
- SUPER_ADMIN
- ADMIN
- USER

Session stores refresh-token sessions and allows logout/session revocation.


Swagger

Swagger is available at:

http://localhost:4000/api/docs

Use Swagger to test:

Auth
Users
Admin
Health

For protected endpoints:

  1. Login using /auth/login
  2. Copy the accessToken
  3. Click Authorize
  4. Enter:
Bearer YOUR_ACCESS_TOKEN

Git Notes

Do not commit real environment files.

Ignored files include:

.env
.env.local
node_modules/
dist/
.next/
out/

Commit example files:

backend/.env.example
frontend/.env.example

Recommended Checks Before Push

Backend

cd backend
npm run build

Frontend

cd frontend
bun run type-check
bun run build

Push to GitHub

From the project root:

git init
git add .
git commit -m "Initial fullstack starter setup"
git branch -M main
git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPOSITORY.git
git push -u origin main

Future Improvements

Possible next improvements:

  • Dockerfile for backend deployment
  • Dockerfile for frontend deployment
  • Production Docker Compose setup
  • Email verification
  • Forgot password flow
  • OTP flow
  • Rate limiting for auth endpoints
  • Request logging
  • Audit logs
  • File upload module
  • Better Swagger DTO response wrappers
  • Unit and e2e tests
  • CI/CD pipeline
  • Deployment guide

License

This project is intended as a starter boilerplate. Update the license based on your project requirements.

About

The scalable full-stack boilerplate you actually want to use. NestJS, Next.js App Router, Dockerized PostgreSQL, Prisma, RBAC, TanStack Query, and Shadcn UI. Stop setting up, start building.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors