{
  "title": "Nhật ký thay đổi Access Hub",
  "home_page_url": "https://developer.accesshub.vn/changelog",
  "entries": [
    {
      "id": "collector-chua-phat-hanh",
      "product": "collector",
      "version": null,
      "released": false,
      "older": false,
      "date": "2026-10-03",
      "title": "Thay đổi trên nhánh chính",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "<code>deploy/redis/aof-preflight.sh</code>: <code>ExecStartPre=</code> of the Redis units runs <code>redis-check-aof</code> on the AOF manifest",
            "<code>accesshub-unit-failed@.service</code>: logs one <code>user.crit</code> line when a Redis unit gives up",
            "Docs 14: sections 4.1 (Redis unit hardening, distro drop-in) and 4.2 (AOF recovery runbook from the 2026-10-02 incident)"
          ]
        },
        {
          "type": "change",
          "items": [
            "Redis units: <code>StartLimitIntervalSec=600</code>, <code>StartLimitBurst=5</code>, <code>OnFailure=</code>, <code>RestartSec=5</code>, <code>TimeoutStartSec=600</code>, so a damaged AOF no longer crash-loops for hours",
            "Redis config templates and the docs 14 sample set <code>aof-load-truncated yes</code> and <code>aof-use-rdb-preamble yes</code> explicitly; RDB snapshots stay enabled as the second recovery source"
          ]
        }
      ]
    },
    {
      "id": "scanner-v0-2-0",
      "product": "scanner",
      "version": "v0.2.0",
      "released": true,
      "older": false,
      "date": "2026-10-03",
      "title": "Bộ gửi riêng và phần nhận dữ liệu, chạy trọn đường tới Access Hub",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "<code>accesshub-scan-uploader</code> (SCN-4): bộ gửi không đặc quyền của Scanner",
            "<code>accesshub-secmatch ingest</code> (SMT-6): vai trò ingest của Scanner",
            "Kiểm thử đầu cuối trong một tiến trình (bộ đọc tới Access Hub giả, hai công ty) và canary mở rộng tới mọi request của bộ gửi",
            "<code>docs/15-benchmarks.md</code>: mọi phép đo (B1 đến B10), máy đo đề xuất, ngưỡng đạt; công cụ <code>tools/bench-rematch</code>, <code>tools/bench-ingest</code>, <code>tools/secdb-diff</code>, <code>scripts/bench/*</code> và các target <code>make bench-*</code>, tự từ chối chạy...",
            "Siêu dữ liệu máy (hostname, IPv4 và IPv6 chính, OS, SHA-256 của machine-id) khi enroll và qua <code>PUT /scan/v1/host</code> (khi đổi và mỗi 24 giờ), có giới hạn từng trường ở ingest",
            "<code>scan_window</code> trong cài đặt quét: bộ đọc chỉ quét trong khung (giờ địa phương theo múi giờ hoặc độ lệch UTC, ngày trong tuần, khung qua nửa đêm); yêu cầu quét sớm vượt khung một lần",
            "Máy Scanner chưa gắn <code>Server</code> (<code>server_id: null</code> từ Access Hub) vẫn gửi và được so khớp: matcher lưu theo <code>host_id</code>, sự kiện có <code>host_id</code> và <code>server_id: null</code> cho tới khi gắn; truy vấn nhận cả <code>server_id</code> đã gắn lẫn..."
          ]
        },
        {
          "type": "change",
          "items": [
            "Gói Scanner có thêm binary <code>accesshub-scan-uploader</code>, unit <code>accesshub-scan-uploader.service</code> và <code>.timer</code> (chỉ chạy sau khi enroll)",
            "Matcher lưu báo cáo của Scanner theo <code>host_id</code> thay cho <code>server_id</code> để <code>finding_key</code> ổn định khi máy được gắn sau"
          ]
        },
        {
          "type": "fix",
          "items": [
            "Bộ nhớ đệm so khớp lại tính mỗi băm inventory đúng một lần khi nhiều worker gặp cùng lúc (kiểm thử đếm lần dùng đệm từng chập chờn)"
          ]
        }
      ]
    },
    {
      "id": "scanner-v0-1-1",
      "product": "scanner",
      "version": "v0.1.1",
      "released": true,
      "older": false,
      "date": "2026-10-03",
      "title": "Đổi tên thành Access Hub Scanner",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "change",
          "items": [
            "Đổi tên sản phẩm thành Access Hub Scanner (gọi tắt Scanner)"
          ]
        },
        {
          "type": "fix",
          "items": [
            "Comment trong mã khớp kiến trúc hiện tại (Q25): bộ gửi của Scanner gửi tới vai trò ingest của secmatch, không qua Collector"
          ]
        }
      ]
    },
    {
      "id": "scanner-v0-1-0",
      "product": "scanner",
      "version": "v0.1.0",
      "released": true,
      "older": false,
      "date": "2026-10-03",
      "title": "Bản thiết kế và nền tảng quét đầu tiên",
      "upgrade": null,
      "notice": "<strong>Chưa dùng cho khách hàng:</strong> bản đầu tiên gồm thiết kế, các spike P0 và phần P1 làm được trên máy thử. ADR đã chấp nhận: 0001, 0002, 0004, 0005, 0007, 0012; các ADR khác còn Đề xuất.",
      "groups": [
        {
          "type": "add",
          "items": [
            "Bộ tài liệu thiết kế <code>docs/00</code> đến <code>docs/14</code>, ADR 0001 đến 0012, lộ trình P0 đến P7, rủi ro và câu hỏi mở",
            "<code>accesshub-scanner</code>: kiểm kê gói dpkg, <code>os-release</code>, kernel; lệnh <code>scan</code>, <code>scan --print</code>, <code>status</code>, <code>version</code>; ghi spool nguyên tử; gói <code>.deb</code> và <code>.tar.gz</code> riêng với unit systemd đã gia cố (điểm...",
            "So sánh phiên bản dpkg, đối chiếu khớp 13.867 cặp với <code>dpkg</code> thật",
            "Bộ kiểm thử &quot;không giá trị nào rời máy&quot; (T-1b) chạy trong <code>make test</code>",
            "<code>secdb-build</code>: chuẩn hóa Debian Security Tracker, Ubuntu OSV, Freexian ELTS (Debian 10, 11 sau LTS); ký Ed25519 bằng khóa ngoại tuyến <code>secdb-2026-a</code>; tệp <code>NOTICE</code> ghi nguồn, giấy phép, ghi công của từng nguồn",
            "<code>accesshub-secmatch</code>: so khớp tập trung, ingest, kho theo công ty, delta, outbox sự kiện cho Access Hub, so khớp lại khi DB đổi, API nội bộ; kho trong bộ nhớ và kho tệp dùng chung một bộ kiểm thử",
            "Golden T-1 cho 5 máy mẫu (Ubuntu 20.04, 22.04, 24.04, Debian 12, Debian 11) và tập con DB kiểm thử <code>testdata/secdb</code> (<code>tools/secdb-subset</code>)",
            "Hợp đồng báo cáo <code>accesshub.scan.v1</code> (<code>docs/contract/security-report-v1.md</code>) và đặc tả phần việc Access Hub <code>HUB-SEC</code> (<code>docs/08</code> mục 11)",
            "Nghiên cứu nguồn nhanh và chính thống (<code>docs/03</code> mục 6): bộ nguồn khuyến nghị và nhịp kéo"
          ]
        },
        {
          "type": "change",
          "items": [
            "Access Hub Scanner độc lập hoàn toàn với Access Hub Agent (Q25): bộ gửi riêng không đặc quyền, danh tính và enroll riêng; gói không còn phụ thuộc <code>accesshub-agent</code>",
            "Bản phát hành hết hỗ trợ giữ mọi finding, đánh dấu <code>no_distro_fix</code> khi distro sẽ không sửa, kèm finding <code>release_eol</code> khuyến nghị nâng cấp (tự đóng khi máy nâng cấp)",
            "Bộ so khớp dùng nguồn cắm được, đối chiếu nhiều nguồn, nguồn nhanh nhất có dữ liệu trước, các nguồn khác xác nhận (ADR 0007)",
            "RAM: <code>secdb-build</code> từ 3,0 GB xuống 0,75 GB, nạp DB của <code>secmatch</code> từ 1,44 GB xuống 0,30 GB, nội dung giữ nguyên",
            "ADR chấp nhận: 0001, 0002, 0004, 0005, 0007, 0012"
          ]
        },
        {
          "type": "fix",
          "items": [
            "Kho tệp xóa mất &quot;bia mộ&quot; khi công ty đã bị xóa gửi dữ liệu mới, khiến báo cáo đến muộn vẫn được nhận"
          ]
        }
      ]
    },
    {
      "id": "collector-v0-3-1",
      "product": "collector",
      "version": "v0.3.1",
      "released": true,
      "older": false,
      "date": "2026-10-03",
      "title": "Đổi tên hiển thị thành Access Hub Collector",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "change",
          "items": [
            "Display name is now Access Hub Collector (short: Collector): README, overview, changelog intro, systemd unit <code>Description</code> lines, the <code>-version</code> line and <code>-h</code> banner of <code>collector</code>"
          ]
        },
        {
          "type": "fix",
          "items": [
            "<code>internal/suppress</code> test no longer depends on the real clock (it failed after 2026-10-01); the silence set uses the injected clock"
          ]
        }
      ]
    },
    {
      "id": "agent-v0-3-1",
      "product": "agent",
      "version": "v0.3.1",
      "released": true,
      "older": false,
      "date": "2026-10-03",
      "title": "Đổi tên hiển thị thành Access Hub Agent",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "change",
          "items": [
            "Đổi tên hiển thị thành Access Hub Agent (gọi tắt Agent): README, tài liệu tổng quan, mô tả gói deb/rpm, <code>Description</code> của unit systemd và dịch vụ Windows (DisplayName vốn đã là Access Hub Agent), dòng đầu <code>version</code>..."
          ]
        }
      ]
    },
    {
      "id": "hub-v3-1-0",
      "product": "hub",
      "version": "v3.1.0",
      "released": true,
      "older": false,
      "date": "2026-10-03",
      "title": "Khu Bảo mật cho Access Hub Scanner, giao diện sự cố Collector",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Khu Bảo mật cho Access Hub Scanner (HUB-SEC P1)",
            "API nội bộ cho dịch vụ secmatch",
            "Quyền nhóm Bảo mật",
            "Lệnh nền đối soát giấy phép Scanner (10 phút) và thống kê nền tảng (02:00); xóa máy chủ hoặc công ty xóa luôn dữ liệu Bảo mật, kể cả bản sao ở secmatch",
            "Giao diện sự cố Collector"
          ]
        },
        {
          "type": "change",
          "items": [
            "Sự cố watchdog chỉ đóng sau 3 lần kiểm tra đạt liên tiếp và lưu số lần lỗi liên tiếp; ngưỡng mặc định 10 phút cho đường dữ liệu im lặng và hàng đợi kẹt"
          ]
        }
      ]
    },
    {
      "id": "hub-v3-0-1",
      "product": "hub",
      "version": "v3.0.1",
      "released": true,
      "older": false,
      "date": "2026-10-03",
      "title": "Cảnh báo khi Collector hỏng, giờ và số theo ngôn ngữ",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Cảnh báo ngoài luồng khi Collector hỏng",
            "Dọn nhật ký lệnh nền"
          ]
        },
        {
          "type": "fix",
          "items": [
            "Thời gian tương đối hiện tiếng Anh",
            "Định dạng số theo ngôn ngữ trình duyệt"
          ]
        }
      ]
    },
    {
      "id": "hub-v3-0-0",
      "product": "hub",
      "version": "v3.0.0",
      "released": true,
      "older": false,
      "date": "2026-10-03",
      "title": "Giao diện mới cho toàn bộ Access Hub, múi giờ theo người dùng",
      "upgrade": "Agent và collector phải cùng lên bản mới để enroll máy mới: body gửi Access Hub dùng trường <code>license</code> thay <code>enroll_token</code>.",
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Giao diện mới cho 8 khu",
            "Ô chọn và bộ lọc tìm trên máy chủ",
            "Số liệu tóm tắt",
            "Múi giờ theo người dùng",
            "Tự đăng xuất thiết bị không hoạt động 30 ngày",
            "API cho ứng dụng di động Access Hub",
            "Monitoring: trang chi tiết agent đầy đủ hơn",
            "Monitoring: trang quản lý collector",
            "Monitoring: tự gắn agent vào collector",
            "Monitoring: đổi tên &quot;Enroll token&quot; thành &quot;License&quot;",
            "Monitoring: tự đồng bộ thông số cơ bản từ agent sang máy chủ",
            "Dashboard chỉ số: thêm 5 loại khối kiểu Grafana",
            "Tab Sức khỏe máy chủ theo kiểu dashboard, nét mảnh mặc định",
            "Dashboard chỉ số: đồng bộ màu ngưỡng với tab Sức khỏe",
            "Dashboard chỉ số: căn trái, giữa, phải cho khối",
            "Biểu đồ thời gian: chấm theo vùng trỏ chuột, chỉnh nét vẽ",
            "Dashboard chỉ số: hai kiểu chú giải, bỏ thanh cuộn",
            "Dashboard chỉ số: lưu thủ công",
            "Dashboard chỉ số: kéo thả và đổi kích thước biểu đồ",
            "Dashboard chỉ số tập trung",
            "Khoảng im lặng, lý do chặn thông báo, dao động, gom sự cố theo nhóm và cài đặt gom nhóm (HUB-13)",
            "Luật ngưỡng giám sát (HUB-9)"
          ]
        },
        {
          "type": "change",
          "items": [
            "Kết nối mới mặc định hết hạn sau 3 tháng, đích proxy mới sau 90 ngày, token API mới sau 90 ngày",
            "Nút xóa hiện theo quyền <code>*.delete</code> (đúng quyền mà route kiểm), không còn theo <code>*.manage</code>",
            "Mã công ty bị khóa khi sửa (cả form và API)",
            "Loại tài nguyên của workflow phê duyệt bị khóa khi sửa; mốc leo thang SLA mặc định là 24 giờ sau hạn",
            "Trang tài liệu &quot;Truy cập nền tảng&quot; viết lại theo chính sách phiên chỉ xem có người duyệt",
            "Bỏ hẳn khái niệm &quot;enroll token&quot;, thay bằng License (Monitoring)"
          ]
        },
        {
          "type": "fix",
          "items": [
            "Monitoring: bộ chọn phạm vi hiện khóa dịch thô",
            "Xử lý cảnh báo an toàn hơn khi nhiều worker gửi cùng lúc (MySQL)",
            "<code>alert.reminder</code> mở lại alert bị mất",
            "Migration gộp F5 virtual IP chạy được trên MySQL",
            "SQLite bớt lỗi <code>database is locked</code>",
            "Sự kiện cảnh báo có <code>labels</code> bị từ chối với lỗi 500"
          ]
        }
      ]
    },
    {
      "id": "collector-v0-3-0",
      "product": "collector",
      "version": "v0.3.0",
      "released": true,
      "older": false,
      "date": "2026-10-02",
      "title": "Check trung tâm phân phối tới agent",
      "upgrade": "Agent và collector phải cùng lên bản mới để enroll máy mới: body gửi Access Hub dùng trường <code>license</code> thay <code>enroll_token</code>.",
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Docs: &quot;Trước khi bắt đầu&quot; and &quot;Áp dụng cho&quot; boxes (front matter <code>prerequisites</code>, <code>appliesTo</code>) on the production deployment guide (14), and a Debian/Ubuntu vs RHEL code group for the trial install",
            "COL-20: central checks",
            "Checks are indexed by (company_id, server_id); lookup uses the authenticated agent record only, so a check never reaches another company",
            "Invalid checks are dropped one by one, at most 50 checks per server, config ETag changes when the check list changes",
            "<code>POST /internal/v1/reload/checks</code>, <code>checks</code> block in <code>GET /internal/v1/status</code>, metrics <code>ahc_checks_*</code>",
            "Config <code>ingest.checks_sync_interval</code> (default 1m)",
            "Fuzz target <code>internal/checks:FuzzCompile</code>",
            "ADR 0017 (docs): VictoriaMetrics cluster for the Cloud system; retention grace is a self-service export"
          ]
        }
      ]
    },
    {
      "id": "agent-v0-3-0",
      "product": "agent",
      "version": "v0.3.0",
      "released": true,
      "older": false,
      "date": "2026-10-02",
      "title": "Dịch vụ Windows, tự xoay token, check chủ động",
      "upgrade": "Agent và collector phải cùng lên bản mới để enroll máy mới: body gửi Access Hub dùng trường <code>license</code> thay <code>enroll_token</code>.",
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Tài liệu: khung &quot;Trước khi bắt đầu&quot; và &quot;Áp dụng cho&quot; (front matter <code>prerequisites</code>, <code>appliesTo</code>) ở trang cài đặt (06) và cấu hình (04); tab Debian/Ubuntu và họ RHEL cho kho gói, tab Linux và Windows cho lệnh enroll",
            "AGT-12 (tài liệu): <code>docs/11-auto-update-proposal.md</code>, đề xuất cho nhóm Collector về manifest cập nhật (bytes được ký, ngữ nghĩa <code>min_version</code>, thu hồi phiên bản, chặn hạ cấp, quay lui) và bài toán quyền hạn khi thay...",
            "AGT-7 (dịch vụ Windows, ADR 0008): <code>internal/winsvc</code> và các lệnh <code>service install, uninstall, start, stop, restart</code>, <code>uninstall</code> trên Windows",
            "AGT-7 (một phần): bộ thu Windows <code>internal/collector/windows</code> bằng API trực tiếp (ADR 0007): CPU (<code>GetSystemTimes</code>), RAM và page file ước lượng, đĩa theo ký tự ổ, mạng (<code>GetIfTable2</code>), uptime, chỉ số agent, kiểm tra...",
            "AGT-10: xoay token tự động (<code>internal/renew</code>)",
            "AGT-8: kiểm tra chủ động <code>service</code>, <code>port</code>, <code>tcp</code>, <code>http</code>, <code>cert</code>, cục bộ và từ trung tâm (<code>AgentConfig.checks</code>)",
            "AGT-9: kiểm kê phần cứng và hệ điều hành, lệnh <code>inventory</code>, cấu hình <code>inventory.*</code>",
            "AGT-10 (phần đầu): cấu hình từ xa có ETag, <code>status</code>, <code>diag</code>, hiệu chỉnh đồng hồ"
          ]
        },
        {
          "type": "change",
          "items": [
            "<code>internal/svc</code> xuất <code>ValidCollectorURL</code> và <code>RenderConfig</code> để dịch vụ Windows dùng chung <code>agent.yaml</code> mẫu",
            "Danh mục: <code>cpu_load1</code>, <code>cpu_load5</code>, <code>cpu_load15</code>, <code>load_per_core_5m</code> chỉ còn Linux (Windows không có tải trung bình)",
            "<code>checks.Options</code> có thêm <code>ServiceUp</code> và <code>PortListening</code> để thay bộ đọc Linux",
            "Sender đọc token qua <code>TokenFunc</code> để token mới có hiệu lực ngay trên mọi luồng gọi collector",
            "Mock collector (<code>internal/mockcollector</code>) hỗ trợ <code>credentials/renew</code> và chồng token 24 giờ"
          ]
        }
      ]
    },
    {
      "id": "collector-v0-2-0",
      "product": "collector",
      "version": "v0.2.0",
      "released": true,
      "older": false,
      "date": "2026-09-30",
      "title": "Chỉ số dashboard máy chủ",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Alerting.seen_interval 1m (fixes agents flapping offline), catalog of 61 metrics"
          ]
        }
      ]
    },
    {
      "id": "collector-v0-1-0",
      "product": "collector",
      "version": "v0.1.0",
      "released": true,
      "older": false,
      "date": "2026-09-30",
      "title": "Bản thử nghiệm đầu tiên",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "First pre-release. Phase 0 foundation plus enterprise architecture docs (L1, L2, L3, ADR)."
          ]
        }
      ]
    },
    {
      "id": "agent-v0-2-0",
      "product": "agent",
      "version": "v0.2.0",
      "released": true,
      "older": false,
      "date": "2026-09-30",
      "title": "Danh mục chỉ số có chọn lọc",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Metric catalog with include/exclude selection, memory breakdown, packets and PSI metrics, all 8 CPU modes"
          ]
        }
      ]
    },
    {
      "id": "agent-v0-1-0",
      "product": "agent",
      "version": "v0.1.0",
      "released": true,
      "older": false,
      "date": "2026-09-30",
      "title": "Bản thử nghiệm đầu tiên",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "First pre-release. Phase 0 foundation plus enterprise architecture docs (L1, L2, L3, ADR)."
          ]
        }
      ]
    },
    {
      "id": "hub-v2-1-0",
      "product": "hub",
      "version": "v2.1.0",
      "released": true,
      "older": false,
      "date": "2026-09-30",
      "title": "Giám sát máy chủ bằng agent",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "fix",
          "items": [
            "Agent chập chờn giữa trực tuyến và ngoại tuyến",
            "Lỗi hệ thống lặp lại ở 21 nơi: user chưa gán công ty bị chặn khỏi gần như mọi thao tác quản trị",
            "Xuất báo cáo compliance &amp; đếm số lệch IaC đều rò rỉ xuyên công ty",
            "Trang chi tiết Domain tải toàn bộ bản ghi DNS không giới hạn",
            "Nút mở menu di động (hamburger) không có <code>aria-label</code>",
            "Trang danh sách Token API thiếu ô tìm kiếm",
            "Cấp Token API có đặt ngày hết hạn bị lỗi, không tạo được token",
            "Mã tham chiếu của yêu cầu IaC (<code>reference</code>) đổi từ tiền tố chung <code>RUN-</code> sang tiền tố theo đúng loại tài nguyên được khai báo",
            "Nộp nhiều manifest dán trực tiếp liên tiếp có thể trùng tên file",
            "Cấp Token API có đặt ngày hết hạn bị lỗi, không tạo được token",
            "Một kết nối chỉ neo (anchor) được vào công ty qua phía Đích (Nguồn là hệ thống ngoài chưa quản lý, trường hợp rất phổ biến: bất kỳ yêu cầu &quot;nhận kết nối từ bên ngoài vào&quot; nào) từng bị biến mất khỏi nhiều nơi",
            "Cùng lỗi trên, thêm một chỗ nữa: nhật ký thay đổi (audit log) của một kết nối chỉ neo qua phía Đích từng bị ghi <code>company_id = null</code>",
            "Dữ liệu mẫu (<code>demo:seed</code>, cả <code>--showcase</code> lẫn chế độ số lượng lớn, và seeder khởi tạo hạ tầng mẫu) từng gán sai <code>server_id</code>/<code>peer_server_id</code> cho những kết nối &quot;inbound&quot;",
            "Rà lại toàn bộ 11 mẫu YAML còn lại (Server, Subnet, PamAccount, Proxy, ProxyTarget, Domain, DnsRecord, F5Device, F5VirtualPort, F5PoolMember, SslCertificate) để quy chuẩn theo đúng nguyên tắc đã áp dụng cho mẫu...",
            "Lỗi &quot;UNIQUE constraint failed: yaml_runs.reference&quot; khi tạo yêu cầu IaC",
            "Kết nối firewall giờ validate đúng IP theo chiều kết nối",
            "Địa chỉ IP máy chủ giờ là duy nhất trên toàn hệ thống"
          ]
        },
        {
          "type": "add",
          "items": [
            "Biểu đồ sức khỏe máy chủ kiểu Node Exporter Full",
            "Giám sát máy chủ bằng agent (HUB-1 đến HUB-8)",
            "Loại tài khoản &quot;Service&quot; cho danh tính API không phải người",
            "Bộ tài liệu kiến trúc giám sát",
            "&quot;Token API&quot; đổi tên hiển thị thành &quot;Quản lý API&quot;, cùng 5 nâng cấp cho tính năng này",
            "Cài đặt hệ thống chia theo danh mục",
            "3 trang quản trị mới: Thông báo đã gửi, Hàng đợi, Webhook gửi ra",
            "Cảnh báo khi sửa tay máy chủ do IaC tạo ra",
            "Chính sách lưu trữ riêng cho nhật ký audit",
            "Cảnh báo sớm trước khi khoá tài khoản vì thiếu 2FA",
            "Chọn nhiều để gia hạn Connection hàng loạt",
            "Xuất CSV cho danh sách Server, Connection, Tài khoản PAM",
            "Tìm kiếm toàn hệ thống (Ctrl+K/Cmd+K)",
            "Xuất ảnh PNG sơ đồ kiến trúc",
            "Xuất báo cáo compliance",
            "Webhook hệ thống cho sự kiện quan trọng",
            "Trang &quot;Cần chú ý&quot; hợp nhất",
            "Thông báo chủ động khi tài nguyên sắp hết hạn",
            "Phát hiện lệch trạng thái IaC (drift detection)",
            "Nền tảng API REST có phiên bản (v1) + tài liệu tự sinh kiểu Swagger",
            "Sơ đồ kiến trúc: nút tải lại dữ liệu",
            "Dải mạng (Subnet) khai được Trung tâm dữ liệu/Vùng mạng, kể cả trên cloud",
            "Gán Vai trò/Nhóm người dùng cho nhiều người cùng lúc",
            "Hạ tầng chọn nhiều dòng + xác nhận trước khi áp dụng dùng chung",
            "Trang danh sách IP Public và Thiết bị F5 giờ có bộ lọc cấu trúc",
            "Sơ đồ kiến trúc: thêm bộ lọc theo công ty và theo phân vùng máy chủ",
            "Sửa Vai trò hiện xem trước quyền sẽ thêm/gỡ trước khi lưu",
            "Widget &quot;Kết nối sắp hết hạn&quot; trên Dashboard giờ nhận diện đúng chủ quản cho kết nối chỉ neo qua Dải mạng",
            "Token API giờ có phạm vi quyền riêng, không còn cấp toàn quyền <code>['*']</code> mặc định",
            "Token API có thể giới hạn theo địa chỉ IP gọi vào",
            "Có thể bắt buộc bật xác thực hai lớp (2FA) sau một số ngày kể từ khi tạo tài khoản, áp dụng cho toàn bộ tài khoản",
            "Trang Cài đặt → Bảo mật có thêm mục &quot;Phiên đăng nhập đang hoạt động&quot;",
            "Sơ đồ kiến trúc: thêm 3 cải tiến + sửa lỗi lệch layout sau phản hồi thực tế",
            "Sơ đồ kiến trúc: 5 cải tiến UX",
            "Sơ đồ kiến trúc giờ vẽ Dải mạng như một nút thật",
            "Mẫu YAML của Dải mạng cập nhật theo chuẩn CIDR-là-danh-tính",
            "Có thể cấp Token API ngay trên trang chi tiết một người dùng",
            "Dải mạng: danh tính thật để xác định trùng/cập nhật giờ là CIDR, không còn là tên",
            "Máy chủ: tên và hostname luôn được chuẩn hoá về chữ thường khi lưu",
            "Máy chủ: <code>ownerEmail</code> giờ là khoá so khớp mềm với người dùng đã có trong hệ thống",
            "Viết lại mẫu YAML của Server",
            "Kết nối (firewall) giờ hỗ trợ Dải mạng ở cả Nguồn và Đích, không chỉ Máy chủ, và không bên nào còn bị bắt buộc phải là loại cụ thể",
            "Mẫu YAML của Connection đổi từ khái niệm &quot;bên khai báo/bên đối tác&quot; (<code>spec.ownerType</code>+<code>spec.owner</code>, <code>spec.peerType</code>+<code>spec.peer</code>, vai trò phụ thuộc chiều kết nối) sang thẳng vị trí thực tế: <code>spec.sourceType</code>+...",
            "Tên rule Connection luôn do hệ thống tự sinh, không nhập tay được, và luôn theo đúng vị trí Nguồn trước, Đích sau, bất kể chiều kết nối",
            "Tiêu đề Yêu cầu IaC tự động sinh khi để trống",
            "Sơ đồ kiến trúc",
            "API nộp yêu cầu IaC cho hệ thống ngoài",
            "Quy ước đường dẫn cho manifest",
            "Trang tài liệu mới &quot;Dùng API để nộp yêu cầu IaC&quot;"
          ]
        },
        {
          "type": "change",
          "items": [
            "Sơ đồ kiến trúc: icon platform giờ hiện đúng logo hãng (Ubuntu, Debian, RHEL, Rocky Linux) thay vì icon chung chung",
            "Sơ đồ kiến trúc: 3 lỗi phát sinh ngay sau đợt thêm huy hiệu số luật và tay cầm kéo phân vùng",
            "Sơ đồ kiến trúc: 4 cải tiến giao diện thêm sau các đợt sửa trước",
            "Sơ đồ kiến trúc: 3 lỗi giao diện phát sinh sau đợt cho phép kéo thả khung phân vùng",
            "Sơ đồ kiến trúc: đường kết nối nổi bật rõ khi rê chuột vào, và các khung phân vùng (Công ty/Trung tâm dữ liệu/Vùng mạng) giờ kéo di chuyển được",
            "Sơ đồ kiến trúc: thẻ Máy chủ hiện thêm số nhân CPU/RAM",
            "Sơ đồ kiến trúc: Domain giờ là tài nguyên toàn cục, không còn hiển thị theo mặc định",
            "Sơ đồ kiến trúc: icon Máy chủ đổi theo vai trò thực tế",
            "Sơ đồ kiến trúc: bảng chi tiết tài nguyên có thêm link mở trang đầy đủ của tài nguyên đó",
            "Xoá 3 sơ đồ: Sơ đồ hệ thống (Topology), Bố trí máy chủ (Server Map), Sơ đồ tổ ong (Honeycomb map)",
            "Trang tài liệu kỹ thuật cập nhật phần giải thích cách một model được cách ly theo công ty (global scope / <code>ScopedToTenantParent</code> / tự kiểm tra thủ công) theo đúng danh sách tài nguyên hiện tại"
          ]
        },
        {
          "type": "security",
          "items": [
            "Lỗi hệ thống trong luồng IaC (lập kế hoạch/áp dụng) không còn hiển thị thông báo gốc cho người dùng",
            "Domain, F5 Device, SSL Certificate, Public IP giờ thuộc về một công ty",
            "Chặn gắn bản ghi con vào tài nguyên cha thuộc công ty khác",
            "Sổ nhật ký (Audit log) giờ được lọc theo công ty",
            "Chuyển giao bước duyệt (reassignment) và tìm người duyệt giờ giới hạn theo công ty",
            "Chặn nâng quyền qua gán Vai trò/Nhóm người dùng mang quyền mình không có",
            "Chặn gán token/tài khoản/máy chủ thuộc công ty khác qua vài request thủ công còn sót",
            "Yêu cầu IaC gửi qua API không có giới hạn tần suất",
            "Sửa lỗi crash &quot;Attempt to read property company_id on null&quot; khi ghi nhật ký thay đổi (audit log) cho PAM access/Proxy",
            "Sơ đồ theo Vùng/Trung tâm dữ liệu (Server Map) tính sai số lượng luật vào/ra của máy chủ",
            "Chặn nốt các chỗ còn sót gán bản ghi con cho tài nguyên thuộc công ty khác qua request thủ công",
            "Giới hạn loại tài nguyên IaC theo công ty (Cài đặt công ty) từng bị áp nhầm cho người dùng được gán nhiều công ty"
          ]
        }
      ]
    },
    {
      "id": "hub-v2-0-0",
      "product": "hub",
      "version": "v2.0.0",
      "released": true,
      "older": false,
      "date": "2026-09-21",
      "title": "Workflow có phiên bản, tài liệu trong ứng dụng",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Ô chọn người/tài nguyên tìm kiếm phía server (<code>AsyncSelectField</code>) dùng chung cho quản lý trực tiếp, người duyệt, chuyển giao bước duyệt",
            "Menu điều hướng dạng sheet cho di động (<code>AppNavMobileSheet</code>)",
            "Thông báo lỗi validate tùy chỉnh (<code>lang/*/validation.php</code>)",
            "Trang tài liệu trong ứng dụng",
            "Workflow phê duyệt có phiên bản (versioning)",
            "Màn hình xét duyệt riêng",
            "Chuyển giao hàng loạt các bước đang chờ duyệt",
            "Điền nhanh từ dropdown khi soạn yêu cầu IaC",
            "Hostname/IP của Connection và PAM Account luôn lấy theo server đã khai báo",
            "Ngày hết hạn hỗ trợ cho từng phiên bản hệ điều hành",
            "Xuất Firewall Request đúng theo biểu mẫu Excel gốc của đội vận hành",
            "Dán/tải giá trị dạng nhãn (vd &quot;Windows Server 2012 / 2012 R2&quot;) vào ô &quot;Giá trị&quot; của Danh mục lựa chọn sẽ tự chuyển đúng định dạng định danh",
            "Tự quản lý tài khoản liên kết",
            "Domain phân biệt Công khai/Riêng tư"
          ]
        },
        {
          "type": "security",
          "items": [
            "Rà soát và chặn rò rỉ dữ liệu chéo công ty",
            "Thêm <code>HasIacOrigin</code>: mọi tài nguyên do IaC tạo ra giờ liên kết ngược lại được tới yêu cầu đã tạo ra nó, tài nguyên tạo thủ công từ UI không thể giả mạo liên kết này"
          ]
        },
        {
          "type": "change",
          "items": [
            "SSL Binding không còn cho phép gắn vào Web Service (tài nguyên đã bị xóa ở trên), chỉ còn gắn vào Domain",
            "Cột <code>value</code> của bản ghi DNS mở rộng từ <code>string</code> sang <code>text</code>, bản ghi TXT (vd DKIM) dài hơn 255 ký tự trước đây bị cắt/lỗi khi lưu",
            "Cho phép gán 1 người dùng vào nhiều công ty",
            "Giới hạn loại yêu cầu IaC theo từng công ty",
            "Quản lý dải mạng (Subnet)",
            "Quản lý IP Public",
            "3 sơ đồ trực quan mới",
            "Đính kèm tệp &amp; mô tả định dạng rich text",
            "Thư viện <code>phpoffice/phpspreadsheet</code> (xuất Excel), <code>league/flysystem-aws-s3-v3</code> và <code>flysystem-ftp</code> (lưu trữ tệp), <code>mews/purifier</code> (làm sạch rich text)",
            "Cấu hình <code>trustProxies</code> để nhận đúng IP thật của client khi chạy sau load balancer nội bộ của nền tảng hosting (không có IP cố định)",
            "Web Service"
          ]
        }
      ]
    },
    {
      "id": "hub-v1-0-0",
      "product": "hub",
      "version": "v1.0.0",
      "released": true,
      "older": false,
      "date": "2026-09-10",
      "title": "Bản phát hành đầu tiên của Access Hub",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Khung điều hướng 2 tầng kiểu rail + flyout",
            "Đổi font toàn ứng dụng sang Tahoma",
            "Tìm kiếm nhanh trên topbar",
            "Menu tài khoản",
            "Quản lý Command chạy dưới nền",
            "Danh mục lựa chọn tách màn hình theo từng loại",
            "Phân quyền 4 cấp cho mọi chức năng",
            "Màn hình gán quyền vai trò (Thêm/Sửa vai trò) hiển thị theo cụm chức năng, mỗi chức năng 1 dòng với các checkbox theo cấp quyền (Xem/ Thêm-sửa/Xóa/Xóa vĩnh viễn...), thay vì liệt kê phẳng từng quyền",
            "Thùng rác theo từng chức năng",
            "Xóa vĩnh viễn (purge)",
            "Cài đặt hệ thống",
            "Tự động dọn thùng rác",
            "Nhật ký thay đổi ghi nhận riêng hành động <strong>xóa vĩnh viễn</strong> (<code>purged</code>), tách bạch với <strong>xóa mềm</strong> (<code>deleted</code>)"
          ]
        },
        {
          "type": "change",
          "items": [
            "<code>AuthorizationSeeder</code> tự dọn permission/nhóm quyền không còn khai báo trong <code>PermissionCatalog</code> mỗi lần seed lại (trước đây chỉ thêm/cập nhật, không bao giờ xóa); có thêm bước chuyển đổi 1 lần cho vai trò tùy chỉnh...",
            "<code>Permission::label()</code> sửa lỗi không dịch được nhãn quyền do khóa quyền chứa dấu chấm (vd <code>servers.manage</code>) khiến Laravel hiểu nhầm thành đường dẫn mảng lồng nhau, nay đọc thẳng từ mảng <code>permissions.items</code> thay vì...",
            "Trang thùng rác tập trung <code>admin/trash</code> và 2 quyền <code>trash.view</code>/ <code>trash.restore</code>",
            "Thùng rác riêng cho Option Lists (không cần vì đây là dữ liệu tham chiếu đơn giản)",
            "Sidebar 1 tầng cũ (<code>AppSidebar.vue</code>, <code>NavMain.vue</code>, <code>NavUser.vue</code>, <code>AppSidebarHeader.vue</code>), thay bằng khung rail + flyout mới"
          ]
        }
      ]
    },
    {
      "id": "hub-truoc-do",
      "product": "hub",
      "version": null,
      "released": false,
      "older": true,
      "date": null,
      "title": "Thay đổi trước bản phát hành đầu tiên",
      "upgrade": null,
      "notice": null,
      "groups": [
        {
          "type": "add",
          "items": [
            "Danh mục lựa chọn (Option Lists)",
            "Xóa mềm toàn hệ thống",
            "Nhật ký thay đổi (audit trail) cấp trường dữ liệu",
            "Validate YAML trước khi Lập kế hoạch"
          ]
        },
        {
          "type": "change",
          "items": [
            "3 trường của Server (Operating System, Datacenter, Zone) chuyển từ nhập tay tự do sang chọn từ danh sách có sẵn; ô chọn người ở &quot;Tạo truy cập PAM mới&quot; hỗ trợ tìm kiếm",
            "Đổi tên ứng dụng thành <strong>Access Hub</strong>, thiết kế lại logo",
            "Thiết kế lại tính năng Proxy: tách <code>Proxy</code> (server + proxy_host + proxy_port) và <code>ProxyTarget</code> (target_host, status, expires_at, note)"
          ]
        }
      ]
    }
  ]
}
