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! 🚀