Giới thiệu dự án

Thương mại điện tử (TMĐT) dành cho sản phẩm số (digital products) như source code, UI/UX design kits, tài liệu kỹ thuật, đồ họa 3D và template web đang có tốc độ tăng trưởng kép hàng năm (CAGR) đạt 14.8% trên toàn cầu. Khác với hàng hóa vật lý phụ thuộc vào chuỗi cung ứng, kho bãi và vận chuyển, sản phẩm số đòi hỏi quy trình phân phối tức thì (instant delivery), cơ chế bảo mật quyền truy cập tệp tin nghiêm ngặt và khả năng đề xuất chính xác theo nhu cầu chuyên môn của lập trình viên và nhà thiết kế.

Tuy nhiên, các nền tảng thương mại điện tử truyền thống không được tối ưu hóa cho vòng đời sản phẩm số. Người bán gặp rào cản về mức phí sàn trung gian cao (từ 20% đến 45% trên các nền tảng quốc tế như Envato hay Creative Market), thiếu công cụ quản lý phiên bản mã nguồn chuyên sâu. Trong khi đó, người mua thường xuyên đối mặt với trải nghiệm tải trang chậm do tệp preview nặng, rủi ro tải file lỗi và giao diện phân cấp danh mục phức tạp.

Đồ án tốt nghiệp "Xây dựng Website Thương mại Điện tử Sản phẩm Số sử dụng MERN Stack" (thực hiện bởi nhóm tác giả Lê Kiên Trung và Trần Mai Tuệ dưới sự hướng dẫn của ThS. Nguyễn Hữu Trung tại Trường Đại học Sư phạm Kỹ thuật TP.HCM) được xây dựng nhằm giải quyết triệt để các bài toán kỹ thuật và nghiệp vụ nêu trên.

+-----------------------------------------------------------------------+
|                         PROJECT OBJECTIVES                            |
+-----------------------------------------------------------------------+
| 1. Thiết kế kiến trúc Client-Server tối ưu bằng MERN Stack            |
| 2. Triển khai phân quyền RBAC đa vai trò (Admin, Vendor, User) qua JWT|
| 3. Tích hợp thuật toán Cosine Similarity đề xuất sản phẩm số          |
| 4. Xây dựng cơ chế lưu trữ và phân phối tệp nhị phân qua Azure Blob  |
| 5. Tối ưu hóa hiệu năng render giao diện với Next.js và TailwindCSS   |
+-----------------------------------------------------------------------+

Dự án lựa chọn hệ giải pháp kiến trúc phân tách độc lập (Decoupled Architecture):

  • Giao diện người dùng (Storefront): Sử dụng Next.js kết hợp TailwindCSS nhằm khai thác thế mạnh của Server-Side Rendering (SSR) và Incremental Static Regeneration (ISR), tối ưu hóa chỉ số Web Vitals và SEO công cụ tìm kiếm.
  • Giao diện quản trị (Admin/Vendor Panel): Sử dụng ReactJS Single Page Application (SPA) cho khả năng xử lý trạng thái dữ liệu thời gian thực mượt mà.
  • Hệ thống Backend API: Sử dụng Node.jsExpress Framework theo mô hình Non-blocking I/O Event-Driven, xử lý đồng thời hàng nghìn kết nối mà không gây nghẽn tài nguyên máy chủ.
  • Hệ cơ sở dữ liệu: Sử dụng MongoDB với kiến trúc Document NoSQL linh hoạt, tối ưu lưu trữ các thuộc tính đa hình của sản phẩm số.
  • Hệ thống Cloud Storage: Tích hợp Microsoft Azure Blob Storage để lưu trữ các tài nguyên ảnh dung lượng cao và tệp mã nguồn đóng gói (.zip, .figma, .sketch).

Chỉ số mục tiêu định lượng:

  • Thời gian phản hồi API trung bình: $< 150\text{ ms}$ cho 95% số request (p95 latency).
  • Tốc độ tải trang đầu tiên (FCP): $< 1.2\text{ s}$ trên môi trường mạng tiêu chuẩn.
  • Độ bao phủ kiểm thử (Test Coverage): $\ge 85%$ trên các luồng nghiệp vụ thanh toán và bảo mật.

Phạm vi đề tài tập trung vào việc số hóa quy trình giao dịch sản phẩm số từ khâu đăng tải, duyệt kiểm tra, thanh toán trực tuyến đến tải tệp tin bảo mật, không bao gồm các nghiệp vụ vận chuyển vật lý hoặc tích hợp thanh toán tiền mã hóa (crypto).


Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Khảo sát các nền tảng phân phối tài nguyên thiết kế và mã nguồn phổ biến trên thị trường giúp làm rõ các khoảng trống kỹ thuật (gaps) cần khắc phục:

Tiêu chí Dribbble UI8 Tailwind Components Hệ thống đề xuất (MERN Stack)
Loại hình chính Portfolio/Showcase UI/UX Kits, 3D Assets Code Snippets/UI All-in-one Digital Marketplace
Mô hình định danh Thuê bao định kỳ (Pro) Mua lẻ / Gói All-Access Mã nguồn mở / Mua lẻ Mua lẻ theo phiên bản, Quản lý bộ sưu tập
Trải nghiệm UX Rối mắt, nhiều quảng cáo Load media không ổn định Bố cục đơn giản, ít filter Tối giản, điều hướng mượt, tải nhanh
Bảo vệ liên kết tải Chuyển hướng bên thứ 3 Tải trực tiếp Tải mã nguồn mở Azure Blob SAS Token có thời hạn
Thuật toán gợi ý Trending cơ bản Dựa trên Category tĩnh Không có Cosine Similarity Vector Engine

Phân loại yêu cầu người dùng theo mô hình MoSCoW (Must - Should - Could - Won't):

  • Must have: Đăng ký/đăng nhập xác thực bằng JWT, xác minh Email, tìm kiếm/lọc sản phẩm đa tiêu chí, giỏ hàng, thanh toán trực tuyến, trang cá nhân tải tài nguyên, bảng điều khiển Admin duyệt sản phẩm và phân quyền.
  • Should have: Đăng ký gian hàng kinh doanh (Business Onboarding), theo dõi tác giả (Follow system), đánh giá/bình luận sản phẩm theo sao, tạo và quản lý Bộ sưu tập (Collections).
  • Could have: Động cơ gợi ý sản phẩm dựa trên độ tương đồng Cosine, thống kê doanh thu biểu đồ thời gian thực cho nhà bán lẻ.
  • Won't have (Giai đoạn 1): Hệ thống affiliate marketing đa tầng, công cụ trực tiếp chỉnh sửa mã nguồn trên trình duyệt (Web IDE).

Thiết kế hệ thống

Kiến trúc hệ thống triển khai theo mô hình 3 tầng (3-Tier Decoupled Client-Server Architecture):

+-------------------------------------------------------------------------+
|                               PRESENTATION TIER                         |
|  [Next.js Client (SSR/ISR) - Port 3000]   [React Admin SPA - Port 5173] |
+-------------------------------------------------------------------------+
                                     | (HTTPS / RESTful API / JSON)
                                     v
+-------------------------------------------------------------------------+
|                               LOGIC TIER (API)                          |
|  [Node.js v20 LTS / Express v4.19 Framework - Port 5000]                |
|  +---------------------+ +----------------------+ +-------------------+ |
|  | Auth (JWT/Bcrypt)   | | Order/Payment Logic  | | Recommendation Eng| |
|  +---------------------+ +----------------------+ +-------------------+ |
+-------------------------------------------------------------------------+
           |                                             |
           v                                             v
+-----------------------+                    +----------------------------+
|      DATA TIER        |                    |     STORAGE & INFRA        |
|  [MongoDB v7.0 Cluster|                    |  [Azure Blob Storage]      |
|   Mongoose ORM Schema]|                    |  - Preview Images, Assets  |
+-----------------------+                    +----------------------------+

Danh mục công nghệ và phiên bản chính xác:

  • Runtime: Node.js v20.12.2 LTS
  • Backend Framework: Express.js v4.19.2
  • Database Management: MongoDB Community Server v7.0.8 / Mongoose ODM v8.3.1
  • Frontend User: Next.js v14.2.3 (App Router), TailwindCSS v3.4.3
  • Frontend Dashboard: React.js v18.3.1, Vite v5.2.0
  • Authentication: JSON Web Token (jsonwebtoken v9.0.2), bcryptjs v2.4.3
  • Cloud Storage SDK: @azure/storage-blob v12.17.0

Thiết kế cơ sở dữ liệu (Database Schema)

Dữ liệu được tổ chức thành các Collections chính với định nghĩa quan hệ tham chiếu rõ ràng:

// Model: Work.js (Mongoose Schema cho Sản phẩm số)
const mongoose = require('mongoose');

const WorkSchema = new mongoose.Schema({
  title: { type: String, required: true, trim: true, index: true },
  slug: { type: String, required: true, unique: true, lowercase: true },
  description: { type: String, required: true },
  price: { type: Number, required: true, min: 0 },
  categories: [{ type: String, required: true, index: true }],
  previewImages: [{ type: String, required: true }],
  sourceFileUrl: { type: String, required: true }, // Đường dẫn an toàn trên Azure Blob
  fileSize: { type: Number, required: true }, // Byte
  fileType: { type: String, enum: ['ZIP', 'FIGMA', 'PDF', 'RAR'], required: true },
  author: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  ratingAverage: { type: Number, default: 0, min: 0, max: 5 },
  ratingCount: { type: Number, default: 0 },
  featureVector: { type: [Number], default: [] }, // Vector đặc trưng cho Cosine Similarity
  isApproved: { type: Boolean, default: false },
  createdAt: { type: Date, default: Date.now }
}, { timestamps: true });

module.exports = mongoose.model('Work', WorkSchema);

Thiết kế API RESTful

Phương thức Endpoint Mô tả Yêu cầu xác thực
POST /api/v1/auth/login Xác thực người dùng, trả về access token Public
GET /api/v1/works Lấy danh sách sản phẩm (có phân trang & lọc) Public
GET /api/v1/works/:id/recommendations Trả về top 5 sản phẩm tương đồng Public
POST /api/v1/works Tạo mới sản phẩm số và upload metadata Vendor / Admin
POST /api/v1/orders/checkout Xử lý thanh toán đơn hàng sản phẩm số User Authenticated
GET /api/v1/orders/my-downloads/:workId Tạo link tải tạm thời (SAS URL) User đã mua

Methodology

Dự án áp dụng mô hình phát triển phần mềm Agile/Scrum với chu kỳ 2 tuần/Sprint kéo dài từ 04/03/2024 đến 02/06/2024:

  • Sprint 1 (04/03 - 17/03): Khảo sát thực trạng, đặc tả Use Case, thiết kế cơ sở dữ liệu MongoDB và phân bổ Module.
  • Sprint 2 (18/03 - 24/03): Thiết kế API Core (Auth, User), xây dựng khung kiến trúc Next.js và TailwindCSS.
  • Sprint 3 (25/03 - 07/04): Xây dựng Mongoose Collections, cấu hình Azure Storage Blob, thiết lập Widget/Component cơ bản.
  • Sprint 4 (08/04 - 21/04): Xây dựng Module giỏ hàng, Bộ sưu tập, Đánh giá và chức năng Vendor.
  • Sprint 5 (22/04 - 05/05): Tích hợp giao diện Frontend với Backend APIs, hoàn thiện luồng thanh toán.
  • Sprint 6 (06/05 - 12/05): Phát triển bảng điều khiển Admin, quản trị người dùng và duyệt sản phẩm.
  • Sprint 7 (13/05 - 02/06): Kiểm thử tích hợp, tối ưu thuật toán gợi ý, quản lý lỗi bằng Jira và triển khai Deployment.

Implementation và kết quả

Development process

Thuật toán Gợi ý Sản phẩm (Cosine Similarity Engine)

Để gợi ý các sản phẩm số tương đồng dựa trên nội dung (Content-Based Filtering), hệ thống trích xuất vector đặc trưng $N$-chiều $\vec{A} = (c_1, c_2, \dots, c_k, p, r)$ biểu diễn các danh mục ($c_i \in {0, 1}$), giá chuẩn hóa ($p \in [0, 1]$) và đánh giá trung bình ($r \in [0, 1]$).

Công thức tính toán độ tương đồng Cosine:

$$\text{Cosine Similarity}(\vec{A}, \vec{B}) = \frac{\vec{A} \cdot \vec{B}}{|\vec{A}| |\vec{B}|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}}$$

Đoạn mã triển khai tính toán vector và trích xuất gợi ý trong dịch vụ Node.js:

// services/recommendationService.js
function calculateCosineSimilarity(vecA, vecB) {
  if (vecA.length !== vecB.length || vecA.length === 0) return 0;

  let dotProduct = 0.0;
  let normA = 0.0;
  let normB = 0.0;

  for (let i = 0; i < vecA.length; i++) {
    dotProduct += vecA[i] * vecB[i];
    normA += vecA[i] * vecA[i];
    normB += vecB[i] * vecB[i];
  }

  if (normA === 0 || normB === 0) return 0;
  return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}

async function getSimilarWorks(targetWorkId, limit = 5) {
  const Work = require('../models/Work');
  const targetWork = await Work.findById(targetWorkId);
  if (!targetWork || !targetWork.featureVector.length) return [];

  const candidates = await Work.find({
    _id: { $ne: targetWorkId },
    isApproved: true
  }).lean();

  const scoredWorks = candidates.map(item => ({
    work: item,
    similarity: calculateCosineSimilarity(targetWork.featureVector, item.featureVector)
  }));

  // Sắp xếp giảm dần theo chỉ số tương đồng
  scoredWorks.sort((a, b) => b.similarity - a.similarity);
  return scoredWorks.slice(0, limit).map(entry => entry.work);
}

module.exports = { calculateCosineSimilarity, getSimilarWorks };

Middleware Xác thực và Phân quyền JWT

// middlewares/authMiddleware.js
const jwt = require('jsonwebtoken');

const verifyTokenAndRole = (allowedRoles = []) => {
  return (req, res, next) => {
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      return res.status(401).json({ success: false, message: 'Authentication required' });
    }

    const token = authHeader.split(' ')[1];
    jwt.verify(token, process.env.JWT_SECRET_KEY, (err, decoded) => {
      if (err) {
        return res.status(403).json({ success: false, message: 'Token invalid or expired' });
      }

      req.user = decoded; // { id, role, email }
      if (allowedRoles.length && !allowedRoles.includes(decoded.role)) {
        return res.status(403).json({ success: false, message: 'Permission denied' });
      }
      next();
    });
  };
};

module.exports = { verifyTokenAndRole };

Testing và validation

Quá trình kiểm thử hệ thống được quản lý thông qua Jira Software với các kịch bản kiểm thử (Test Cases) chi tiết:

  • Kiểm thử chức năng (Unit & Integration Test): 68 test cases trên toàn bộ các controller (Auth, Work, Order, Review, Business). Đạt tỷ lệ Pass 100%.
  • Kiểm thử hiệu năng (Load Testing với k6 / Apache JMeter):
    • Mô phỏng 200 người dùng đồng thời (Virtual Users) gửi request liên tục trong 10 phút.
    • Tỷ lệ lỗi (Error Rate): $0.00%$.
    • Độ trễ trung bình (Average Response Time): $118\text{ ms}$.
    • Throughput: Đạt $850\text{ req/s}$.
  • Kiểm thử chấp nhận người dùng (UAT): Thực hiện thử nghiệm trên 30 sinh viên và nhà phát triển tự do. Đánh giá giao diện đạt điểm trung bình 4.6/5.0 theo thang đo SUS (System Usability Scale).
  • Thống kê lỗi Jira: Tổng số 42 lỗi được phát hiện trong các Sprint; 100% các lỗi nghiêm trọng (Critical/High) liên quan đến xác thực và upload file đã được khắc phục hoàn toàn trước thời điểm triển khai.

Kết quả đạt được

Hệ thống đã hoàn thành trọn vẹn 100% các mục tiêu tính năng đề ra trong đề cương:

  1. Module Khách hàng: Duyệt sản phẩm tốc độ cao, xem trước tệp thiết kế, giỏ hàng động, thanh toán trực tiếp và nhận quyền tải file an toàn.
  2. Module Nhà kinh doanh (Vendor): Hệ thống đăng ký xét duyệt linh hoạt, bảng điều khiển đăng tải sản phẩm, upload file trực tiếp lên Azure Blob Storage, thống kê doanh số.
  3. Module Quản trị viên (Admin): Quản lý người dùng, kiểm duyệt chất lượng nội dung trước khi xuất bản (Content Moderation), theo dõi tình trạng thanh toán toàn sàn.

Đổi mới và đóng góp

  • Tích hợp cơ chế bảo vệ liên kết tải thông qua Azure Blob SAS: Thay vì trả về đường dẫn tĩnh trực tiếp có nguy cơ bị chia sẻ lậu tài nguyên số, hệ thống sinh URL chứa Shared Access Signature (SAS) có hiệu lực trong 60 phút chỉ dành riêng cho tài khoản đã hoàn tất giao dịch.
  • Cải tiến tốc độ dựng trang với Next.js SSR/ISR: Giảm thời gian kết xuất giao diện lần đầu (First Contentful Paint) từ $2.4\text{ s}$ (ở mô hình CSR truyền thống) xuống còn $0.9\text{ s}$, tăng hiệu quả lập chỉ mục SEO cho hàng nghìn trang chi tiết sản phẩm.
  • Động cơ gợi ý Cosine Vector nhẹ và hiệu quả: Cho phép tính toán độ tương đồng nội dung trực tiếp tại tầng Logic Service mà không cần phụ thuộc vào các engine cồng kềnh bên thứ ba, đạt độ chính xác gợi ý top 5 lên tới $88.5%$.
  • Mô hình mã nguồn chuẩn mực cho sinh viên và kỹ sư phần mềm: Đồ án đóng góp một bộ mã nguồn hoàn chỉnh tuân thủ kiến trúc phân tầng, là tài liệu tham khảo giá trị cho việc triển khai MERN Stack theo tiêu chuẩn công nghiệp hiện đại.

Ứng dụng thực tế và triển khai

Kịch bản ứng dụng thực tế

  1. Sàn giao dịch mã nguồn (Source Code Marketplace): Lập trình viên mua bán các thư viện component React/Vue, script tự động hóa, đồ án mẫu.
  2. Chợ tài nguyên thiết kế UI/UX: Designer phân phối các bộ Design System dạng Figma/Sketch/Adobe XD cho các dự án khởi nghiệp.
  3. Kho học liệu và tài liệu số: Giảng viên và sinh viên chia sẻ tài liệu ôn tập, slide bài giảng kỹ thuật, ebook chuyên ngành có bản quyền.

Chiến lược triển khai (Deployment Architecture)

[Vercel Global Edge Network] ---> Next.js Client (Storefront)
[Render / AWS EC2 Container] ---> Express.js API Server (Dockerized)
[MongoDB Atlas Cloud]        ---> NoSQL Database Replica Set
[Microsoft Azure Storage]    ---> Encrypted Binary & Media Storage

Phân tích chi phí & ROI

  • Chi phí hạ tầng máy chủ cơ sở: ~15 - 30 USD/tháng (nhờ tận dụng gói Serverless của Vercel, MongoDB Atlas M0/M10 và Azure Blob Storage dung lượng linh hoạt).
  • Khả năng sinh lời: Với mức phí sàn cố định $10%$ trên mỗi giao dịch (thấp hơn nhiều so với mức $30\text{ - }40%$ của Envato), nền tảng ước tính đạt điểm hòa vốn chỉ sau 200 giao dịch đầu tiên mỗi tháng.

Hạn chế và hướng phát triển

Hạn chế kỹ thuật

  • Thuật toán Cosine Similarity hiện tại chỉ dựa trên metadata tĩnh (Category, Price, Rating), chưa tích hợp ma trận hành vi người dùng (Collaborative Filtering / Matrix Factorization) do hạn chế về lượng dữ liệu tương tác thực tế ban đầu (Cold-Start Problem).
  • Cổng thanh toán mới hỗ trợ kịch bản mô phỏng giao dịch nội địa, chưa tích hợp tự động thanh toán đa tiền tệ qua cổng Stripe/PayPal quốc tế.

Hướng phát triển trong tương lai

  • Tích hợp Elasticsearch để nâng cao tốc độ và khả năng tìm kiếm ngữ nghĩa (Semantic & Fuzzy Search) khi quy mô dữ liệu vượt mức $100,000$ sản phẩm.
  • Triển khai kiến trúc Microservices và kết nối hàng đợi tin nhắn RabbitMQ nhằm tối ưu hóa xử lý bất đồng bộ các tác vụ nén file dung lượng lớn và gửi email tự động.
  • Phát triển thuật toán AI phân loại tự động chất lượng mã nguồn trước khi duyệt đăng tải.

Đối tượng hưởng lợi

  • Sinh viên CNTT: Nguồn tài liệu tham khảo chi tiết về quy trình xây dựng đồ án tốt nghiệp chuẩn mực từ khâu phân tích Use Case, thiết kế cơ sở dữ liệu đến triển khai thực tế.
  • Lập trình viên (Developers): Nắm vững cách kết hợp giữa Next.js 14, Node.js RESTful API, xác thực JWT an toàn và kỹ thuật tích hợp Azure Cloud Blob Storage.
  • Doanh nghiệp & Tác giả số: Sở hữu giải pháp nền tảng mở giúp nhanh chóng thiết lập sàn giao dịch tài sản số với chi phí vận hành tối thiểu.
  • Nhà nghiên cứu: Dữ liệu thực nghiệm về ứng dụng độ đo Cosine trong bài toán gợi ý sản phẩm số trên cơ sở dữ liệu phi quan hệ NoSQL.

Câu hỏi thường gặp

1. Yêu cầu cấu hình hệ thống để triển khai dự án là gì?

  • Môi trường Backend: Máy chủ Linux (Ubuntu 22.04 LTS), tối thiểu 1 vCPU, 2GB RAM, Node.js v20+, MongoDB v7.0.
  • Môi trường Client: Trình duyệt hỗ trợ ES6+ (Chrome, Firefox, Safari, Edge phiên bản mới).

2. Hệ thống xử lý bài toán tải file dung lượng lớn như thế nào?

Hệ thống sử dụng cơ chế Direct Stream Upload lên Azure Blob Storage thông qua @azure/storage-blob SDK. Backend đóng vai trò xác thực và sinh Signed URL / SAS Token, giúp giải phóng băng thông cho máy chủ Node.js và ngăn ngừa tình trạng nghẽn I/O.

3. Khả năng mở rộng (Scalability) của hệ thống đến đâu?

Kiến trúc hoàn toàn là Stateless tại tầng Backend API, cho phép dễ dàng scale ngang (Horizontal Scaling) bằng cách triển khai nhiều container Node.js phía sau bộ cân bằng tải Nginx Load Balancer kết hợp cơ chế Caching với Redis.

4. Hệ thống bảo mật thông tin đơn hàng và tài khoản bằng cách nào?

Mật khẩu được băm một chiều với thuật toán bcrypt (Salt rounds = 10). Mọi request nhạy cảm đều được bảo vệ bởi JSON Web Token đặt trong Authorization Header và truyền tải qua giao thức HTTPS có chứng chỉ SSL/TLS.

5. Dự án có thể tích hợp thêm các cổng thanh toán như VNPay, MoMo không?

Hoàn toàn khả thi. Cấu trúc mã nguồn tại controllers/orderController.js được thiết kế theo mẫu Service Layer, cho phép dễ dàng tích hợp thêm Webhook IPN từ các cổng thanh toán như VNPay, MoMo hay Stripe.


Kết luận

Đề tài "Xây dựng Website Thương mại Điện tử Sản phẩm Số sử dụng MERN Stack" đã giải quyết trọn vẹn mục tiêu nghiên cứu và ứng dụng thực tiễn. Thông qua việc kết hợp sức mạnh của Node.js, Express, MongoDB, Next.js và Azure Cloud, nhóm tác giả đã xây dựng thành công một nền tảng thương mại điện tử chuyên biệt cho sản phẩm số đạt chuẩn cao về tốc độ, bảo mật và trải nghiệm người dùng.

Dự án không chỉ khẳng định tính khả thi của hệ sinh thái JavaScript/TypeScript toàn diện trong việc phát triển các hệ thống TMĐT phức tạp, mà còn mở ra hướng tiếp cận mới trong việc phân phối tài nguyên số an toàn và tối ưu hóa chi phí vận hành. Đây là cơ sở vững chắc để tiếp tục mở rộng thành một sản phẩm thương mại hoàn chỉnh trong tương lai.