Farmily Fresh Produce Website là một ứng dụng web thương mại điện tử chuyên về sản phẩm nông sản tươi sống. Dự án được xây dựng theo kiến trúc Client-Server với sự tách biệt rõ ràng giữa Frontend và Backend.
┌─────────────────────────────────────────────────────────────┐
│ CLIENT (FRONTEND) │
│ • Next.js 15 + React 19 │
│ • TailwindCSS + shadcn/ui │
└──────────────────────┬──────────────────────────────────────┘
│ HTTP/REST API
│
┌──────────────────────▼──────────────────────────────────────┐
│ SERVER (BACKEND) │
│ • Node.js + Express.js │
│ • RESTful API Architecture │
└──────────────────────┬──────────────────────────────────────┘
│
│
┌──────────────────────▼──────────────────────────────────────┐
│ EXTERNAL SERVICES │
│ • Supabase (Database + Storage) │
│ • PayOS (Payment Gateway) │
│ • Gemini AI (AI Features) │
└─────────────────────────────────────────────────────────────┘
- Framework: Next.js 15 (App Router)
- UI Library: React 19
- Styling: TailwindCSS 4 + shadcn/ui components
- Form Management: React Hook Form + Zod validation
- State Management: React Context API
- Icons: Lucide React, Bootstrap Icons
- Notifications: Sonner
graph TD
subgraph App_Layer ["App Layer"]
Layout[layout.tsx / page.tsx]
Config[next.config.ts / tailwind.config.js]
end
subgraph Presentation_Layer ["Presentation Layer"]
App[📂 app/]
Components[📂 components/]
Public[📂 public/]
end
subgraph Logic_Layer ["Logic Layer"]
Context[📂 context/]
Lib[📂 lib/]
end
subgraph Service_Layer ["Service Layer"]
Services[📂 services/]
end
Layout --> App
App --> Components
Components --> Context
Context --> Services
Config -.Config.-> App
frontend/
├── src/
│ ├── app/ # Next.js App Router (Pages)
│ │ ├── account/ # Trang quản lý tài khoản
│ │ ├── cart/ # Giỏ hàng
│ │ ├── checkout/ # Thanh toán
│ │ ├── contact/ # Liên hệ
│ │ ├── forgot-password/ # Quên mật khẩu
│ │ ├── login/ # Đăng nhập
│ │ ├── news/ # Tin tức
│ │ ├── product/ # Chi tiết sản phẩm
│ │ ├── receipt/ # Hóa đơn
│ │ ├── register/ # Đăng ký
│ │ ├── reset-password/ # Đặt lại mật khẩu
│ │ ├── subscription/ # Đăng ký gói
│ │ ├── verify-email/ # Xác thực email
│ │ ├── layout.tsx # Root layout
│ │ ├── page.tsx # Trang chủ
│ │ └── globals.css # Global styles
│ │
│ ├── components/ # React Components
│ │ ├── ui/ # shadcn/ui components
│ │ ├── auth/ # Authentication components
│ │ ├── account/ # Account management components
│ │ ├── cart/ # Cart components
│ │ ├── checkout/ # Checkout components
│ │ ├── contact/ # Contact form components
│ │ ├── Home/ # Homepage components
│ │ ├── news/ # News components
│ │ ├── product/ # Product display components
│ │ ├── subscription/ # Subscription components
│ │ ├── Header.jsx # Header component
│ │ ├── Footer.jsx # Footer component
│ │ └── ... # Shared components
│ │
│ ├── context/ # React Context (State Management)
│ │ └── ... # Global state providers
│ │
│ ├── services/ # API Service Layer
│ │ └── ... # API calls to backend
│ │
│ ├── lib/ # Utility Libraries
│ │ └── ... # Helpers, utils, constants
│ │
│ └── style/ # Additional Styles
│ └── ... # Component-specific styles
│
├── public/ # Static Assets
│ └── ... # Images, icons, etc.
│
├── package.json # Dependencies
├── next.config.ts # Next.js configuration
├── tailwind.config.js # TailwindCSS configuration
└── tsconfig.json # TypeScript configuration
-
Authentication System
- Đăng nhập/Đăng ký
- Xác thực email với OTP
- Quên mật khẩu và đặt lại mật khẩu
- Quản lý session
-
Product Management
- Danh sách sản phẩm với phân trang
- Tìm kiếm và lọc sản phẩm
- Chi tiết sản phẩm
- Đánh giá và nhận xét
-
Shopping Cart & Checkout
- Thêm/xóa/cập nhật giỏ hàng
- Tính toán tổng tiền
- Áp dụng voucher
- Thanh toán qua PayOS
-
User Account
- Quản lý thông tin cá nhân
- Lịch sử đơn hàng
- Địa chỉ giao hàng
- Đăng ký gói subscription
-
News & Content
- Tin tức nông sản
- Hướng dẫn chăm sóc sản phẩm
- Runtime: Node.js
- Framework: Express.js 5
- Database: Supabase (PostgreSQL)
- Authentication: JWT + bcrypt
- File Upload: Multer
- Payment: PayOS SDK
- AI: Google Generative AI
graph TD
subgraph App_Layer ["App Layer"]
Entry[server.js / app.js]
Env[.env]
end
subgraph Presentation_Layer ["Presentation Layer (Routes)"]
Routes[📂 routes/]
Middleware[📂 middlewares/]
end
subgraph Business_Logic_Layer ["Business Logic Layer (MVC)"]
Controllers[📂 controllers/]
Services[📂 services/]
end
subgraph Data_Access_Layer ["Data Access Layer (Model)"]
Repositories[📂 repositories/]
end
subgraph Config_Layer ["Configuration"]
Config[📂 config/]
end
subgraph External_Services ["External Services"]
Supabase[(Supabase<br/>PostgreSQL)]
PayOS[PayOS<br/>Payment API]
GeminiAI[Gemini AI<br/>AI API]
end
Entry --> Routes
Routes --> Controllers
Controllers --> Services
Services --> Repositories
Repositories -.Database Queries.-> Supabase
Services -.Payment API.-> PayOS
Services -.AI API.-> GeminiAI
Middleware -.Auth/Validation.-> Controllers
Config -.Configuration.-> Entry
backend/
├── src/
│ ├── app.js # Express app setup
│ │
│ ├── config/ # Configuration files
│ │ ├── database.js # Supabase config
│ │ └── ...
│ │
│ ├── controllers/ # Request Handlers
│ │ ├── auth.controller.js # Authentication logic
│ │ ├── user.controller.js # User management
│ │ ├── product.controller.js # Product management
│ │ ├── product-type.controller.js
│ │ ├── news.controller.js # News management
│ │ ├── receipt.controller.js # Order/Receipt management
│ │ ├── payment.controller.js # Payment processing
│ │ ├── subscription.controller.js
│ │ ├── voucher.controller.js # Voucher management
│ │ └── ai.controller.js # AI features
│ │
│ ├── services/ # Business Logic Layer
│ │ ├── auth.service.js
│ │ ├── user.service.js
│ │ ├── product.service.js
│ │ ├── payment.service.js
│ │ └── ...
│ │
│ ├── repositories/ # Data Access Layer
│ │ ├── auth.repository.js
│ │ ├── user.repository.js
│ │ ├── product.repository.js
│ │ └── ...
│ │
│ ├── routes/ # API Routes Definition
│ │ ├── auth.routes.js
│ │ ├── user.routes.js
│ │ ├── product.routes.js
│ │ ├── product-type.routes.js
│ │ ├── news.routes.js
│ │ ├── receipt.routes.js
│ │ ├── payment.routes.js
│ │ ├── subscription.routes.js
│ │ ├── voucher.routes.js
│ │ └── ai.routes.js
│ │
│ ├── middlewares/ # Express Middlewares
│ │ ├── auth.middleware.js # JWT verification
│ │ ├── upload.middleware.js # File upload
│ │ └── ...
│ │
│ └── utils/ # Utility Functions
│ └── ...
│
├── server.js # Entry point
├── package.json # Dependencies
└── .env # Environment variables
Backend được tổ chức theo mô hình 3-tier architecture với sự tách biệt rõ ràng giữa các tầng:
┌─────────────────────────────────────────────────────────┐
│ PRESENTATION TIER (Routes + Middlewares) │
│ • Xử lý HTTP requests/responses │
│ • Routing & API endpoint definitions │
│ • Authentication & Validation │
└────────────────────┬────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────┐
│ BUSINESS LOGIC TIER (Controllers + Services) │
│ • Controllers: Điều phối request flow │
│ • Services: Business logic & nghiệp vụ │
│ • Xử lý logic phức tạp │
└────────────────────┬────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────┐
│ DATA ACCESS TIER (Repositories) │
│ • Truy cập database │
│ • CRUD operations │
│ • Query building │
└────────────────────┬────────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────────┐
│ DATABASE (Supabase PostgreSQL) │
└─────────────────────────────────────────────────────────┘
Backend áp dụng MVC pattern được điều chỉnh cho RESTful API:
- Đại diện cho data layer
- Chứa logic truy cập database
- Thực hiện các CRUD operations
- Ví dụ:
auth.repository.js,user.repository.js,product.repository.js
Ví dụ Repository:
// user.repository.js
async function findUserByEmail(email) {
const { data, error } = await supabase
.from('users')
.select('*')
.eq('email', email)
.single();
return { data, error };
}- Trong RESTful API, "View" là JSON response
- Routes định nghĩa các endpoints (API contract)
- Không có HTML templates như MVC truyền thống
Ví dụ Route:
// auth.routes.js
router.post('/login', authController.login);
router.post('/register', authController.register);- Nhận request từ routes
- Gọi services để xử lý business logic
- Trả về response cho client
Ví dụ Controller:
// auth.controller.js
async function login(req, res) {
const { email, password } = req.body;
const result = await authService.login(email, password);
if (result.error) {
return res.status(401).json({ error: result.error });
}
res.json({ token: result.token, user: result.user });
}Repository Pattern được sử dụng để tách biệt logic truy cập dữ liệu khỏi business logic:
Lợi ích:
- Dễ dàng thay đổi database (từ Supabase sang MySQL chẳng hạn)
- Dễ test (có thể mock repositories)
- Tái sử dụng code (các query phức tạp được viết một lần)
- Tuân thủ Single Responsibility Principle
Cấu trúc:
Repositories/
├── auth.repository.js # Truy vấn liên quan đến authentication
├── user.repository.js # Truy vấn user data
├── product.repository.js # Truy vấn product data
└── ...
Service Layer chứa toàn bộ business logic của ứng dụng:
Vai trò:
- Xử lý business rules
- Validate dữ liệu
- Orchestrate (điều phối) các repositories
- Gọi external APIs (PayOS, Gemini AI)
- Transaction management
Ví dụ Service:
// payment.service.js
async function createPayment(userId, orderData) {
// 1. Validate order data
// 2. Create order in database (via repository)
const order = await receiptRepository.create(orderData);
// 3. Create payment link with PayOS (external API)
const paymentLink = await payOsClient.createPaymentLink({
amount: order.total,
orderCode: order.id,
...
});
// 4. Return payment link to user
return paymentLink;
}Middlewares được sử dụng cho cross-cutting concerns:
// Request flow với middlewares
Request → Auth Middleware → Validation Middleware → Controller → Response
↓ (verify JWT) ↓ (check data) ↓
Reject nếu Reject nếu Process &
không có token data invalid return responseCác middleware chính:
auth.middleware.js- Xác thực JWT tokenupload.middleware.js- Xử lý file upload với Multervalidation.middleware.js- Validate request dataerrorHandler.middleware.js- Xử lý lỗi global
sequenceDiagram
participant User as 👤 User / Frontend
participant Route as 🛣️ Route & Middleware
participant Controller as 🎮 Controller
participant Service as 🔧 Service
participant Repo as 💾 Repository
participant DB as 🗄️ Supabase DB
participant Ext as 🌐 External Service<br/>(PayOS/Gemini)
User->>Route: 1. Gửi request (HTTP Method + URL)
Route->>Route: 2. Kiểm tra Auth (JWT) & Validation (Zod)
Route->>Controller: 3. Chuyển tiếp Request đã validate
Controller->>Service: 4. Gọi nghiệp vụ tương ứng
alt Logic nghiệp vụ cần dữ liệu
Service->>Repo: 5a. Yêu cầu truy vấn dữ liệu
Repo->>DB: 6. Thực thi query SQL/Supabase
DB-->>Repo: 7. Trả về dữ liệu thô
Repo-->>Service: 8. Trả về Data Object / Array
else Logic nghiệp vụ cần dịch vụ bên ngoài
Service->>Ext: 5b. Gọi API (Thanh toán/AI)
Ext-->>Service: 6. Trả về kết quả API
end
Service-->>Controller: 9. Trả về kết quả đã xử lý logic
Controller-->>User: 10. Trả về JSON Response (Status + Data)
- Client gửi request ↓
- Routes nhận request ↓
- Middleware xử lý (auth, validation) ↓
- Controller nhận request ↓
- Controller gọi Service ↓
- Service xử lý business logic ↓
- Service gọi Repository ↓
- Repository truy vấn Database ↓
- Data trả về Service ↓
- Service xử lý data (nếu cần) ↓
- Controller format response ↓
- Response trả về Client
### API Endpoints
#### Authentication
- `POST /api/auth/register` - Đăng ký tài khoản
- `POST /api/auth/verify-email` - Xác thực email
- `POST /api/auth/resend-otp` - Gửi lại OTP
- `POST /api/auth/login` - Đăng nhập
- `POST /api/auth/forgot-password` - Quên mật khẩu
- `POST /api/auth/reset-password` - Đặt lại mật khẩu
#### User Management
- `GET /api/users/profile` - Lấy thông tin user
- `PUT /api/users/profile` - Cập nhật thông tin
- `GET /api/users/addresses` - Quản lý địa chỉ
- `POST /api/users/addresses` - Thêm địa chỉ
#### Products
- `GET /api/products` - Danh sách sản phẩm
- `GET /api/products/:id` - Chi tiết sản phẩm
- `GET /api/product-types` - Loại sản phẩm
#### News
- `GET /api/news` - Danh sách tin tức
- `GET /api/news/:id` - Chi tiết tin tức
#### Orders/Receipts
- `GET /api/receipts` - Lịch sử đơn hàng
- `POST /api/receipts` - Tạo đơn hàng
#### Payment
- `POST /api/payment/create` - Tạo payment link
- `POST /api/payment/webhook` - PayOS webhook
#### Subscription
- `GET /api/subscriptions` - Danh sách gói
- `POST /api/subscriptions/subscribe` - Đăng ký gói
#### Voucher
- `GET /api/vouchers` - Danh sách voucher
- `POST /api/vouchers/apply` - Áp dụng voucher
#### AI Features
- `POST /api/ai/chat` - AI chatbot
---
## 🔐 Authentication Flow
User Registration:
- User submits registration form
- Backend creates user with 'Pending' status
- Backend generates OTP and sends to email
- User enters OTP to verify email
- Backend verifies OTP and activates account
- Returns JWT token
User Login:
- User submits credentials
- Backend validates credentials
- Backend generates JWT token
- Frontend stores token in memory/cookie
- All subsequent requests include JWT in headers
---
## 💳 Payment Integration
Sử dụng **PayOS** để xử lý thanh toán:
1. User chọn sản phẩm và checkout
2. Frontend gọi API tạo payment link
3. Backend tạo payment order với PayOS
4. User được redirect đến PayOS payment page
5. User hoàn tất thanh toán
6. PayOS gửi webhook về backend
7. Backend cập nhật trạng thái đơn hàng
8. User được redirect về receipt page
---
## 🗄️ Database Schema (Supabase)
### Main Tables
- `users` - Thông tin người dùng
- `products` - Sản phẩm
- `product_types` - Loại sản phẩm
- `receipts` - Đơn hàng/Hóa đơn
- `receipt_details` - Chi tiết đơn hàng
- `addresses` - Địa chỉ giao hàng
- `vouchers` - Mã giảm giá
- `subscriptions` - Gói đăng ký
- `news` - Tin tức
- `reviews` - Đánh giá sản phẩm
---
## 🚀 Development Setup
### Prerequisites
- Node.js >= 18
- npm hoặc yarn
- Supabase account
- PayOS account
### Installation
1. **Clone repository**
```bash
git clone <repository-url>
cd Farmily-Fresh-Produce-Website/code
- Setup Backend
cd backend
npm install
# Tạo file .env với các biến môi trường cần thiết
npm run dev- Setup Frontend
cd ../frontend
npm install
npm run dev- Access Application
- Frontend: http://localhost:3000
- Backend: http://localhost:5000 (hoặc port được cấu hình)
next: 15.5.9 - React frameworkreact: 19.1.0 - UI libraryreact-hook-form: Form managementzod: Schema validationtailwindcss: Styling@radix-ui/*: Accessible UI componentssonner: Toast notifications
express: 5.2.1 - Web framework@supabase/supabase-js: Database clientjsonwebtoken: JWT authenticationbcrypt: Password hashing@payos/node: Payment integration@google/generative-ai: AI featuresmulter: File upload
SUPABASE_URL=
SUPABASE_KEY=
JWT_SECRET=
PAYOS_CLIENT_ID=
PAYOS_API_KEY=
PAYOS_CHECKSUM_KEY=
GOOGLE_AI_API_KEY=
NEXT_PUBLIC_API_URL=http://localhost:5000
- MVC Pattern - Controllers handle requests, Services contain business logic
- Repository Pattern - Abstraction layer for data access
- Middleware Pattern - Authentication, validation, error handling
- Service Layer Pattern - Separation of business logic
- Context API - State management in frontend
Frontend được thiết kế responsive với TailwindCSS breakpoints:
- Mobile: < 640px
- Tablet: 640px - 1024px
- Desktop: > 1024px
- JWT-based authentication
- Password hashing with bcrypt
- CORS configuration
- Input validation with Zod
- SQL injection prevention (Supabase parameterized queries)
- XSS protection
- Rate limiting (middleware)
- Admin dashboard
- Real-time notifications (WebSocket)
- Advanced search with filters
- Product recommendations
- Social media integration
- Mobile app (React Native)
- Multi-language support (i18n)
Dự án môn học: Nhập môn Công nghệ Phần mềm
This project is for educational purposes.