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
| Phase | Thời gian | Kết quả chính | Release |
|---|---|---|---|
| 0 — Chốt kiến trúc | 01–20/10 | Quyết định kỹ thuật, mô hình dữ liệu, VPS, 2 spike | — |
| 1 — Lõi Tầng 1 + lên mạng | 10–25/10 | 4 dịch vụ bắt buộc chạy headless sau API Gateway; bản đầu tiên chạy trên VPS | v0.1.0 |
| 2 — Ứng dụng [P] Văn phòng điện tử | 26/10–08/11 | Vă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ự động | v0.2.0 |
| 3 — 4 nguyên lý + [D] | 09–20/11 | Mộ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ành | v0.5.0 |
| 4 — [I] / đệm | 21–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ài | 26/11–06/12 | Đóng băng tính năng, tự chấm PoF, gửi thư 05/12 | v1.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án | Ai gặp | Vấ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ình | Lõ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 đóng | Vă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ất | Tính từ dòng thời gian văn bản |
| Tỷ lệ văn bản xử lý quá hạn | Sổ 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ìm | Bấ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ại | So 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 đủ —
/admincủa Keycloak và/v1/metadatacủ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) dosvc-workflowxử 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.documentsgiữ 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-workflowbằng HTTP task. registerIncoming: trong một giao dịch, cấp số đến và ghistatus = registered→ khởi chạy processvan-ban-denvớibusinessKey = document.id→ ghiprocess_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 theobusinessKeyvà sửa lệch.submitOutgoinglàm theo cùng cách vớivan-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ần | Ngôn ngữ | Nhiệm vụ |
|---|---|---|
gateway/ | YAML | Route danh sách trắng + plugin APISIX (standalone), render từ .env |
services/svc-files | Python · FastAPI | Tả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-workflow | Python · FastAPI | Xử 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-ai | Python | Đọc văn bản đến, trợ lý hỏi đáp, tác tử (Phase 4) |
db/ | SQL | Schema core + office, ràng buộc CHECK, trigger sổ kiểm toán, migrations + metadata Hasura |
processes/ | BPMN XML | van-ban-den, van-ban-di; tự deploy lên Flowable khi khởi động |
templates/ | HTML · CSS | Mẫ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/dxos | Python · Typer | install, doctor, backup, restore, audit verify, tenant create |
ops/reconciler | Shell · systemd timer | GitOps: kéo nhánh deploy, áp cấu hình, khởi động lại container unhealthy |
apps/office | TypeScript · Nuxt 4 | Văn phòng điện tử (Tầng 2) |
apps/verify | TypeScript · Nuxt 4 | Cổ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ệc | Người |
|---|---|---|
| 0.1 | Hỏ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.2 | Chố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.3 | Mô 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.md | Backend + 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ài | Backend |
| 0.5 | Spike 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.6 | Spike 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-admin | Backend |
| 0.7 | Lậ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.8 | Liê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/10 | AI |
| 0.9 | Cả độ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ăng | Mã nguồn mở | Giấy phép |
|---|---|---|---|
| F1.1 | SSO + 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) | Keycloak | Apache-2.0 |
| F1.2 | API Gateway zero-trust: route danh sách trắng như §2; kiểm JWT tại biên; rate-limit; CORS; X-Request-Id | Apache APISIX (standalone) | Apache-2.0 |
| F1.3 | Dữ 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ắt | PostgreSQL 16 + Hasura v2.51.0-ce.cli-migrations-v3 | PostgreSQL / Apache-2.0 |
| F1.4 | Workflow: BPMN trong processes/ tự deploy; Hasura Actions → svc-workflow; callback + job đối soát theo §2.1 | Flowable REST 8.0 | Apache-2.0 |
| F1.5 | Dữ 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-files | SeaweedFS | Apache-2.0 |
| F1.6 | Trạ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) | ClamAV | GPL-2.0 (dịch vụ độc lập) |
| F1.7 | Tìm kiếm toàn văn: /api/search qua svc-files, gắn bộ lọc thuê ước phía server | Meilisearch CE | MIT |
| F1.8 | Cà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.9 | Lên mạng: deploy lên VPS, HTTPS, Keycloak sau proxy (KC_HOSTNAME, KC_PROXY_HEADERS); reconciler bản đầu kéo nhánh deploy | Mã của đội | — |
| F1.10 | Tài liệu API: schema GraphQL + OpenAPI của svc-* xuất tự động | Mã 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(profilecore) dựng toàn bộ lõi trên máy sạch; chỉ cổng gateway mở. Gọi/adminvà/v1/metadataqua gateway → bị chặn.make smokechạ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ăng | Dịch vụ lõi dùng | Mã 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 đội | Keycloak | — |
| F2.2 | Tiế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-files | Ajv (MIT), jsonschema (MIT) |
| F2.3 | Và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 đạo | Flowable | — |
| F2.4 | Soạ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ề sau | Flowable, svc-files | WeasyPrint (BSD-3-Clause), segno (BSD-3-Clause); phông Liberation Serif (OFL-1.1) cài từ gói hệ thống |
| F2.5 | Hộp việc của tôi + thông báo realtime trên kênh riêng của từng người | svc-workflow | Centrifugo (Apache-2.0) |
| F2.6 | Dòng thời gian văn bản: ai nhận, ai chỉ đạo, ai xử lý, ý kiến, lúc nào | Hasura | — |
| F2.7 | Tì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.8 | Sổ đăng ký văn bản đến / đi theo năm; xuất PDF để in (NĐ 30, Điều 16) | Hasura, svc-files | — |
| F2.9 | Song 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.10 | Dữ 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.11 | Cộ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ỗi | PostgreSQL (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ử đến | svc-files, APISIX | Web 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
PT1Mtự 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/verifykhông cần đăng nhập; vượt giới hạn tốc độ thì bị chặn. dxos audit verifybáo chuỗi nguyên vẹn; sửa tay một dòng trongcore.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ụm | Chức năng | Mã nguồn mở | Ưu tiên |
|---|---|---|---|---|
| F3.1 | (iv) Kiểm dịch | Mà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) | ClamAV | Should |
| F3.2 | (iv) Két bí mật | Static 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 đĩa | OpenBao (MPL-2.0) | Should |
| F3.3 | (iv) GitOps + tự phục hồi | Reconciler 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 đội | Should |
| F3.4 | ⑥ Sao lưu | dxos backup / dxos restore: pg_dump + restic cho CSDL và dữ liệu SeaweedFS | restic (BSD-2-Clause) | Should |
| F3.5 | ⑥ Lịch sử thay đổi | Tab "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 RAM | Vă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ước | OpenBao | Should |
| F3.8 | (i) Nóng → lạnh | Lậ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 DuckDB | Kestra · DuckDB | Should |
| F3.9 | (iii) Lineage + chất lượng | Job 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áo | Marquez (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 đạo | Scorpio all-in-one-runner (BSD-3-Clause) | Should |
| F3.11 | [D] Dashboard điều hành | Trang 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ê ước | Apache 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ận | Keycloak | Should — cắt đầu tiên nếu trễ (cột tenant_id từ Phase 1 đã đủ để demo cách ly) |
| F3.13 | ⑥ Giám sát | Sức khỏe dịch vụ (chỉ trong mạng nội bộ) | Prometheus · Grafana (grafana/grafana) | Should |
| F3.14 | Log tập trung | Tra log xuyên dịch vụ theo X-Request-Id | Vector · Parseable | Could |
| F3.15 | WAF | Chặn SQLi/XSS theo OWASP CRS tại gateway — chỉ spike nếu dư thời gian | Coraza (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.mdcó đủ 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ăng | Mã 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án | pypdf · Tesseract (vie) · Ollama + Qwen3 | BSD-3-Clause · Apache-2.0 · MIT · Apache-2.0 |
| F4.2 | Trợ 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ục | Ollama + Qwen3 · Qwen3-Embedding · Meilisearch (tìm lai) | MIT · Apache-2.0 · Apache-2.0 · MIT |
| F4.3 | Tá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ình | gó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ộng | pyHanko | MIT |
| F4.6 | Thu 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ày | Việc |
|---|---|
| 26/11 | Đóng băng tính năng — từ đây chỉ sửa lỗi |
| 26–30/11 | Tự 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/11 | Rà 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/12 | Release 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/12 | Gửi thư nộp bài |
| Từ 17:00 06/12 | Khô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/12 | Slide 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/12 | Chung kết |
3. Phân công (đội 3 người: Backend · AI · Frontend)
| Mảng | Phase 0 | Phase 1 | Phase 2 | Phase 3 | Phase 4 | Phase 5 |
|---|---|---|---|---|---|---|
| Backend — @Vanvuong2005827 (chủ PoF & phát hành) | Mô hình dữ liệu + Actions, Spike 1 + 2, kiểm tra VPS | APISIX, Flowable, svc-workflow + Actions, make install, make smoke, deploy VPS | Centrifugo, 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/search | Poka-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ình | Mã 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 — @nguyenlehoainam | Hỏ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 Backend | app-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 Anh | Dashboard [D] (ECharts), tab Lịch sử, phòng đọc ảo, giao diện IT/OT + cảm biến giả lập | Giao diện trợ lý + đọc văn bản đến | Slide, 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ực | Cần gì | Tình trạng |
|---|---|---|
| Đội 3 người | Backend, AI (kiêm dữ liệu), Frontend; ~7 tuần đến 06/12, trong đó có đệm 21–25/11 | Có; mỗi người điền lịch thi giữa kỳ (việc 0.7) |
| Giảng viên hướng dẫn | Giới thiệu đơn vị chạy thử; xem demo cuối mỗi phase; đứng tên trong thư nộp bài | Chư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ực | Cần gì | Tình trạng |
|---|---|---|
| Server chạy bản online | RAM 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 đội | Má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 + HTTPS | Tên miền hoặc tên miền con; chứng chỉ Let's Encrypt | Có: https://signet.htechcs.com, HTTPS qua Cloudflare Tunnel (trien-khai.md mục 5b) |
| Máy phát triển | Docker Engine + Docker Compose v2; ≥ 8 GB RAM để chạy core, 16 GB để chạy thoải mái | Mỗi người tự kiểm bằng make check |
| Máy dự phòng cho chung kết | Mộ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 OCR | Có |
RAM theo profile (ước lượng — đo lại ở Phase 1):
| Profile | Thành phần | RAM ước tính |
|---|---|---|
core | PostgreSQL, Keycloak, APISIX, Hasura, SeaweedFS, Meilisearch, Flowable, ClamAV, svc-files, svc-workflow | ~4–6 GB |
+ app | app-office, app-verify, Centrifugo | thêm ~0,5 GB → mục tiêu SME 8 GB |
+ ops | OpenBao, Kestra, Marquez, Scorpio, Prometheus, Grafana | thêm ~3–4 GB |
+ ai | Ollama + Qwen3 4B/8B (4-bit), bge-m3, Qdrant, OCR, svc-ai | thê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ệu | Dùng cho | Tình trạng |
|---|---|---|
| ~50 công văn, thông báo trường đã công bố công khai | make seed (F2.10) | Chưa thu thập |
| ~20 công văn scan và ảnh chụp | Spike OCR (Phase 2), F4.1 | Chưa có |
| Mẫu công văn, thông báo đúng thể thức | Mẫ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.2 | Chờ đơn vị chạy thử — không đưa vào repo |
| 10 câu hỏi kiểm thử kèm đáp án | Trợ lý hỏi đáp (F4.2) | Làm ở Phase 4 |
4.5. Kiến thức cần học
| Mảng | Cần nắm |
|---|---|
| Backend | APISIX, Flowable BPMN, Centrifugo, vận hành Docker trên server, systemd timer cho reconciler |
| AI | Quyền theo dòng của Hasura, trigger PostgreSQL cho chuỗi băm, WeasyPrint, OCR tiếng Việt, RAG |
| Frontend | Keycloak và OIDC, Nuxt 4, Playwright, ECharts |
| Cả đội | Thể 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)
- 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).
- Tên miền.
- Đơn vị chạy thử và tên giảng viên hướng dẫn (việc 0.8).
- 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 checkchạy sạch.
5. Rủi ro và cách chặn
| Rủi ro | Cá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 Must | Bả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ày | Mỗ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ả đội | Chỉ 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ả định | Hỏ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ốn | Windows 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 demo | Bả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ày | CI đăng nhập Docker Hub và cache image; giữ volume chữ ký ClamAV |
| Mạng hỏng lúc chung kết | Video demo dự phòng; một bản chạy được trên laptop |
| LLM chậm hoặc kém tiếng Việt | Spike 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ết | Mỗ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ừng | Ghim phiên bản image; rà lại DEPENDENCIES.md ở Phase 5 |
6. Không làm — và lý do
| Hạng mục | Lý do |
|---|---|
| Tầng 3 (ứng dụng ngành) | Đề không bắt buộc |
| Kubernetes / Argo CD | QĐ-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 Flutter | Không đủ thời gian |
| Kafka, Lakehouse Iceberg đầy đủ | Nặng; Parquet trên object storage + DuckDB đủ cho nguyên lý (i) |
| Metabase | Bả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-js | Giấ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ài | Bỏ qua ClamAV và buộc SeaweedFS mở cổng ra Internet |
| n8n, HashiCorp Vault, Redpanda, MongoDB, immudb | Khô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ật | Luậ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, HSM | Cầ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
/admincủa Keycloak,/v1/metadatacủa Hasura); bỏ URL ký sẵn ra ngoài; tìm kiếm đi quasvc-filesvì Meilisearch không nhận JWT Keycloak. - Nguồn sự thật: Hasura Actions +
svc-workflowlà 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êmmake installvà 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:
SHA256SUMSvà 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-filessang 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êmdepartment_id,make smokedùngregisterIncoming. - 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ườngMOC_*, gói phát hànhmoc-<phiên bản>.tar.gz. Repo giữ tênHVL. - 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ờiv0.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.003/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ànhtenant_admin. Chạy thử cho thấy Hasura coiadmintrong 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ảngcore.audit_logđằng nào cũng tạo ở F1.3. Phase 2 còn job neo hash, lệnhdxos audit verifyvà màn xem sổ. office.document_files,office.document_aclthêm cộttenant_id; khóa ngoại giữa các bảng nghiệp vụ đi kèmtenant_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.