Skip to contentPedro Farbo
Lesson 23 / 2560 min

E-commerce Project - Part 1

E-commerce Project - Part 1

Let's build a complete e-commerce API applying everything we learned.

Project Structure

src/
├── config/
├── modules/
│   ├── auth/
│   ├── users/
│   ├── products/
│   ├── categories/
│   ├── cart/
│   └── orders/
├── shared/
│   ├── middlewares/
│   └── errors/
├── app.ts
└── server.ts

Database Schema

prisma
model User {  id        String   @id @default(uuid())  email     String   @unique  password  String  name      String  role      Role     @default(USER)  orders    Order[]  cart      Cart?} model Product {  id          String   @id @default(uuid())  name        String  slug        String   @unique  price       Decimal  @db.Decimal(10, 2)  stock       Int      @default(0)  category    Category @relation(fields: [categoryId], references: [id])  categoryId  String} model Category {  id       String    @id @default(uuid())  name     String    @unique  slug     String    @unique  products Product[]} model Cart {  id     String     @id @default(uuid())  user   User       @relation(fields: [userId], references: [id])  userId String     @unique  items  CartItem[]} model Order {  id     String      @id @default(uuid())  user   User        @relation(fields: [userId], references: [id])  userId String  items  OrderItem[]  total  Decimal     @db.Decimal(10, 2)  status OrderStatus @default(PENDING)}

App Setup

typescript
// src/app.tsimport express from 'express';import helmet from 'helmet';import cors from 'cors';import { errorHandler } from './shared/middlewares/error.middleware'; import authRoutes from './modules/auth/auth.routes';import productRoutes from './modules/products/product.routes';import cartRoutes from './modules/cart/cart.routes';import orderRoutes from './modules/orders/order.routes'; const app = express(); app.use(helmet());app.use(cors());app.use(express.json()); app.use('/api/auth', authRoutes);app.use('/api/products', productRoutes);app.use('/api/cart', cartRoutes);app.use('/api/orders', orderRoutes); app.use(errorHandler); export { app };

Auth Module

typescript
// src/modules/auth/auth.service.tsexport class AuthService {  async register(data: RegisterDTO) {    const exists = await prisma.user.findUnique({ where: { email: data.email } });    if (exists) throw new AppError('Email already registered', 400);     const hashedPassword = await bcrypt.hash(data.password, 12);    const user = await prisma.user.create({      data: { ...data, password: hashedPassword },    });     await prisma.cart.create({ data: { userId: user.id } });     return { user, token: this.generateToken(user.id) };  }}

Product Module

typescript
// src/modules/products/product.service.tsexport class ProductService {  async findAll(params: FindAllParams) {    const { page = 1, limit = 20, search, category } = params;     const where: any = { active: true };    if (search) where.name = { contains: search, mode: 'insensitive' };    if (category) where.category = { slug: category };     const [products, total] = await Promise.all([      prisma.product.findMany({        where,        skip: (page - 1) * limit,        take: limit,        include: { category: true },      }),      prisma.product.count({ where }),    ]);     return { data: products, pagination: { page, limit, total } };  }}

Summary

  • ✅ Modular project structure
  • ✅ Complete database schema
  • ✅ Auth module
  • ✅ Products with filters

Next lesson: E-commerce Project - Part 2! 🚀

Enjoyed the content? Your contribution helps keep everything online and free!

PIX:0737160d-e98f-4a65-8392-5dba70e7ff3e