Chuyển tới nội dung chính

Kế hoạch phát triển DX-OS Open-Core — OLP PMNM 2026

Lập ngày 01/10/2026 · cập nhật 05/10/2026 sau rà soát · cập nhật 15/10/2026: đổi bài toán nghiệp vụ sang quản lý văn bản, đổi tên sản phẩm thành Mộc · cập nhật 18/10/2026: dời lịch Phase 1–4 (xem §7 — Nhật ký thay đổi) · 23/10/2026: đổi tên hiển thị thành Signet (đặc tả §10). Dựa trên olp-2026-de-thi.md. Phạm vi sản phẩm: dac-ta-san-pham.md. Mô hình dữ liệu: mo-hinh-du-lieu.md. Khung thời gian: 01/10 → 06/12/2026 (hạn nộp 17:00), chung kết 10/12/2026.


0. Tóm tắt​

PhaseThời gianKết quả chínhRelease
0 — Chốt kiến trúc01–20/10Quyết định kỹ thuật, mô hình dữ liệu, VPS, 2 spike—
1 — Lõi Tầng 1 + lên mạng10–25/104 dịch vụ bắt buộc chạy headless sau API Gateway; bản đầu tiên chạy trên VPSv0.1.0
2 — Ứng dụng [P] Văn phòng điện tử26/10–08/11Văn bản đến: tiếp nhận → kiểm dịch → vào sổ → chỉ đạo → xử lý; văn bản đi: soạn → trình → duyệt → cấp số → phát hành PDF có mã QR. Sổ kiểm toán chuỗi băm; cổng xác thực văn bản công khai. Chạy end-to-end, có test tự độngv0.2.0
3 — 4 nguyên lý + [D]09–20/11Một màn demo cho mỗi nguyên lý (i)–(iv); lưu trữ chống sửa xóa; dashboard điều hànhv0.5.0
4 — [I] / đệm21–25/11Đọc văn bản đến, trợ lý hỏi đáp, tác tử gợi ý giao việc — hoặc dùng làm đệm nếu trễv0.9.0
5 — Đóng gói, nộp bài26/11–06/12Đóng băng tính năng, tự chấm PoF, gửi thư 05/12v1.5.0

Phiên bản thực tế: các phần việc của Phase 1–4 làm xong sau v0.1.0 được phát hành chung trong v1.0.0 (23/10), v1.1.0 (25/10), v1.2.0 (27/10, kèm bản vá v1.2.1 ngày 28/10), v1.3.0 (30/10) và v1.4.0 (31/10, vá pypdf, bản online tự nâng theo bản phát hành — bản phát hành cuối trước vòng trường 01/11); không phát hành riêng v0.2.0, v0.5.0, v0.9.0. Bản nộp chấm của Phase 5 là v1.5.0.

Ưu tiên (MoSCoW)​

  • Must — Phase 1 + Phase 2 + bản chạy online: toàn bộ yêu cầu bắt buộc R1–R8 của đề, cùng lớp tin cậy của lõi — sổ kiểm toán chuỗi băm (F2.12) và cổng xác thực văn bản (F2.13), vì đây là điểm khác biệt chính mà README nêu ngay dòng đầu. Trễ thì cắt Should/Could, không cắt ở đây.
  • Should — Phase 3: bằng chứng cho cả 4 nguyên lý thiết kế, lưu trữ chống sửa xóa, dashboard [D], đa thuê ước đầy đủ.
  • Could — Phase 4 ([I]), WAF, log tập trung, che PII, ký số.
  • Won't — xem §6.

Đệm và lịch học​

  • 21–25/11 là đệm chính thức (5 ngày; trước 18/10 là một tuần). Nếu đến 20/11 Must/Should chưa xong, cả đội dồn vào hoàn thiện; [I] chỉ giữ trợ lý RAG hoặc bỏ hẳn.
  • Gửi thư 05/12 — đệm thêm 1 ngày trước hạn 17:00 06/12.
  • Mỗi người điền lịch thi giữa kỳ vào GitHub Project ngay Phase 0; tuần có người thi thì giảm phạm vi tuần đó, không kéo dài phase.

1. Bài toán sản phẩm giải quyết​

Các tổ chức nhỏ chuyển đổi số bằng cách mua thêm phần mềm, nhưng mỗi phần mềm lại là một ốc đảo dữ liệu, hoặc buộc họ lệ thuộc một nhà cung cấp. Signet là lõi nền tảng nguồn mở, tự cài, cung cấp sẵn định danh, cổng API, dữ liệu và quy trình cho mọi ứng dụng. Lõi "đóng dấu" lên mọi thứ đi qua nó: biết ai đã làm, tệp được quét mã độc trước khi lưu, mọi thay đổi vào sổ kiểm toán nên không sửa lén được, và những gì tổ chức phát hành ra ngoài thì người nhận kiểm chứng được. Ứng dụng Văn phòng điện tử chạy trên lõi cho thấy một công văn có thể đi trọn vòng đời — tiếp nhận, vào sổ, chỉ đạo, xử lý, trả lời, lưu trữ — mà không thất lạc, không quá hạn mà không ai hay, không bị sửa lén; và người nhận kiểm tra được văn bản là thật.

Tầng bài toánAi gặpVấn đềSignet giải bằng
Nền tảng (đề giao)SME, cơ quan nhà nước đang chuyển đổi sốPhần mềm rời rạc → ốc đảo dữ liệu; hệ thống nguyên khối → lệ thuộc một nhà cung cấp; ứng dụng nào cũng phải dựng lại đăng nhập, lưu tệp, phân quyền, quy trìnhLõi Tầng 1 dùng chung, không giao diện, nguồn mở, tự cài; lớp tin cậy dùng chung (danh tính, quét mã độc, sổ kiểm toán chuỗi băm, API xác thực)
Nghiệp vụ (ứng dụng minh họa)Văn thư, chuyên viên, lãnh đạo của khoa, trường, cơ quan nhỏCông văn giấy và bản scan qua email, Zalo; sổ tay hoặc Excel; không biết văn bản đang ở đâu, quá hạn chưa; khó tìm lại; không kiểm được văn bản điện tử nhận được là thật; phần mềm quản lý văn bản phổ biến là sản phẩm đóngVăn phòng điện tử (quản lý văn bản theo NĐ 30/2020) + cổng xác thực văn bản, chạy trên lõi

Vì sao chọn bài toán này, vai trò người dùng, phạm vi chức năng, kịch bản demo: dac-ta-san-pham.md.

1.1. Đơn vị chạy thử​

Bài toán nghiệp vụ cần người dùng thật, nếu không giám khảo sẽ hỏi "ai đang gặp vấn đề này?". Đơn vị nhắm tới: văn thư văn phòng khoa (hoặc phòng hành chính của trường), để:

  • Lấy quy trình thật: sổ văn bản, cách lãnh đạo giao việc, mẫu công văn đang dùng.
  • Có người dùng thật dùng bản online từ Phase 2; góp ý ghi thành issue (tiêu chí "thu hút cộng đồng").
  • Có số đo trước và sau để trình bày (§1.2).

Phương án dự phòng nếu không tìm được đơn vị: dữ liệu là công văn, thông báo trường đã công bố công khai; người dùng thử là giảng viên và sinh viên đóng vai văn thư, lãnh đạo; nói rõ điều này khi trình bày.

Dữ liệu nội bộ của đơn vị chạy thử không đưa vào repo.

1.2. Số đo thành công​

Chỉ sốHiện trạng (đo ở Phase 1)Sau khi dùng Signet (đo ở Phase 4)
Thời gian từ khi văn bản đến tới khi được giao xử lýHỏi văn thư, đếm 20 văn bản gần nhấtTính từ dòng thời gian văn bản
Tỷ lệ văn bản xử lý quá hạnSổ tay / Excel của văn thưHạn giải quyết so với lúc hoàn thành
Thời gian tìm lại một văn bản cũBấm giờ 5 lần tìmBấm giờ 5 lần tìm trên hệ thống
Số bước chuyển tay (in, ký, mang đi, nhắn tin nhắc)Quan sát quy trình hiện tạiSo với quy trình trên Signet

Chỉ trình bày số đo thật. Chỉ số nào chưa đo được thì nói rõ là chưa đo, không ước đoán.


2. Kiến trúc mục tiêu​

Cán bộ của đơn vị (trình duyệt) Người ngoài (điện thoại)
│ HTTPS │ HTTPS
┌─────────────────────▼────────────────────────┐ ┌───────────────▼───────────┐
│ TẦNG 2 — app-office (Nuxt 4) │ │ app-verify │
│ Văn phòng điện tử [P] · dashboard [D] │ │ cổng xác thực văn bản │
│ · trợ lý [I] │ │ công khai, chỉ đọc │
└─────────────────────┬────────────────────────┘ └───────────────┬───────────┘
└───────────────────┬──────────────────────┘
│ một cửa duy nhất
┌─────────────────────────────────────────▼──────────────────────────────────┐
│ TẦNG 1 — DX-OS Core (headless, không UI) │
│ │
│ Apache APISIX — xác thực JWT tại biên · rate-limit · X-Request-Id │
│ ├ /realms/* /resources/* → Keycloak (chặn /admin) │
│ ├ /v1/graphql → Hasura v2 CE (chặn /v1/metadata, │
│ │ │ /v2/query, /console) │
│ │ ├ dữ liệu → PostgreSQL (schema core + office, sổ kiểm toán) │
│ │ └ Actions → svc-workflow → Flowable REST (BPMN) │
│ ├ /api/files/* → svc-files → ClamAV → SeaweedFS │
│ ├ /api/search → svc-files → Meilisearch (lọc quyền ở server) │
│ ├ /api/verify/* → svc-files (ẩn danh, giới hạn tốc độ chặt) │
│ ├ /api/documents/ask → svc-files → Meilisearch · Ollama (Phase 4) │
│ └ /realtime → Centrifugo (tự kiểm JWT Keycloak qua JWKS) │
│ │
│ Chỉ trong mạng nội bộ: Keycloak admin · Hasura metadata · Flowable · │
│ SeaweedFS · Meilisearch · ClamAV · OpenBao · Kestra · Marquez · Grafana │
└────────────────────────────────────────────────────────────────────────────┘

Nguyên tắc headless:

  • Chỉ APISIX mở cổng ra ngoài, và chỉ cho những đường dẫn liệt kê ở trên (danh sách trắng). Tắt console thôi chưa đủ — /admin của Keycloak và /v1/metadata của Hasura phải bị chặn ở gateway.
  • Giao diện quản trị (Keycloak admin, Kestra, Marquez, Grafana) chỉ truy cập qua mạng nội bộ / SSH tunnel.
  • Không phát URL ký sẵn của SeaweedFS ra ngoài: tải lên/tải xuống luôn đi qua svc-files, nếu không tệp sẽ bỏ qua ClamAV và SeaweedFS phải mở cổng ra Internet.
  • Route ẩn danh duy nhất là /api/verify/* của cổng xác thực: chỉ trả các trường công khai của văn bản đã phát hành, tra theo mã hoặc theo băm, không liệt kê được; giới hạn tốc độ theo IP.

2.1. Một nguồn sự thật cho văn bản​

Tránh để Flowable và PostgreSQL cùng giữ trạng thái văn bản rồi lệch nhau:

  • Ứng dụng chỉ nói chuyện với GraphQL. Thao tác nghiệp vụ là Hasura Actions (registerIncoming, submitOutgoing, completeTask) do svc-workflow xử lý. Người dùng và thuê ước lấy từ session variables mà Hasura chuyển sang, không tin dữ liệu client gửi.
  • Flowable là chủ trạng thái quy trình (đang ở bước nào, ai phải làm). Bảng office.documents giữ dữ liệu nghiệp vụ và một bản chiếu trạng thái; chỉ svc-workflow được ghi vào cột trạng thái.
  • Chuyển trạng thái do Flowable tự gây ra (timer nhắc, leo thang) → Flowable gọi lại svc-workflow bằng HTTP task.
  • registerIncoming: trong một giao dịch, cấp số đến và ghi status = registered → khởi chạy process van-ban-den với businessKey = document.id → ghi process_id. Lỗi giữa chừng → job đối soát (mỗi 5 phút) tìm văn bản đã vào sổ mà chưa có process, so khớp với Flowable theo businessKey và sửa lệch. submitOutgoing làm theo cùng cách với van-ban-di.
  • Bảng, quyền, Actions, task và định dạng sự kiện: mo-hinh-du-lieu.md.

2.2. Phần mã đội tự viết ("lớp keo" — nơi chứa tính nguyên gốc)​

Thành phầnNgôn ngữNhiệm vụ
gateway/YAMLRoute danh sách trắng + plugin APISIX (standalone), render từ .env
services/svc-filesPython · FastAPITải lên → ClamAV → SeaweedFS; tải xuống sau khi kiểm quyền; tìm kiếm (lọc quyền phía server); dựng PDF văn bản đi từ mẫu, chèn số, ký hiệu, mã QR; API xác thực văn bản; mã hóa và giải mã văn bản hạn chế trong bộ nhớ; đọc hồ sơ lưu trữ lạnh bằng DuckDB
services/svc-workflowPython · FastAPIXử lý Hasura Actions, cấp số theo sổ, nhận callback từ Flowable, job đối soát, ánh xạ vai trò Keycloak → candidate group Flowable
services/svc-aiPythonĐọc văn bản đến, trợ lý hỏi đáp, tác tử (Phase 4)
db/SQLSchema core + office, ràng buộc CHECK, trigger sổ kiểm toán, migrations + metadata Hasura
processes/BPMN XMLvan-ban-den, van-ban-di; tự deploy lên Flowable khi khởi động
templates/HTML · CSSMẫu văn bản đi đúng thể thức NĐ 30 (công văn, thông báo), dựng thành PDF
cli/dxosPython · Typerinstall, doctor, backup, restore, audit verify, tenant create
ops/reconcilerShell · systemd timerGitOps: kéo nhánh deploy, áp cấu hình, khởi động lại container unhealthy
apps/officeTypeScript · Nuxt 4Văn phòng điện tử (Tầng 2)
apps/verifyTypeScript · Nuxt 4Cổng xác thực văn bản (Tầng 2, công khai); tính SHA-256 ngay trên trình duyệt

Ngôn ngữ mặc định: Python cho dịch vụ (cùng ngôn ngữ với phần AI) và TypeScript cho giao diện. Đổi nếu đội mạnh ngôn ngữ khác — chốt ở QĐ-007 (Phase 0).

2.3. Quy tắc làm việc​

  • GitHub Project + một milestone cho mỗi phase; mọi việc là một issue (cũng là bằng chứng cho PoF #1 "có dùng repo thật" và PoF #6 "có bug tracker").
  • Mỗi tính năng: nhánh → PR → một người khác review → merge. Tài liệu của tính năng nằm trong cùng PR — không dồn viết tài liệu cuối kỳ.
  • Cả 3 người commit đều đặn; không dồn commit lớn sát hạn.
  • CI cho mỗi PR: kiểm tra header giấy phép, docker compose config, make smoke (từ Phase 1), e2e Playwright (từ Phase 2).
  • Quyết định kỹ thuật ghi thành QĐ-00x trong docs/architecture.md, tiếp nối QĐ-001…003.
  • Cấu hình mọi thành phần render từ .env; không ghi cứng URL hay mật khẩu (PoF #4).
  • Cuối mỗi phase: demo cho giảng viên hướng dẫn, góp ý ghi thành issue.

Phase 0 — Chốt kiến trúc (01–20/10)​

Tính đến 05/10 chưa có đầu ra → chỉ giữ 8 việc tối thiểu, hạn 09/10. Phần trễ được bù bằng việc dời đa thuê ước đầy đủ khỏi Phase 1. Đến 18/10 vẫn chưa có issue, PR nào trên GitHub → hạn mới 20/10; hai spike chạy song song với những ngày đầu Phase 1.

#ViệcNgười
0.1Hỏi BTC các câu còn lại ở olp-2026-de-thi.md §8 trên nhóm Telegram (câu 1 về hạn nộp đã rõ)Frontend
0.2Chốt gọn (mỗi QĐ ≤ nửa trang): QĐ-004 kiến trúc 3 tầng · QĐ-005 stack lõi + thay thế thành phần non-OSI · QĐ-006 GitOps = Compose + reconciler · QĐ-007 ngôn ngữCả đội
0.3Mô hình dữ liệu (core.tenants, core.files, core.audit_log, office.documents, office.registers, office.assignments…) + danh sách Hasura Actions + định dạng sự kiện — để 3 người code song song không giẫm nhau. Bản nháp: mo-hinh-du-lieu.mdBackend + AI
0.4✅ Đã có máy chạy bản online. Kế hoạch đầu là một server 16 GB RAM dùng chung; bản online chạy trên laptop của đội, từ 31/10/2026 trên một máy Windows qua WSL2, ra Internet qua Cloudflare Tunnel (không cần IP công khai, không mở cổng 80/443); tên miền https://signet.htechcs.com; Docker đã càiBackend
0.5Spike 1: Keycloak → APISIX → Hasura. APISIX kiểm JWT ở biên; Hasura đọc tenant_id + vai trò qua claims_map. Lưu ý: iss trong token là URL công khai, còn Hasura lấy JWKS qua URL nội bộBackend + Frontend
0.6Spike 2: flowable/flowable-rest:8.0.0 + PostgreSQL, deploy 1 BPMN qua REST, đổi mật khẩu mặc định của user rest-adminBackend
0.7Lập GitHub Project + 6 milestone; điền lịch thi; xác nhận với trường đội đã có trong danh sách đăng kýFrontend
0.8Liên hệ đơn vị chạy thử (§1.1) — văn thư văn phòng khoa — nhờ giảng viên hướng dẫn giới thiệu; một buổi hỏi quy trình văn thư, và hỏi khoa có tự đánh số văn bản đi không; chốt đơn vị hoặc chuyển sang phương án dự phòng trước 25/10AI
0.9Cả đội đồng ý bài toán nghiệp vụ theo dac-ta-san-pham.md và tên sản phẩm Mộc (đã đổi trong tài liệu và cấu hình 15/10; §10 của đặc tả)Cả đội

Dời sang Phase 1: viết lại architecture.md đầy đủ, đổi profile docker-compose.yml thành core / app / ops / ai, cập nhật README.md, ROADMAP.md, DEPENDENCIES.md.

Hoàn thành khi: 2 spike chạy được; QĐ-004…007 và mô hình dữ liệu đã merge; bài toán nghiệp vụ đã chốt.


Phase 1 — Lõi Tầng 1 + lên mạng (10–25/10) → v0.1.0​

Mục tiêu: đáp ứng R1–R6 — một PaaS headless mà ứng dụng nào cũng gọi được qua một cổng duy nhất, và chạy được trên Internet ngay từ bản đầu.

MãChức năngMã nguồn mởGiấy phép
F1.1SSO + MFA: realm dxos import từ JSON trong git; vai trò clerk / staff / manager / director / tenant_admin (văn thư / chuyên viên / lãnh đạo phòng / lãnh đạo đơn vị / quản trị đơn vị — không đặt tên admin: vai trò có sẵn của Hasura, bỏ qua mọi quyền); TOTP bắt buộc cho clerk, manager, director; tenant_id và department_id là thuộc tính người dùng, đưa vào JWT bằng mapper (mỗi người thuộc một thuê ước, một phòng)KeycloakApache-2.0
F1.2API Gateway zero-trust: route danh sách trắng như §2; kiểm JWT tại biên; rate-limit; CORS; X-Request-IdApache APISIX (standalone)Apache-2.0
F1.3Dữ liệu có cấu trúc: GraphQL tự sinh; quyền theo vai trò + tenant_id (cách ly cấp dòng); migrations + metadata tự áp từ git khi khởi động; console tắtPostgreSQL 16 + Hasura v2.51.0-ce.cli-migrations-v3PostgreSQL / Apache-2.0
F1.4Workflow: BPMN trong processes/ tự deploy; Hasura Actions → svc-workflow; callback + job đối soát theo §2.1Flowable REST 8.0Apache-2.0
F1.5Dữ liệu phi cấu trúc: một bucket, khóa đối tượng có tiền tố tenant/<id>/…; tải lên/xuống luôn qua svc-filesSeaweedFSApache-2.0
F1.6Trạm kiểm dịch: quét mọi tệp trước khi ghi. Giữ volume /var/lib/clamav (CDN của ClamAV chặn nếu tải chữ ký quá dày); để ConcurrentDatabaseReload mặc định: lúc cập nhật chữ ký vẫn quét, RAM gần gấp đôi trong khoảng 10 giây (#288)ClamAVGPL-2.0 (dịch vụ độc lập)
F1.7Tìm kiếm toàn văn: /api/search qua svc-files, gắn bộ lọc thuê ước phía serverMeilisearch CEMIT
F1.8Cài ra ngoài thư mục nguồn: make install PREFIX=/opt/dxos chép compose + cấu hình đã render; hệ thống chạy được từ PREFIX (PoF #4)Mã của đội—
F1.9Lên mạng: deploy lên VPS, HTTPS, Keycloak sau proxy (KC_HOSTNAME, KC_PROXY_HEADERS); reconciler bản đầu kéo nhánh deployMã của đội—
F1.10Tài liệu API: schema GraphQL + OpenAPI của svc-* xuất tự độngMã của đội—

Dời khỏi Phase 1: Centrifugo → Phase 2; Keycloak Organizations, bucket riêng từng thuê ước, dxos tenant create → Phase 3 (Should).

Hoàn thành khi​

  • make up (profile core) dựng toàn bộ lõi trên máy sạch; chỉ cổng gateway mở. Gọi /admin và /v1/metadata qua gateway → bị chặn.
  • make smoke chạy trong CI: lấy token → truy vấn GraphQL → tải tệp lên (tệp mẫu EICAR bị chặn) → thêm văn bản đến → registerIncoming (có số đến) → completeTask. Người của thuê ước A không đọc được dữ liệu thuê ước B.
  • Đo RAM thực tế của profile core, ghi vào README.
  • Đã có đơn vị chạy thử, bộ quy chế và số đo hiện trạng theo §1.2 — hoặc đã chuyển sang phương án dự phòng.
  • URL công khai chạy v0.1.0; release .tar.gz + SHA256SUMS.

Phase 2 — Ứng dụng [P] Văn phòng điện tử (26/10–08/11) → v0.2.0​

Mục tiêu: đáp ứng R7 — một ứng dụng có giao diện, dùng cả 4 dịch vụ bắt buộc trong một kịch bản — và có lớp tin cậy của lõi: mọi thay đổi vào sổ kiểm toán chuỗi băm, văn bản phát hành kiểm chứng được từ bên ngoài.

MãChức năngDịch vụ lõi dùngMã nguồn mở thêm
F2.1Đăng nhập SSO, hồ sơ cá nhân. Tài khoản dùng thử cho giám khảo ở vai trò staff (không MFA); tài khoản văn thư, lãnh đạo dùng TOTP trên điện thoại của độiKeycloak—
F2.2Tiếp nhận văn bản đến: tải PDF/ảnh (hiển thị trạng thái quét) → nhập số ký hiệu, ngày ban hành, cơ quan ban hành, loại, trích yếu, độ khẩn, hạn giải quyết. Poka-yoke 3 lớp với một JSON Schema dùng chung: kiểm ở form → kiểm lại trong Action handler → ràng buộc CHECK trong PostgreSQL. Chặn vào sổ trùng (cùng cơ quan, số ký hiệu, ngày)Hasura Actions, svc-filesAjv (MIT), jsonschema (MIT)
F2.3Vào sổ và xử lý văn bản đến (BPMN van-ban-den): văn thư vào sổ, hệ thống cấp số đến liên tiếp theo năm → lãnh đạo đơn vị ghi ý kiến chỉ đạo, giao chủ trì / phối hợp, hạn giải quyết → lãnh đạo phòng phân công → chuyên viên xử lý, báo kết quả. Văn bản khẩn lên đầu hộp việc. Timer tham số hóa MOC_SLA_DURATION (ISO 8601 — thật PT24H, demo PT1M) → nhắc → leo thang; quá hạn giải quyết → báo lãnh đạoFlowable—
F2.4Soạn và phát hành văn bản đi (BPMN van-ban-di): dự thảo từ mẫu đúng thể thức (công văn, thông báo) hoặc tải tệp, giữ các phiên bản → trình lãnh đạo phòng → lãnh đạo đơn vị duyệt hoặc trả lại → văn thư cấp số đi → hệ thống dựng PDF có số, ký hiệu, ngày, mã QR và SHA-256 để xác thực về sauFlowable, svc-filesWeasyPrint (BSD-3-Clause), segno (BSD-3-Clause); phông Liberation Serif (OFL-1.1) cài từ gói hệ thống
F2.5Hộp việc của tôi + thông báo realtime trên kênh riêng của từng ngườisvc-workflowCentrifugo (Apache-2.0)
F2.6Dòng thời gian văn bản: ai nhận, ai chỉ đạo, ai xử lý, ý kiến, lúc nàoHasura—
F2.7Tìm kiếm theo số ký hiệu, trích yếu, cơ quan ban hành và nội dung PDF có lớp chữsvc-files—
F2.8Sổ đăng ký văn bản đến / đi theo năm; xuất PDF để in (NĐ 30, Điều 16)Hasura, svc-files—
F2.9Song ngữ Việt/Anh: dùng khóa i18n từ ngày đầu; bản dịch tiếng Anh làm nếu kịp—@nuxtjs/i18n (MIT)
F2.10Dữ liệu mẫu: make seed tạo người dùng (realm import), phòng ban, sổ rồi chạy kịch bản qua API để có ~50 văn bản ở nhiều trạng thái — không chèn thẳng vào CSDL, nếu không Flowable sẽ không có process tương ứng. Văn bản đến lấy từ công văn, thông báo trường đã công bố công khai——
F2.11Cộng đồng: mời đơn vị chạy thử dùng bản online; README tiếng Anh; người ngoài báo lỗi, góp ý qua issue theo mẫu, đội sửa; bài giới thiệu kèm URL demo trong nhóm Telegram VFOSSA——
F2.12⑥ Sổ kiểm toán chuỗi băm (trước là F3.5): trigger core.audit() ghi mọi thay đổi của bảng nghiệp vụ thành chuỗi băm SHA-256 (khóa advisory để ghi tuần tự); dxos audit verify tính lại chuỗi và chỉ ra dòng bị sửa; job định kỳ neo hash đầu chuỗi ra ngoài CSDL (bucket lạnh + tệp trong repo), để superuser không thể sửa rồi tính lại cả chuỗi; hash của mọi văn bản phát hành nằm trong chuỗiPostgreSQL (schema core)—
F2.13[D] Cổng xác thực văn bản (trước là F3.6, apps/verify): mã QR trên PDF mở thẳng trang xác thực → thông tin công khai + kết quả khớp; nhập mã tay được; thả tệp PDF → trình duyệt tự tính SHA-256 (không tải tệp lên) → so khớp. svc-files trả /api/verify/*; APISIX mở route này ẩn danh, giới hạn tốc độ theo IP, không liệt kê được. Văn thư dùng cùng chức năng khi tiếp nhận văn bản điện tử đếnsvc-files, APISIXWeb Crypto API của trình duyệt

Giao diện: Nuxt 4 / Vue 3 + Tailwind CSS (MIT) — Nuxt 4 thay Nuxt 3 trong gợi ý của BTC vì Nuxt 3 chỉ còn nhận bản vá bảo trì. Tiến trình quy trình hiển thị dạng dòng các bước do đội tự vẽ. Không nhúng bpmn-js: giấy phép là MIT có thêm điều khoản bắt buộc giữ watermark, không thuộc danh sách OSI. Xem PDF trên trình duyệt bằng PDF.js (Apache-2.0).

Hoàn thành khi​

  • Kịch bản 5 phút: văn thư nhận công văn đến → vào sổ → lãnh đạo đơn vị chỉ đạo, giao phòng Đào tạo → chuyên viên xử lý, soạn công văn trả lời → trình → duyệt → văn thư cấp số, phát hành PDF có mã QR; có thông báo realtime ở từng bước; timer PT1M tự nhắc khi để quá hạn.
  • Kịch bản trên chạy tự động bằng Playwright (Apache-2.0) trong CI.
  • Form sai bị chặn ở cả 3 lớp, có test cho từng lớp. Hai người ở hai phòng chỉ thấy văn bản của mình và phòng mình (test quyền).
  • Quét QR trên một văn bản đã phát hành bằng điện thoại thật → "khớp"; sửa một ký tự trong PDF → "không khớp". Gọi /api/verify không cần đăng nhập; vượt giới hạn tốc độ thì bị chặn.
  • dxos audit verify báo chuỗi nguyên vẹn; sửa tay một dòng trong core.audit_log → lệnh chỉ ra đúng dòng đó; hash đầu chuỗi đã được neo ra ngoài CSDL. Có test cho cả hai trường hợp.
  • Demo cho giảng viên hướng dẫn và văn thư của đơn vị chạy thử.

Phase 3 — Bằng chứng 4 nguyên lý + không gian [D] (09–20/11) → v0.5.0​

Mục tiêu: mỗi nguyên lý (i)–(iv) có một màn demo ≤ 1 phút, chạy lại được bằng một lệnh, ghi ở docs/demo-script.md; văn bản đã nộp lưu sang kho lạnh vẫn tìm và xác thực được.

MãNguyên lý / cụmChức năngMã nguồn mởƯu tiên
F3.1(iv) Kiểm dịchMàn demo: tệp EICAR bị từ chối trước khi lưu và ghi file.rejected vào sổ kiểm toán (ClamAV đã có từ Phase 1)ClamAVShould
F3.2(iv) Két bí mậtStatic seal để tự mở khóa khi khởi động lại (không thì két bị khóa, phá màn tự phục hồi); dịch vụ lấy mật khẩu CSDL qua AppRole; khóa Transit cho F3.7. Khi trình bày nói rõ: khóa mở và credential AppRole vẫn nằm trên đĩaOpenBao (MPL-2.0)Should
F3.3(iv) GitOps + tự phục hồiReconciler chạy bằng systemd timer trên host (không gắn socket Docker vào container): mỗi 60 giây kéo nhánh deploy → docker compose up -d; khởi động lại container unhealthy. Demo: docker rm -f một dịch vụ → tự dựng lại. Chuẩn bị bảng đối chiếu 4 nguyên tắc OpenGitOps để trả lời "GitOps mà không có Argo CD?"Docker Compose + mã của độiShould
F3.4⑥ Sao lưudxos backup / dxos restore: pg_dump + restic cho CSDL và dữ liệu SeaweedFSrestic (BSD-2-Clause)Should
F3.5⑥ Lịch sử thay đổiTab "Lịch sử" trên trang văn bản hiển thị diff từng lần sửa, đọc từ sổ kiểm toán. Bản thân sổ kiểm toán đã lên Must (F2.12)—Should
F3.6—Đã lên Must: cổng xác thực văn bản là F2.13——
F3.7[P] giải mã tài liệu trên RAMVăn bản hạn chế truy cập: tệp lưu mã hóa (khóa dữ liệu bọc bằng OpenBao Transit), chỉ giải mã trong bộ nhớ của svc-files cho người trong danh sách; xem có watermark; không đưa nội dung vào chỉ mục. Không dùng cho bí mật nhà nướcOpenBaoShould
F3.8(i) Nóng → lạnhLập hồ sơ và nộp lưu: hồ sơ công việc đóng quá MOC_ARCHIVE_AFTER_DAYS → gói Parquet + PDF + manifest có băm trên bucket cold → gỡ chi tiết khỏi OLTP, giữ bản ghi rút gọn. Văn bản đã lưu vẫn tìm thấy và xác thực được; xem trong phòng đọc ảo (chỉ xem, watermark) qua svc-files đọc Parquet bằng DuckDBKestra · DuckDBShould
F3.9(iii) Lineage + chất lượngJob phát sự kiện OpenLineage cho từng bước, quy ước tên dataset thống nhất từ đầu; kiểm tra chất lượng (số dòng khớp, không null) → lỗi thì cảnh báoMarquez (Apache-2.0)Should
F3.10(ii) IT/OT (bản rút gọn)Cảm biến nhiệt độ phòng máy chủ (giả lập) → context broker NGSI-LD → subscription → svc-workflow dựng nháp "báo cáo sự cố" từ mẫu → vào luồng văn bản đi để trình lãnh đạoScorpio all-in-one-runner (BSD-3-Clause)Should
F3.11[D] Dashboard điều hànhTrang trong app-office: văn bản đến theo trạng thái, quá hạn theo phòng, thời gian xử lý trung bình, văn bản khẩn, văn bản đi theo tháng. Lấy số liệu qua view + aggregate của Hasura → tự đúng SSO và quyền thuê ướcApache ECharts (Apache-2.0)Should
F3.12Đa thuê ước đầy đủKeycloak Organizations, bucket riêng từng thuê ước, tenantId trong Flowable, dxos tenant create; văn bản đi gửi đơn vị khác trong hệ thống tự thành văn bản đến của đơn vị nhậnKeycloakShould — cắt đầu tiên nếu trễ (cột tenant_id từ Phase 1 đã đủ để demo cách ly)
F3.13⑥ Giám sátSức khỏe dịch vụ (chỉ trong mạng nội bộ)Prometheus · Grafana (grafana/grafana)Should
F3.14Log tập trungTra log xuyên dịch vụ theo X-Request-IdVector · ParseableCould
F3.15WAFChặn SQLi/XSS theo OWASP CRS tại gateway — chỉ spike nếu dư thời gianCoraza (proxy-wasm)Could

Thứ tự cắt khi trễ: F3.15 → F3.14 → F3.12 → F3.13 → F3.5 → F3.7. Không cắt 4 màn nguyên lý. Cổng xác thực và sổ kiểm toán — màn demo chính — đã lên Must ở Phase 2.

Hoàn thành khi​

  • docs/demo-script.md có đủ 4 màn (i)–(iv), mỗi màn chạy bằng một lệnh.
  • Văn bản đã nộp lưu sang kho lạnh: quét QR → vẫn "khớp".
  • Diễn tập: xóa volume PostgreSQL → dxos restore → hệ thống trở lại đúng dữ liệu.

Phase 4 — [I] Trí tuệ / đệm (21–25/11) → v0.9.0​

Quy tắc: nếu đến 20/11 Must/Should chưa xong, 5 ngày này là đệm; [I] chỉ giữ F4.1 hoặc bỏ.

Người làm AI bắt đầu 2 spike từ Phase 2 (tuần 26/10), lúc khối lượng phần dữ liệu còn nhẹ, để Phase 4 chỉ còn tích hợp:

  • Spike OCR: Tesseract (vie) so với PaddleOCR và VietOCR trên ~20 công văn scan và ảnh chụp thật — ảnh chụp tiếng Việt thường sai dấu, chọn theo kết quả đo. Đo cả tỷ lệ đọc đúng số ký hiệu và ngày ban hành bằng quy tắc, không cần mô hình ngôn ngữ.
  • Spike mô hình: Qwen3 4B so với 8B — chất lượng tiếng Việt, tốc độ trên CPU của VPS, và giấy phép ghi trên model card của từng kích cỡ.
MãChức năngMã nguồn mởGiấy phép
F4.1Đọc văn bản đến: PDF có lớp chữ → đọc thẳng; ảnh / bản scan → OCR. Quy tắc cho số ký hiệu, ngày ban hành, cơ quan ban hành; mô hình ngôn ngữ chỉ tóm trích yếu. Điền sẵn form tiếp nhận, văn thư xác nhận. Tác tử dùng tài khoản dịch vụ riêng, hành động vào sổ kiểm toánpypdf · Tesseract (vie) · Ollama + Qwen3BSD-3-Clause · Apache-2.0 · MIT · Apache-2.0
F4.2Trợ lý hỏi đáp trên kho văn bản: trả lời kèm số ký hiệu và trang; lọc thuê ước và quyền ở bước truy xuất (bộ lọc Meilisearch + hậu kiểm Hasura, QĐ-004), không dựa vào prompt; văn bản hạn chế không vào chỉ mụcOllama + Qwen3 · Qwen3-Embedding · Meilisearch (tìm lai)MIT · Apache-2.0 · Apache-2.0 · MIT
F4.3Tác tử gợi ý giao việc: là một service task bất đồng bộ trong BPMN, nhánh song song từ lúc vào sổ (QĐ-005), xong trước khi lãnh đạo mở việc chỉ đạo; đề xuất đơn vị chủ trì và hạn dựa trên văn bản tương tự trước đây. Người quyết định (Human-in-the-loop); hành động của tác tử vào sổ kiểm toán; quá thời gian thì bỏ qua gợi ý, không chặn quy trìnhgói assist của svc-files (dùng chung với F4.2)—
F4.4 (Could)Che PII: che số định danh / CCCD, số điện thoại, email, số tài khoản trong log và trong chữ gửi cho LLM; chỉ mục, câu trích nguyên văn, sổ kiểm toán giữ bản gốc (QĐ-006)pii.py tự viết, chỉ thư viện chuẩn (không dùng Presidio)—
F4.5 (Could)Ký số PDF văn bản đi (PAdES) bằng PKI nội bộ do OpenBao cấp, khóa ký từng đơn vị nằm trong Transit (QĐ-007) — chỉ minh họa, không có giá trị pháp lý như chữ ký số công cộngpyHankoMIT
F4.6Thu góp ý và đo kết quả: đơn vị chạy thử + ≥ 5 người ngoài đội dùng bản online và để lại issue; đo các chỉ số "sau" theo §1.2——

Không dùng framework AI: truy xuất, trả lời và tác tử tự viết trong svc-files (QĐ-004 trong architecture.md). Không dùng Llama hoặc Gemma vì trọng số không mang giấy phép OSI.

Hoàn thành khi​

  • Trên 20 công văn mẫu, số ký hiệu và ngày ban hành được điền đúng ở phần lớn văn bản; ghi tỷ lệ đo được vào README (không ước đoán).
  • 10 câu hỏi kiểm thử đều có trích dẫn đúng văn bản.
  • Gợi ý của tác tử đã có sẵn khi lãnh đạo mở việc chỉ đạo.
  • Bản online chạy ổn định liên tục từ 25/11 đến ngày nộp.

Phase 5 — Đóng gói và nộp bài (26/11–06/12) → v1.5.0​

NgàyViệc
26/11Đóng băng tính năng — từ đây chỉ sửa lỗi
26–30/11Tự chấm theo pof-checklist.md (Backend chủ trì). Nhờ một người ngoài đội cài từ README trên máy sạch, cài ra PREFIX ngoài thư mục nguồn và chạy được (PoF #4)
26–30/11Rà tài liệu (đã viết dần theo PR): kiến trúc, API, vận hành (sao lưu/phục hồi/nâng cấp), demo-script.md, ROADMAP.md sau cuộc thi; đối chiếu DEPENDENCIES.md với phiên bản đã ghim
03/12Release v1.5.0: .tar.gz + .sha256 + CHANGELOG. Dòng đầu ghi chú phát hành (release.yml tự ghi) chỉ rõ tệp chính thức là .tar.gz (GitHub luôn tự gắn "Source code (zip)" và không gỡ được)
05/12Gửi thư nộp bài
Từ 17:00 06/12Không push lên nhánh chính — kho mã được chấm 7–9/12. Slide và video làm ở nhánh hoặc repo khác
07–09/12Slide 15 phút theo 4 phần BTC yêu cầu, mở đầu bằng bài toán (§1) và kết bằng số đo trước/sau; quay video demo dự phòng; tập ít nhất 3 lần; kiểm tra VPS trước giờ thi
10/12Chung kết

3. Phân công (đội 3 người: Backend · AI · Frontend)​

MảngPhase 0Phase 1Phase 2Phase 3Phase 4Phase 5
Backend — @Vanvuong2005827 (chủ PoF & phát hành)Mô hình dữ liệu + Actions, Spike 1 + 2, kiểm tra VPSAPISIX, Flowable, svc-workflow + Actions, make install, make smoke, deploy VPSCentrifugo, cấp số theo sổ, timer nhắc + callback, seed qua API, CI e2e, route ẩn danh /api/verify/* + giới hạn tốc độOpenBao (+ khóa Transit), reconciler, sao lưu, giám sát, nhận sự kiện IT/OT, đa thuê ước + liên thông giữa đơn vị (Should)Ổn định online, thu góp ý, ký số (Could)Tự chấm PoF, release
AI — @HoangTechCS-AIE (kiêm dữ liệu)Mô hình dữ liệu, liên hệ đơn vị chạy thửSchema core + office, Hasura (migrations, quyền), SeaweedFS, svc-files + ClamAV, Meilisearch + /api/searchPoka-yoke lớp CSDL + JSON Schema chung, dựng PDF văn bản đi từ mẫu + mã QR, sổ kiểm toán chuỗi băm + neo hash, API xác thực, sổ đăng ký, view cho dashboard, spike OCR + chọn mô hìnhMã hóa văn bản hạn chế, nộp lưu nóng→lạnh, MarquezĐọc văn bản đến, trợ lý hỏi đáp, tác tửRà tài liệu
Frontend — @nguyenlehoainamHỏi BTC, GitHub Project, Spike 1 (phần Keycloak)Keycloak realm (vai trò, mapper tenant_id + department_id, TOTP, giao diện đăng nhập), khung Nuxt + đăng nhập OIDC, vẽ quy trình BPMN cùng Backendapp-office: tiếp nhận văn bản đến, chỉ đạo / giao việc, soạn văn bản đi, hộp việc, chi tiết văn bản, sổ, tìm kiếm, i18n, Playwright; app-verify (cổng xác thực); README tiếng AnhDashboard [D] (ECharts), tab Lịch sử, phòng đọc ảo, giao diện IT/OT + cảm biến giả lậpGiao diện trợ lý + đọc văn bản đếnSlide, kịch bản demo, video

svc-files (dữ liệu phi cấu trúc, dựng PDF, xác thực, tìm kiếm) do AI làm vì gắn với dữ liệu và việc đọc văn bản về sau; Backend review. Mỗi mảng có một người khác thường xuyên review PR, để có người thay khi ai đó vắng dài ngày.


4. Tài nguyên cần có​

Dự án gần như không tốn tiền: mọi phần mềm đều nguồn mở, mô hình AI chạy trên server của đội. Thứ cần nhiều nhất là thời gian của 3 người, một server đủ RAM, dữ liệu và người dùng thật. Cột "Tình trạng" ghi theo ngày 15/10/2026 — cập nhật khi có thay đổi.

4.1. Con người và thời gian​

Nguồn lựcCần gìTình trạng
Đội 3 ngườiBackend, AI (kiêm dữ liệu), Frontend; ~7 tuần đến 06/12, trong đó có đệm 21–25/11Có; mỗi người điền lịch thi giữa kỳ (việc 0.7)
Giảng viên hướng dẫnGiới thiệu đơn vị chạy thử; xem demo cuối mỗi phase; đứng tên trong thư nộp bàiChưa điền
Văn thư khoa (đơn vị chạy thử)Một buổi hỏi quy trình; số đo "trước" theo §1.2; dùng bản online từ Phase 2Đang liên hệ; có phương án dự phòng (§1.1)
Người ngoài đội≥ 5 người dùng thử và để lại issue (F4.6); 1 người tự cài từ README trên máy sạch (Phase 5, PoF #4)Chưa có

4.2. Hạ tầng​

Nguồn lựcCần gìTình trạng
Server chạy bản onlineRAM theo bảng dưới; đĩa ước ≥ 50 GB cho image Docker, mô hình AI, chữ ký ClamAV và dữ liệu (ước tính, đo lại ở Phase 1); cổng 80/443; tài khoản SSH riêng của độiMáy Windows qua WSL2 từ 31/10/2026 (trước đó là laptop của đội), ra Internet qua Cloudflare Tunnel nên không cần IP công khai, cổng 80/443; RAM đo thật ở hoi-dap-hoi-dong.md mục 9 (việc 0.4)
Tên miền + HTTPSTên miền hoặc tên miền con; chứng chỉ Let's EncryptCó: https://signet.htechcs.com, HTTPS qua Cloudflare Tunnel (trien-khai.md mục 5b)
Máy phát triểnDocker Engine + Docker Compose v2; ≥ 8 GB RAM để chạy core, 16 GB để chạy thoải máiMỗi người tự kiểm bằng make check
Máy dự phòng cho chung kếtMột laptop chạy được bản demo khi mạng hoặc server hỏng (§5)Có
Điện thoạiỨng dụng TOTP nguồn mở (FreeOTP) cho tài khoản văn thư, lãnh đạo; camera quét QR khi demo và chụp công văn cho spike OCRCó

RAM theo profile (ước lượng — đo lại ở Phase 1):

ProfileThành phầnRAM ước tính
corePostgreSQL, Keycloak, APISIX, Hasura, SeaweedFS, Meilisearch, Flowable, ClamAV, svc-files, svc-workflow~4–6 GB
+ appapp-office, app-verify, Centrifugothêm ~0,5 GB → mục tiêu SME 8 GB
+ opsOpenBao, Kestra, Marquez, Scorpio, Prometheus, Grafanathêm ~3–4 GB
+ aiOllama + Qwen3 4B/8B (4-bit), bge-m3, Qdrant, OCR, svc-aithêm ~5–8 GB

VPS hiện có: 16 GB RAM — thừa cho core + app + ops (~8–10 GB). Bật thêm ai thì tổng ước 13–18 GB, sát hoặc vượt 16 GB. Cách xử lý, theo thứ tự ưu tiên: (1) đo RAM thật thay cho ước lượng; (2) chọn Qwen3 4B nếu 8B không vừa; (3) lúc demo [I] tạm tắt Kestra và Marquez (job ngầm, không ảnh hưởng màn demo khác). Không cần nâng cấp VPS trừ khi số đo thật buộc phải nâng.

4.3. Tài khoản và dịch vụ — đều miễn phí​

  • GitHub: repo công khai, Actions (repo công khai không giới hạn phút chạy), Discussions, Projects, Releases. Mỗi thành viên bật xác thực 2 lớp.
  • Docker Hub: CI đăng nhập để không bị giới hạn lượt tải image ẩn danh (§5).
  • Nhóm Telegram của BTC: hỏi đáp.
  • Không dùng API trả phí: mô hình ngôn ngữ chạy bằng Ollama trên server.
  • Phần mềm: tất cả mang giấy phép OSI, ghim phiên bản trong DEPENDENCIES.md; phông Liberation Serif thay Times New Roman.

4.4. Dữ liệu​

Dữ liệuDùng choTình trạng
~50 công văn, thông báo trường đã công bố công khaimake seed (F2.10)Chưa thu thập
~20 công văn scan và ảnh chụpSpike OCR (Phase 2), F4.1Chưa có
Mẫu công văn, thông báo đúng thể thứcMẫu văn bản đi (F2.4)Có theo Phụ lục NĐ 30; chờ mẫu đơn vị chạy thử đang dùng
Quy trình thật và số đo "trước"§1.2Chờ đơn vị chạy thử — không đưa vào repo
10 câu hỏi kiểm thử kèm đáp ánTrợ lý hỏi đáp (F4.2)Làm ở Phase 4

4.5. Kiến thức cần học​

MảngCần nắm
BackendAPISIX, Flowable BPMN, Centrifugo, vận hành Docker trên server, systemd timer cho reconciler
AIQuyền theo dòng của Hasura, trigger PostgreSQL cho chuỗi băm, WeasyPrint, OCR tiếng Việt, RAG
FrontendKeycloak và OIDC, Nuxt 4, Playwright, ECharts
Cả độiThể thức và quy trình văn thư theo NĐ 30 — phần trích ở dac-ta-san-pham.md §2.1

4.6. Chi phí​

Ước 0 đồng tiền phần mềm và dịch vụ: mọi thành phần là phần mềm nguồn mở, GitHub và Cloudflare gói Free đủ dùng; chi phí là máy và điện (bản online chạy trên một máy Windows qua WSL2 từ 31/10/2026). Nếu mua tên miền riêng thì thêm phí tên miền theo năm. Không nâng cấp server trừ khi số đo RAM thật buộc phải nâng (§4.2).

4.7. Phải có trước 25/10 (v0.1.0 chạy trên Internet)​

  1. Thông số và quyền truy cập server: CPU, đĩa, hệ điều hành, tài khoản SSH riêng, cổng 80/443 (việc 0.4).
  2. Tên miền.
  3. Đơn vị chạy thử và tên giảng viên hướng dẫn (việc 0.8).
  4. Máy của từng thành viên: Docker Compose v2, cấu hình Git theo git_flow.md §4.1, make check chạy sạch.

5. Rủi ro và cách chặn​

Rủi roCách chặn
Trễ tiến độMoSCoW; đệm 21–25/11; thứ tự cắt của Phase 3; mỗi phase kết thúc bằng một release dùng được
Phase 2 nặng thêm vì F2.12, F2.13 lên MustBảng core.audit_log và trigger viết luôn cùng schema ở F1.3 nếu Phase 1 còn giờ; app-verify chỉ là một trang, không đăng nhập. Phase 2 trễ thì để sau phần bản dịch tiếng Anh của F2.9 (vốn chỉ làm nếu kịp), không cắt F2.12, F2.13
Thi giữa kỳLịch thi điền từ Phase 0; giảm phạm vi tuần có thi
Thành viên vắng dài ngàyMỗi mảng có người thứ hai review PR thường xuyên
Không tìm được đơn vị chạy thửPhương án dự phòng ở §1.1: công văn đã công bố của trường, người dùng thử là giảng viên và sinh viên đóng vai
Nghiệp vụ văn thư mới với cả độiChỉ làm phần quy định ở dac-ta-san-pham.md §2.1; một buổi hỏi văn thư khoa ngay Phase 1
Giám khảo hỏi "khác gì VNPT iOffice?" hoặc hiểu nhầm ký số nội bộ có giá trị pháp lýTrả lời theo dac-ta-san-pham.md §9; ký số chỉ là Could và chỉ minh họa
BTC trả lời khác giả địnhHỏi ngay Phase 0; ví dụ nếu cấm cả console nội bộ thì tắt hẳn
Máy chạy bản online (Windows qua WSL2 từ 31/10/2026) bị khởi động lại hoặc tắt ngoài ý muốnWindows khởi động lại thì phải có người đăng nhập để bật lại WSL, Docker, cron (demo-script.md mục Phương án dự phòng); hoãn cập nhật Windows quanh ngày demo và 05–10/12; laptop chạy bản online trước đó giữ bản cài để lùi về; luôn có bản chạy trên laptop dự phòng
VPS 16 GB không đủ khi bật cả 4 profileĐo RAM thật ở Phase 1 và Phase 3; lúc demo [I] tắt Kestra/Marquez, chọn mô hình 4B nếu 8B không vừa
Lỗi chỉ lộ khi chạy thật (HTTPS, proxy, redirect URI, websocket)Lên mạng từ Phase 1; mỗi release tự deploy qua reconciler
Push nhầm lên máy demoBản online chỉ nâng lên thẻ phát hành mới (MOC_GITOPS_FOLLOW=release, MOC_GITOPS_MODE=nang-cap), push lên nhánh không đổi bản online; nâng cấp lỗi thì reconciler tự lùi về bản cũ
Docker Hub giới hạn pull ẩn danh; CDN ClamAV chặn tải dàyCI đăng nhập Docker Hub và cache image; giữ volume chữ ký ClamAV
Mạng hỏng lúc chung kếtVideo demo dự phòng; một bản chạy được trên laptop
LLM chậm hoặc kém tiếng ViệtSpike từ Phase 2; [I] là Could; số ký hiệu và ngày đọc bằng quy tắc, không cần mô hình; tác tử bất đồng bộ có timeout
Mất điểm PoF vì dịch vụ tự viếtMỗi svc-* có Dockerfile, header SPDX, cấu hình qua .env, không bundle thư viện; make install ra ngoài thư mục nguồn
Thành phần đổi giấy phép giữa chừngGhim phiên bản image; rà lại DEPENDENCIES.md ở Phase 5

6. Không làm — và lý do​

Hạng mụcLý do
Tầng 3 (ứng dụng ngành)Đề không bắt buộc
Kubernetes / Argo CDQĐ-006: Compose + reconciler đủ cho GitOps ở quy mô SME, không thêm 1–2 GB RAM và độ phức tạp
Ứng dụng di động FlutterKhông đủ thời gian
Kafka, Lakehouse Iceberg đầy đủNặng; Parquet trên object storage + DuckDB đủ cho nguyên lý (i)
MetabaseBản mã nguồn mở không đăng nhập được bằng Keycloak (OIDC là tính năng trả phí) và đọc thẳng CSDL, bỏ qua quyền thuê ước → thay bằng dashboard trong app-office
bpmn-jsGiấy phép không thuộc danh sách OSI (điều khoản watermark)
URL ký sẵn của SeaweedFS ra ngoàiBỏ qua ClamAV và buộc SeaweedFS mở cổng ra Internet
n8n, HashiCorp Vault, Redpanda, MongoDB, immudbKhông mang giấy phép OSI — xem olp-2026-de-thi.md §5
Văn bản Mật, Tối mật, Tuyệt mậtLuật Bảo vệ bí mật nhà nước 2018 (Điều 5) cấm soạn thảo, lưu giữ trên máy kết nối Internet
Liên thông Trục văn bản quốc gia (edXML, QCVN 102:2016/BTTTT)Cần mã định danh và kết nối do cơ quan nhà nước cấp — để ở định hướng phát triển
Chữ ký số công cộng, USB token, HSMCần tổ chức chứng thực được cấp phép; PKI nội bộ chỉ minh họa (F4.5)

7. Nhật ký thay đổi kế hoạch​

05/10/2026 — sau rà soát toàn bộ kế hoạch:

  • Lịch: Phase 0 rút còn 8 việc, kéo đến 09/10; thêm tuần đệm 19–25/11; lên mạng từ Phase 1 thay vì Phase 4; thêm quy tắc lịch thi.
  • Gateway: route danh sách trắng (chặn /admin của Keycloak, /v1/metadata của Hasura); bỏ URL ký sẵn ra ngoài; tìm kiếm đi qua svc-files vì Meilisearch không nhận JWT Keycloak.
  • Nguồn sự thật: Hasura Actions + svc-workflow là bên ghi trạng thái duy nhất; callback từ Flowable; job đối soát.
  • Phase 1: bỏ đa thuê ước đầy đủ (chỉ giữ cột tenant_id); ClamAV chuyển từ Phase 3 về; thêm make install và deploy VPS; Centrifugo sang Phase 2; dùng image Hasura -ce.cli-migrations-v3.
  • Phase 2: JSON Forms → một JSON Schema dùng chung (Ajv + jsonschema); SLA tham số hóa; tài khoản demo cho giám khảo; seed qua API; e2e Playwright; bắt đầu hoạt động cộng đồng.
  • Phase 3: thêm bản rút gọn IT/OT (ii) cho khớp mục tiêu "đủ 4 nguyên lý"; OpenBao static seal; reconciler chạy trên host, kéo nhánh deploy; pg_dump + restic thay pgBackRest; bỏ docker-autoheal; neo hash sổ kiểm toán ra ngoài CSDL; đường đọc hồ sơ lưu trữ lạnh; Metabase → ECharts; Vector, Parseable, Coraza hạ xuống Could.
  • Phase 4: một framework AI duy nhất; 2 spike từ 05/11; tác tử là service task bất đồng bộ trong BPMN.
  • Phase 5: SHA256SUMS và ghi chú về tệp zip của GitHub; không push lên nhánh chính sau hạn nộp.
  • Phân công: chuyển svc-files sang A, dashboard và Marquez sang B; A làm chủ PoF và phát hành.
  • Tài nguyên: cộng thêm bge-m3, OCR, Scorpio vào ước lượng; kế hoạch nâng VPS theo phase.
  • Bài toán: thêm §1 (câu phát biểu bài toán, đơn vị chạy thử, số đo thành công) và việc 0.8; đánh số lại các mục phía sau. Câu phát biểu cũng được đưa vào README.md.

09/10/2026

  • Hạn nộp đã rõ: 17:00 06/12/2026 (đề in nhầm năm 2025).
  • Đã có VPS 16 GB RAM → việc 0.4 chỉ còn ghi cấu hình, trỏ tên miền, cài Docker; bỏ kế hoạch nâng VPS theo phase, thay bằng đo RAM thật và tắt bớt job ngầm khi demo [I].
  • Phân công theo 3 mảng thật của đội: Backend · AI · Frontend thay cho A/B/C. AI kiêm phần dữ liệu (schema, Hasura, svc-files, sổ kiểm toán, nóng→lạnh, lineage); Frontend nhận cấu hình Keycloak và vẽ BPMN; spike AI dời sớm lên Phase 2.
  • Điền thành viên: Backend @Vanvuong2005827 · AI @HoangTechCS-AIE · Frontend @nguyenlehoainam.

15/10/2026 — đổi bài toán nghiệp vụ, lý do đầy đủ ở dac-ta-san-pham.md §1:

  • Bài toán: từ "luồng phê duyệt đề xuất mua sắm / tạm ứng / nghỉ phép" sang quản lý văn bản đến / đi theo NĐ 30/2020 + cổng xác thực văn bản công khai. Lý do: đề định nghĩa Tầng 2 là "cổng dịch vụ nghiệp vụ dùng chung" và xếp ứng dụng chuyên ngành vào Tầng 3; các kho mã công khai của đội khác đã có cổng yêu cầu nội bộ, mua sắm, vận hành phòng máy; chưa đội nào làm quản lý văn bản và xác thực văn bản.
  • Lõi Tầng 1 và Phase 1 giữ nguyên, trừ: vai trò thêm clerk, JWT thêm department_id, make smoke dùng registerIncoming.
  • Phase 2: F2.2–F2.4, F2.8 viết lại cho văn bản đến / đi và sổ đăng ký; PDF phát hành có mã QR + SHA-256.
  • Phase 3: đánh mã F3.1–F3.15; thêm cổng xác thực (F3.6), văn bản hạn chế giải mã trên RAM (F3.7); nóng → lạnh thành lập hồ sơ, nộp lưu (F3.8); IT/OT tạo nháp báo cáo sự cố (F3.10).
  • Phase 4: F4.1 thành đọc văn bản đến (giữ đầu tiên nếu dùng tuần đệm); trợ lý hỏi đáp trên kho văn bản; tác tử gợi ý giao việc; ký số chỉ minh họa.
  • Không làm: thêm văn bản mật, liên thông Trục văn bản quốc gia, chữ ký số công cộng.
  • Thêm việc 0.9 (chốt bài toán, tên sản phẩm) và bản nháp mô hình dữ liệu mo-hinh-du-lieu.md.
  • Tên sản phẩm: DX-Lab → Mộc (theo chữ "đóng mộc"). "DX-Lab" là tên Trạm thực hành số trong chủ đề cuộc thi và trùng ứng dụng của đội HaUI. Tên kỹ thuật đổi theo: Compose project và CSDL mặc định moc, biến môi trường MOC_*, gói phát hành moc-<phiên bản>.tar.gz. Repo giữ tên HVL.
  • Phát biểu sản phẩm: kể lõi trước, ứng dụng sau; điểm khác biệt là lớp tin cậy của lõi (danh tính, quét mã độc, sổ kiểm toán chuỗi băm, API xác thực).
  • Sổ kiểm toán chuỗi băm và cổng xác thực lên Must: F3.5 → F2.12, F3.6 → F2.13, làm trong Phase 2 (v0.2.0). Lý do: đây là điểm khác biệt README nêu ngay dòng đầu, không được để rơi vào nhóm có thể cắt. Phần còn lại của F3.5 (tab "Lịch sử" hiển thị diff) giữ ở Phase 3, mức Should; mã F3.6 bỏ trống để các mã F3.x khác không đổi.
  • §4 mở rộng thành "Tài nguyên cần có": con người, hạ tầng, tài khoản, dữ liệu, kiến thức, chi phí và những thứ phải có trước 21/10; bảng RAM theo profile giữ nguyên ở §4.2.

18/10/2026 — dời lịch:

  • Đến 18/10 repo vẫn chưa có issue, PR hay dòng mã nào của lõi; còn 3 ngày tới v0.1.0 (21/10) là không kịp. Dời v0.1.0 → 25/10, Phase 2 → 26/10–08/11 (giữ đủ 2 tuần vì đây là sản phẩm chính), Phase 3 → 09–20/11 (rút 2 ngày), Phase 4 → 21–25/11 (rút 2 ngày, cũng là đệm).
  • Giữ nguyên ngày đóng băng 26/11, v1.0.0 03/12, gửi thư 05/12. Phase 0 kéo đến 20/10, hai spike chạy song song đầu Phase 1. Không kịp 25/10 thì cắt F1.10 sang đầu Phase 2, không lùi thêm.

18/10/2026 — làm #18 (schema + Hasura):

  • Vai trò admin đổi thành tenant_admin. Chạy thử cho thấy Hasura coi admin trong JWT là quản trị toàn quyền: đọc được dữ liệu của mọi thuê ước. Realm (#21) phải dùng tên mới.
  • Phần CSDL của F2.12 làm luôn trong #18 (trigger chuỗi băm, core.audit_verify()), vì bảng core.audit_log đằng nào cũng tạo ở F1.3. Phase 2 còn job neo hash, lệnh dxos audit verify và màn xem sổ.
  • office.document_files, office.document_acl thêm cột tenant_id; khóa ngoại giữa các bảng nghiệp vụ đi kèm tenant_id, để CSDL tự chặn việc trỏ sang dữ liệu của thuê ước khác.

18/10/2026 (tối) — Frontend và Backend chưa bắt đầu (chưa có realm Keycloak, khung Nuxt, Compose); người làm AI làm thay toàn bộ lát cắt đầu tiên theo chiều dọc thay vì làm xong lõi rồi mới làm giao diện. Đã chạy được bằng make up && make seed: #13 (Compose, Makefile), #14 (APISIX), #15 (svc-workflow + Actions), #16 (seed, smoke), #21 (realm), #22 (giao diện), #23 (BPMN văn bản đến), cùng #18–#20. Vai trò lấy từ thuộc tính moc_role (một giá trị cho cả hai claim vai trò của Hasura) thay vì vai trò realm. Danh bạ core.users đồng bộ từ Keycloak. Kế tiếp: lát văn bản đi + PDF có mã QR + cổng xác thực (F2.4, F2.13). Rủi ro mới: lịch sử commit chỉ một tác giả (PoF #1) — cần hai bạn nhận việc Phase 2.