1. Architecture
Social Tool Documentation
  • Tổng quan
  • Bussiness | Logic
    • Bussiness | Logic
  • Project
    • ADMIN
      • Tổng quan ADMIN
      • Architecture
        • System architecture
        • Code structure
      • Deployment
        • Local
        • Staging
        • Product
      • Hướng dẫn sử dụng
        • Đăng nhập
        • FAQ
        • Mạng xã hội
          • Tài khoản mạng xã hội
          • Nội dung bài viết & bình luận
          • Quản lý liên kết
          • Thư viện hình ảnh
          • Thu thập dữ liệu
        • Hệ thống
          • Quản lý proxy
        • Chiến dịch
          • Tạo & quản lý chiến dịch
          • Đăng nhập tài khoản
          • Check Proxy
          • Join Group
    • API
      • Tổng quan API
      • Architecture
        • System architecture
        • Database schema
        • Code structure
      • Deployment
        • Local
        • Staging
        • Product
      • API Interface
        • 🔑 Identity & Session
          • List users
          • Create user
          • Update info user
          • Update info user
          • List user departments
          • Delete user
          • List user's AI keys
          • Create AI key
          • Get user's active API key
          • Get supported services
          • Get supported AI models
          • Update AI key
          • Delete AI key
          • Get AI key by ID
          • List departments
          • Create department
          • Update department
          • Create department
          • Update department
          • Update department roles
          • Get department roles
          • Update department status
          • Delete department
          • List user sessions
          • Create user session
          • Delete user session
          • Get user sessions by user ID
          • Delete all user sessions
          • Update user session status
          • List user activity logs
          • Create user activity log
          • Get user activity logs
          • Delete user activity logs
          • User login
          • User registration
          • User logout
          • Logout from all devices
          • Refresh access token
          • Create api key
          • Reset password
          • Get current user
          • Get user roles
          • Create role
          • Update role
          • Update role
          • Update role
          • List user permission groups
          • Get user permission group by ID
          • Delete user permission group
          • Create user permission group
          • Update user permission group
          • Get all user permission groups with permissions
        • 🛰️ Proxy & Connectivity
          • List proxies
          • Create proxy
          • Create many proxies
          • Update proxy
          • Delete proxy
          • Get proxy by ID
          • Import proxies from CSV/Excel
          • Check expired proxies
          • Kiểm tra proxy (qua Campaign)
          • Xóa proxy
          • Cập nhật proxy
          • Proxy Group list
          • Create a Proxy Group
          • Get a Proxy Group by ID
          • Update a Proxy Group
          • Delete a Proxy Group
          • Delete a Proxy Group
          • List proxy providers
          • Create proxy provider
          • Update proxy provider
          • Delete proxy provider
          • Get proxy provider by ID
          • Import proxy packages from CSV
          • List proxy packages
          • Create proxy package
          • Update proxy package
          • Delete proxy package
          • Get proxy package by ID
          • Import proxy packages from CSV
        • 📱 Social Management
          • List socials
          • Create social
          • Update social
          • Delete social
          • Get social by ID
          • List social accounts
          • Create social account
          • Create social account
          • Get account tasks
          • Assign proxies to social account
          • Update social account
          • Delete social account
          • Get social account by ID
          • Join social account
          • Cancel social accounts
          • Cancel social accounts
          • Import social accounts from file
          • Get account usage statistics
          • Push cookies manually for specific accounts (via Campaign)
          • Đổi tên nhiều tài khoản (qua Campaign)
          • Đổi mật khẩu nhiều tài khoản (qua Campaign)
          • Đổi ảnh đại diện (qua Campaign)
          • Social Account Group list
          • Create a Social Account Group
          • Get a Social Account Group by ID
          • Create a Social Account Group
          • Delete a Social Account Group
          • List social pages
          • Create social page
          • Update social page
          • Delete social page
          • Get social page by ID
          • Batch update social page status
          • Batch delete social pages
          • Import social pages from file
          • Search social pages
          • Batch delete social pages
          • Social Page Group list
          • Create a Social Page Group
          • Get a Social Page Group by ID
          • Update a Social Page Group
          • Delete a Social Page Group
          • List social actions
          • Create social action
          • Update social type
          • Delete social action
          • Get social type by ID
          • List social pages
          • Create social content
          • Update social content
          • Delete social content
          • Get social content by ID
          • Batch delete social content
          • Import social accounts from file
          • Create a new social content group
          • Get paginated list of social content groups
          • Get social content group by ID
          • Update social content group
          • Soft delete social content group
          • Batch delete social content groups
          • Delete social content group
          • Get groups by social platform ID
          • Social Image list
          • Create a Social Image
          • Get a Social Image by ID
          • Update a Social Image
          • Delete a Social Image
          • Social Collect Data list
          • Create a Social Collect Data
          • Get a Social Collect Data by ID
        • 📁 Campaign Management
          • List campaigns
          • Create campaign
          • Update campaign
          • Delete campaign
          • Get campaign by ID
          • Create campaign platform
          • List campaign platforms
          • Update campaign platform
          • Delete campaign platform
          • Get campaign platform by ID
          • Create campaign platform
          • Create campaign platform
          • Clone campaign platforms
          • Cancel multiple campaign platforms
          • List campaign joins
          • Create campaign platform
          • List campaign joins
          • Update campaign platform
          • Update campaign platform
          • Update campaign platform
          • Update campaign platform
          • List jobs
          • Update job
          • Delete job
          • Get job by ID
          • List campaign platform tasks
          • Create campaign platform task
          • Update campaign platform task
          • Delete campaign platform task
          • Get campaign platform job task by ID
          • List Report Categories
          • Create Report Categories
          • Create Report Categories
          • Create Report Categories
          • List Report Details
          • Create Report Details
          • Create Report Details
          • Create Report Details
    • TOOL
      • Tổng quan TOOL
      • Architecture
        • Database schema
        • System architecture
        • Code structure
      • Deployment
        • Local
        • Staging
        • Product
      • API Interface
        • 🎯 NATS — Task
          • [NATS RPC] Tạo batch Task mới
          • [NATS RPC] Lấy danh sách tất cả Tasks
          • [NATS RPC] Đếm số Task đang chờ xử lý
          • [NATS RPC] Xóa tất cả Tasks
        • 🍪 NATS — Cookie
          • [NATS RPC] Thêm batch Cookie (Auto Login)
          • [NATS RPC] Lấy danh sách tất cả Cookies
          • [NATS RPC] Xóa tất cả Cookies
        • 🌐 NATS — Proxy
          • [NATS RPC] Gửi batch Proxy để kiểm tra
        • 🔗 NATS — TaskJoin
          • [NATS RPC] Tạo lệnh tham gia Group
          • [NATS RPC] Kiểm tra trạng thái tham gia Group
        • 📤 NATS — Callbacks
          • [NATS PUB] Kết quả thực thi Task
          • [NATS PUB] Kết quả Crawl dữ liệu
          • [NATS PUB] Kết quả Auto Login
          • [NATS PUB] Kết quả kiểm tra Proxy
          • [NATS PUB] Kết quả tham gia Group
          • [NATS PUB] Kết quả kiểm tra trạng thái tham gia
        • 📊 HTTP — Logs & Info
          • Service Root — Thông tin Worker
          • Health Check
          • Đọc file log
          • Log hôm nay
          • Log theo ngày cụ thể
          • Danh sách ngày có log
          • Test kết nối ChatGPT
        • 📋 HTTP — Data Query
          • Danh sách Tasks (phân trang + lọc)
          • Xóa tất cả Tasks
          • Danh sách tất cả Cookies
          • Xóa tất cả Cookies
          • Xóa Cookie theo _id
          • Danh sách Proxies (lọc theo task_id)
          • Xóa tất cả Proxies
          • Proxy Checks đang chờ xử lý
          • Proxy Checks đã hoàn thành
          • Xóa Proxy theo _id
          • Danh sách Task Join (phân trang + lọc)
          • Tạo Task Join (HTTP mode)
          • Xóa tất cả Task Join
  • Schemas
    • AIInfo
    • CommentInfo
    • ReplyInfo
    • ShareInfo
    • CaptchaInfo
    • PageInfo
    • SocialAccountInfo
    • ProxyInfo
    • SocialInfo
    • ActionInfo
    • CreateTaskPayload
    • CreateCookiePayload
    • CreateProxyPayload
    • CreateTaskJoinPayload
    • NatsAcceptedResponse
    • NatsRejectedResponse
    • NatsErrorResponse
    • TaskCompletedPayload
    • CookieUpdatePayload
    • ProxyCheckResultPayload
    • TaskJoinResultPayload
    • TaskJoinCheckResultPayload
    • PagingInfo
    • AppError
  1. Architecture

Code structure

Kiến trúc & Luồng Xử lý — Social Tool API#

Tài liệu kỹ thuật dành cho Developer tiếp nhận dự án
Phiên bản 1.0 — Cập nhật lần cuối: 2026

🧭 Giới thiệu tài liệu#

Tài liệu này mô tả toàn bộ kiến trúc, luồng xử lý và các quyết định thiết kế của Social Tool API — đủ để hiểu hệ thống hoạt động như thế nào, tại sao nó được xây dựng theo cách đó, và cần làm gì khi có vấn đề xảy ra.
Nội dung bao gồm: tổng quan hệ thống, cấu trúc thư mục, pipeline xử lý tác vụ 3 giai đoạn, ví dụ end-to-end, chi tiết các Cron Jobs, module phụ trợ, hướng dẫn debug và các quy ước cần tuân thủ.

1. Hệ thống này làm gì?#

Social Tool API là backend của một hệ thống tự động hóa tương tác mạng xã hội. Hệ thống cho phép:
Người dùng (qua Dashboard) tạo chiến dịch (campaign) — ví dụ: "Like 500 bài viết Facebook bằng 100 tài khoản".
Backend tự động phân rã chiến dịch thành hàng trăm/nghìn task nhỏ, rồi phân phối cho các Worker thực thi song song.
Worker ( Tool ) mở trình duyệt ẩn danh (headless), nạp cookie + proxy của từng tài khoản, thực hiện hành động (like, comment...), và báo kết quả về.
Backend tổng hợp kết quả, xử lý lỗi, và hiển thị báo cáo.
Điểm mấu chốt cần hiểu ngay: Đây là hệ thống bất đồng bộ hoàn toàn. API Server không trực tiếp điều khiển Worker — mọi giao tiếp đều qua NATS message queue. Điều này giúp scale Worker (Tool) dễ dàng nhưng cũng tạo ra một số phức tạp khi debug.

Các thành phần chính trong hệ thống#

#Thành phầnLoạiChức năng chínhTrigger / Tần suất
1CampaignJobAutomationServiceService + CronQuét chiến dịch active, phân rã thành các Task PENDINGMỗi 1 phút
2CampaignTaskProcessorServiceService + CronChuẩn bị payload (Cookie, Proxy, nội dung) và đẩy task lên NATSMỗi 30s – 2 phút
3NatsReceiverServiceNATS ListenerNhận kết quả từ Worker, cập nhật trạng thái Task, xử lý lỗiLiên tục (event-driven)
4accountAutoLoginCron JobPhát hiện tài khoản mất session, kích hoạt đăng nhập lạiMỗi 5 phút
5proxyExpirationCheckCron JobKiểm tra hạn proxy, cảnh báo sắp hết hạnMỗi 1 giờ
6campaignStatisticsCron JobTổng hợp số liệu Like/Comment vào báo cáoMỗi 5 phút
7cleanupLogsCron JobXóa log & task cũ, tối ưu dung lượng databaseHàng ngày
8controllers/HTTP LayerTiếp nhận request từ Frontend, validate đầu vào, gọi ServiceTheo HTTP request
9repositories/Data LayerTruy vấn và ghi dữ liệu vào MySQL thông qua Drizzle ORMĐược gọi bởi Service
10nats/MessagingĐóng gói và gửi lệnh tới Worker; lắng nghe kết quả trả vềEvent-driven (NATS)
11models/SchemaKhai báo cấu trúc bảng và quan hệ bằng Drizzle ORMBuild-time / Migration
12middleware/Cross-cuttingXác thực JWT, phân quyền, logging request/responseMỗi HTTP request
13errors/UtilityChuẩn hóa cấu trúc lỗi trả về clientKhi có exception
14utils/UtilityHàm dùng chung: xử lý Date, JSON, sinh Device ProfileĐược gọi khi cần
15types/TypeScriptKhai báo Interface & Type toàn cụcCompile-time

2. Kiến trúc tổng quan#

Hệ thống sử dụng mô hình Event-Driven + Service-Oriented Architecture (SOA). Thay vì Worker kết nối trực tiếp vào database, mọi giao tiếp giữa API Server và Worker đều đi qua NATS Messaging.
┌─────────────────────────────────────────────────────────┐
│                      API Server (Core)                  │
│                                                         │
│   /jobs ──────► /services ──────► /repositories        │
│   (Cron)        (Business Logic)   (DB Access)          │
│                      │                    │             │
│                  /nats                 MySQL DB          │
│                 (Message Handler)                       │
└──────────────────────┬──────────────────────────────────┘
                       │  NATS Messaging
          ┌────────────┼────────────┐
          ▼            ▼            ▼
       Worker 1     Worker 2    Worker N
Tại sao dùng NATS thay vì gọi thẳng?
Worker có thể nằm trên server khác, không nhất thiết cùng host với API.
NATS tự cân bằng tải: nếu có 10 Worker đang lắng nghe, NATS tự phân phối đều task — không cần API phải biết Worker nào đang rảnh.
Nếu một Worker crash, task sẽ được retry hoặc chuyển sang Worker khác mà không làm mất dữ liệu.

3. Cấu trúc thư mục /src#

src/
├── api/
│   ├── jobs/           ← Cron Jobs: gọi Service định kỳ theo lịch
│   ├── services/       ← Business Logic: xử lý nghiệp vụ chính
│   ├── repositories/   ← Data Access Layer: tất cả câu query MySQL đều ở đây
│   ├── nats/           ← Gửi message lên NATS, lắng nghe kết quả từ Worker
│   ├── models/         ← Định nghĩa schema bảng DB bằng Drizzle ORM
│   ├── controllers/    ← Nhận HTTP request từ Frontend, gọi Service tương ứng
│   ├── routes/         ← Khai báo REST API endpoints (URL mapping)
│   ├── middleware/      ← Auth JWT, logging, phân quyền — chạy trước mọi request
│   └── errors/         ← Class lỗi tùy chỉnh, format thông báo lỗi trả về client
├── utils/              ← Hàm tiện ích dùng chung (Date, JSON, tạo Device Profile...)
└── types/              ← TypeScript Interface & Type — không có logic, chỉ khai báo kiểu
Quy tắc phân tầng (quan trọng khi thêm tính năng mới):
HTTP Request
    │
    ▼
Controller  ← Chỉ validate input, không viết business logic ở đây
    │
    ▼
Service     ← Toàn bộ logic nghiệp vụ nằm ở đây
    │
    ├──► Repository  ← Chỉ query DB, không xử lý logic
    │
    └──► NATS Module ← Chỉ đóng gói và gửi message
⚠️ Lưu ý: Tuyệt đối không viết query SQL trực tiếp trong Controller hoặc Service. Mọi tương tác với DB phải đi qua repositories/. Điều này giúp dễ test và refactor sau này.

4. Pipeline thực thi tác vụ (3 Giai đoạn)#

Đây là phần quan trọng nhất cần hiểu. Khi người dùng tạo một chiến dịch, hệ thống xử lý qua 3 giai đoạn tuần tự, mỗi giai đoạn do một Cron Job hoặc Event Listener phụ trách.
[Giai đoạn 1]          [Giai đoạn 2]           [Giai đoạn 3]
 Lập lịch               Điều phối               Thực thi & Kết quả
 (Task Creation)  ───►  (Task Dispatch)  ───►   (Result Handling)

 CampaignJob            CampaignTask            NatsReceiver
 AutomationService      ProcessorService        Service
 (chạy mỗi 1 phút)     (chạy mỗi 30s–2p)      (event-driven, liên tục)

Giai đoạn 1 — Tạo chiến dịch tự động#

File chính: jobs/campaignJobAutomation.ts → gọi services/CampaignJobAutomationService.ts
Giai đoạn này làm gì?
Đọc từ bảng campaign_platforms những chiến dịch đang chờ (status=pending, is_tasks_created=false), sau đó phân rã mỗi chiến dịch thành nhiều task nhỏ trong bảng campaign_platform_tasks.
Ví dụ cụ thể:
Giả sử người dùng tạo chiến dịch: "Like 5 bài viết bằng 3 tài khoản". Service này sẽ tạo ra 5 × 3 = 15 task, mỗi task tương ứng với một cặp (tài khoản, bài viết). Mỗi task được gán thêm: proxy nào dùng, server nào xử lý, độ ưu tiên bao nhiêu.
Luồng xử lý chi tiết:
[Cron kích hoạt mỗi 1 phút]
        │
        ▼
Quét bảng campaigns
→ Lọc: active=true, start_date ≤ now()
        │
        ▼
Quét bảng campaign_platforms
→ Lọc: status='pending', is_tasks_created=false
        │
        ▼
Đọc metadata_json của từng platform
→ Giải nén ra: danh sách accounts[], danh sách target links[], nội dung comment mẫu
        │
        ▼
Vòng lặp: với mỗi (account × target_link)
→ INSERT một row vào bảng campaign_platform_tasks
→ Gán: action_type, proxy_id, server_id, priority, status='PENDING'
        │
        ▼
Cập nhật campaign_platforms:
→ status = 'running'
→ is_tasks_created = true
💡 Lưu ý debug: Nếu campaign không chạy, kiểm tra đầu tiên ở đây — xem is_tasks_created đã được set true chưa và status của platform có phải pending không.

Giai đoạn 2 — Phân phối task#

File chính: jobs/campaignTaskAutomation.ts → gọi services/CampaignTaskProcessorService.ts
Giai đoạn này làm gì?
Lấy các task đang ở trạng thái PENDING từ Giai đoạn 1, chuẩn bị đầy đủ payload (cookie, proxy, nội dung) rồi đẩy lên NATS để Worker nhận và thực thi.
Tại sao tách thành 2 giai đoạn thay vì làm 1 lần?
Giai đoạn 1 chỉ tạo các task cần thực thi. Giai đoạn 2 mới đi lấy dữ liệu nhạy cảm và nặng như cookie (có thể cần giải mã), proxy credentials, template nội dung — tránh lưu dữ liệu nhạy cảm vào DB không cần thiết, đồng thời tách biệt mối quan tâm (separation of concerns).
Luồng xử lý chi tiết:
[Cron kích hoạt mỗi 30s – 2 phút]
        │
        ▼
Lấy batch task từ campaign_platform_tasks
→ Lọc: status='PENDING', start_date ≤ now()
→ Giới hạn số lượng mỗi lần để tránh quá tải
        │
        ▼
Với mỗi task, chuẩn bị payload:

  ┌── Tài khoản (từ bảng accounts):
  │   - Cookie string (đã giải mã nếu cần)
  │   - User-Agent header
  │   - Device viewport size
  │
  ├── Proxy (từ bảng proxies):
  │   - IP:Port
  │   - Username/Password
  │   - Protocol (http/socks5)
  │
  └── Nội dung:
      - URL bài viết cần thao tác
      - Template comment (nếu là action COMMENT)
      - Các tham số hành động khác
        │
        ▼
Đóng gói thành một Payload object
Publish lên NATS subject: "task.request.create"
        │
        ▼
NATS tự động điều phối tới Worker đang idle
(API không cần biết Worker nào nhận)
⚠️ Điểm dễ gây lỗi: Nếu cookie hoặc proxy bị thiếu/null, task sẽ bị skip hoặc gửi payload không đầy đủ. Luôn kiểm tra nullable checks trong CampaignTaskProcessorService khi debug task bị stuck ở PENDING.

Giai đoạn 3 — Thực thi & Nhận kết quả#

File chính: nats/NatsReceiverService.ts
Giai đoạn này làm gì?
Đây là listener chạy liên tục, không phải Cron. Service này lắng nghe 2 NATS subjects:
task.completed — Worker báo thành công
task.failed — Worker báo thất bại (kèm lý do)
Và xử lý tương ứng.
Luồng xử lý chi tiết — Trường hợp THÀNH CÔNG:
Worker gửi kết quả lên "task.completed"
        │
        ▼
NatsReceiverService nhận message
        │
        ▼
Cập nhật campaign_platform_tasks:
→ status = 'COMPLETED'
→ Lưu result_data (link bài đã like, timestamp...)
        │
        ▼
Tăng counter thống kê cho campaign
Luồng xử lý chi tiết — Trường hợp THẤT BẠI:
Worker gửi kết quả lên "task.failed" (kèm error_code)
        │
        ▼
Cập nhật campaign_platform_tasks:
→ status = 'FAILED'
→ Lưu error_reason
        │
        ▼
Kiểm tra nguyên nhân lỗi:

  ├── error_code = COOKIE_EXPIRED
  │     → Đánh dấu account: session_status = 'expired'
  │     → Tìm account dự phòng trong cùng chiến dịch
  │     → Tạo task mới với account thay thế (nếu có)
  │
  ├── error_code = PROXY_ERROR
  │     → Đánh dấu proxy: is_available = false
  │     → Log lý do để admin kiểm tra
  │
  └── Lỗi khác (network timeout, captcha, v.v.)
        → Ghi log chi tiết
        → Tùy config: retry hoặc bỏ qua
💡 Khi một account bị expired: Hệ thống không đơn giản là bỏ task đó — nó sẽ cố gắng điều chuyển sang account dự phòng nếu còn. Logic này nằm trong NatsReceiverService, tìm hàm xử lý COOKIE_EXPIRED.

5. Ví dụ end-to-end: Chiến dịch Like bài viết#

Dưới đây là toàn bộ hành trình từ lúc người dùng bấm "Tạo chiến dịch" đến khi nhìn thấy kết quả:
[Người dùng Dashboard]
        │
        │  POST /api/campaigns  (HTTP)
        ▼
[Controller]
→ Validate request body
→ Gọi CampaignService.create()
        │
        ▼
[CampaignService]
→ INSERT vào bảng campaigns
→ INSERT vào bảng campaign_platforms
→ Lưu metadata_json (accounts[], target_links[], content_template)
        │
        │  (Đợi tối đa 1 phút...)
        ▼
[Cron: campaignJobAutomation]
→ Phát hiện platform mới với is_tasks_created=false
→ Đọc metadata_json
→ Tạo 100 task PENDING (100 accounts × 1 link mỗi)
→ SET is_tasks_created=true
        │
        │  (Đợi tối đa 30 giây...)
        ▼
[Cron: campaignTaskAutomation]
→ Lấy batch 50 task PENDING đầu tiên
→ Với mỗi task: lấy cookie + proxy
→ Đẩy 50 payload lên NATS subject "task.request.create"
        │
        ▼
[NATS]
→ Load balancing: phân phối đều cho các Worker đang idle
        │
        ├──► Worker 1 nhận 17 task
        ├──► Worker 2 nhận 17 task
        └──► Worker 3 nhận 16 task
        │
        ▼  (Song song, mỗi Worker...)
[Tool]
→ Nhận payload từ NATS
→ Khởi tạo Puppeteer/Playwright session
→ Nạp cookie vào browser
→ Route traffic qua proxy
→ Mở URL bài viết
→ Click nút Like
→ Verify like thành công
→ Publish "task.completed" lên NATS
        │
        ▼
[NatsReceiverService]
→ Nhận "task.completed"
→ UPDATE campaign_platform_tasks SET status='COMPLETED'
→ Lưu timestamp thành công
        │
        │  (Mỗi 5 phút...)
        ▼
[Cron: campaignStatistics]
→ Đếm số task COMPLETED trong mỗi chiến dịch
→ Cập nhật bảng thống kê
→ Dashboard hiển thị: "87/100 Likes thành công"
Timeline thực tế (trường hợp lý tưởng):
Thời điểmSự kiện
T+0sNgười dùng tạo chiến dịch
T+60sCron tạo xong 100 task PENDING
T+90sCron đẩy batch đầu lên NATS
T+95sWorker bắt đầu thực thi
T+5–10 phútPhần lớn task hoàn thành
T+15 phútThống kê cập nhật trên Dashboard

6. Danh sách Cron Jobs — Chi tiết#

campaignJobAutomation — Chạy mỗi 1 phút#

Đây là "bộ não điều phối" đầu vào. Nếu cron này ngừng hoạt động, mọi chiến dịch mới sẽ không bao giờ được khởi động (task không được tạo).
Kiểm tra hoạt động: Xem log, tìm dòng [campaignJobAutomation] Scanned X campaigns — nếu không thấy log trong > 2 phút thì có vấn đề.

campaignTaskAutomation — Chạy mỗi 30 giây đến 2 phút#

Tần suất chạy có thể thay đổi tùy config. Đây là nơi điều tiết throughput của hệ thống — số lượng task được đẩy vào NATS mỗi lần chạy quyết định tốc độ xử lý tổng thể.
Kiểm tra hoạt động: Nếu task bị stuck ở PENDING quá lâu (> 5 phút), kiểm tra cron này trước.

accountAutoLogin — Chạy mỗi 5 phút#

Quét các tài khoản có session_status='expired', kích hoạt luồng đăng nhập lại tự động (thường là gửi yêu cầu login qua Worker). Sau khi login thành công, cập nhật cookie mới vào DB.
Lưu ý: Không phải account nào cũng có thể tự login lại — một số nền tảng yêu cầu 2FA. Với những account đó, cron sẽ gửi thông báo cần xử lý thủ công.

proxyExpirationCheck — Chạy mỗi 1 giờ#

So sánh proxy.expiry_date với thời gian hiện tại. Nếu proxy hết hạn trong vòng X ngày (cấu hình được), gửi cảnh báo. Nếu đã hết hạn, đánh dấu is_active=false và loại khỏi pool.
Tại sao quan trọng: Proxy hết hạn mà không biết sẽ dẫn đến hàng loạt task failed với lý do PROXY_ERROR.

campaignStatistics — Chạy mỗi 5 phút#

Aggregate data từ campaign_platform_tasks, đếm số task COMPLETED/FAILED, ghi vào bảng thống kê để Frontend hiển thị. Đây là cron "chậm nhất" được phép — không ảnh hưởng đến việc thực thi, chỉ ảnh hưởng đến độ trễ của báo cáo.

cleanupLogs — Chạy hàng ngày (thường lúc 3–4 giờ sáng)#

Xóa các record cũ hơn N ngày (cấu hình được) trong các bảng log và task history. Không xóa campaign hay account. Mục đích: giữ database không phình to vô hạn.
⚠️ Cẩn thận khi điều chỉnh: Nếu giảm retention period quá thấp, dữ liệu thống kê lịch sử sẽ bị xóa trước khi cần dùng.

7. Các module phụ trợ — Vai trò và quy tắc sử dụng#

controllers/#

Tầng tiếp nhận HTTP request. Quy tắc: Controller chỉ được làm 3 việc: (1) validate input, (2) gọi Service, (3) format response trả về. Không có business logic ở đây.

routes/#

Khai báo endpoint URL và ánh xạ tới Controller tương ứng. Khi thêm API mới, bắt đầu từ đây để đăng ký route trước.

middleware/#

Chạy trước mọi request. Gồm:
Auth: Verify JWT token, lấy thông tin user hiện tại
Permission: Kiểm tra user có quyền thực hiện action không
Logger: Ghi log request/response để debug

errors/#

Định nghĩa các class lỗi tùy chỉnh (ví dụ: CampaignNotFoundException, ProxyUnavailableError). Mọi lỗi đều được format về cùng một cấu trúc JSON trước khi trả về client.
Cấu trúc lỗi chuẩn:
{
  "success": false,
  "error": {
    "code": "CAMPAIGN_NOT_FOUND",
    "message": "Chiến dịch không tồn tại hoặc đã bị xóa",
    "details": {}
  }
}

utils/#

Hàm tiện ích không gắn với nghiệp vụ cụ thể nào:
Date utils: Format, parse, tính khoảng cách thời gian
JSON utils: Safe parse (không throw exception khi JSON lỗi)
Device Profile generator: Sinh ngẫu nhiên User-Agent và viewport size thực tế — dùng khi tạo task để Worker giả lập thiết bị thật

types/#

Chỉ chứa TypeScript Interface và Type. Không có logic, không có import từ các module khác.

8. Hướng dẫn debug nhanh#

Task bị stuck ở trạng thái PENDING mãi không chạy#

1.
Kiểm tra log campaignTaskAutomation — cron có đang chạy không?
2.
Kiểm tra task đó có start_date ≤ now() không?
3.
Kiểm tra account và proxy của task đó có is_active=true không?
4.
Kiểm tra NATS connection — server có up không?

Nhiều task đột ngột failed cùng lúc#

1.
Nếu error là PROXY_ERROR: kiểm tra proxy đó còn hoạt động không, có thể hết hạn.
2.
Nếu error là COOKIE_EXPIRED: batch account bị logout đồng loạt — cần trigger login lại hoặc import cookie mới.
3.
Nếu error là network/timeout: kiểm tra Worker server — có thể tắt hoặc bị giới hạn băng thông.

Dashboard không cập nhật số liệu chiến dịch#

Kiểm tra cron campaignStatistics — nếu cron đang lỗi, số liệu sẽ không được cập nhật dù task vẫn chạy bình thường.

Chiến dịch không khởi động sau khi tạo#

1.
Kiểm tra campaign_platforms.status — có phải pending không?
2.
Kiểm tra campaign_platforms.is_tasks_created — nếu đã là true nhưng không có task thì có bug trong Giai đoạn 1.
3.
Kiểm tra log campaignJobAutomation — cron có đang chạy không?

9. Những điều KHÔNG nên làm#

Không query DB trực tiếp trong Controller hoặc Service — luôn đi qua Repository.
Không lưu cookie hoặc thông tin nhạy cảm dưới dạng plain text — dùng encryption.
Không tăng batch size của campaignTaskAutomation quá lớn — có thể làm nghẽn NATS và Worker không kịp xử lý.
Không bỏ qua phần xử lý lỗi trong NatsReceiverService — một message xử lý lỗi có thể kéo theo việc retry hàng trăm task.
Không chỉnh cleanupLogs retention quá thấp (dưới 7 ngày) trong môi trường production — dữ liệu thống kê lịch sử sẽ bị mất.

Tài liệu được cập nhật lần cuối: 2026. Mọi thắc mắc vui lòng liên hệ đội ngũ kỹ thuật.
Modified at 2026-03-30 10:16:52
Previous
Database schema
Next
Local
Built with