# NCV DCIMS

**NCV DCIMS — NCV Dental Clinical Image Management System**

Hệ thống quản lý hình ảnh lâm sàng – Nha khoa Nụ Cười Việt.

## Trạng thái

**Cập nhật vận hành 30/09/2026:** operator xác nhận migration và role provisioning đạt, API/Web/Gateway healthy, DSM sync và HTTPS smoke đạt; Dockerfile trên NAS đã lưu bản sửa quyền, đăng nhập và giao diện bình thường. Bộ r2 chứa Dockerfile sửa quyền và [hướng dẫn chính gồm 5 khối NAS](docs/operations/synology-update-0.2.30.md), tổng hợp upload/backup/credential/update/verify và các lỗi đã gặp; NAS đang chạy không cần update lại để nhận bộ này. Xem [hướng xử lý và bằng chứng NAS](docs/operations/synology-recover-permissions-0.2.30.md). Chưa coi kiểm đăng nhập là nghiệm thu đầy đủ DR/offsite/reboot hoặc mọi luồng nghiệp vụ.

Source ứng dụng **0.2.30** xử lý bảy vấn đề đã duyệt về bảo mật và hiệu suất, có migration mới và tách credential database. Bổ sung khôi phục Back/Forward cho hồ sơ ngoài trang và bỏ icon trước tiêu đề các khối Cài đặt. Xem [hướng dẫn cập nhật 0.2.30](docs/operations/synology-update-0.2.30.md) và [bằng chứng kiểm chứng](docs/evidence/release-0.2.30-verification-2026-09-30.md). Theo task “Di chuyển share folder sang Volume 2” chốt 15/09/2026, NAS đã chạy 0.2.29; project/database/media/ledger/backup ở Volume 2, Docker Root/Container Manager giữ Volume 1. Đây là trạng thái trước cập nhật do task Volume 2 cung cấp; kết quả NAS ngày 30/09 được ghi ở chú thích vận hành và evidence. Site dùng updater ngoài source có DSM sync; bản 0.2.30 cung cấp revision có guard cho layout secret DB mới. Không dùng updater chuẩn chỉ có Compose base cho site này.

- workspace TypeScript tại `apps/*` và `packages/*`;
- giao diện responsive tại `apps/web`;
- NestJS API tại `apps/api` với REST version `v1`, health tổng quát không lộ phiên bản, request ID, lỗi chuẩn hóa, cấu hình fail-fast và OpenAPI chỉ ngoài production;
- đăng nhập Argon2id, session cookie riêng tư, CSRF, giới hạn thử đăng nhập, khóa tài khoản, đăng xuất một phiên/tất cả phiên và audit;
- các package nền tảng `ui`, `contracts`, `shared`, `config`.

Giao diện production chỉ dùng API thật; không có công tắc bật dữ liệu demo và lỗi API không fallback sang dữ liệu giả. PostgreSQL/Prisma identity-access baseline, authentication, quản trị người dùng, Patient, TreatmentCase/TreatmentSession, checklist snapshot và CaseAssignment API đã có. Media API nhận ảnh lâm sàng/avatar JPEG/PNG tối đa 10 MiB và hợp đồng JPEG/PNG tối đa 10 MiB hoặc PDF tối đa 5 MiB vào quarantine, kiểm MIME/chữ ký và giải mã an toàn, tạo preview và stream private theo quyền. Treatment UI đã nối upload theo slot, tổng quan/lightbox/tải từng original và ZIP theo lần điều trị, thay ảnh có lý do, xem lịch sử phiên bản và chia sẻ các preview được chọn bằng link 3 ngày có watermark/thu hồi/audit. Replace giữ original cũ, dùng optimistic row version và chỉ chuyển bản mới thành current sau khi xử lý hợp lệ. Confirm/reopen tạo manifest/lịch sử bất biến, kiểm permission/scope/optimistic version/idempotency; ADMIN/DOCTOR được xác nhận/mở lại, LABO bị từ chối. Xác nhận phiên TREATMENT hoàn tất ca và mở lại kích hoạt lại ca trong cùng transaction; Chỉnh nha chỉ hoàn tất từng phiên. Ca điều trị có lưu trữ/khôi phục riêng bằng optimistic version, idempotency và audit; thao tác này không xóa dữ liệu con. Checklist v2/v3 có `allowedRoles`: ADMIN/DOCTOR mọi slot, LABO chỉ DSD/phục hình/phôi sứ và dữ liệu bảo hành; template Chỉnh nha v3 có thêm Phim pano và Phim cephalo. Pipeline `ContractFile` riêng đã nối upload/xem/tải hợp đồng JPEG/PNG/PDF bằng `contract.upload|view|download`, dùng quarantine, kiểm tra định dạng và preview an toàn rồi đưa vào manifest xác nhận schema v2. Tệp hợp đồng đã có xóa mềm bằng `contract.archive`, thùng rác/preview private và khôi phục trong đúng 30 ngày bằng `contract.restore` cho ADMIN/DOCTOR theo data scope; ảnh đại diện cũng có xóa mềm bằng `patient.update`, thùng rác/preview private và khôi phục 30 ngày bằng `patient.restore`. Backend kiểm scope, optimistic version, xung đột avatar/upload hiện hành, integrity original/preview và audit. PDF được kiểm tra trong worker cô lập có giới hạn 50 trang/heap/timeout, chặn active content và chỉ phục vụ original dạng attachment. Từ bản 0.1.19, runtime production không còn malware scanner; nguồn file nội bộ không phải là bảo đảm an toàn, nên quyết định giảm RAM này đồng thời giảm một lớp phòng vệ. Purge foundation sau 30 ngày đã có task queue, lease token, retry/audit, xóa original/preview idempotent và tombstone create-only ở volume riêng trước khi ghi `purgedAt`. Ledger reader read-only và restore apply engine đã có để kiểm canonical/digest, xóa lại file đã purge, áp deletion state và ghi receipt/audit sau restore. Backup scheduler 02:00, rotation 60 ngày và receipt Ed25519 đã có; purge scheduler/execution vẫn mặc định tắt và execution còn bắt buộc deletion ledger riêng, receipt còn mới và xác nhận hold rõ ràng. Runtime preflight, NAS staging preflight fail-closed và benchmark inventory read-only đã có; probe NAS chỉ ghi/đọc lại/xóa file ngẫu nhiên 64 KiB khi operator bật cờ rõ ràng. PostgreSQL 17.10 portable đã áp sạch 33 migration, seed ba loại người dùng và đạt integration harness D-07/D-13; Docker/NAS/SMB benchmark vẫn chờ thiết bị staging. Bản 0.1.17 loại ca đã xóa khỏi thẻ dịch vụ và số liệu bệnh nhân, sửa khôi phục ca Chỉnh nha xung đột theo hướng khôi phục ở trạng thái lưu trữ, đưa danh sách ca đã xóa vào popup gọn gàng, sửa nhãn xóa và ẩn thanh cuộn sidebar. Bản này kế thừa cơ chế khôi phục 30 ngày của 0.1.16 và hotfix migration 0.1.15 và chỉ đưa vào vận hành lâm sàng sau smoke test gateway/NAS, migration cùng tài khoản theo vai trò trên môi trường đích.

## Bộ tài liệu thiết kế

| Tài liệu | Nội dung |
|---|---|
| [PRD](docs/PRD.md) | Mục tiêu, phạm vi, yêu cầu nghiệp vụ và tiêu chí thành công |
| [Kiến trúc](docs/architecture.md) | Kiến trúc tổng thể, module, luồng dữ liệu và quyết định kỹ thuật |
| [Database schema](docs/database-schema.md) | Mô hình dữ liệu, ràng buộc, index và ERD |
| [Ma trận phân quyền](docs/permissions-matrix.md) | Role, permission, data scope và quy tắc theo đối tượng |
| [Quản trị tài khoản](docs/admin-account-management.md) | Tạo tài khoản, khóa/mở khóa, mật khẩu tạm thời và giới hạn an toàn của giao diện Admin |
| [Mô hình bảo mật](docs/security-model.md) | Threat model, kiểm soát bảo mật, logging và vận hành |
| [Media workflow](docs/media-workflow.md) | Upload, checklist, xác nhận, mở lại, thay thế, xóa và khôi phục |
| [Tích hợp CRM](docs/crm-integration.md) | Đối chứng, access grant, token và API bảo hành |
| [External Customer API](docs/external-customer-api.md) | API Client, token, tra cứu tên/số điện thoại, preview, bảo mật, cache và bàn giao |
| [Backup/restore](docs/backup-restore.md) | Backup, retention, integrity, restore và diễn tập |
| [Kế hoạch triển khai](docs/implementation-plan.md) | Các giai đoạn, nhóm thay đổi, kiểm thử và tiêu chí nghiệm thu |
| [Tiến độ triển khai](docs/implementation-progress.md) | Phần đã có trong code, kiểm tra đã chạy và nhóm tiếp theo |
| [Docker/Synology development](docs/deployment-development.md) | Container baseline, secret, network, migration và giới hạn kiểm chứng |
| [Chứng nhận NAS/SMB staging](docs/nas-staging-certification.md) | Topology, quyền tối thiểu, ACL/WORM, mã hóa/offsite và cổng nghiệm thu |
| [API hồ sơ bệnh nhân](docs/api-patients.md) | Endpoint Patient, tìm kiếm, field-level DTO, IDOR, idempotency và archive/restore |
| [API lần điều trị](docs/api-treatments.md) | TreatmentCase, tái khám Chỉnh nha, checklist snapshot, assignment và IDOR |
| [API Media processing](docs/api-media.md) | Upload intent, quarantine, decode/preview, replace/version chain, media-status, private read và ZIP theo lần điều trị |
| [API thông tin bảo hành](docs/api-warranties.md) | Mã bảo hành, thời hạn, ngày hiệu lực, scope, idempotency và checklist xác nhận |
| [Giả định và quyết định mở](docs/assumptions.md) | Giả định tạm thời, rủi ro và câu hỏi cần chủ dự án xác nhận |
| [Hệ thống giao diện thương hiệu](docs/ui-brand-system.md) | Token thương hiệu, typography và quy tắc responsive của prototype |

## Nguyên tắc không thương lượng

- Original, hợp đồng, backup, storage key và đường dẫn NAS không bao giờ được public trực tiếp; chia sẻ khách hàng chỉ phục vụ preview đã chọn và được đóng watermark ở server qua link 3 ngày có thể thu hồi.
- Backend kiểm tra cả quyền chức năng, phạm vi dữ liệu và quan hệ sở hữu của từng resource.
- Không dùng dữ liệu bệnh nhân thật trong seed, test, ảnh chụp màn hình, log hoặc tài liệu.
- Không lưu secret thật trong repository; mọi cấu hình runtime đi qua biến môi trường hoặc secret file.
- Xác nhận bộ ảnh là bản ghi bất biến; mọi sửa đổi sau xác nhận phải qua quy trình mở lại và xác nhận mới.
- RAID/snapshot không thay thế backup; restore phải được diễn tập và có bằng chứng.

## Bước tiếp theo

Release 0.2.28 kế thừa toàn bộ 0.2.27, đổi tiêu đề tab trình duyệt của ứng dụng chính cùng trang chia sẻ thành **DCIMS - Nụ Cười Việt** và chuẩn hóa dòng mô tả dưới **Danh sách cơ sở** thành chữ 10 px, màu nhạt, line-height 1.55 như dòng mô tả **Mẫu checklist theo dịch vụ**. Metadata Open Graph/Twitter dùng cùng tiêu đề; smoke test NAS kiểm tra chính xác thẻ `title`. Không có migration mới và không thay đổi API, database, permission, data scope, media lifecycle, retention.

Release 0.2.11 kế thừa toàn bộ 0.2.10. Các nhóm Ảnh, Phim và Hợp đồng lấy thẻ viền bao đầy đủ làm chuẩn trên iPad dọc/ngang và điện thoại ngang. Sidebar điện thoại ngang chuyển sang một scroll owner thực sự, không còn grid co và clip menu chính. Contract status trả thêm kết quả upload gần nhất để UI hiển thị tệp bị từ chối/hết hạn và cho phép tải lại thay vì quay về ô trống. Không có migration hoặc quyền mới.

Release 0.2.10 kế thừa toàn bộ 0.2.9. Menu ba chấm trên tablet dọc/ngang mở trong mép sidebar; sidebar điện thoại ngang cuộn độc lập để không mất mục. Điện thoại ngang dùng layout Settings một rail, nhóm tìm kiếm hai hàng, các thao tác tài khoản/hồ sơ 2 × 2, checklist ba cột và danh sách hồ sơ tách tiêu đề khỏi controls. Thẻ cơ sở điện thoại dọc/ngang theo mẫu đầy đủ ba metric và hai thao tác. Hợp đồng PDF được fetch có session từ endpoint original hiện hành, kiểm MIME/dung lượng 5 MiB, hiển thị bằng Blob URL tạm và thu hồi khi đổi/đóng; chỉ tài khoản có `contract.download` dùng được nên không mở rộng quyền. Không có migration hoặc API mới.

Release 0.2.9 kế thừa toàn bộ 0.2.8 và chỉ tinh chỉnh responsive tablet. Tablet dọc tách tiêu đề danh sách hồ sơ khỏi hàng tìm kiếm/bộ lọc, dùng hai thẻ cơ sở và hai thẻ tài khoản mỗi hàng; thao tác tài khoản xếp 2 × 2. Tablet ngang giữ hai hồ sơ mỗi hàng, một row-card cơ sở/tài khoản mỗi hàng, bỏ khoảng thụt trái của lưới media và chia đều bốn nút tài khoản. Các nhóm media có lại đường phân cách và bộ lọc giữ đủ chiều rộng để không tràn chữ. Không có migration mới và không thay đổi API, database, permission, data scope, media lifecycle, retention, NAS, backup hoặc External API.

Release 0.2.8 kế thừa toàn bộ 0.2.7 và khóa kích thước header tablet dọc: header 64 px, hamburger 42 px và logo 132 × 43 px. Tablet ngang giữ sidebar desktop và menu con Cài đặt dạng cột căn trái; tablet dọc chuyển sang header/hamburger, menu off-canvas và menu con toàn chiều rộng với nhãn căn trái. Cơ sở dùng row-card gọn trên tablet; hồ sơ bệnh nhân xếp các khối toàn chiều rộng; các nhóm ảnh Implant, Răng sứ và Chỉnh nha trở thành từng hàng ngang toàn chiều rộng với lưới vị trí ba cột ở tablet ngang, hai cột ở tablet dọc. Mobile dùng account card và branch card với thao tác rõ ràng. Root document là vùng cuộn dọc duy nhất; không thay đổi API, database, permission, media, retention hoặc External API.

Release 0.2.4 kế thừa toàn bộ 0.2.3, chuyển các trang tablet hẹp sang một content rail, thay bảng Bệnh nhân/Tài khoản bị cắt bằng thẻ responsive, cân lại lưới Cơ sở và workspace bộ ảnh. Trên điện thoại, mọi nhóm Implant, Răng sứ và Chỉnh nha xếp dọc toàn chiều rộng; ba thẻ Mẫu checklist không còn bị selector flex ép ngang. Hiệu ứng khôi phục viewport chỉ phụ thuộc định danh/trạng thái đổi mật khẩu ổn định nên heartbeat kiểm tra phiên 3 giây không còn kéo trang về đầu. Không thay đổi API, database, permission, media, retention hoặc External API.

Release 0.2.3 kế thừa toàn bộ 0.2.2, bỏ nút sao chép gộp Client ID + secret và thay bằng nút copy riêng. Client ID, secret một lần và Client ID trong danh sách đều che mặc định, có mắt ẩn/hiện. Khối credential một lần nằm trong đúng thẻ API Client theo internal admin ID và có fallback gắn tên client nếu refresh danh sách thất bại. Đây là UI privacy/clarity, không biến Client ID thành secret và không thay đổi API, database, permission, token, scope hoặc lifecycle.

Release 0.2.2 kế thừa toàn bộ 0.2.1 và thiết kế lại vùng secret, empty/loading state cùng thẻ API Client theo cấp bậc rõ ràng; thông báo thành công không còn lặp khi secret đang hiển thị. Menu con Cài đặt tăng chữ từ 10 px lên 13 px và icon từ 17 px lên 19 px; responsive 1180/700/560 px được bổ sung. Không thay đổi API, permission, token, scope, database, retention hoặc cơ chế tải hợp đồng.

Release 0.2.1 kế thừa toàn bộ 0.2.0 và cải tiến quản trị External API: Admin sửa tên/IP/quyền hợp đồng, xem thống kê sử dụng và cảnh báo credential; đổi IP hoặc quyền sẽ thu hồi token cũ. Quyền `contract.list|contract.download` mặc định tắt, chỉ trả hợp đồng current/VALID của ca ACTIVE và phiên CONFIRMED theo `contractRef` opaque. Khách hàng bấm tải là nhận file qua backend cổng ngoài, không có OTP/xác nhận bổ sung trong NCV DCIMS; ảnh lâm sàng vẫn chỉ preview và không có original/download. Không có migration mới so với 0.2.0.

Release 0.1.50 kế thừa toàn bộ 0.1.49 và sửa đúng vùng được khoanh: lưới popup **Chỉnh sửa tài khoản** dùng khoảng cách dọc 12 px giữa hàng **Họ và tên/Vai trò** với hàng **Cơ sở chính/Phạm vi toàn hệ thống**, tránh dính viền hoặc dải tiếp giáp bất thường. Popup tạo tài khoản và nghiệp vụ giữ nguyên.

Release 0.1.49 kế thừa toàn bộ 0.1.48 và sửa lỗi khối **Phạm vi toàn hệ thống** trong popup **Chỉnh sửa tài khoản** chỉ rộng nửa form. Trường **Cơ sở chính** hoặc thông báo phạm vi ở hàng thứ hai nay chiếm trọn hai cột; popup tạo tài khoản và toàn bộ nghiệp vụ giữ nguyên. Không có migration database hoặc thay đổi API, permission, session, media, retention, NAS hay backup.

Release 0.1.48 kế thừa toàn bộ 0.1.47, gộp **Đổi cơ sở** và **Đổi vai trò** thành **Chỉnh sửa tài khoản**. Endpoint mới cập nhật nguyên tử họ tên, vai trò và cơ sở chính; Admin/Labo không nhận cơ sở, backend kiểm đủ permission/scope và bảo vệ Admin cuối cùng. Khóa/xóa thu hồi toàn bộ session trong transaction, còn web dùng heartbeat 3 giây cùng kiểm tra focus/visibility để giao diện đang mở trở về đăng nhập nhanh. Không có migration database; bằng chứng tại `docs/evidence/release-0.1.48-verification-2026-08-24.md`.

Release 0.1.47 kế thừa toàn bộ 0.1.46 và đồng bộ ảnh đại diện hồ sơ vào hai danh sách **Bộ ảnh chưa hoàn tất** và **Bệnh nhân mới cập nhật** trên trang Tổng quan. Dashboard API chỉ trả URL preview private cùng-origin khi bệnh nhân có avatar current/VALID/chưa xóa/chưa purge; giao diện hiển thị ảnh ở kích thước 52 px desktop và 48 px mobile, chỉ dùng chữ viết tắt khi không có ảnh. Không public media, không trả storage key, không có migration database và không thay đổi permission, retention, NAS hoặc backup.

Release 0.1.46 kế thừa toàn bộ 0.1.45 và xử lý đúng hai khu vực giao diện đã chốt: tăng cỡ chữ cùng cân lại khoảng dọc của khối nhận diện menu trái; trong popup **Sửa thông tin bệnh nhân**, tăng cỡ chữ tiêu đề/hướng dẫn ảnh nhận diện và đưa nhãn **Đổi ảnh nhận diện** sang mép phải, căn giữa dọc với hình dáng nút rõ ràng nhưng không tạo control mới. Popup thêm bệnh nhân giữ nguyên. Không thay đổi nghiệp vụ, API, database, permission, media, retention, NAS hoặc backup.

Release 0.1.44 kế thừa toàn bộ 0.1.43 và sửa riêng popup **Chia sẻ dữ liệu với khách hàng** trên điện thoại: bỏ giới hạn chiều cao nội bộ làm các nhóm ảnh tràn đè lên nhau, dùng một vùng cuộn duy nhất cho danh sách nhóm và giữ tiêu đề cùng nút **Chọn tất cả** không bị ép dòng. Không thay đổi logic chọn/chia sẻ, thời hạn link, watermark, API, database, permission, media, retention, NAS hoặc backup.

Release 0.1.45 kế thừa toàn bộ 0.1.44 và chuẩn hóa khả năng đọc trên màn hình Full HD/laptop: tăng cỡ chữ có chọn lọc cho Tổng quan, Bệnh nhân, Tài khoản, Cơ sở, Mẫu checklist, Trợ giúp, checklist điều trị, Tổng quan bộ ảnh và trang chia sẻ; tăng avatar bệnh nhân trong danh sách; làm rõ bộ đếm nhóm như `0/9`. Không scale toàn trang, không thay đổi nghiệp vụ, API, database, permission, media, retention, NAS hoặc backup.

Release 0.1.43 kế thừa toàn bộ 0.1.42 và hoàn thiện giao diện quản trị đã được duyệt: danh sách tài khoản dùng bảng năm cột toàn chiều rộng, nhóm thao tác trực tiếp căn phải theo thứ tự cố định; danh sách cơ sở dùng lưới 3/2/1 cột và giữ tìm kiếm tên/mã/địa chỉ. Tài khoản có username chuẩn hóa `admin` được bảo vệ bất biến ở backend và frontend: không ai có thể khóa, mở khóa hoặc xóa tài khoản này. Không thay đổi database, media, retention, NAS hoặc backup.

Release 0.1.42 kế thừa toàn bộ 0.1.41 và xử lý nguyên nhân Safari giữ mức phóng sau đăng nhập: ô nhập ở điện thoại/tablet dùng cỡ chữ tối thiểu 16 px, trang đăng nhập có bố cục riêng cho điện thoại dọc và tablet dọc, và sau xác thực thành công frontend tải lại URL đúng một lần để Dashboard khởi tạo bằng viewport mới. Desktop giữ bố cục hiện có; pinch-zoom không bị khóa thường trực. Không có migration database, thay đổi API, quyền, media, retention, NAS hoặc backup.
Release 0.1.40 kế thừa toàn bộ 0.1.39 và sửa riêng hai lỗi Safari sau xác thực: vẫn cho phép phóng tự nhiên khi người dùng đang nhập, nhưng chủ động bỏ focus, khôi phục viewport và cuộn về đầu trang sau khi đăng nhập hoặc đổi mật khẩu thành công; hàng tài khoản cuối menu di động được nâng khỏi thanh trình duyệt bằng safe-area. Không có migration database, thay đổi API, quyền, media, retention, NAS hoặc backup. UAT iPhone Safari sau triển khai NAS vẫn là điều kiện nghiệm thu.
Release 0.1.39 kế thừa toàn bộ 0.1.38, sửa thông báo đăng nhập và responsive mobile, bổ sung xóa quyền truy cập tài khoản tức thời có bảo vệ tự xóa/Admin cuối cùng, chuyển danh sách tài khoản thành thẻ 3/2/1 cột với nút thao tác trực tiếp, thêm tìm kiếm cơ sở và tách khoảng cách nút trên thẻ cơ sở. Bản này có migration tiến về phía trước thêm `users.deleted_at`; PII/quyền/phiên của tài khoản bị xóa ngay nhưng UUID kỹ thuật vô danh được giữ để bảo toàn hồ sơ lâm sàng và audit. **Nhắc checklist bộ ảnh** giữ nguyên.
Release 0.1.38 kế thừa toàn bộ 0.1.37 và căn giữa theo chiều dọc số thứ tự cùng nội dung trong từng bước của popup **Trợ giúp**, loại bỏ trạng thái chữ bị neo lệch lên trên. Không thay đổi nội dung hướng dẫn, popup, Mẫu checklist hoặc Nhắc checklist bộ ảnh; không có migration database, thay đổi retention, permission, API, media, storage hoặc backup.
Release 0.1.37 kế thừa toàn bộ 0.1.36 và hoàn thiện hai tương tác giao diện: các mục **Xem hướng dẫn** mở trong popup responsive có thể đóng bằng nút, phím Esc hoặc nền mờ; ba thẻ **Mẫu checklist theo dịch vụ** luôn đồng đều và mở nội dung trong popup thay vì làm lệch hàng. Tính năng **Nhắc checklist bộ ảnh** được giữ nguyên theo quyết định mới của chủ dự án. Không có migration database, thay đổi retention, permission, API, media, storage hoặc backup.
Release 0.1.36 kế thừa toàn bộ 0.1.35, hoàn thiện trang **Hồ sơ đã xóa gần đây** với 12 hồ sơ/trang, tìm kiếm tên/số điện thoại, lọc cơ sở/dịch vụ, sắp xếp và lưới responsive 4/2/1 cột. Trang **Trợ giúp** nay bao phủ 9 nhóm tính năng đang có theo vai trò Admin/Bác sĩ/Labo; hai khối kêu gọi hỗ trợ thủ công đã được loại bỏ và khoảng menu được cân lại. Không có migration database, thay đổi retention, permission, media hoặc storage.

Release 0.1.35 kế thừa toàn bộ 0.1.34 và thay pattern watermark tự lặp bằng tối đa 10 logo hữu hạn trên mỗi preview public. Logo giữ nguyên kích thước đã duyệt, được phân bố thưa theo tỷ lệ ảnh, xoay chéo và có alpha tối đa 40%. Original, preview private và byte upload không bị sửa hoặc nén. Không có migration database.

Release 0.1.34 kế thừa toàn bộ 0.1.33 và sửa luồng preview public khi một link có nhiều ảnh: giới hạn nghiệp vụ vẫn là 200 ảnh/link nên 90 ảnh được hỗ trợ, gateway chỉ xử lý tối đa 32 kết nối preview đồng thời cho mỗi IP, thumbnail tải lười và tự thử lại tối đa ba lần khi gặp lỗi tạm thời. Watermark logo NCV được thu nhỏ và lặp chéo trên toàn preview với alpha tối đa 70%; original, preview nội bộ và byte upload không bị sửa hoặc nén. Không có migration database.

Release 0.1.33 kế thừa toàn bộ 0.1.32 và thay watermark chữ lặp chéo trên preview chia sẻ bằng logo NCV màu trắng có alpha do chủ dự án cung cấp. Logo được cắt bỏ vùng trong suốt thừa, đặt một lần ở góc phải dưới, rộng khoảng 21% ảnh (có giới hạn tối thiểu/tối đa) và có lề an toàn. Original, preview nội bộ, giới hạn upload và pipeline kiểm tra tệp không thay đổi; không có nén ảnh và không có migration database.

Release 0.1.32 kế thừa toàn bộ 0.1.31 và sửa luồng xử lý tệp bất đồng bộ: ngay sau khi backend hoàn tất nhận tệp vào quarantine và chuyển sang `VALIDATING`, worker được đánh thức để xử lý ngay thay vì chờ nhịp quét nền; giao diện tiếp tục làm mới trạng thái với backoff thích ứng cho đến khi tệp hợp lệ, bị từ chối hoặc cần phục hồi. Mọi kiểm tra kích thước, MIME, chữ ký, giải mã an toàn, quarantine và phân quyền vẫn giữ nguyên; không có migration database.

Release 0.1.31 kế thừa toàn bộ 0.1.30 và siết bốn ranh giới production: chỉ tin `CF-Connecting-IP` từ đúng container cloudflared, API chỉ tin một gateway proxy; CSP dùng nonce cho script và bỏ `script-src 'unsafe-inline'`; token chia sẻ dùng secret riêng tối thiểu 32 byte; trang nội bộ `noindex`, tắt `x-powered-by` và không public endpoint phiên bản. Không có migration database hoặc thay đổi nghiệp vụ.
Release 0.1.29 kế thừa toàn bộ 0.1.28 và hoàn thiện Chỉnh nha: lần tái khám dùng đúng hai cột **Ảnh lần tái khám** và **Phim** trên desktop, một cột trên điện thoại; một link chia sẻ có thể chọn ảnh/hợp đồng từ toàn bộ các lần khám không bị hủy trong cùng một ca Chỉnh nha. Backend vẫn kiểm quyền, scope bệnh nhân/ca, chỉ nhận tài sản current/VALID và từ chối mọi tài sản khác ca; giới hạn lựa chọn được nâng lên 200 mục để đáp ứng liệu trình dài.

Release 0.1.28 kế thừa toàn bộ 0.1.27 và đồng bộ trang khách hàng với cấu trúc **Tổng quan bộ ảnh**: các tệp được chọn được nhóm theo checklist snapshot, giữ đúng thứ tự nhóm/vị trí, tách riêng khối Phim Chỉnh nha và không hiển thị mục chưa được chia sẻ. Lịch sử điều trị đồng thời phân biệt rõ `Chỉnh nha mắc cài` và `Chỉnh nha Invisalign` theo từng ca; thay đổi chỉ ở manifest public và giao diện, không có migration database.

Release 0.1.27 kế thừa toàn bộ 0.1.26 và hoàn thiện luồng chia sẻ: hợp đồng dùng đúng `MediaAsset.id` nên không còn HTTP 400 khi chọn hợp đồng; hộp chọn nhóm ảnh theo thứ tự Tổng quan bộ ảnh; link mới có thể sao chép lại trong suốt ba ngày còn hiệu lực mà database vẫn chỉ lưu digest; hết hạn hoặc thu hồi thì đường dẫn không còn được trả. Trang khách hàng cho phép bấm preview watermark để xem lớn trong popup, không có tải original, và thẻ bảo hành hiển thị đúng phần trăm cùng số ngày còn lại.

Không còn giai đoạn lập trình lớn nào trong phạm vi 0.1.50. Còn **1 giai đoạn vận hành**: triển khai lên NAS, xác nhận IP container cloudflared, chạy smoke test gateway/storage/security và UAT bằng dữ liệu giả với ảnh dọc/ngang/vuông cùng link 90 ảnh. Link được tạo trước 0.1.27 chỉ lưu digest ngẫu nhiên nên không thể khôi phục sau khi tải lại trang; cần tạo link mới nếu muốn nút sao chép luôn khả dụng. Purge production vẫn mặc định tắt cho đến khi chứng nhận hạ tầng và backup/restore trên thiết bị thật đạt yêu cầu.
## Quy ước định danh

- Tên hiển thị: `NCV DCIMS`
- Repository: `ncv-dcims`
- Database prefix: `ncv_dcims`
- Docker/service prefix: `ncv-dcims`
- Không sử dụng tên dự án cũ trong code, cấu hình, tài liệu hoặc giao diện.

## Lịch sử bộ bàn giao 0.2.28

Bộ tài liệu trước 0.2.29: [README FINAL 0.2.28](docs/final/0.2.28/README-FINAL.md). Gồm installer nguyên bản, hướng dẫn cài mới/cập nhật, PDF độc lập cho ADMIN/DOCTOR/LABO có ảnh giao diện bằng dữ liệu giả và bảng kiểm chứng. NAS được chủ hệ thống xác nhận đã chạy 0.2.28; ưu tiên kiểm tra/bàn giao, không mặc định cài lại. Bộ đã sắp xếp ngày 09/09/2026: [Mở danh mục trực quan](release/NCV-DCIMS-BAN-GIAO-0.2.28/MO_DANH_MUC.html), [ZIP bàn giao mới](release/NCV-DCIMS-BAN-GIAO-0.2.28.zip). Sáu thư mục đánh số tách bộ cài, hướng dẫn cập nhật, PDF vai trò, kiểm chứng, nguồn tài liệu và ảnh giao diện. ZIP FINAL trước đó và PDF tại `output/pdf` được giữ để đối chiếu. Các giới hạn integration/NAS chưa kiểm chứng được ghi trong tài liệu, không coi tên FINAL là nghiệm thu vận hành.

## Bộ bàn giao lưu trữ 0.2.29

[Mở danh mục](release/NCV-DCIMS-BAN-GIAO-0.2.29/MO_DANH_MUC.html) · [ZIP đầy đủ](release/NCV-DCIMS-BAN-GIAO-0.2.29.zip) · [Hướng dẫn cập nhật](docs/operations/synology-update-0.2.29.md).

Bộ 0.2.29 thay thế 0.2.28/r2. Bốn PDF, cấu hình mẫu, version API/Web/Compose và checksum được cập nhật đồng bộ. Tham chiếu tên scanner cũ trong updater/Dockerfile/exclude chỉ dùng dọn hoặc bỏ qua mã đã nghỉ khi cài đè; không chứa công cụ chạy hay sinh mẫu thử. Chưa có kết quả antivirus hoặc Google Drive cho ZIP mới.
