---
title: "TaxPal — Dashboard sales cho môi giới kế toán — Tran Manh Tuan"
description: "Dashboard phân tích sales cho nền tảng môi giới dịch vụ kế toán tại Nhật: case, KPI target so với actual, xếp hạng và tỷ lệ chuyển đổi theo nhân viên, team và công ty."
canonical: "https://tmtuan.dev/vi/projects/taxpal"
language: "vi"
image: "https://tmtuan.dev/_img/projects/taxpal/taxpal.ac7aeb13-og.jpg"
tokens: 5144
---

# TaxPal

**TaxPal** là nền tảng môi giới dịch vụ kế toán tại Nhật Bản, kết nối ba phía: khách hàng cần kế toán viên hoặc chuyên gia, đội sales / môi giới tiếp nhận và theo đến cùng từng yêu cầu, và kế toán viên / chuyên gia cung cấp dịch vụ. Mỗi phía có khu vực riêng trong sản phẩm, nhưng cùng dùng chung dữ liệu company, case và lịch sử cung cấp dịch vụ.

Năm 2022, tôi là **Tech Lead** của team tại Việt Nam và điều phối phía Việt Nam trong giai đoạn phát triển chính. Phạm vi của team là **Sales Dashboard**: hệ thống analytics nội bộ mà đội môi giới và quản lý dùng để theo dõi case, KPI, hiệu suất sales và tỷ lệ chuyển đổi — theo từng nhân viên, từng team và toàn công ty.

> **Vì sao đây là dự án hệ thống quản lý:** phần khó chưa bao giờ là vẽ biểu đồ, mà là quyết định một con số có nghĩa là gì — case nào được đếm, theo ngày làm việc nào, trong kỳ quyết toán nào, với nhân viên đã nghỉ thì sao — rồi trả những con số đó về thật nhanh. Đây cũng là dự án brownfield: xây dashboard mới trên codebase AWS có sẵn, cùng GraphQL resolver, database, authentication và quy trình release của hệ thống cũ.

## Nền tảng và người dùng

Khách hàng mang nhu cầu tới. Đội sales / môi giới biến nhu cầu đó thành case, follow và đưa case tới hợp đồng; quản lý theo dõi hiệu suất của từng người, từng team và toàn công ty. Kế toán viên / chuyên gia nhận các case tới lượt mình và có dashboard riêng.

```mermaid
flowchart LR
    accTitle: Hệ sinh thái TaxPal
    accDescr: Khách hàng cần dịch vụ đi vào khu vực khách hàng, nơi tạo ra dữ liệu company, customer và case. Case được chuyển tới đội Sales / môi giới làm việc trong khu vực Sales; khu vực này cập nhật lại case và dẫn tới Sales Dashboard. Case cũng được chuyển tới kế toán viên / chuyên gia, những người dùng khu vực Accountant / Expert và Expert Dashboard.

    CUSTOMER["Khách hàng cần dịch vụ"]
    SALES["Đội Sales / môi giới"]
    EXPERT["Kế toán viên / Chuyên gia"]

    CUSTOMER_PORTAL["Khu vực khách hàng"]
    SALES_PORTAL["Khu vực Sales / môi giới"]
    EXPERT_PORTAL["Khu vực Accountant / Expert"]

    CASE["Company / Customer / Case"]
    DASH["Sales Dashboard"]
    EXPERT_DASH["Expert Dashboard"]

    CUSTOMER --> CUSTOMER_PORTAL
    CUSTOMER_PORTAL --> CASE

    CASE --> SALES
    SALES --> SALES_PORTAL

    SALES_PORTAL --> CASE
    SALES_PORTAL --> DASH

    CASE --> EXPERT
    EXPERT --> EXPERT_PORTAL
    EXPERT_PORTAL --> EXPERT_DASH
```

_Ba nhóm người dùng, một bộ dữ liệu company và case dùng chung. Sales Dashboard nằm ở phía môi giới của sản phẩm._

## Vai trò của tôi

- Theo dõi và kiểm soát tiến độ kỹ thuật, schedule và workload của team theo từng menu / milestone.
- Điều phối giữa Backend, Frontend và IT Communicator; làm việc định kỳ với khách hàng Nhật Bản.
- Phân tích yêu cầu nghiệp vụ thành thiết kế kỹ thuật; breakdown task và estimate.
- Review API design và pull request.
- Hỗ trợ xử lý các vấn đề khó về GraphQL, Prisma, database và integration; điều phối sửa bug giữa FE và BE.
- Đánh giá rủi ro ảnh hưởng tiến độ, làm rõ với khách hàng các điểm chưa rõ trong tài liệu nghiệp vụ.
- Quản lý bàn giao và release theo quy trình repository của khách hàng; tổng hợp tình trạng, issue, nguyên nhân và phương án xử lý để báo cáo.

## Từ yêu cầu tới hợp đồng: pipeline của case

Mỗi nhu cầu của khách hàng là một **case**, gắn với dữ liệu company — dữ liệu master mà lịch hẹn, tiến độ và hợp đồng đều liên kết vào. Saler có thể được chỉ định thủ công — hệ thống không ép tổ chức theo một thuật toán auto-assign cứng. Từ đó case đi qua nhiều trạng thái sales: khả năng cao lấy được lịch hẹn, đang có vấn đề cần giải quyết, khó hoặc không khả thi, đang liên hệ nhưng chưa kết nối được, đã xác nhận hoặc bị cancel lịch hẹn, đang follow, đã lên hợp đồng, đã lên hợp đồng kế toán, tạm dừng, hủy hợp đồng, hủy khi renew. Ở phiên bản nghiệp vụ được mô tả, saler tự chọn status trên màn hình case thay vì một state machine tự động hoàn toàn.

```mermaid
flowchart TD
    accTitle: Luồng xử lý một case
    accDescr: Khách hàng phát sinh nhu cầu, hệ thống tạo hoặc tìm company, tạo case, assign saler, rồi saler liên hệ khách hàng. Chưa kết nối được thì retry và liên hệ lại. Kết nối được thì tiếp tục follow và xét khả năng đặt lịch: không khả thi thì dừng và đóng case; có khả năng thì xác nhận appointment, meeting và follow-up. Nếu tiến tới hợp đồng thì lập contract rồi accounting contract / service; nếu không thì cancel / close. Đây là bản đơn giản hóa từ hệ thống status thực tế.

    A["Khách hàng phát sinh nhu cầu"]
    B["Tạo / tìm Company"]
    C["Tạo Case"]
    D["Assign Saler"]
    E["Liên hệ khách hàng"]

    F{"Kết nối được?"}
    G["Tiếp tục follow"]
    H["Chưa kết nối / retry"]

    I{"Có khả năng đặt lịch?"}
    J["Xác nhận Appointment"]
    K["Không khả thi / dừng"]

    L["Meeting / Follow-up"]
    M{"Tiến tới hợp đồng?"}
    N["Contract"]
    O["Accounting Contract / Service"]
    P["Cancel / Close"]

    A --> B
    B --> C
    C --> D
    D --> E

    E --> F
    F -- "Không" --> H
    H --> E

    F -- "Có" --> G
    G --> I

    I -- "Không" --> K
    I -- "Có" --> J

    J --> L
    L --> M

    M -- "Có" --> N
    N --> O

    M -- "Không" --> P
    K --> P
```

_Bản đơn giản hóa từ hệ thống status thực tế. Case — không phải khách hàng — là đơn vị để tính mọi số lượng, KPI và tỷ lệ chuyển đổi._

## Sales Dashboard hiển thị những gì

Dashboard biến case thành các góc nhìn quản trị: case mới và đang xử lý, số lượng tiếp nhận, KPI, kết quả thực tế, sales, tỷ lệ thành công, hiệu suất theo từng người, từng team và toàn công ty. Trong đó có bảng case theo tuần cho từng thành viên và team, KPI theo ngày / tháng / năm, sales ranking, doanh số theo dịch vụ trong 4 năm gần nhất, và tỷ lệ thành công của pipeline trong khoảng từ hai tuần tới một năm.

```mermaid
flowchart TB
    accTitle: Luồng dữ liệu của Sales Dashboard
    accDescr: Sáu nguồn dữ liệu — case và company, staff master, team master, KPI / sales target, ngày làm việc / ngày nghỉ và sales status — cùng đi vào GraphQL Analytics API. API chuyển dữ liệu qua lớp aggregation và business rule, tạo ba góc nhìn: thống kê theo staff, theo team và toàn công ty. Thống kê theo staff hiển thị thành bảng và sales ranking; thống kê theo team và toàn công ty hiển thị thành biểu đồ.

    CASE["Case / Company Data"]
    STAFF["Staff Master"]
    TEAM["Team Master"]
    TARGET["KPI / Sales Target"]
    HOLIDAY["Working Day / Holiday"]
    STATUS["Sales Status"]

    API["GraphQL Analytics API"]

    AGG["Aggregation / Business Rules"]

    STAFF_VIEW["Thống kê theo Staff"]
    TEAM_VIEW["Thống kê theo Team"]
    COMPANY_VIEW["Thống kê toàn công ty"]

    TABLE["Tables"]
    CHART["Charts"]
    RANK["Sales Ranking"]

    CASE --> API
    STAFF --> API
    TEAM --> API
    TARGET --> API
    HOLIDAY --> API
    STATUS --> API

    API --> AGG

    AGG --> STAFF_VIEW
    AGG --> TEAM_VIEW
    AGG --> COMPANY_VIEW

    STAFF_VIEW --> TABLE
    TEAM_VIEW --> CHART
    COMPANY_VIEW --> CHART
    STAFF_VIEW --> RANK
```

_Sáu nguồn dữ liệu, một analytics API, một lớp business rule, ba cấp tổng hợp._

## KPI target so với actual

Quản lý nhập sales target theo năm, tháng, nhân viên và loại chỉ tiêu. Kỳ chưa có dữ liệu mở ra ở trạng thái trống để nhập mới; kỳ đã có dữ liệu mở ra để chỉnh sửa. Target sau đó được so với kết quả thực tế theo ngày, tháng và năm, để thấy được chênh lệch và xu hướng chứ không chỉ con số tổng.

```mermaid
flowchart LR
    accTitle: KPI target so với actual
    accDescr: Manager hoặc người dùng của đội Sales nhập KPI target, lưu thành dữ liệu sales target. Song song, dữ liệu case, sales và contract được dùng để tính actual. Target và actual gặp nhau ở bước so sánh target với actual, rồi hiển thị theo ba mức thời gian: ngày, tháng và năm.

    MANAGER["Manager / người dùng Sales"]
    INPUT["Nhập KPI Target"]
    TARGET_DB["Sales Target Data"]

    BUSINESS["Case / Sales / Contract Data"]
    ACTUAL["Tính Actual"]

    COMPARE["Target vs Actual"]
    DAILY["Daily"]
    MONTHLY["Monthly"]
    YEARLY["Yearly"]

    MANAGER --> INPUT
    INPUT --> TARGET_DB

    BUSINESS --> ACTUAL

    TARGET_DB --> COMPARE
    ACTUAL --> COMPARE

    COMPARE --> DAILY
    COMPARE --> MONTHLY
    COMPARE --> YEARLY
```

_Target nhập một lần; actual lấy từ chính dữ liệu case, sales và hợp đồng mà cả nền tảng đang dùng._

## Đếm một khách hàng một lần: rule xử lý case trùng

Cùng một khách hàng có thể tới nhiều lần, qua các kênh liên hệ khác nhau hoặc vào các thời điểm khác nhau. Rule gom các case có cùng người đại diện, email hoặc số điện thoại phù hợp, và ngày tiếp nhận nằm trong một khoảng quy định. Nhóm có thể là chuỗi: A trùng B, B trùng C thì cả ba thuộc cùng một nhóm. Với mỗi nhóm, dashboard chọn một record đại diện và một giá trị forecast, để số lượng mail, contact và case không bị tăng sai.

```mermaid
flowchart TD
    accTitle: Rule xử lý case trùng
    accDescr: Hệ thống lấy các case có khả năng liên quan rồi kiểm tra lần lượt ba điều kiện: cùng thông tin người đại diện, email hoặc điện thoại phù hợp, và ngày tiếp nhận nằm trong khoảng của rule. Case trượt bất kỳ điều kiện nào được xử lý như case độc lập. Case qua cả ba điều kiện được đưa vào duplicate group; hệ thống kiểm tra quan hệ chuỗi A-B-C, chọn record đại diện, chọn dữ liệu forecast theo rule, rồi đếm cả nhóm như một case trong thống kê.

    A["Lấy các Case có khả năng liên quan"]
    B{"Cùng thông tin đại diện?"}
    C{"Email / điện thoại phù hợp?"}
    D{"Ngày tiếp nhận nằm trong rule?"}

    E["Đưa vào Duplicate Group"]
    F["Kiểm tra quan hệ chuỗi A-B-C"]
    G["Chọn record đại diện"]
    H["Chọn dữ liệu forecast theo rule"]
    I["Count nhóm như một Case trong thống kê"]

    X["Xử lý như Case độc lập"]

    A --> B

    B -- "Không" --> X
    B -- "Có" --> C

    C -- "Không" --> X
    C -- "Có" --> D

    D -- "Không" --> X
    D -- "Có" --> E

    E --> F
    F --> G
    G --> H
    H --> I
```

_Con số trên dashboard chỉ đúng khi rule đếm đúng. Case trùng được xử lý trước khi cộng bất kỳ thứ gì._

## Con số phải đúng theo lịch và theo tổ chức

- **Bảng analytics tối ưu cho việc đọc.** Để không phải tính lại toàn bộ từ các bảng giao dịch mỗi lần mở dashboard, bảng thống kê lưu sẵn những gì aggregation cần: kỳ tính toán cùng ngày bắt đầu / kết thúc, thứ tự team, loại thống kê, trạng thái nhân viên, ngày làm việc. Đọc nhanh và query đơn giản hơn; đánh đổi là khi business rule thay đổi có thể phải rebuild lại dữ liệu đó.
- **Ngày làm việc.** Số ngày làm việc còn lại và ngày tiếp nhận hợp lệ được tính theo dữ liệu ngày nghỉ, không theo lịch thông thường.
- **Kỳ quyết toán.** Năm chọn trên màn hình có thể là năm tài chính chạy từ tháng 10 tới tháng 9, nên frontend và backend phải thống nhất date range thay vì lọc theo năm dương lịch.
- **Nhân viên đã nghỉ.** Cờ nghỉ việc nằm ngay trong dữ liệu thống kê, để báo cáo lịch sử vẫn giữ nhân viên cũ mà không xử lý họ như nhân viên đang làm trong mọi phép tính.

## Expert Dashboard

Tài liệu dự án còn bao gồm dashboard dành cho chính kế toán viên / chuyên gia: thu nhập, hiệu quả kinh doanh, chiến lược, nhân sự, thừa kế, mức độ ứng dụng CNTT và sự hài lòng khách hàng, so sánh trên radar chart với các mốc cá nhân, nhóm, công ty và giá trị trung bình tham chiếu.

```mermaid
flowchart TB
    accTitle: Cấu trúc Expert Dashboard
    accDescr: Expert Dashboard có bảy nhóm màn hình: thu nhập, hiệu quả kinh doanh, chiến lược, nhân sự, thừa kế, mức độ ứng dụng CNTT và sự hài lòng khách hàng. Cả bảy nhóm cùng đổ về radar chart và benchmark để so sánh nhiều chiều. Trang tổng quan còn dẫn tới phần search / reference.

    HOME["Expert Dashboard"]

    EARN["Thu nhập"]
    EFF["Hiệu quả kinh doanh"]
    STRATEGY["Chiến lược"]
    HR["Nhân sự"]
    INHERIT["Thừa kế"]
    IT["Mức độ ứng dụng CNTT"]
    CS["Sự hài lòng khách hàng"]

    RADAR["Radar Chart / Benchmark"]
    SEARCH["Search / Reference"]

    HOME --> EARN
    HOME --> EFF
    HOME --> STRATEGY
    HOME --> HR
    HOME --> INHERIT
    HOME --> IT
    HOME --> CS

    EARN --> RADAR
    EFF --> RADAR
    STRATEGY --> RADAR
    HR --> RADAR
    INHERIT --> RADAR
    IT --> RADAR
    CS --> RADAR

    HOME --> SEARCH
```

_Analytics không chỉ dành cho đội sales nội bộ: chuyên gia có góc nhìn riêng trên bảy chiều hoạt động._

## Kiến trúc

Frontend không bao giờ truy cập database trực tiếp. Next.js và React gọi AWS AppSync qua Apollo; schema GraphQL được phân quyền bằng Cognito User Pools và IAM; mỗi request đi qua resolver, use case và repository, rồi Prisma truy cập PostgreSQL trên AWS. Codebase còn có Elasticsearch / OpenSearch cho search và indexing, và hạ tầng AWS được định nghĩa bằng Terraform.

```mermaid
flowchart TB
    accTitle: Kiến trúc kỹ thuật mức high-level của TaxPal
    accDescr: Trình duyệt chạy ứng dụng Next.js, React và TypeScript; ứng dụng gọi Apollo GraphQL client, client gọi AWS AppSync GraphQL. Cognito và IAM cấp quyền cho AppSync. AppSync chuyển request qua resolver layer, use case / interactor và repository. Repository đọc ghi PostgreSQL trên AWS qua Prisma, và làm việc với Elasticsearch / OpenSearch. Terraform định nghĩa hạ tầng AWS cho AppSync, Cognito / IAM, PostgreSQL và search. Đây là sơ đồ mức portfolio dựa trên các thành phần trong codebase và tài liệu, không phải bản sao sơ đồ hạ tầng production.

    USER["Browser"]

    NEXT["Next.js / React / TypeScript"]
    APOLLO["Apollo / GraphQL Client"]

    APPSYNC["AWS AppSync GraphQL"]

    AUTH["Cognito / IAM"]
    RESOLVER["Resolver Layer"]
    USECASE["Use Case / Interactor"]
    REPO["Repository"]

    PRISMA["Prisma"]
    POSTGRES["PostgreSQL on AWS"]

    SEARCH["Elasticsearch / OpenSearch"]
    INFRA["Terraform / AWS Infrastructure"]

    USER --> NEXT
    NEXT --> APOLLO
    APOLLO --> APPSYNC

    AUTH --> APPSYNC

    APPSYNC --> RESOLVER
    RESOLVER --> USECASE
    USECASE --> REPO

    REPO --> PRISMA
    PRISMA --> POSTGRES

    REPO --> SEARCH

    INFRA --> APPSYNC
    INFRA --> AUTH
    INFRA --> POSTGRES
    INFRA --> SEARCH
```

_Sơ đồ mức portfolio dựng từ các thành phần trong codebase và tài liệu — không phải bản sao sơ đồ hạ tầng production._

Thêm một API luôn đi cùng một con đường: schema, code generation, resolver, use case, repository, Prisma query, rồi test và seed data. Pull request được phía khách hàng review và phải pass toàn bộ GitHub checks. Migration và seed data tách thành pull request riêng, để một thay đổi schema không bao giờ bị merge lẫn với code nghiệp vụ, vốn khó review và khó rollback.

```mermaid
flowchart TB
    accTitle: Quy trình phát triển một GraphQL API
    accDescr: Từ yêu cầu màn hình hoặc nghiệp vụ, team thiết kế API, viết GraphQL schema, chạy GraphQL codegen, rồi viết resolver, use case / interactor, repository và Prisma query tới PostgreSQL. Sau đó chuẩn bị test và seed data, rồi mở pull request.

    REQ["Yêu cầu màn hình / nghiệp vụ"]
    DESIGN["API Design"]

    SCHEMA["GraphQL Schema"]
    CODEGEN["GraphQL Codegen"]
    RESOLVER["Resolver"]
    USECASE["Use Case / Interactor"]
    REPOSITORY["Repository"]
    PRISMA["Prisma Query"]
    DB["PostgreSQL"]

    TEST["Test / Seed Data"]
    PR["Pull Request"]

    REQ --> DESIGN
    DESIGN --> SCHEMA
    SCHEMA --> CODEGEN
    CODEGEN --> RESOLVER

    RESOLVER --> USECASE
    USECASE --> REPOSITORY
    REPOSITORY --> PRISMA
    PRISMA --> DB

    DB --> TEST
    TEST --> PR
```

_Một con đường cho mọi API mới, từ yêu cầu tới pull request._

## Tối ưu tốc độ dashboard

Dashboard có nhiều widget và nhiều phép thống kê nên hiệu năng là chuyện hằng ngày. Các vấn đề ghi nhận rất cụ thể: API select nhiều field hơn màn hình cần, load cả relation trong khi chỉ cần vài field, kiểm tra dữ liệu bằng nhiều request lặp, một màn hình chỉ khoảng 120 record mà API mất hơn 1 giây, và có dashboard gọi API riêng cho từng team. Cách xử lý: chỉ select dữ liệu cần, dùng relation thay cho query lặp, giảm kích thước response, trả dữ liệu nhiều team trong một API, giảm số request từ frontend, lazy load các widget người dùng chưa xem tới — kèm loading state để phân biệt "đang tải" với "không có dữ liệu".

```mermaid
flowchart TD
    accTitle: Tối ưu API cho dashboard
    accDescr: Một dashboard widget có hai cách lấy dữ liệu. Cách chưa tối ưu gửi nhiều request, mỗi team một request, select quá nhiều field và relation, nên response chậm. Cách tối ưu chỉ select dữ liệu cần, giảm query lặp bằng relation, aggregate nhiều team trong một API và lazy load widget, cho kết quả ít request hơn, payload nhỏ hơn và load tốt hơn.

    FE["Dashboard Widget"]

    OLD["Cách chưa tối ưu"]
    MANY["Nhiều request / team"]
    OVER["Select nhiều field / relation"]
    SLOW["Response chậm"]

    OPT["Thiết kế tối ưu"]
    SELECT["Chỉ select dữ liệu cần"]
    RELATION["Giảm query lặp bằng relation"]
    GROUP["Aggregate nhiều team trong một API"]
    LAZY["Lazy load widget"]

    RESULT["Ít request hơn / payload nhỏ hơn / load tốt hơn"]

    FE --> OLD
    OLD --> MANY
    MANY --> OVER
    OVER --> SLOW

    FE --> OPT
    OPT --> SELECT
    SELECT --> RELATION
    RELATION --> GROUP
    GROUP --> LAZY
    LAZY --> RESULT
```

_Cùng một widget, hai cách lấy dữ liệu. Phần lớn cải thiện đến từ việc hỏi ít hơn, và hỏi thưa hơn._

## Biểu đồ và QA cho một dashboard dùng để quản trị

Dashboard dùng để quản trị phải chịu được dữ liệu khó. Màu theo team phải dễ đọc khi số team tăng, team vượt ngưỡng dùng chung một style, và một số thống kê chỉ hiện team có thành viên. Giá trị vượt 100% — tới khoảng 200% — vẫn phải nằm trong biểu đồ, tooltip vẫn đọc được, scale đổi theo rule. Vì vậy QA không dừng ở giao diện: field mapping, công thức total, ngày làm việc, case trùng, sort, status, date range, filter, giá trị 0 và null, và cấu trúc từng API response.

## Dự án bao phủ những gì

| Bài toán của một hệ thống quản lý lớn | Thể hiện trong TaxPal |
| --- | --- |
| Pipeline sales nhiều trạng thái | Status của case từ lần liên hệ đầu tới hợp đồng, do saler cập nhật |
| Quản lý KPI | Target theo năm, tháng, nhân viên, loại chỉ tiêu; target so với actual theo ngày, tháng, năm |
| Tổng hợp nhiều cấp | Góc nhìn staff, team, toàn công ty; ranking; doanh số theo dịch vụ trong 4 năm |
| Rule đảm bảo đúng số liệu | Nhóm case trùng, ngày làm việc, kỳ quyết toán, nhân viên đã nghỉ |
| Hiệu năng đọc | Bảng analytics tính sẵn, chỉ select dữ liệu cần, một API cho nhiều team, lazy load |
| Phát triển brownfield | Module mới trên codebase AppSync, Prisma và PostgreSQL có sẵn; migration tách pull request riêng |
| Làm việc với khách hàng Nhật | Họp định kỳ, làm rõ yêu cầu, release qua repository của khách hàng |

Các sơ đồ được dựng lại ở mức thành phần từ tài liệu dự án. Chúng lược bỏ URL nội bộ, định danh hệ thống, source code độc quyền và dữ liệu của khách hàng. Ảnh chụp là mockup thiết kế và mô hình dữ liệu đã vẽ lại; tên nhân viên, một logo và một ảnh chân dung đã được làm mờ.

## Thông tin

- **Vai trò:** Technical Lead · Backend

## Công nghệ

- Next.js
- React
- TypeScript
- Apollo Client
- GraphQL
- AWS AppSync
- AWS Cognito
- AWS Lambda
- PostgreSQL
- Prisma
- Elasticsearch
- Terraform
- Docker

## Dịch vụ thể hiện qua dự án

- [Hệ thống quản lý nghiệp vụ](https://tmtuan.dev/vi/services/business-systems)
- [Hệ thống Backend & API](https://tmtuan.dev/vi/services/backend-development)
- [Xử lý sự cố Production](https://tmtuan.dev/vi/services/production-troubleshooting)

## Bài viết liên quan

- [Knowledge Base docs-as-code + Context Graph cho portfolio 15 dự án](https://tmtuan.dev/vi/articles/knowledge-base-docs-as-code-context-graph)
- [Truy vết HTTP 500 chỉ xảy ra với Googlebot, xuyên Next.js, Cloud Run và hosting edge](https://tmtuan.dev/vi/articles/googlebot-500-firebase-hosting-nextjs)

## Structured data (JSON-LD)

```json
{"@context":"https://schema.org","@graph":[{"@type":"WebPage","@id":"https://tmtuan.dev/vi/projects/taxpal#webpage","url":"https://tmtuan.dev/vi/projects/taxpal","name":"TaxPal — Dashboard sales cho môi giới kế toán","description":"Dashboard phân tích sales cho nền tảng môi giới dịch vụ kế toán tại Nhật: case, KPI target so với actual, xếp hạng và tỷ lệ chuyển đổi theo nhân viên, team và công ty.","inLanguage":"vi","isPartOf":{"@id":"https://tmtuan.dev/#website"},"about":{"@id":"https://tmtuan.dev/#person"}},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Trang chủ","item":"https://tmtuan.dev/vi"},{"@type":"ListItem","position":2,"name":"Dự án","item":"https://tmtuan.dev/vi/projects"},{"@type":"ListItem","position":3,"name":"TaxPal","item":"https://tmtuan.dev/vi/projects/taxpal"}]}]}
```
