An e-commerce web application built with ASP.NET Core 8 MVC, featuring product management, shopping cart, voucher system, and Google OAuth authentication. Containerized with Docker and automated with Jenkins CI/CD.
| Layer | Technology |
|---|---|
| Backend | ASP.NET Core 8, C# |
| Frontend | Razor Views, Bootstrap, jQuery |
| Database | SQL Server 2022 |
| ORM | Entity Framework Core 8 |
| Auth | ASP.NET Identity + Google OAuth 2.0 |
| Testing | xUnit, EF Core InMemory |
| Container | Docker, Docker Compose |
| CI/CD | Jenkins (Declarative Pipeline) |
MiniShopee/
├── Areas/
│ ├── Admin/Controllers/ # Admin CRUD (Category, Product, Voucher)
│ └── Identity/ # Auth pages (Login, Register)
├── Controllers/
│ ├── HomeController # Landing page
│ ├── ProductController # Product listing, detail, filter
│ ├── ShoppingCartController # Cart + Checkout + Order
│ └── VoucherController # Voucher claiming & usage
├── Models/
│ ├── Entities/ # Category, Product, Order, Voucher, UserVoucher
│ ├── Enums/ # OrderStatus, DiscountType, VoucherStatus, SortOption
│ ├── ViewModels/ # View-specific models
│ └── ShoppingCart.cs # Cart logic (Add, Remove, ChangeQty, Totals)
├── Repositories/
│ ├── Interfaces/ # ICategoryRepo, IProductRepo, IOrderRepo, IVoucherRepo
│ └── Implementations/ # Concrete implementations with EF Core
├── Views/ # Razor views
├── MiniShopee.Tests/
│ ├── Helpers/ # TestDbContextFactory (InMemory DB)
│ ├── Models/ # ShoppingCartTests, UserVoucherStatusTests
│ └── Repositories/ # Category, Product, Order, Voucher repo tests
├── Dockerfile # Multi-stage build
├── docker-compose.yml # App + SQL Server
├── Jenkinsfile # CI/CD pipeline
└── Program.cs # App entry point
Customer
- 🔍 Browse & search products with pagination, filtering, sorting
- 📦 Product detail with similar products suggestion
- 🛒 Shopping cart (session-based) with quantity management
- 🎟 Checkout with voucher discount (Amount Off / Percentage / Free Ship)
- 📋 Order history
- 🔐 Google OAuth login
Admin
- ⚙️ CRUD Category, Product (with image upload), Voucher
- 🎫 Voucher management (usage limit, date range, min order amount)
Pipeline Stages:
- Checkout — Pull source code from Git
- Restore —
dotnet restoreNuGet packages - Build —
dotnet buildRelease mode - Test — Run unit tests, archive
.trxresults - Docker Build — Multi-stage image (SDK → Runtime)
- Deploy —
docker compose up -d
| Test Class | Tests | Coverage |
|---|---|---|
| CategoryRepositoryTests | 10 | CRUD operations |
| ProductRepositoryTests | 17 | CRUD + pagination + filter + sort |
| OrderRepositoryTests | 7 | Create + query by ID/user |
| VoucherRepositoryTests | 25 | CRUD + availability + user vouchers + freeship |
| ShoppingCartTests | 16 | Add/Remove/ChangeQty/Clear/Totals |
| UserVoucherStatusTests | 7 | All 5 VoucherStatus states |
| Total | 82 |
# Clone
git clone https://github.com/tuananhit1612/MiniShopee.git
cd MiniShopee
# Config
cp .env.example .env
# Edit .env with your SA_PASSWORD, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
# Run
docker compose up --build -d
# App: http://localhost:8080
# SQL: localhost:1433# Requires SQL Server installed locally
# Update connection string in appsettings.json if needed
dotnet restore
dotnet ef database update
dotnet run
# App: https://localhost:5001dotnet test MiniShopee.Tests/MiniShopee.Tests.csproj| Variable | Description |
|---|---|
SA_PASSWORD |
SQL Server SA password |
GOOGLE_CLIENT_ID |
Google OAuth Client ID |
GOOGLE_CLIENT_SECRET |
Google OAuth Client Secret |
┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
│ Category │ │ Product │ │ ProductImage │
├──────────────┤ ├──────────────┤ ├──────────────────┤
│ Id │◄───┐│ Id │◄───┐│ Id │
│ Name │ ││ Name │ ││ Url │
│ Description │ ││ Price │ ││ ProductId (FK) │
└──────────────┘ ││ Description │ │└──────────────────┘
││ CategoryId │────┘
││ ThumbnailUrl │
│└──────────────┘
│
┌──────────────┐ │ ┌──────────────┐ ┌──────────────────┐
│ Order │ │ │ OrderDetail │ │ AspNetUsers │
├──────────────┤ │ ├──────────────┤ ├──────────────────┤
│ Id │◄──┐│ │ Id │ │ Id │
│ UserId (FK) │ ││ │ OrderId (FK) │────▶│ FullName │
│ OrderDate │ ││ │ ProductId(FK)│ │ Address │
│ TotalPrice │ │└─▶│ Quantity │ └──────────────────┘
│ Status │ │ │ Price │
│ VoucherId │ │ └──────────────┘
└──────────────┘ │
│
┌──────────────┐ │ ┌──────────────────┐
│ Voucher │ │ │ UserVoucher │
├──────────────┤ │ ├──────────────────┤
│ Id │◄──┼──▶│ Id │
│ Code │ │ │ UserId (FK) │
│ DiscountType │ │ │ VoucherId (FK) │
│ DiscountValue│ │ │ UsedCount │
│ MinOrder │ │ │ Status (computed)│
│ StartAt │ └───│ │
│ EndAt │ └──────────────────┘
└──────────────┘

