Skip to content

Tài liệu Kiến trúc Giải pháp (SA)

Solution Architecture Document — Website TMĐT TechVN

Thông tin tài liệu
Mã tài liệuSA-TECHVN-2026-001
Phiên bản1.0
Ngày tạo20/04/2026
Ngày cập nhật09/05/2026
Tác giảLê Văn Cường — CTO / Solution Architect
Đồng tác giảĐặng Hoàng Nam — Senior Backend Engineer
Người phê duyệtTrần Quốc Hùng — CEO
Trạng tháiĐã phê duyệt (Approved)
Mức độ bảo mậtNội bộ — Hạn chế (Internal — Restricted)
BRD tham chiếuBRD-TECHVN-2026-001 v1.0
PRD tham chiếuPRD-TECHVN-2026-001 v1.0
SRS tham chiếuSRS-TECHVN-ECOM-2026-001 v1.0

Lịch sử thay đổi

Phiên bảnNgàyNgười thay đổiMô tả
0.120/04/2026Lê Văn CườngKhởi tạo, kiến trúc tổng quan
0.428/04/2026Đặng Hoàng NamBổ sung chi tiết backend, database schema
0.703/05/2026Lê Văn CườngBổ sung tích hợp, bảo mật, vận hành
0.907/05/2026Security TeamReview bảo mật, bổ sung threat model
1.009/05/2026Lê Văn CườngHoàn thiện sau phê duyệt

Mục lục

  1. Tổng quan kiến trúc
  2. Quyết định kiến trúc (ADR)
  3. Kiến trúc ứng dụng
  4. Thiết kế cơ sở dữ liệu
  5. Thiết kế API
  6. Tích hợp hệ thống bên ngoài
  7. Kiến trúc hạ tầng
  8. Bảo mật
  9. Hiệu năng và Khả năng mở rộng
  10. Giám sát và Vận hành
  11. Disaster Recovery
  12. CI/CD Pipeline
  13. Phụ lục

1. Tổng quan kiến trúc

1.1 Nguyên tắc kiến trúc

#Nguyên tắcMô tảÁp dụng
AP-01Đơn giản trước, phức tạp khi cầnBắt đầu với monolith modular, tách microservice khi có bottleneck rõ ràngKhông over-engineer từ đầu
AP-02Cloud-native nhưng không lock-inSử dụng managed services nhưng abstract qua interfaceCó thể chuyển cloud provider
AP-03API-firstMọi tính năng đều expose qua REST API trước, UI consume APIFrontend/Backend phát triển song song
AP-04Security by designBảo mật là yêu cầu chức năng, không phải afterthoughtOWASP top 10, mã hóa, audit log
AP-05ObservableMọi thành phần phải có logging, metrics, tracingDebug production issues nhanh
AP-06Infrastructure as CodeHạ tầng quản lý bằng code, reproducibleTerraform, Docker, K8s manifests

1.2 Sơ đồ kiến trúc tổng quan (C4 Level 1 — System Context)

                              ┌─────────────┐
                              │  Khách hàng  │
                              │  (Browser /  │
                              │   Mobile)    │
                              └──────┬───────┘
                                     │ HTTPS

                         ┌───────────────────────┐
                         │                       │
                         │    WEBSITE TECHVN      │
                         │    (techvn.vn)         │
                         │                       │
                         │  ┌─────────────────┐  │
                         │  │   Frontend      │  │
                         │  │   (Next.js)     │  │
                         │  └────────┬────────┘  │
                         │           │ API       │
                         │  ┌────────▼────────┐  │
                         │  │   Backend       │  │
                         │  │   (NestJS)      │  │
                         │  └────────┬────────┘  │
                         │           │           │
                         └───────────┼───────────┘

                    ┌────────────────┼────────────────┐
                    │                │                │
              ┌─────▼─────┐  ┌──────▼──────┐  ┌─────▼──────┐
              │  Thanh     │  │  Vận        │  │  ERP       │
              │  toán      │  │  chuyển     │  │  (SAP B1)  │
              │            │  │             │  │            │
              │ VNPAY      │  │ GHTK        │  │ Tồn kho   │
              │ MoMo       │  │ GHN         │  │ Giá       │
              │ Bank       │  │ Viettel     │  │ Sản phẩm  │
              └────────────┘  └─────────────┘  └────────────┘
                    │                │                │
              ┌─────▼─────┐  ┌──────▼──────┐  ┌─────▼──────┐
              │  Trả góp  │  │  SMS        │  │  Analytics │
              │            │  │  Gateway    │  │            │
              │ HD Saison  │  │ SpeedSMS    │  │ GA4        │
              │ FE Credit  │  │ Twilio      │  │ FB Pixel   │
              └────────────┘  └─────────────┘  └────────────┘

1.3 Sơ đồ kiến trúc chi tiết (C4 Level 2 — Container)

┌─────────────────────────────────────────────────────────────────────┐
│                         AWS ap-southeast-1                          │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────────┐   │
│  │  CloudFront CDN                                              │   │
│  │  ├── Static assets (JS, CSS, Images, Fonts)                  │   │
│  │  └── Edge caching, Gzip/Brotli compression                   │   │
│  └──────────────────────────┬───────────────────────────────────┘   │
│                              │                                      │
│  ┌──────────────────────────▼───────────────────────────────────┐   │
│  │  Application Load Balancer (ALB)                              │   │
│  │  ├── SSL Termination (TLS 1.3)                                │   │
│  │  ├── Health check                                             │   │
│  │  └── Path-based routing:                                      │   │
│  │      /api/*  → Backend Service                                │   │
│  │      /*      → Frontend Service                               │   │
│  └────────┬─────────────────────────────┬───────────────────────┘   │
│           │                             │                           │
│  ┌────────▼──────────┐       ┌──────────▼──────────┐               │
│  │  ECS Fargate      │       │  ECS Fargate         │               │
│  │  Frontend         │       │  Backend             │               │
│  │                   │       │                      │               │
│  │  Next.js 15       │       │  NestJS              │               │
│  │  TypeScript       │       │  TypeScript          │               │
│  │  Tailwind CSS     │       │  Node.js 20 LTS      │               │
│  │  React 19         │       │                      │               │
│  │                   │       │  Modules:            │               │
│  │  Features:        │       │  ├── Auth            │               │
│  │  ├── SSR/SSG      │       │  ├── Product         │               │
│  │  ├── ISR (15min)  │       │  ├── Order           │               │
│  │  ├── Image Opt    │       │  ├── Payment         │               │
│  │  └── API Routes   │       │  ├── Shipping        │               │
│  │                   │       │  ├── Promotion       │               │
│  │  Instances: 2-6   │       │  ├── User            │               │
│  │  (auto-scale)     │       │  ├── Notification    │               │
│  │                   │       │  ├── Review          │               │
│  └───────────────────┘       │  ├── Search          │               │
│                              │  ├── Analytics       │               │
│                              │  └── Admin           │               │
│                              │                      │               │
│                              │  Instances: 2-8      │               │
│                              │  (auto-scale)        │               │
│                              └──────────┬───────────┘               │
│                                         │                           │
│         ┌───────────────────────────────┼──────────────────┐        │
│         │                               │                  │        │
│  ┌──────▼───────┐  ┌───────────────┐  ┌▼──────────────┐   │        │
│  │ PostgreSQL   │  │ Redis         │  │ Elasticsearch │   │        │
│  │ 16           │  │ 7             │  │ 8             │   │        │
│  │              │  │               │  │               │   │        │
│  │ RDS Multi-AZ │  │ ElastiCache   │  │ OpenSearch    │   │        │
│  │              │  │ Cluster       │  │ Service       │   │        │
│  │ Primary +    │  │               │  │               │   │        │
│  │ Read Replica │  │ Uses:         │  │ Uses:         │   │        │
│  │              │  │ ├── Session   │  │ ├── Product   │   │        │
│  │ Storage:     │  │ ├── Cache     │  │ │   full-text │   │        │
│  │ ├── Users    │  │ ├── Cart     │  │ ├── Auto-     │   │        │
│  │ ├── Products │  │ ├── OTP      │  │ │   complete  │   │        │
│  │ ├── Orders   │  │ ├── Rate     │  │ └── Faceted   │   │        │
│  │ ├── Payments │  │ │   Limit    │  │     search    │   │        │
│  │ └── Reviews  │  │ └── Queue    │  │               │   │        │
│  │              │  │               │  │               │   │        │
│  └──────────────┘  └───────────────┘  └───────────────┘   │        │
│                                                            │        │
│  ┌──────────────┐  ┌───────────────┐  ┌───────────────┐   │        │
│  │ S3           │  │ SQS           │  │ SES           │   │        │
│  │              │  │               │  │               │   │        │
│  │ Product      │  │ Message Queue │  │ Email         │   │        │
│  │ Images       │  │               │  │ Service       │   │        │
│  │ Documents    │  │ Queues:       │  │               │   │        │
│  │ Backups      │  │ ├── order-    │  │ Transactional │   │        │
│  │              │  │ │   events    │  │ + Marketing   │   │        │
│  │              │  │ ├── notif-    │  │               │   │        │
│  │              │  │ │   ications  │  │               │   │        │
│  │              │  │ ├── inventory │  │               │   │        │
│  │              │  │ │   sync      │  │               │   │        │
│  │              │  │ └── payment-  │  │               │   │        │
│  │              │  │     webhooks  │  │               │   │        │
│  └──────────────┘  └───────────────┘  └───────────────┘   │        │
│                                                            │        │
└────────────────────────────────────────────────────────────┘        │
└─────────────────────────────────────────────────────────────────────┘

2. Quyết định kiến trúc (ADR)

ADR-001: Monolith modular thay vì Microservices

Trạng tháiĐã chấp nhận
Ngày20/04/2026
Người quyết địnhCTO — Lê Văn Cường

Bối cảnh: Đội phát triển 5-7 người. Sản phẩm mới, yêu cầu có thể thay đổi. Budget hạn chế.

Quyết định: Sử dụng kiến trúc monolith modular (NestJS modules) thay vì microservices.

Lý do:

Tiêu chíMonolith ModularMicroservices
Độ phức tạp vận hànhThấp ✅Cao ❌
Phù hợp đội nhỏ (5-7 người)Cao ✅Thấp ❌
Tốc độ phát triển ban đầuNhanh ✅Chậm ❌
Chi phí hạ tầngThấp ✅Cao ❌
Khả năng tách service sau nàyCó (nhờ module boundary) ✅N/A
Scale độc lập từng serviceKhông ❌Có ✅

Hệ quả:

  • Các NestJS modules phải có boundary rõ ràng, communicate qua interface — không import trực tiếp internal class.
  • Khi traffic vượt 10.000 CCU, đánh giá lại việc tách Search và Order thành service riêng.

ADR-002: Next.js cho Frontend

Trạng tháiĐã chấp nhận
Ngày22/04/2026

Quyết định: Next.js 15 với App Router.

Lý do:

  • SSR/SSG/ISR cho SEO: Trang sản phẩm, danh mục cần Google index tốt.
  • React ecosystem: Thư viện phong phú, dễ tuyển dụng tại VN.
  • Image Optimization: Built-in, giảm bandwidth 30-50%.
  • Edge Runtime: Middleware tại edge cho geo-routing, A/B testing.

Phương án đã loại:

FrameworkLý do loại
Nuxt.js (Vue)Ecosystem nhỏ hơn React tại VN, khó tuyển dụng
RemixCommunity nhỏ, ít production case study tại VN
SPA thuần (Vite + React)Không có SSR built-in → SEO yếu cho ecommerce

ADR-003: PostgreSQL cho Database chính

Trạng tháiĐã chấp nhận
Ngày22/04/2026

Quyết định: PostgreSQL 16 trên AWS RDS Multi-AZ.

Lý do:

  • JSONB support: Lưu thông số kỹ thuật sản phẩm linh hoạt (mỗi danh mục có spec khác nhau).
  • Full-text search (bổ trợ): Tìm kiếm cơ bản trước khi Elasticsearch sẵn sàng.
  • Mature, reliable: Proven cho ecommerce workload.
  • AWS RDS: Managed, Multi-AZ failover, automated backup.

Phương án đã loại:

DatabaseLý do loại
MySQLJSONB support yếu hơn, Full-text search tiếng Việt hạn chế
MongoDBKhông cần schemaless toàn bộ, SQL tốt hơn cho reporting
Trạng tháiĐã chấp nhận
Ngày25/04/2026

Quyết định: AWS OpenSearch Service (Elasticsearch 8 compatible).

Lý do:

  • Full-text search tiếng Việt: Plugin ICU + Vietnamese analyzer.
  • Faceted search: Bộ lọc đa chiều (giá, brand, specs) với aggregation.
  • Autocomplete: Completion suggester cho gợi ý realtime.
  • Performance: Search < 100ms cho 5.000 SKU.

Thay thế xem xét: Meilisearch (đơn giản hơn nhưng ít mature cho production, thiếu Vietnamese analyzer tốt).

ADR-005: SQS cho Message Queue

Trạng tháiĐã chấp nhận
Ngày28/04/2026

Quyết định: AWS SQS thay vì RabbitMQ self-hosted.

Lý do:

  • Managed: Không cần quản lý cluster, auto-scale.
  • Reliability: 99.999999999% durability.
  • Chi phí thấp cho workload ecommerce (vài nghìn messages/ngày).
  • Dead Letter Queue: Built-in retry + DLQ cho failed messages.

Use cases:

QueueProducerConsumerMục đích
order-eventsOrder ModuleNotification, Inventory, AnalyticsXử lý async sau đặt hàng
notificationsOrder, Promotion, SystemNotification ModuleGửi email, SMS, push
inventory-syncERP ConnectorProduct ModuleĐồng bộ tồn kho từ SAP
payment-webhooksAPI GatewayPayment ModuleXử lý callback thanh toán

3. Kiến trúc ứng dụng

3.1 Backend — NestJS Module Structure

src/
├── main.ts
├── app.module.ts

├── common/                          # Shared utilities
│   ├── decorators/
│   ├── filters/                     # Exception filters
│   ├── guards/                      # Auth, Role guards
│   ├── interceptors/                # Logging, Transform
│   ├── pipes/                       # Validation pipes
│   ├── interfaces/
│   └── utils/

├── config/                          # Configuration module
│   ├── database.config.ts
│   ├── redis.config.ts
│   ├── aws.config.ts
│   └── app.config.ts

├── modules/
│   ├── auth/                        # Authentication & Authorization
│   │   ├── auth.module.ts
│   │   ├── auth.controller.ts
│   │   ├── auth.service.ts
│   │   ├── strategies/              # JWT, Google, Facebook
│   │   ├── guards/
│   │   └── dto/
│   │
│   ├── user/                        # User management
│   │   ├── user.module.ts
│   │   ├── user.controller.ts
│   │   ├── user.service.ts
│   │   ├── entities/
│   │   │   ├── user.entity.ts
│   │   │   └── address.entity.ts
│   │   └── dto/
│   │
│   ├── product/                     # Product catalog
│   │   ├── product.module.ts
│   │   ├── controllers/
│   │   │   ├── product.controller.ts
│   │   │   ├── category.controller.ts
│   │   │   └── brand.controller.ts
│   │   ├── services/
│   │   │   ├── product.service.ts
│   │   │   ├── category.service.ts
│   │   │   ├── variant.service.ts
│   │   │   └── product-search.service.ts
│   │   ├── entities/
│   │   │   ├── product.entity.ts
│   │   │   ├── product-variant.entity.ts
│   │   │   ├── product-spec.entity.ts
│   │   │   ├── category.entity.ts
│   │   │   └── brand.entity.ts
│   │   └── dto/
│   │
│   ├── order/                       # Order management
│   │   ├── order.module.ts
│   │   ├── controllers/
│   │   ├── services/
│   │   │   ├── order.service.ts
│   │   │   ├── cart.service.ts
│   │   │   └── checkout.service.ts
│   │   ├── entities/
│   │   │   ├── order.entity.ts
│   │   │   ├── order-item.entity.ts
│   │   │   └── cart.entity.ts
│   │   └── events/                  # Order domain events
│   │
│   ├── payment/                     # Payment processing
│   │   ├── payment.module.ts
│   │   ├── payment.controller.ts
│   │   ├── services/
│   │   │   ├── payment.service.ts
│   │   │   ├── vnpay.service.ts
│   │   │   ├── momo.service.ts
│   │   │   └── installment.service.ts
│   │   ├── entities/
│   │   └── webhooks/                # Payment callbacks
│   │
│   ├── shipping/                    # Shipping integration
│   │   ├── shipping.module.ts
│   │   ├── services/
│   │   │   ├── shipping.service.ts
│   │   │   ├── ghtk.service.ts
│   │   │   └── ghn.service.ts
│   │   └── dto/
│   │
│   ├── promotion/                   # Coupon & Promotion
│   │   ├── promotion.module.ts
│   │   ├── services/
│   │   │   ├── coupon.service.ts
│   │   │   └── flash-sale.service.ts
│   │   └── entities/
│   │
│   ├── review/                      # Product reviews
│   │   ├── review.module.ts
│   │   ├── review.controller.ts
│   │   ├── review.service.ts
│   │   └── entities/
│   │
│   ├── notification/                # Multi-channel notification
│   │   ├── notification.module.ts
│   │   ├── services/
│   │   │   ├── notification.service.ts
│   │   │   ├── email.service.ts
│   │   │   ├── sms.service.ts
│   │   │   └── push.service.ts
│   │   └── templates/
│   │
│   ├── search/                      # Search & Indexing
│   │   ├── search.module.ts
│   │   ├── search.controller.ts
│   │   ├── search.service.ts
│   │   └── indexer.service.ts
│   │
│   ├── admin/                       # Admin back-office
│   │   ├── admin.module.ts
│   │   ├── controllers/
│   │   │   ├── admin-product.controller.ts
│   │   │   ├── admin-order.controller.ts
│   │   │   ├── admin-user.controller.ts
│   │   │   └── dashboard.controller.ts
│   │   └── services/
│   │       ├── dashboard.service.ts
│   │       └── report.service.ts
│   │
│   └── integration/                 # External system integration
│       ├── integration.module.ts
│       └── services/
│           └── erp-sync.service.ts

├── database/
│   ├── migrations/
│   └── seeds/

└── workers/                         # Background jobs
    ├── inventory-sync.worker.ts
    ├── notification.worker.ts
    ├── cart-cleanup.worker.ts
    └── report-generator.worker.ts

3.2 Frontend — Next.js App Structure

src/
├── app/                             # App Router (Next.js 15)
│   ├── layout.tsx                   # Root layout (header, footer)
│   ├── page.tsx                     # Homepage (SSG + ISR 15min)
│   ├── loading.tsx                  # Global loading skeleton
│   ├── error.tsx                    # Error boundary
│   ├── not-found.tsx
│   │
│   ├── (auth)/                      # Auth group (no header)
│   │   ├── dang-nhap/page.tsx
│   │   ├── dang-ky/page.tsx
│   │   └── quen-mat-khau/page.tsx
│   │
│   ├── (shop)/                      # Shop group (with header)
│   │   ├── [category]/              # Dynamic category pages (SSG)
│   │   │   └── page.tsx
│   │   ├── [category]/[product]/    # Product detail (SSG + ISR)
│   │   │   └── page.tsx
│   │   ├── tim-kiem/page.tsx        # Search results (SSR)
│   │   ├── so-sanh/page.tsx         # Compare (CSR)
│   │   └── khuyen-mai/page.tsx      # Promotions (SSR)
│   │
│   ├── gio-hang/page.tsx            # Cart (CSR)
│   ├── thanh-toan/                  # Checkout (CSR, protected)
│   │   └── page.tsx
│   │
│   ├── tai-khoan/                   # Account (CSR, protected)
│   │   ├── layout.tsx
│   │   ├── thong-tin/page.tsx
│   │   ├── don-hang/page.tsx
│   │   ├── don-hang/[id]/page.tsx
│   │   ├── dia-chi/page.tsx
│   │   └── yeu-thich/page.tsx
│   │
│   ├── admin/                       # Admin (CSR, role-protected)
│   │   ├── layout.tsx
│   │   ├── page.tsx                 # Dashboard
│   │   ├── san-pham/
│   │   ├── don-hang/
│   │   ├── khach-hang/
│   │   ├── khuyen-mai/
│   │   └── bao-cao/
│   │
│   └── api/                         # API routes (BFF pattern)
│       ├── auth/[...nextauth]/
│       └── revalidate/

├── components/
│   ├── ui/                          # Design system atoms
│   │   ├── Button/
│   │   ├── Input/
│   │   ├── Modal/
│   │   ├── Skeleton/
│   │   ├── Badge/
│   │   └── Toast/
│   ├── layout/                      # Layout components
│   │   ├── Header/
│   │   ├── Footer/
│   │   ├── MegaMenu/
│   │   └── Sidebar/
│   ├── product/                     # Product domain
│   │   ├── ProductCard/
│   │   ├── ProductGallery/
│   │   ├── ProductSpecs/
│   │   ├── ProductFilter/
│   │   ├── CompareTable/
│   │   └── QuickView/
│   ├── cart/
│   ├── checkout/
│   └── account/

├── hooks/                           # Custom React hooks
│   ├── useCart.ts
│   ├── useAuth.ts
│   ├── useSearch.ts
│   └── useDebounce.ts

├── lib/                             # Utilities
│   ├── api-client.ts                # Axios/Fetch wrapper
│   ├── format.ts                    # Price, date formatting
│   └── validators.ts

├── stores/                          # State management (Zustand)
│   ├── cart.store.ts
│   ├── compare.store.ts
│   └── auth.store.ts

└── styles/
    └── globals.css                  # Tailwind + custom tokens

3.3 Rendering Strategy

TrangPhương phápRevalidationLý do
Trang chủSSG + ISR15 phútNội dung ít thay đổi, SEO quan trọng
Trang danh mụcSSG + ISR15 phútSEO, danh sách SP ít thay đổi theo phút
Trang chi tiết SPSSG + ISR60 phútSEO, thông tin SP ổn định, giá update qua ISR
Tìm kiếmSSRMỗi requestKết quả dynamic theo từ khóa
Giỏ hàngCSRN/ADữ liệu cá nhân, không cần SEO
CheckoutCSRN/ADữ liệu cá nhân, bảo mật
Tài khoảnCSRN/ADữ liệu cá nhân
AdminCSRN/AInternal tool, không cần SEO

4. Thiết kế cơ sở dữ liệu

4.1 Sơ đồ ERD

┌──────────────────┐       ┌──────────────────────┐
│     users         │       │     addresses         │
├──────────────────┤       ├──────────────────────┤
│ id          PK   │───┐   │ id               PK  │
│ email        UQ  │   │   │ user_id          FK  │
│ phone        UQ  │   └──>│ recipient_name       │
│ password_hash    │       │ phone                │
│ full_name        │       │ province_code        │
│ avatar_url       │       │ district_code        │
│ status           │       │ ward_code            │
│ role             │       │ address_detail       │
│ loyalty_points   │       │ is_default           │
│ created_at       │       │ created_at           │
│ updated_at       │       └──────────────────────┘
└──────────────────┘

         │ 1:N

┌──────────────────┐       ┌──────────────────────┐
│     orders        │       │     order_items       │
├──────────────────┤       ├──────────────────────┤
│ id          PK   │───┐   │ id               PK  │
│ order_code   UQ  │   │   │ order_id         FK  │
│ user_id      FK  │   └──>│ product_id       FK  │
│ address_id   FK  │       │ variant_id       FK  │
│ subtotal         │       │ product_name         │
│ discount_amount  │       │ sku                  │
│ shipping_fee     │       │ unit_price           │
│ total            │       │ quantity             │
│ status           │       │ total                │
│ payment_method   │       └──────────────────────┘
│ payment_status   │
│ shipping_provider│       ┌──────────────────────┐
│ tracking_code    │       │     payments          │
│ note             │       ├──────────────────────┤
│ internal_note    │       │ id               PK  │
│ coupon_code      │   ┌──>│ order_id         FK  │
│ created_at       │───┘   │ method               │
│ confirmed_at     │       │ provider             │
│ shipped_at       │       │ transaction_id       │
│ delivered_at     │       │ amount               │
│ cancelled_at     │       │ status               │
└──────────────────┘       │ provider_response    │
                           │ created_at           │
                           └──────────────────────┘

┌──────────────────┐       ┌──────────────────────┐
│    categories     │       │      brands           │
├──────────────────┤       ├──────────────────────┤
│ id          PK   │       │ id               PK  │
│ parent_id   FK   │──┐    │ name                 │
│ name             │  │    │ slug             UQ  │
│ slug         UQ  │  │    │ logo_url             │
│ image_url        │<─┘    │ description          │
│ description      │       │ sort_order           │
│ sort_order       │       └──────────────────────┘
│ is_active        │
│ level            │
└──────────────────┘

         │ 1:N

┌──────────────────┐       ┌──────────────────────┐
│    products       │       │  product_variants     │
├──────────────────┤       ├──────────────────────┤
│ id          PK   │───┐   │ id               PK  │
│ category_id  FK  │   │   │ product_id       FK  │
│ brand_id     FK  │   └──>│ name                 │
│ name             │       │ sku            UQ    │
│ slug         UQ  │       │ price                │
│ sku          UQ  │       │ sale_price           │
│ price            │       │ stock_quantity       │
│ sale_price       │       │ attributes     JSONB │
│ stock_quantity   │       │ is_active            │
│ short_desc       │       └──────────────────────┘
│ description      │
│ status           │       ┌──────────────────────┐
│ is_featured      │       │   product_specs       │
│ avg_rating       │       ├──────────────────────┤
│ review_count     │       │ id               PK  │
│ sold_count       │   ┌──>│ product_id       FK  │
│ specs      JSONB │───┘   │ spec_group           │
│ seo_title        │       │ spec_name            │
│ seo_description  │       │ spec_value           │
│ created_at       │       │ sort_order           │
│ updated_at       │       └──────────────────────┘
│ published_at     │
└──────────────────┘       ┌──────────────────────┐
         │                 │   product_images      │
         │ 1:N             ├──────────────────────┤
         └────────────────>│ id               PK  │
                           │ product_id       FK  │
                           │ url                  │
                           │ alt_text             │
                           │ sort_order           │
                           │ is_primary           │
                           └──────────────────────┘

┌──────────────────┐       ┌──────────────────────┐
│     reviews       │       │      coupons          │
├──────────────────┤       ├──────────────────────┤
│ id          PK   │       │ id               PK  │
│ product_id   FK  │       │ code           UQ    │
│ user_id      FK  │       │ type                 │
│ order_id     FK  │       │ value                │
│ rating           │       │ max_discount         │
│ title            │       │ min_order_value      │
│ content          │       │ usage_limit          │
│ images     JSONB │       │ used_count           │
│ status           │       │ per_user_limit       │
│ admin_reply      │       │ applicable_categories│
│ created_at       │       │ start_date           │
│ approved_at      │       │ end_date             │
└──────────────────┘       │ is_active            │
                           │ created_at           │
                           └──────────────────────┘

┌──────────────────┐
│   audit_logs      │
├──────────────────┤
│ id          PK   │
│ admin_id     FK  │
│ action           │
│ entity_type      │
│ entity_id        │
│ old_values JSONB │
│ new_values JSONB │
│ ip_address       │
│ user_agent       │
│ created_at       │
└──────────────────┘

4.2 Indexing Strategy

BảngIndexLoạiLý do
products(category_id, status, sort_order)B-treeDanh sách SP theo danh mục
products(brand_id, status)B-treeLọc theo thương hiệu
products(status, is_featured, created_at DESC)B-treeTrang chủ, SP nổi bật
products(slug)UniqueURL lookup
products(specs)GINJSONB query thông số kỹ thuật
orders(user_id, created_at DESC)B-treeLịch sử đơn hàng
orders(status, created_at DESC)B-treeAdmin danh sách đơn hàng
orders(order_code)UniqueTra cứu theo mã đơn
order_items(order_id)B-treeJoin chi tiết đơn
reviews(product_id, status, created_at DESC)B-treeHiển thị đánh giá
users(email)UniqueĐăng nhập
users(phone)UniqueĐăng nhập SĐT

4.3 Data Partitioning (kế hoạch tương lai)

BảngChiến lượcTrigger
ordersRange partition theo created_at (monthly)> 1 triệu đơn
audit_logsRange partition theo created_at (monthly)> 10 triệu records
product_views (analytics)Range partition theo ngàyTừ khi tạo

5. Thiết kế API

5.1 Quy ước API

Quy ướcChi tiết
Base URLhttps://api.techvn.vn/v1
FormatJSON (application/json)
AuthenticationBearer JWT token trong header Authorization
VersioningURL path (/v1/, /v2/)
NamingLowercase, kebab-case cho URL, camelCase cho JSON fields
PaginationCursor-based (default) hoặc Offset-based (admin)
Error Format{ "statusCode": 400, "message": "...", "error": "Bad Request" }
Rate Limiting100 req/phút/IP (public), 300 req/phút/user (authenticated)
CompressionGzip / Brotli

5.2 API Endpoints chính

Authentication

MethodEndpointMô tảAuth
POST/v1/auth/registerĐăng ký tài khoảnPublic
POST/v1/auth/verify-otpXác thực OTPPublic
POST/v1/auth/loginĐăng nhập email/SĐTPublic
POST/v1/auth/login/googleĐăng nhập Google OAuthPublic
POST/v1/auth/login/facebookĐăng nhập Facebook OAuthPublic
POST/v1/auth/forgot-passwordYêu cầu đặt lại mật khẩuPublic
POST/v1/auth/reset-passwordĐặt lại mật khẩuPublic
POST/v1/auth/refresh-tokenLàm mới access tokenRefresh Token
POST/v1/auth/logoutĐăng xuất (invalidate token)User

Products

MethodEndpointMô tảAuth
GET/v1/productsDanh sách SP (filter, sort, paginate)Public
GET/v1/products/:slugChi tiết sản phẩmPublic
GET/v1/products/:id/reviewsĐánh giá của sản phẩmPublic
GET/v1/products/compare?ids=1,2,3So sánh sản phẩmPublic
GET/v1/categoriesCây danh mụcPublic
GET/v1/categories/:slug/productsSP theo danh mụcPublic
GET/v1/brandsDanh sách thương hiệuPublic
GET/v1/search?q=...Tìm kiếm sản phẩmPublic
GET/v1/search/suggest?q=...Gợi ý tìm kiếm (autocomplete)Public

Cart & Orders

MethodEndpointMô tảAuth
GET/v1/cartXem giỏ hàngUser
POST/v1/cart/itemsThêm SP vào giỏUser
PATCH/v1/cart/items/:idCập nhật số lượngUser
DELETE/v1/cart/items/:idXóa SP khỏi giỏUser
POST/v1/cart/couponÁp dụng mã giảm giáUser
DELETE/v1/cart/couponXóa mã giảm giáUser
POST/v1/ordersTạo đơn hàng (checkout)User
GET/v1/ordersLịch sử đơn hàngUser
GET/v1/orders/:idChi tiết đơn hàngUser
POST/v1/orders/:id/cancelHủy đơn hàngUser
POST/v1/orders/:id/reviewsĐánh giá sản phẩm trong đơnUser

Payment (Webhooks)

MethodEndpointMô tảAuth
POST/v1/payments/vnpay/callbackVNPAY IPN callbackVNPAY signature
POST/v1/payments/momo/callbackMoMo IPN callbackMoMo signature
GET/v1/payments/vnpay/returnVNPAY return URLPublic

Shipping

MethodEndpointMô tảAuth
POST/v1/shipping/calculateTính phí vận chuyểnUser
GET/v1/shipping/provincesDanh sách Tỉnh/ThànhPublic
GET/v1/shipping/districts?province=...Quận/HuyệnPublic
GET/v1/shipping/wards?district=...Phường/XãPublic

Admin (prefix /v1/admin/)

MethodEndpointMô tảAuth
GET/v1/admin/dashboardDữ liệu dashboardAdmin
CRUD/v1/admin/productsQuản lý sản phẩmAdmin
POST/v1/admin/products/importImport ExcelAdmin
CRUD/v1/admin/ordersQuản lý đơn hàngAdmin
POST/v1/admin/orders/:id/confirmXác nhận đơnAdmin
POST/v1/admin/orders/:id/shipTạo đơn vận chuyểnAdmin
POST/v1/admin/orders/:id/refundHoàn tiềnAdmin
CRUD/v1/admin/couponsQuản lý mã giảm giáAdmin
CRUD/v1/admin/usersQuản lý khách hàngAdmin
GET/v1/admin/reports/revenueBáo cáo doanh thuAdmin
GET/v1/admin/audit-logsNhật ký thao tácSuperAdmin

5.3 Authentication Flow

┌────────┐                ┌──────────┐               ┌──────────┐
│ Client │                │  Backend │               │  Redis   │
└───┬────┘                └────┬─────┘               └────┬─────┘
    │                          │                          │
    │  POST /auth/login        │                          │
    │  {email, password}       │                          │
    ├─────────────────────────>│                          │
    │                          │  Verify credentials      │
    │                          │  Generate tokens         │
    │                          │                          │
    │                          │  Store refresh token     │
    │                          ├─────────────────────────>│
    │                          │                          │
    │  {accessToken (15min),   │                          │
    │   refreshToken (30d)}    │                          │
    │<─────────────────────────┤                          │
    │                          │                          │
    │  GET /products           │                          │
    │  Authorization: Bearer   │                          │
    │  <accessToken>           │                          │
    ├─────────────────────────>│                          │
    │                          │  Verify JWT              │
    │  200 OK                  │  (no DB call needed)     │
    │<─────────────────────────┤                          │
    │                          │                          │
    │  --- Access token expired ---                       │
    │                          │                          │
    │  POST /auth/refresh      │                          │
    │  {refreshToken}          │                          │
    ├─────────────────────────>│                          │
    │                          │  Verify refresh token    │
    │                          ├─────────────────────────>│
    │                          │  Valid? Rotate token     │
    │                          │<─────────────────────────┤
    │  {new accessToken,       │                          │
    │   new refreshToken}      │                          │
    │<─────────────────────────┤                          │

JWT Payload:

json
{
  "sub": "user-uuid",
  "email": "[email protected]",
  "role": "customer",
  "iat": 1715230000,
  "exp": 1715230900
}

6. Tích hợp hệ thống bên ngoài

6.1 Ma trận tích hợp

Hệ thốngGiao thứcHướngTần suấtRetry Policy
VNPAYREST HTTPSBidirectionalPer transaction3 retries, exponential backoff
MoMoREST HTTPSBidirectionalPer transaction3 retries, exponential backoff
GHTKREST HTTPSOutbound + WebhookPer order3 retries, 30s interval
GHNREST HTTPSOutbound + WebhookPer order3 retries, 30s interval
SAP Business OneREST HTTPS (DI API)BidirectionalPoll every 5 minQueue + retry
SpeedSMSREST HTTPSOutboundPer event2 retries
AWS SESAWS SDKOutboundPer eventSQS + retry
Google OAuthOAuth 2.0InboundPer loginN/A
Facebook OAuthOAuth 2.0InboundPer loginN/A
Google Analytics 4JavaScript SDKOutboundPer eventClient-side
Facebook PixelJavaScript SDKOutboundPer eventClient-side

6.2 Luồng thanh toán VNPAY

┌────────┐    ┌──────────┐    ┌──────────┐    ┌────────┐
│ Client │    │ Backend  │    │  VNPAY   │    │  SQS   │
└───┬────┘    └────┬─────┘    └────┬─────┘    └───┬────┘
    │              │               │              │
    │ Place order  │               │              │
    ├─────────────>│               │              │
    │              │ Create order  │              │
    │              │ status=       │              │
    │              │ PENDING_PAY   │              │
    │              │               │              │
    │              │ Create VNPAY  │              │
    │              │ payment URL   │              │
    │              ├──────────────>│              │
    │              │ Payment URL   │              │
    │              │<──────────────┤              │
    │              │               │              │
    │ Redirect to  │               │              │
    │ VNPAY        │               │              │
    │<─────────────┤               │              │
    │              │               │              │
    ├──────────────────────────────>│              │
    │     Customer completes       │              │
    │     payment on VNPAY         │              │
    │<─────────────────────────────┤              │
    │              │               │              │
    │ Return URL   │  IPN Callback │              │
    ├─────────────>│<──────────────┤              │
    │              │               │              │
    │              │ Verify VNPAY  │              │
    │              │ checksum      │              │
    │              │               │              │
    │              │ Update order  │              │
    │              │ status=PAID   │              │
    │              │               │              │
    │              │ Emit event ──────────────────>│
    │              │ "order.paid"  │              │
    │              │               │              │
    │ Order        │               │    Workers:  │
    │ success page │               │    - Email   │
    │<─────────────┤               │    - SMS     │
    │              │               │    - Stock   │

6.3 Đồng bộ tồn kho với ERP (SAP Business One)

Chiến lược: Polling + Event-driven hybrid

┌──────────────────────────────────────────────┐
│           INVENTORY SYNC FLOW                │
│                                              │
│  ┌─────────┐   Poll every 5 min  ┌────────┐ │
│  │ SAP B1  │ ──────────────────> │ Sync   │ │
│  │ DI API  │                     │ Worker │ │
│  └─────────┘                     └───┬────┘ │
│                                      │      │
│                              ┌───────▼────┐ │
│                              │ Compare &  │ │
│                              │ Diff       │ │
│                              └───────┬────┘ │
│                                      │      │
│                         ┌────────────┼────┐ │
│                         │            │    │ │
│                    No change    Has changes │ │
│                    (skip)        │         │ │
│                              ┌───▼───────┐ │
│                              │ Update    │ │
│                              │ PostgreSQL│ │
│                              └───┬───────┘ │
│                                  │         │
│                              ┌───▼───────┐ │
│                              │ Invalidate│ │
│                              │ Redis     │ │
│                              │ Cache     │ │
│                              └───┬───────┘ │
│                                  │         │
│                              ┌───▼───────┐ │
│                              │ Re-index  │ │
│                              │ Elastic-  │ │
│                              │ search    │ │
│                              └───────────┘ │
│                                            │
│  Website purchase ──> Deduct stock in DB   │
│                   ──> Sync back to SAP     │
│                       (via SQS queue)      │
└──────────────────────────────────────────────┘

Xử lý xung đột:

Kịch bảnXử lý
SAP stock = 0, Web stock > 0Cập nhật Web = 0, đánh dấu "Hết hàng"
Khách đặt hàng trong lúc syncKiểm tra stock tại thời điểm checkout (DB lock), nếu hết → thông báo
SAP giá thay đổiCập nhật giá trên Web, thông báo khách có SP trong giỏ
SAP không phản hồi (timeout)Retry 3 lần, sau đó alert ops team, giữ nguyên dữ liệu hiện tại

7. Kiến trúc hạ tầng

7.1 AWS Infrastructure

ServiceMục đíchCấu hìnhƯớc tính chi phí/tháng
ECS FargateApp containers (Frontend + Backend)Frontend: 2-6 tasks (0.5 vCPU, 1GB), Backend: 2-8 tasks (1 vCPU, 2GB)~$350
RDS PostgreSQLDatabase chínhdb.r6g.large, Multi-AZ, 100GB gp3, 1 Read Replica~$450
ElastiCache RedisCache, Session, Queuecache.r6g.large, 2 nodes (cluster mode)~$300
OpenSearchFull-text searcht3.medium.search, 2 nodes, 50GB~$180
S3Object storage (images, backups)Standard, ~500GB (estimate)~$15
CloudFrontCDN~2TB transfer/tháng~$120
ALBLoad Balancer1 ALB, path-based routing~$30
SQSMessage Queue~100K messages/tháng~$5
SESEmail Service~50K emails/tháng~$5
Route 53DNStechvn.vn~$1
ACMSSL CertificateWildcard *.techvn.vnFree
CloudWatchLogging, MonitoringLogs + Metrics + Alarms~$50
WAFWeb Application FirewallCore rule set + rate limiting~$30
ECRContainer RegistryDocker images~$5
Secrets ManagerSecrets managementAPI keys, DB credentials~$5
Tổng ước tính~$1.546 (~15 triệu VNĐ/tháng)

7.2 Network Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        VPC: 10.0.0.0/16                         │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  Public Subnet (10.0.1.0/24, 10.0.2.0/24)               │   │
│  │  ├── ALB                                                  │   │
│  │  ├── NAT Gateway                                          │   │
│  │  └── Bastion Host (optional, for emergency access)        │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  Private Subnet — App (10.0.10.0/24, 10.0.11.0/24)      │   │
│  │  ├── ECS Fargate Tasks (Frontend)                         │   │
│  │  ├── ECS Fargate Tasks (Backend)                          │   │
│  │  └── ECS Fargate Tasks (Workers)                          │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │  Private Subnet — Data (10.0.20.0/24, 10.0.21.0/24)     │   │
│  │  ├── RDS PostgreSQL (Primary + Read Replica)              │   │
│  │  ├── ElastiCache Redis Cluster                            │   │
│  │  └── OpenSearch Domain                                    │   │
│  └──────────────────────────────────────────────────────────┘   │
│                                                                 │
│  Security Groups:                                               │
│  ├── sg-alb: Inbound 80, 443 from 0.0.0.0/0                   │
│  ├── sg-app: Inbound from sg-alb only                          │
│  ├── sg-db:  Inbound 5432 from sg-app only                    │
│  ├── sg-redis: Inbound 6379 from sg-app only                  │
│  └── sg-es:  Inbound 9200 from sg-app only                    │
└─────────────────────────────────────────────────────────────────┘

7.3 Multi-AZ Deployment

ComponentAZ-aAZ-bFailover
ALBAutomatic
ECS Tasks✅ (min 1)✅ (min 1)Automatic (ECS scheduler)
RDS PrimaryAutomatic failover to standby
RDS StandbyPromoted automatically
RDS Read ReplicaManual promotion if needed
Redis Node 1Automatic failover
Redis Node 2Promoted automatically
NAT GatewayRedundant

8. Bảo mật

8.1 Security Architecture Layers

┌──────────────────────────────────────────────┐
│  Layer 1: Edge Security                      │
│  ├── CloudFront (DDoS L3/L4)                │
│  ├── AWS WAF (OWASP rules, rate limiting)    │
│  └── AWS Shield Standard                     │
├──────────────────────────────────────────────┤
│  Layer 2: Network Security                   │
│  ├── VPC with private subnets                │
│  ├── Security Groups (least privilege)       │
│  ├── NACLs                                   │
│  └── No public IP on app/data instances      │
├──────────────────────────────────────────────┤
│  Layer 3: Application Security               │
│  ├── JWT authentication                      │
│  ├── RBAC authorization                      │
│  ├── Input validation (class-validator)       │
│  ├── SQL injection prevention (TypeORM)       │
│  ├── XSS prevention (React auto-escape)      │
│  ├── CSRF protection (SameSite cookies)       │
│  ├── Rate limiting (per IP, per user)         │
│  └── Helmet.js (security headers)            │
├──────────────────────────────────────────────┤
│  Layer 4: Data Security                      │
│  ├── Encryption at rest (AES-256, RDS)       │
│  ├── Encryption in transit (TLS 1.3)         │
│  ├── Password hashing (bcrypt, cost=12)      │
│  ├── PII masking in logs                     │
│  ├── Secrets Manager (no hardcoded secrets)  │
│  └── Database audit logging                  │
├──────────────────────────────────────────────┤
│  Layer 5: Operational Security               │
│  ├── IAM roles (least privilege)             │
│  ├── MFA for AWS console                     │
│  ├── Container image scanning (ECR)          │
│  ├── Dependency vulnerability scanning       │
│  └── Security monitoring (CloudTrail)        │
└──────────────────────────────────────────────┘

8.2 OWASP Top 10 Mitigation

#Lỗ hổngBiện pháp
A01Broken Access ControlRBAC, resource-level authorization checks, JWT validation
A02Cryptographic FailuresTLS 1.3, AES-256 at-rest, bcrypt passwords, no sensitive data in URL
A03InjectionTypeORM parameterized queries, class-validator input validation
A04Insecure DesignThreat modeling, security review in PR process
A05Security MisconfigurationInfrastructure as Code, security headers (Helmet), disable debug in production
A06Vulnerable ComponentsDependabot, npm audit in CI, container scanning
A07Auth FailuresRate limiting login, account lockout, secure password policy, OTP
A08Data Integrity FailuresHMAC verification for payment callbacks, signed URLs for S3
A09Logging FailuresStructured logging, PII masking, audit trail for admin actions
A10SSRFAllowlist for outbound requests, no user-controlled URLs in server requests

8.3 Tuân thủ pháp lý

Quy địnhYêu cầuImplementation
Nghị định 13/2023/NĐ-CP (Bảo vệ DLCN)Xin đồng ý trước khi thu thập PII, quyền xóa dữ liệu, thông báo khi rò rỉConsent popup, API xóa tài khoản, Incident response plan
Nghị định 52/2013/NĐ-CP (TMĐT)Đăng ký website TMĐT, hiển thị thông tin DN, chính sách rõ ràngĐăng ký online.gov.vn, trang "Giới thiệu", các trang chính sách
PCI-DSSKhông lưu thông tin thẻ, sử dụng cổng thanh toán certifiedRedirect to VNPAY/MoMo, no card data touches our server

9. Hiệu năng và Khả năng mở rộng

9.1 Caching Strategy

LayerCông nghệCache TargetTTLInvalidation
CDNCloudFrontStatic assets (JS, CSS, images, fonts)30 ngàyDeploy invalidation
CDNCloudFrontSSG/ISR pages15-60 phútISR revalidation
ApplicationRedisProduct catalog (list, detail)15 phútOn product update
ApplicationRedisCategory tree1 giờOn category update
ApplicationRedisSearch results (top queries)10 phútOn product index
ApplicationRedisUser session30 phút (idle)On logout
ApplicationRedisShopping cart30 ngàyOn cart update
ApplicationRedisOTP codes5 phútOne-time use
ApplicationRedisRate limit counters1 phútAuto-expire
DatabasePostgreSQLQuery plan cacheAutoAuto
BrowserService WorkerShell + critical assetsUntil updateSW update

9.2 Performance Budget

MetricTargetĐo bằng
FCP (First Contentful Paint)≤ 1.5sLighthouse, Web Vitals
LCP (Largest Contentful Paint)≤ 2.5sLighthouse, Web Vitals
CLS (Cumulative Layout Shift)≤ 0.1Lighthouse, Web Vitals
INP (Interaction to Next Paint)≤ 200msWeb Vitals
TTFB (Time to First Byte)≤ 500msLighthouse
JS Bundle (initial)≤ 150KB gzippedWebpack Analyzer
Total page weight (homepage)≤ 1.5MBNetwork tab
API response (P95)≤ 500msApplication monitoring
Search response (P95)≤ 300msApplication monitoring
Image load (above fold)≤ 1sWeb Vitals

9.3 Auto-scaling Configuration

ComponentMetricScale OutScale InMinMax
Frontend ECSCPU > 70% (3 min)+2 tasksCPU < 30% (10 min), -1 task26
Backend ECSCPU > 60% (3 min)+2 tasksCPU < 25% (10 min), -1 task28
Worker ECSSQS queue depth > 100+1 taskQueue depth = 0 (5 min), -1 task14
RDS Read ReplicaThêm replica khi cầnManualManual13

Flash Sale scaling plan:

  • T-24h: Scale Backend lên 6 tasks, Redis lên r6g.xlarge.
  • T-1h: Scale Backend lên 8 tasks, pre-warm cache cho SP flash sale.
  • T+0: Monitor realtime, sẵn sàng manual scale nếu cần.
  • T+2h: Bắt đầu scale down nếu traffic giảm.

10. Giám sát và Vận hành

10.1 Monitoring Stack

┌──────────────────────────────────────────────┐
│              OBSERVABILITY STACK              │
│                                              │
│  ┌────────────────┐  ┌────────────────────┐  │
│  │   Metrics      │  │   Logs             │  │
│  │                │  │                    │  │
│  │ CloudWatch     │  │ CloudWatch Logs    │  │
│  │ Metrics        │  │ + Log Insights     │  │
│  │                │  │                    │  │
│  │ Custom:        │  │ Structured JSON:   │  │
│  │ - Order count  │  │ - Request logs     │  │
│  │ - Revenue      │  │ - Error logs       │  │
│  │ - Cart abandon │  │ - Audit logs       │  │
│  │ - API latency  │  │ - Business events  │  │
│  └───────┬────────┘  └────────┬───────────┘  │
│          │                    │               │
│          ▼                    ▼               │
│  ┌──────────────────────────────────────────┐│
│  │        CloudWatch Dashboards              ││
│  │        + Alarms + SNS Notifications       ││
│  └──────────────────────────────────────────┘│
│                                              │
│  ┌────────────────┐  ┌────────────────────┐  │
│  │   Errors       │  │   Uptime           │  │
│  │                │  │                    │  │
│  │ Sentry         │  │ AWS Synthetics     │  │
│  │ (Error track)  │  │ (Canary checks)    │  │
│  └────────────────┘  └────────────────────┘  │
└──────────────────────────────────────────────┘

10.2 Alerting Rules

AlertĐiều kiệnSeverityThông báoHành động
API Error Rate High5xx > 5% trong 5 phút🔴 CriticalSlack + SMS oncallInvestigate immediately
API Latency HighP95 > 2s trong 5 phút🟡 WarningSlackCheck slow queries, cache
CPU High> 85% trong 10 phút🟡 WarningSlackAuto-scale should handle
Memory High> 90% trong 5 phút🔴 CriticalSlack + SMSCheck memory leak, restart
DB Connection Pool> 80% used🟡 WarningSlackCheck connection leaks
DB Replication Lag> 10s🟡 WarningSlackCheck replica health
Disk Usage> 80%🟡 WarningSlackExtend volume / cleanup
Payment Failure Rate> 10% trong 15 phút🔴 CriticalSlack + SMS + Email POCheck payment gateway
Order Volume Drop< 50% so với cùng giờ hôm qua🟡 WarningSlackCheck if site is accessible
SSL Certificate Expiry< 30 ngày🟡 WarningEmailRenew (ACM auto-renew)
Health Check Failed3 consecutive failures🔴 CriticalSlack + SMSCheck service, ALB routing

10.3 On-call Rotation

TuầnPrimarySecondaryEscalation
ChẵnBackend Engineer 1DevOps EngineerCTO
LẻBackend Engineer 2DevOps EngineerCTO

SLA phản hồi:

SeverityThời gian phản hồiThời gian xử lý
🔴 Critical (site down, payment broken)15 phút1 giờ
🟡 Warning (degraded performance)30 phút4 giờ
🟢 Info (non-urgent)Next business day1 tuần

11. Disaster Recovery

11.1 Backup Strategy

ComponentPhương thứcTần suấtRetentionVị trí
RDS PostgreSQLAutomated snapshotHàng ngày (02:00 UTC+7)30 ngàySame region (ap-southeast-1)
RDS PostgreSQLManual snapshotTrước mỗi deployment90 ngàyCross-region (ap-northeast-1)
RedisRDB snapshotMỗi 6 giờ7 ngàyS3
S3 (Product images)Cross-region replicationRealtimeIndefiniteap-northeast-1
ElasticsearchIndex snapshotHàng ngày14 ngàyS3
Application codeGit repositoryEvery commitIndefiniteGitHub
InfrastructureTerraform stateEvery applyVersionedS3 + DynamoDB lock

11.2 Recovery Procedures

Kịch bảnRPORTOQuy trình
Single AZ failure0 (Multi-AZ)< 5 phútAutomatic failover (RDS, Redis, ECS)
Database corruption≤ 24 giờ≤ 2 giờRestore từ RDS snapshot gần nhất
Application bug (bad deploy)0≤ 15 phútRollback ECS task definition to previous version
Region failure≤ 1 giờ≤ 4 giờDeploy to backup region (ap-northeast-1) từ Terraform + DB snapshot
Data breachN/A≤ 1 giờKích hoạt Incident Response Plan, revoke tokens, notify users

11.3 Disaster Recovery Test

TestTần suấtScope
Backup restore testHàng thángRestore RDS snapshot to test instance, verify data
Failover drillHàng quýForce RDS failover, verify app reconnection
Full DR drill6 tháng/lầnSimulate region failure, deploy to backup region

12. CI/CD Pipeline

12.1 Pipeline Architecture

┌─────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│  Code   │───>│  Build   │───>│  Test    │───>│  Deploy  │───>│  Verify  │
│  Push   │    │  & Lint  │    │  & Scan  │    │  Stage   │    │  & Ship  │
└─────────┘    └──────────┘    └──────────┘    └──────────┘    └──────────┘
     │              │               │               │               │
     │         ┌────┴────┐    ┌────┴────┐    ┌────┴────┐    ┌────┴────┐
     │         │TypeScript│    │Unit Test│    │ Deploy  │    │ Smoke   │
     │         │ compile  │    │ (Jest)  │    │ Staging │    │ Tests   │
     │         │         │    │         │    │         │    │         │
     │         │ESLint   │    │Int Test │    │ Manual  │    │ Health  │
     │         │Prettier │    │(Supertest│   │ QA      │    │ Check   │
     │         │         │    │         │    │ Sign-off│    │         │
     │         │Docker   │    │Security │    │         │    │ Deploy  │
     │         │ Build   │    │ Scan    │    │ Deploy  │    │ Prod    │
     │         │         │    │(Trivy,  │    │ Prod    │    │         │
     │         │Push ECR │    │ npm     │    │ (Blue/  │    │ Monitor │
     │         │         │    │ audit)  │    │  Green) │    │ 30 min  │
     │         └─────────┘    └─────────┘    └─────────┘    └─────────┘

     │         Triggers:
     ├── Push to main      → Build + Test + Deploy Staging (auto)
     ├── PR to main        → Build + Test (auto), no deploy
     ├── Tag v*            → Build + Test + Deploy Staging + Deploy Prod (manual approval)
     └── Hotfix branch     → Build + Test + Deploy Prod (manual approval)

12.2 Environment Strategy

EnvironmentBranchURLMục đíchAuto Deploy
Developmentdevelopdev.techvn.vnDevelopment testing
Stagingmainstaging.techvn.vnQA, UAT, demo
ProductionTag v*techvn.vnLiveManual approval

12.3 Deployment Strategy — Blue/Green

                    ALB

              ┌──────┴──────┐
              │              │
         ┌────▼────┐   ┌────▼────┐
         │  BLUE   │   │  GREEN  │
         │ (live)  │   │ (new)   │
         │         │   │         │
         │ v1.2.0  │   │ v1.3.0  │
         └─────────┘   └─────────┘

Step 1: Deploy new version to GREEN
Step 2: Run smoke tests against GREEN
Step 3: Switch ALB traffic to GREEN
Step 4: Monitor 30 minutes
Step 5: If OK → decommission BLUE
        If NOT OK → switch back to BLUE (rollback < 1 min)

13. Phụ lục

13.1 Technology Stack Summary

LayerCông nghệPhiên bảnLicense
FrontendNext.js15.xMIT
React19.xMIT
TypeScript5.xApache 2.0
Tailwind CSS4.xMIT
Zustand5.xMIT
React Query5.xMIT
BackendNestJS11.xMIT
Node.js20 LTSMIT
TypeORM0.3.xMIT
class-validator0.14.xMIT
Passport.js0.7.xMIT
Bull (job queue)5.xMIT
DatabasePostgreSQL16.xPostgreSQL License
CacheRedis7.xBSD
SearchOpenSearch (ES-compatible)2.xApache 2.0
InfrastructureDocker25.xApache 2.0
Terraform1.7.xMPL 2.0
GitHub ActionsN/AGitHub
MonitoringSentrySaaSPaid
CloudWatchAWSAWS pricing

13.2 Ước lượng tài nguyên theo giai đoạn

Giai đoạnTraffic (CCU)Backend InstancesDB InstanceRedisChi phí/tháng
Launch (T1-3)5002 × 1vCPU/2GBdb.r6g.largecache.r6g.large~$1.500
Growth (T4-12)2.0004 × 1vCPU/2GBdb.r6g.xlargecache.r6g.xlarge~$2.500
Scale (T13-24)5.0006 × 2vCPU/4GBdb.r6g.2xlarge + replicacache.r6g.xlarge cluster~$4.500
Flash Sale (peak)20.0008 × 2vCPU/4GB+ 2 read replicas+ Redis replica~$7.000 (temporary)

13.3 Tài liệu liên quan

TênQuan hệ
BRD-TECHVN-2026-001Business Requirements DocumentYêu cầu kinh doanh
PRD-TECHVN-2026-001Product Requirements DocumentYêu cầu sản phẩm
SRS-TECHVN-ECOM-2026-001Software Requirements SpecificationYêu cầu phần mềm chi tiết
IEEE 42010:2011Systems and Software Engineering — Architecture DescriptionTiêu chuẩn tham chiếu

13.4 Glossary kỹ thuật

Thuật ngữĐịnh nghĩa
SSRServer-Side Rendering — render HTML trên server mỗi request
SSGStatic Site Generation — pre-render HTML tại build time
ISRIncremental Static Regeneration — SSG + revalidation theo thời gian
CSRClient-Side Rendering — render trên browser bằng JavaScript
ALBApplication Load Balancer — phân phối traffic đến app instances
ECS FargateAWS Elastic Container Service (serverless) — chạy container không cần quản lý server
Multi-AZMulti-Availability Zone — triển khai trên nhiều data center cùng region
Blue/GreenChiến lược deploy với 2 môi trường song song, chuyển traffic zero-downtime
RBACRole-Based Access Control — phân quyền dựa trên vai trò
DLQDead Letter Queue — hàng đợi lưu message xử lý thất bại

Ghi chú: Tài liệu kiến trúc này là cơ sở cho quá trình phát triển và vận hành hệ thống. Mọi thay đổi kiến trúc đáng kể cần được ghi nhận dưới dạng ADR (Architecture Decision Record) và được CTO phê duyệt trước khi triển khai. Các thông số cấu hình cụ thể (instance size, threshold...) sẽ được fine-tune dựa trên dữ liệu thực tế sau go-live.

Last updated: