Tech stack đằng sau 8 sản phẩm logistics — cách WOKA ship nhanh và giữ maintainability

Ship và maintain 8 sản phẩm SaaS logistics với đội 6 dev — lựa chọn stack, hạ tầng dùng chung, pipeline deploy, và những đánh đổi giữ cho team đỡ gãy.

Woka vận hành 8 sản phẩm SaaS logistics — vận tải đường bộ, mua hộ, vận tải đường sắt, giao chặng cuối, giao nhận quốc tế (freight forwarding), phát triển website, tự động hóa AI và quản lý fulfilment. Các sản phẩm đều đang chạy thật, phục vụ khách tại Việt Nam và Đông Nam Á.

Đội kỹ thuật gồm 6 người (3 backend, 2 frontend, 1 DevOps). Làm sao duy trì 8 sản phẩm mà không kiệt sức? Hạ tầng dùng chung, tái sử dụng mã triệt để và chọn stack có chủ đích.

Triết lý cốt lõi: Xây cơ sở hạ tầng chung một lần, tái sử dụng trên tất cả sản phẩm. 40% codebase của WOKA là component, service, và schema chung.

Tổng quan stack

Kiến trúc nền tảng Woka

Frontend

  • React 18 + Next.js 14 App Router — Mọi ứng dụng phía khách và bảng điều khiển nội bộ
  • React Native — App mobile tài xế (vận tải đường bộ, chặng cuối) và app scanner kho (fulfilment)
  • TypeScript — Strict mode enforced; không cho phép JS trong code mới
  • TanStack Query — Quản lý server state (thay Redux cho 90% use case)
  • Tailwind CSS — Utility-first styling; design token chung trên tất cả sản phẩm

Tại sao Next.js? Server-side rendering cho SEO và performance. Incremental static regeneration (ISR) cho trang sản phẩm và marketing content. API routes cho backend task đơn giản (form liên hệ, webhook).

Tại sao React Native thay Flutter? Đội WOKA biết TypeScript. Code sharing giữa web và mobile (shared types, API client, business logic) giảm duplication 40%.

Backend

  • NestJS (Node.js) — Tất cả HTTP API và business logic
  • Python + FastAPI — AI/ML service (dự báo nhu cầu, tối ưu tuyến, NLP chatbot)
  • PostgreSQL 16 — Database chính cho dữ liệu transactional
  • Redis 7 — Caching, session storage, pub/sub cho tính năng thời gian thực
  • Elasticsearch 8 — Search và analytics (tra đơn hàng, tra SKU, log aggregation)

Tại sao NestJS thay Express? Hỗ trợ TypeScript built-in, dependency injection, kiến trúc có cấu trúc (controller, service, repository). Dễ onboard developer mới và giữ consistency trên các sản phẩm.

Tại sao Python cho AI? Thư viện ML trưởng thành (PyTorch, scikit-learn, transformers). FastAPI đủ performant cho inference workload (p95 latency < 200ms).

Cơ sở hạ tầng

  • Docker + Kubernetes — Tất cả service containerized; K8s cho orchestration
  • Google Cloud Platform — GKE (Kubernetes), Cloud SQL (managed Postgres), Memorystore (managed Redis)
  • Cloudflare — CDN, DNS, DDoS protection, WAF
  • GitHub Actions — CI/CD pipeline (lint, test, build, deploy)

Tại sao Kubernetes? Horizontal scaling cho traffic spike (ví dụ giao hàng chặng cuối peak 6–8pm hàng ngày). Resource isolation giữa các sản phẩm (freight forwarding không ảnh hưởng performance vận tải đường bộ).

Tại sao GCP thay AWS? Độ trễ thấp hơn đến Việt Nam/Đông Nam Á (GCP Singapore region vs AWS Singapore). Giá đơn giản hơn cho managed service.

Giám sát và observability

  • Sentry — Error tracking và performance monitoring
  • Grafana + Prometheus — Metrics dashboard (request latency, error rate, resource usage)
  • Loki — Log aggregation và search
  • Uptime Robot — External uptime monitoring (cảnh báo qua Slack và email)

SLA target: 99.8% uptime per sản phẩm. Đạt 99.9% trung bình trong 12 tháng qua.

Chiến lược tái sử dụng code

1. Thư viện component chung

WOKA duy trì internal npm package (@woka/ui) với 50+ React component tái sử dụng:

  • Data table — Table sortable, filterable, paginated cho danh sách đơn, view tồn kho, roster tài xế
  • Form — Input field, select, date picker với validation (react-hook-form + zod)
  • Modal và drawer — UX nhất quán cho workflow create/edit
  • Chart — Recharts wrapper cho SLA dashboard, báo cáo doanh thu, analytics

Lợi ích: Rút thời gian build sản phẩm mới 30–40% — component table và form không build lại từ đầu, chỉ wire data + business rule riêng cho domain.

2. Backend service chung

Ba microservice phổ biến dùng trên tất cả sản phẩm:

  • Auth service — JWT-based authentication, role-based access control (RBAC), quản lý session
  • Notification service — Email (Nodemailer), SMS (Twilio), push notification (FCM), webhook
  • File storage service — S3-compatible object storage cho ảnh POD, chứng từ hải quan, danh sách đóng gói

Kiến trúc: Deploy như standalone service với REST API. Mỗi sản phẩm gọi những service này thay vì implement auth hoặc notification logic riêng.

Lợi ích: Security update (ví dụ thay đổi thuật toán hash password) lan toả đến tất cả sản phẩm bằng cách cập nhật một service.

3. Database schema chung

Entity phổ biến model một lần và tái sử dụng:

  • User — id, email, password_hash, role, created_at, updated_at
  • Organization — id, name, tax_id, address, subscription_tier
  • Order — id, org_id, status, created_at, items[], total_amount
  • Location — id, name, address, lat, lng, type (warehouse, hub, customer)

Mỗi sản phẩm mở rộng những base schema này với field riêng sản phẩm (ví dụ vận tải đường bộ thêm driver_idvehicle_id vào Order; fulfilment thêm sku_idbin_location).

Lợi ích: Data model nhất quán trên các sản phẩm làm cross-product reporting dễ hơn (ví dụ “Khách hàng này đặt bao nhiêu đơn trên tất cả sản phẩm tháng trước?”).

Kiến trúc triển khai

Mô hình multi-tenancy

Mỗi customer organization là một tenant. Dữ liệu logically isolated bằng foreign key org_id. Tất cả tenant chia sẻ cùng database và application server (không physically isolated như DB riêng per tenant).

Tại sao shared database?

  • Chi phí cơ sở hạ tầng thấp hơn (1 Postgres instance thay vì 100)
  • Dễ chạy aggregate query trên tenant cho analytics
  • Backup/restore đơn giản hơn (một backup job thay vì 100)

Bảo mật: Row-level security enforced trong application code (mọi query filter theo org_id). PostgreSQL row-level security (RLS) policy làm safety net.

Continuous deployment

Pipeline:

  1. Developer push đến GitHub (main branch)
  2. GitHub Actions chạy:
    • Lint (ESLint, Prettier)
    • Type check (TypeScript, strict mode)
    • Unit test (Jest)
    • Integration test (Supertest cho API, Playwright cho web)
  3. Nếu tất cả check pass, build Docker image và push đến Google Container Registry
  4. Trigger K8s rolling update (zero-downtime deployment)
  5. Smoke test production endpoint
  6. Nếu smoke test fail, tự rollback về version trước

Tần suất: 5–10 deploy mỗi ngày trên tất cả sản phẩm. Thay đổi nhỏ, incremental thay vì big-bang release.

Database migration

WOKA dùng Prisma cho quản lý schema và migration.

Migration workflow:

  1. Developer định nghĩa thay đổi schema trong schema.prisma (ví dụ thêm cột mới vào table orders)
  2. Chạy prisma migrate dev để tạo migration SQL
  3. Commit migration file vào Git
  4. CI pipeline chạy migration với staging database
  5. Manual QA trên staging
  6. Merge vào main → CI chạy migration với production database trong quá trình deployment

An toàn: Migration backward-compatible (không drop column hoặc rename table mà không có kế hoạch migration nhiều bước).

Tối ưu performance

1. Tối ưu database query

  • Indexing: Tất cả foreign key có index. Query phức tạp (tra đơn hàng, lookup tồn kho) có composite index.
  • Connection pooling: PgBouncer trước Postgres để giảm connection overhead (10,000 request/sec với 50 DB connection).
  • Read replica: Query báo cáo (dashboard, export) hit read replica; transactional write đi primary.

2. Chiến lược caching

  • Redis cho hot data: Session người dùng, lookup truy cập thường xuyên (chi tiết SKU, giá vận chuyển), vị trí GPS thời gian thực
  • CDN cho static asset: Hình ảnh, CSS, JS bundle cached at edge (Cloudflare)
  • API response caching: TanStack Query trên frontend cache API response 5 phút (giảm backend load 60%)

3. Xử lý background job

Task chạy lâu (tạo khai báo hải quan, tạo PDF hoá đơn, gửi email) được offload đến background worker.

Queue: BullMQ (Redis-backed job queue)
Worker: Node.js worker process; scale horizontally dựa trên queue depth

Ví dụ: Khi kho ship 200 đơn, hệ thống queue 200 “send tracking notification” job. 5 worker process xử lý song song (40 job mỗi cái). Tổng thời gian xử lý: 30 giây thay vì 5 phút nếu làm đồng bộ.

Bài học rút ra

1. Đừng over-engineer sớm

Sản phẩm đầu tiên của WOKA (Vận tải đường bộ) bắt đầu như monolith. WOKA trích xuất shared service (auth, notification) chỉ sau khi build sản phẩm thứ hai (Mua hộ) và thấy duplication.

Sai lầm: Cố xây kiến trúc microservice “hoàn hảo” từ ngày đầu sẽ làm WOKA chậm 3–6 tháng.

2. TypeScript everywhere tiết kiệm thời gian debug

Strict TypeScript bắt 70% bug tại compile time (type mismatch, null pointer error, thiếu field). Điều này giảm production incident ~50% so với JavaScript.

Đầu tư: Phát triển chậm hơn 10–15% (viết type, sửa type error) nhưng debug nhanh 3× — TypeScript bắt type mismatch tại compile, không đợi runtime trên production.

3. Monitoring không optional

WOKA ship sản phẩm đầu tiên không có structured logging. Khi bug xảy ra, không biết điều gì sai. Thêm Sentry + Loki sau là đau đớn (retrofit error handling, thêm context vào log).

Bài học: Setup monitoring và logging từ ngày đầu, ngay cả trước khách hàng đầu tiên.

4. Database migration cần kế hoạch rollback

WOKA có 2 production incident từ migration xấu (một thêm non-nullable column không có default value, crash app; một lock table 10 phút trong peak traffic).

Cách xử lý: Test migration trên copy của production data. Với table lớn (trên 10M row), dùng công cụ thay đổi schema online (pt-online-schema-change cho MySQL, pgroll cho Postgres).

Tiếp theo là gì

Ba sáng kiến kỹ thuật cho 2026:

  1. OpenTelemetry cho distributed tracing — Theo dõi request trên nhiều microservice (frontend → API gateway → NestJS → Python AI service → Postgres)
  2. Edge function cho tính năng thời gian thực — Di chuyển GPS tracking và tính tuyến gần người dùng hơn (Cloudflare Worker ở VN/Singapore)
  3. GraphQL API — Thay REST cho nhu cầu client phức tạp (ví dụ “fetch order + driver + vehicle + route trong một query”)

Nếu bạn đang xây phần mềm logistics và muốn trao đổi kinh nghiệm, liên hệ tại info@woka.io. Luôn vui khi chat với đồng nghiệp engineer.