Schema: laptop-shop-db · mysql
TL;DR
CSDL của ứng dụng bán laptop (Prisma + MySQL), gồm 12 bảng chia 4 cụm: Phân quyền (User · Role · Permission · RolePermission), Thương mại (Product · Cart · CartDetail · Order · OrderDetail), Phiên (Session), và Vận hành nền (EmailQueue · CronjobLog).
Sơ đồ ERD
⚠️ Order.userId có trong schema nhưng không khai báo @relation tới User (không có FK Prisma), nên ERD không vẽ cạnh User—Order. Cần review xem đây là chủ ý hay thiếu sót.
Từ điển dữ liệu (Data Dictionary)
Bảng users (model User)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| username | VarChar(255) | UNIQUE | No | Tên đăng nhập |
| password | VarChar(255) | — | No | Mật khẩu (đã hash) |
| fullName | VarChar(255) | — | Yes | Họ tên |
| address | VarChar(255) | — | Yes | Địa chỉ |
| phone | VarChar(255) | — | Yes | Số điện thoại |
| accountType | VarChar(255) | — | No | Loại tài khoản ⚠️ cần review (giá trị hợp lệ) |
| avatar | VarChar(255) | — | Yes | Ảnh đại diện |
| roleId | Int | FK → roles.id, default 1 | No | Vai trò của user |
| refresh_token | Text | — | Yes | Refresh token (cột map refresh_token) |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
| deleted_at | DateTime | — | Yes | Soft-delete (null = chưa xóa) |
Bảng roles (model Role)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| description | VarChar(255) | — | No | Mô tả vai trò |
| name | VarChar(100) | UNIQUE | No | Tên vai trò (vd ADMIN, USER) |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
| deleted_at | DateTime | — | Yes | Soft-delete |
Bảng permissions (model Permission)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| name | VarChar(100) | UNIQUE | No | Tên quyền |
| description | VarChar(255) | — | No | Mô tả quyền |
| resource | VarChar(100) | UNIQUE(resource, action) | No | Tài nguyên (users, products, orders…) |
| action | VarChar(50) | UNIQUE(resource, action) | No | Hành động (create, read, update, delete, list) |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
| deleted_at | DateTime | — | Yes | Soft-delete |
Bảng role_permissions (model RolePermission)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| roleId | Int | FK → roles.id (onDelete Cascade), UNIQUE(roleId, permissionId) | No | Vai trò |
| permissionId | Int | FK → permissions.id (onDelete Cascade), UNIQUE(roleId, permissionId) | No | Quyền |
| created_at | DateTime | default now() | No | Thời điểm tạo |
Bảng nối M:N giữa roles và permissions.
Bảng products (model Product)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| name | VarChar(255) | — | No | Tên sản phẩm |
| price | Int | — | No | Giá |
| image | VarChar(255) | — | Yes | Ảnh sản phẩm |
| detailDesc | MediumText | — | No | Mô tả chi tiết |
| shortDesc | VarChar(255) | — | No | Mô tả ngắn |
| quantity | Int | — | No | Tồn kho |
| sold | Int | default 0 | Yes | Đã bán |
| factory | VarChar(255) | — | No | Hãng/nhà sản xuất |
| target | VarChar(255) | — | No | Đối tượng/phân khúc |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
| deleted_at | DateTime | — | Yes | Soft-delete |
Bảng carts (model Cart)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| sum | Int | — | No | Tổng tiền giỏ hàng |
| userId | Int | FK → users.id, UNIQUE | No | Chủ giỏ (mỗi user 1 giỏ) |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
Bảng cart_detail (model CartDetail)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| price | Int | — | No | Giá tại thời điểm thêm |
| quantity | Int | — | No | Số lượng |
| cartId | Int | FK → carts.id | No | Giỏ hàng |
| productId | Int | FK → products.id | No | Sản phẩm |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
Bảng orders (model Order)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| totalPrice | Int | — | No | Tổng giá trị đơn |
| paymentMethod | String | — | No | Phương thức thanh toán |
| paymentRef | String | — | Yes | Mã tham chiếu thanh toán |
| paymentStatus | String | — | No | Trạng thái thanh toán |
| receiverAddress | VarChar(255) | — | No | Địa chỉ người nhận |
| receiverName | VarChar(255) | — | No | Tên người nhận |
| receiverPhone | VarChar(255) | — | No | SĐT người nhận |
| receiverMail | VarChar(255) | default "" | No | Email người nhận |
| status | String | default "PENDING" | No | Trạng thái đơn |
| userId | Int | ⚠️ không có FK @relation | No | ID người đặt (cần review quan hệ) |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
| deleted_at | DateTime | — | Yes | Soft-delete |
Bảng order_detail (model OrderDetail)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| price | Int | — | No | Giá tại thời điểm đặt |
| quantity | Int | — | No | Số lượng |
| orderId | Int | FK → orders.id | No | Đơn hàng |
| productId | Int | FK → products.id | No | Sản phẩm |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
Bảng Session (model Session)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | String | PK | No | Khóa chính |
| sid | String | UNIQUE | No | Session ID |
| data | MediumText | — | No | Dữ liệu phiên (serialized) |
| expiresAt | DateTime | — | No | Thời điểm hết hạn |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
⚠️ Model Session không có @@map, nên tên bảng giữ nguyên Session.
Bảng email_queue (model EmailQueue)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | String (uuid) | PK, default uuid() | No | Khóa chính |
| type | VarChar(50) | INDEX | No | Loại email (welcome, password-reset, order-confirmation) |
| recipient | VarChar(255) | — | No | Người nhận |
| data | Json | — | No | Dữ liệu email (JSON) |
| retryCount | Int | default 0 | No | Số lần đã thử lại |
| maxRetries | Int | default 3 | No | Số lần thử tối đa |
| status | VarChar(20) | default "pending", INDEX | No | pending, processing, sent, failed |
| error | Text | — | Yes | Thông báo lỗi (nếu có) |
| scheduled_at | DateTime | default now(), INDEX | No | Thời điểm dự kiến gửi |
| processed_at | DateTime | — | Yes | Thời điểm đã xử lý |
| created_at | DateTime | default now() | No | Thời điểm tạo |
| updated_at | DateTime | @updatedAt | No | Thời điểm cập nhật |
Bảng cronjob_logs (model CronjobLog)
| Cột | Kiểu | Khóa/Ràng buộc | Nullable | Mô tả |
|---|
| id | Int | PK, auto-increment | No | Khóa chính |
| jobName | VarChar(100) | INDEX | No | Tên cronjob |
| status | VarChar(20) | INDEX | No | started, completed, failed |
| startTime | DateTime | INDEX | No | Thời điểm bắt đầu |
| endTime | DateTime | — | Yes | Thời điểm kết thúc |
| duration | Int | — | Yes | Thời lượng (ms) |
| error | Text | — | Yes | Thông báo lỗi |
| details | Json | — | Yes | Chi tiết bổ sung (JSON) |
| created_at | DateTime | default now() | No | Thời điểm tạo |
Quan hệ chính
Role 1—N User (users.roleId)
Role M—N Permission qua RolePermission (roleId, permissionId; cascade)
User 1—1 Cart (carts.userId UNIQUE)
Cart 1—N CartDetail (cart_detail.cartId)
Product 1—N CartDetail (cart_detail.productId)
Order 1—N OrderDetail (order_detail.orderId)
Product 1—N OrderDetail (order_detail.productId)
- ⚠️
Order.userId — không có FK @relation trong Prisma (liên kết logic, cần review)
Session, EmailQueue, CronjobLog — bảng độc lập, không có quan hệ FK.
Code đọc/ghi (Service ↔ Model — CodeGraph)
Service truy cập các bảng (qua PrismaService), xác định từ CodeGraph index của laptop-shop.
| Cụm bảng | Service chính | File |
|---|
| Product, Cart, CartDetail, Order, OrderDetail | ProductsService | src/products/products.service.ts:17 |
| User | UsersService, AuthService | src/users/users.service.ts:13, src/auth/auth.service.ts:10 |
| Role, RolePermission | RolesService, PermissionService | src/roles/roles.service.ts:11, src/auth/services/permission.service.ts:5 |
| Permission | PermissionService | src/auth/services/permission.service.ts:5 |
| EmailQueue | MailService / consumer queue email | src/mail/services/mail.service.ts:9 |
| CronjobLog | CronjobService | src/cronjob/services/cronjob.service.ts:14 |
| (mọi bảng) | PrismaService (data access chung) | src/database/prisma.service.ts:11 |
Source of truth
- Schema file:
/Users/nhatnguyen/Documents/Github/code-demo/laptop-shop/prisma/schema.prisma
- Catalog:
01_Raw/database/schemas.json
- CodeGraph:
laptop-shop/.codegraph (73 file, 681 node)
Liên kết