Skip to content

saniya1831/fullstack_intern_coding_challenge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

101 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Store Rating Platform

A full-stack web application where users can rate stores (1–5 stars).
Supports three roles with role-isolated dashboards: System Administrator, Normal User, and Store Owner.

Tech Stack

Layer Technology
Backend Node.js, Express.js, Prisma ORM
Database PostgreSQL 14+
Auth JWT (24 h expiry, role claim)
Frontend React 19, Vite, Tailwind CSS
Testing Node built-in test runner (backend), Vitest (frontend)
Linting ESLint (both sides)
CI GitHub Actions

Project Structure

/
├── backend/
│   ├── prisma/
│   │   ├── schema.prisma       # User, Store, Rating models
│   │   ├── migrations/         # Versioned DB migrations
│   │   └── seed.js             # Demo data seeder
│   ├── src/
│   │   ├── config/env.js       # Startup env validation
│   │   ├── lib/prisma.js       # Prisma singleton
│   │   ├── middleware/
│   │   │   ├── auth.js         # JWT authentication
│   │   │   ├── checkRole.js    # Role-based access guard
│   │   │   └── errorHandler.js # Global error handler
│   │   ├── routes/
│   │   │   ├── auth.routes.js       # /api/v1/auth
│   │   │   ├── admin.routes.js      # /api/v1/admin
│   │   │   ├── stores.routes.js     # /api/v1/stores
│   │   │   ├── ratings.routes.js    # /api/v1/ratings
│   │   │   └── storeOwner.routes.js # /api/v1/store-owner
│   │   └── utils/
│   │       ├── validation.js   # Name/email/password/address validators
│   │       ├── pagination.js   # parsePagination, parseSort, paginatedResponse
│   │       └── storeHelpers.js # avgRating calculation helpers
│   └── tests/
│       ├── validation.test.js
│       └── storeHelpers.test.js
├── frontend/
│   └── src/
│       ├── components/
│       │   ├── ErrorBanner.jsx
│       │   ├── Layout.jsx
│       │   ├── LoadingSpinner.jsx
│       │   ├── Pagination.jsx
│       │   ├── ProtectedRoute.jsx
│       │   ├── SortableTable.jsx
│       │   ├── StarRating.jsx
│       │   └── StatCard.jsx
│       ├── context/AuthContext.jsx
│       ├── hooks/useListQuery.js
│       ├── pages/
│       │   ├── admin/
│       │   │   ├── AdminDashboardPage.jsx
│       │   │   ├── AdminAddStorePage.jsx
│       │   │   ├── AdminAddUserPage.jsx
│       │   │   ├── AdminStoreListPage.jsx
│       │   │   ├── AdminUserListPage.jsx
│       │   │   └── AdminUserDetailPage.jsx
│       │   ├── ChangePasswordPage.jsx
│       │   ├── LoginPage.jsx
│       │   ├── SignupPage.jsx
│       │   ├── StoreOwnerDashboardPage.jsx
│       │   └── UserStoreBrowsePage.jsx
│       ├── services/api.js
│       └── utils/
│           ├── formatRole.js
│           └── validation.js
├── .github/workflows/ci.yml   # CI: lint + test + build on push/PR
├── docker-compose.yml
└── package.json               # Root workspace scripts

Prerequisites

  • Node.js 18+
  • PostgreSQL 14+ (or Docker)
  • npm 9+

Quick Start

1. Start PostgreSQL

docker compose up -d

Or point DATABASE_URL at an existing PostgreSQL instance.

2. Backend

cd backend
cp .env.example .env
# Edit .env — set DATABASE_URL, JWT_SECRET, and CORS_ORIGIN at minimum

npm install
npx prisma migrate deploy
npx prisma db seed
npm run dev

API runs at http://localhost:5000.

3. Frontend

cd frontend
cp .env.example .env
npm install
npm run dev

App runs at http://localhost:3000. All /api/* requests are proxied to the backend.

4. Run both together (from root)

npm install
npm run dev

Demo Accounts (created by seed)

Role Email Password
Admin admin@store-rating.com Admin@123456
Store Owner owner@store-rating.com DemoUser@123456
Normal User user@store-rating.com DemoUser@123456

The seed also creates one demo store owned by the Store Owner and one rating submitted by the Normal User.
Re-running the seed is safe — it upserts all records.


Environment Variables

Backend (backend/.env)

Variable Required Description Default
DATABASE_URL PostgreSQL connection string
JWT_SECRET Secret used to sign JWTs — change in production
PORT API server port 5000
CORS_ORIGIN Allowed frontend origin for CORS http://localhost:3000
NODE_ENV Set to production for safe error logging development

Security: The server will refuse to start in production if JWT_SECRET still contains the placeholder value change-in-production.

Frontend (frontend/.env)

Variable Required Description Default
VITE_API_URL Backend API base URL /api/v1

API Reference

All endpoints are versioned under /api/v1.

Error Response Shape

All errors use a consistent shape:

{ "error": { "message": "...", "field": "optional-field-name" } }

Validation errors include a nested errors map:

{ "error": { "message": "Validation failed", "errors": { "name": "...", "email": "..." } } }

Auth (/api/v1/auth)

Rate-limited: 100 requests per 15 minutes per IP.

Method Path Auth Description
POST /signup Public Register a new Normal User
POST /login Public Login for any role — returns JWT + user
GET /me Any Validate session and return current user
PUT /change-password Any Change password (validates new password rules)

Admin (/api/v1/admin) — requires ADMIN role

Method Path Description
GET /stats Live counts: total users, stores, ratings
GET /stores Paginated, sortable, filterable store list
POST /stores Create a store and assign owner
GET /users Paginated, sortable, filterable user list
POST /users Create a user with any role
GET /users/:id User detail; includes avg store rating for STORE_OWNER
GET /store-owners List all STORE_OWNER users (for the owner dropdown)

Query params for list endpoints: page, limit, sortBy, order (asc/desc), plus field filters (name, email, address, role).

Normal User (/api/v1/stores, /api/v1/ratings) — requires NORMAL_USER role

Method Path Description
GET /stores Browse all stores with avg rating and own rating; supports name + address search
POST /ratings Submit or update a rating (1–5) — upserts, never duplicates

Store Owner (/api/v1/store-owner) — requires STORE_OWNER role

Method Path Description
GET /dashboard Returns owned stores, list of raters (name, email, value), and overall avg rating

Roles

Role Capabilities
ADMIN Dashboard stats; create/list/filter/sort all users and stores; view user detail with store avg rating
NORMAL_USER Browse stores; search by name/address; submit or modify ratings
STORE_OWNER View all users who rated their store(s); see overall avg rating

Role routing is enforced on both backend (middleware) and frontend (ProtectedRoute). Authenticated users visiting /login or /signup are redirected to their role's home page.


Validation Rules

Enforced independently on both frontend and backend:

Field Rule
Name 20–60 characters
Address Max 400 characters
Password 8–16 characters, at least one uppercase letter and one special character
Email Standard email format

Security

  • Passwords hashed with bcrypt (10 rounds) — never stored or returned in plaintext
  • JWTs expire after 24 hours; invalid/expired tokens return 401
  • Role middleware returns 403 (not 500) for wrong-role access
  • Auth routes are rate-limited (100 req / 15 min per IP), including /change-password
  • CORS restricted to CORS_ORIGIN env variable
  • Prisma parameterized queries — no raw string interpolation
  • JWT_SECRET placeholder detected and rejected at startup in production
  • console.error logs full errors in development; terse summary only in production

Testing & CI

# From root — runs backend + frontend tests
npm test

# Backend only (Node built-in test runner)
cd backend && npm test

# Frontend only (Vitest)
cd frontend && npm test

GitHub Actions (.github/workflows/ci.yml) runs on every push and pull request:

  • Backend: npm test + npm run lint
  • Frontend: npm test + npm run lint + npm run build

Scripts

Root

Script Description
npm run dev Start backend and frontend concurrently
npm test Run all tests
npm run lint Lint both backend and frontend
npm run build Production frontend build

Backend (cd backend)

Script Description
npm run dev Start with nodemon
npm test Run unit tests
npm run lint ESLint check
npm run db:migrate Run Prisma migrations
npm run db:seed Seed demo data
npm run db:generate Regenerate Prisma client

Frontend (cd frontend)

Script Description
npm run dev Start Vite dev server (port 3000)
npm test Run Vitest tests
npm run lint ESLint check
npm run build Production build

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages