Skip to content

PRD: Quản lý asset & media

ModuleNền tảng (CORE-16)PRD IDPRD-AST-001
StatusShippedOwnerPlatform squad
Date2026-06-15Versionv1.0
Packages@nx/asset · @nx/coreURDAST · MTL · BNK

TL;DR

Cho mọi service của KICKO một cách dùng chung để lưu, định địa chỉ, và phục vụ media nhị phân - ảnh sản phẩm, logo tổ chức, tài liệu - trên object storage tương thích S3. Một upload multipart được xác thực đặt mỗi tệp dưới một object name duy nhất, an toàn URL, và ghi một meta-link bền vững: tọa độ lưu trữ của object cộng mimetype, size, etag của nó, và một ràng buộc tùy chọn tới thực thể nghiệp vụ nó thuộc về (một product, một variant, một organizer, một ledger…). Object stream lại inline hoặc tải về dạng attachment theo tên; meta-link truy vấn được như một tài nguyên CRUD nên mọi object tìm được theo chủ của nó. Cùng backbone đó phục vụ một bundle bản địa hóa dùng chung và một registry ngân hàng Việt Nam chỉ-đọc kèm logo ngân hàng, để storefront và back office render lựa chọn ngân hàng và bản dịch từ một nguồn.

1. Bối cảnh & Vấn đề

Mỗi module sản phẩm cần đính kèm media. Product và variant cần ảnh, organizer cần logo, ledger và ticket cần tài liệu hỗ trợ, và storefront cần logo ngân hàng cùng một bundle bản dịch dùng chung. Không có một backbone dùng chung, mỗi service sẽ tự phát minh đường upload riêng, sơ đồ đặt tên object riêng, và cách riêng để nhớ tệp nào thuộc bản ghi nào - và dữ liệu tham chiếu ngân hàng sẽ bị copy-paste và trôi dạt.

Khoảng trống có hai phần. Thứ nhất, một primitive lưu-và-nhớ: một nơi để đặt một nhị phân, lấy lại một link ổn định, và giữ một bản ghi bền vững gắn object với thực thể nó minh họa, để catalogue tìm được "ảnh cho variant này" mà không phải quét bucket. Thứ hai, media tham chiếu dùng chung: một bundle bản địa hóa và một registry ngân hàng Việt Nam (kèm logo) mà cả nền tảng đọc thay vì mỗi app mang bản sao riêng.

PRD này đặc tả backbone media dùng chung đó: upload được xác thực lên object storage với một bản ghi meta-link cho mỗi object, ràng buộc principal và một API truy vấn meta-link, phục vụ và liệt kê công khai, bundle bản địa hóa, và registry ngân hàng cùng các endpoint logo.

2. Mục tiêu & Không-mục-tiêu

Mục tiêu

  • Một upload multipart được xác thực lên một bucket tương thích S3 gán cho mỗi tệp một object name duy nhất, an toàn URL, và trả về một link định địa chỉ được (AST).
  • Một bản ghi meta-link cho mỗi object đã lưu ghi tọa độ lưu trữ, mimetype, size, etag, metadata, và storage type của nó (MTL).
  • Ràng buộc principal tại lúc upload - một object có thể mang principalType / principalId / variant để tìm được theo thực thể nó thuộc về (MTL).
  • Phục vụ công khai: stream một object inline theo tên, tải về dạng attachment, và liệt kê một bucket theo prefix; cộng delete xóa cả object và meta-link cùng nhau (AST).
  • Một bundle bản địa hóa dùng chung phục vụ inline và tải về được từ bucket cấu hình (AST).
  • Một registry ngân hàng Việt Nam chỉ-đọc dạng JSON - mỗi entry kèm tên, cờ năng lực, và một logo URL tuyệt đối - cộng một endpoint logo PNG theo từng ngân hàng (BNK).
  • Định địa chỉ an toàn: object name / độ sâu thư mục được kiểm tra, tên tệp logo nghiêm ngặt, header phản hồi trong danh sách trắng, và nosniff trên mọi stream (AST, BNK).

Không-mục-tiêu

  • Biến đổi ảnh, tạo thumbnail, hoặc resize động - object được phục vụ như đã lưu.
  • Cô lập bucket theo từng merchant hoặc lưu trữ giới hạn theo tenant - một bucket cấu hình duy nhất hậu thuẫn service chủ.
  • Một UI duyệt thư viện media được quản lý - PRD này cung cấp bề mặt API, không phải màn hình gallery.
  • Tác giả hoặc sửa registry ngân hàng - đây là dữ liệu tham chiếu chỉ-đọc đóng gói cùng service.
  • Pipeline thông báo real-time (ACT, WSS) - đặc tả trong PRD-ACT-001.

3. Chỉ số thành công

Chỉ sốMục tiêu / tín hiệu
Toàn vẹn uploadMọi object lưu thành công có một meta-link khớp với size, mimetype, và etag của nó
Khả năng tìmMột object upload kèm ràng buộc principal lấy được theo type + id của principal đó
An toàn đặt tênKhông object name nào trùng hoặc mang đường dẫn không an toàn; mọi stream đặt nosniff
Tái dùng tham chiếuStorefront và back office render lựa chọn và logo ngân hàng từ một registry, không phải bản sao cục bộ
Toàn vẹn dọn dẹpXóa một object không để lại meta-link mồ côi cho bucket + object đó

4. Nhân vật & Tình huống

Nhân vậtMục tiêu trong tính năng
Owner / ManagerĐính một ảnh vào product hoặc một logo vào tổ chức và hiện nó ở mọi nơi thực thể đó xuất hiện
Service tạo sự kiệnUpload một object, ràng buộc nó với một bản ghi, và sau đó phân giải media của bản ghi theo meta-link
Storefront / clientStream một ảnh theo tên, render lựa chọn và logo ngân hàng, và tải bundle bản dịch dùng chung
Người vận hành nền tảngTin rằng object name an toàn và delete dọn dẹp cả lưu trữ lẫn metadata

Tình huống cốt lõi: một manager thêm một ảnh khi sửa một variant. Client upload tệp kèm principalTypeprincipalId của variant; service lưu nó dưới một object name duy nhất, trả về link, và ghi một meta-link ghi object và ràng buộc của nó. Bất cứ đâu variant đó xuất hiện sau này, media của nó được phân giải theo meta-link. Riêng biệt, màn hình checkout lấy registry ngân hàng một lần và render mỗi nhà cung cấp kèm logo URL tuyệt đối của nó.

5. User Stories

  • Là một manager, tôi đính một ảnh vào một product và nó xuất hiện ở mọi nơi product hiện, để catalogue trông hoàn chỉnh.
  • Là một service tạo sự kiện, tôi ràng buộc một object đã upload với bản ghi nó minh họa, để sau này tìm được media của bản ghi mà không phải quét bucket.
  • Là một client, tôi stream một ảnh theo object name và tải một tài liệu dạng attachment, để media chỉ việc hoạt động trong UI.
  • Là một client, tôi đọc một registry ngân hàng kèm logo URL tuyệt đối, để render lựa chọn thanh toán mà không tự nối đường dẫn.
  • Là một người vận hành, tôi xóa một object và tin rằng meta-link của nó cũng được dọn, để không gì lủng lẳng.
  • Là một client, tôi tải một bundle bản địa hóa dùng chung, để mọi bề mặt dịch từ cùng một nguồn.

6. Yêu cầu chức năng

#Yêu cầuURD ref
FR-1Upload multipart được xác thực lưu một hoặc nhiều tệp trong bucket cấu hình, mỗi cái dưới một object name duy nhất an toàn URL, trả về object name và link định địa chỉ của nóURD-AST-001
FR-2Một upload có thể mang một folder path (được kiểm tra, tối đa hai cấp) và một ràng buộc principal (principalType / principalId / variant)URD-AST-002 · URD-MTL-002
FR-3Sau khi lưu thành công, một meta-link được tạo cho mỗi object ghi bucket, object name, link, mimetype, size, etag, metadata, storage type, và cờ syncURD-MTL-001
FR-4Một object đã lưu stream inline theo object name; đường dẫn object lồng tới hai cấp thư mục được hỗ trợURD-AST-003
FR-5Một object đã lưu tải về dạng attachment (content-disposition) theo object nameURD-AST-004
FR-6Một delete được xác thực xóa object khỏi lưu trữ và dọn các bản ghi meta-link của nó cho bucket + object đóURD-AST-005 · URD-MTL-004
FR-7Một list được xác thực trả về các object của một bucket lọc theo prefix, recursion, và max-keysURD-AST-006
FR-8Một bundle bản địa hóa dùng chung phục vụ inline và tải về được dạng attachment từ bucket cấu hìnhURD-AST-007
FR-9Meta-link được phơi bày như một tài nguyên CRUD (find, find-by-id, find-one, count, create, update, delete) qua xác thực JWT / BasicURD-MTL-003
FR-10Registry ngân hàng Việt Nam phục vụ dạng JSON - mỗi entry với tên ngắn, tên đầy đủ, cờ năng lực (VietQR, disburse, NAPAS), và một logo URL tuyệt đốiURD-BNK-001..002
FR-11Mỗi logo ngân hàng phục vụ dạng PNG theo tên tệp <code>.png, kiểm tra theo một mẫu nghiêm ngặt, với caching immutable lâu dàiURD-BNK-003
FR-12Object name, folder path, và tên tệp logo được kiểm tra; chỉ các header metadata trong danh sách trắng được phản chiếu và nosniff được đặt trên mọi streamURD-AST-008 · URD-BNK-004

Toàn văn yêu cầu và tiêu chí chấp nhận sống trong Platform URD - AST · MTL · BNK. PRD này tham chiếu chúng thay vì lặp lại.

7. Yêu cầu phi chức năng

Lĩnh vựcYêu cầu
An toàn đặt tênObject name là duy nhất và an toàn URL; độ sâu thư mục bị giới hạn và mọi segment đường dẫn được kiểm tra trước khi lưu hoặc lấy
Vệ sinh headerChỉ các header metadata trong danh sách trắng được phản chiếu lên phản hồi; nosniff luôn được đặt; giá trị header bị loại CR/LF
Trừu tượng lưu trữLưu trữ được tiếp cận qua một helper tương thích S3 duy nhất cấu hình từ môi trường (endpoint, access key, secret key, bucket)
Khả năng phục hồiMột meta-link ghi lỗi không làm mất object đã lưu - object được báo cáo kèm lỗi meta-link theo từng tệp; dọn meta-link khi delete là best-effort và được log
CachingRegistry ngân hàng cacheable (max-age); logo ngân hàng phục vụ immutable với max-age dài
Xác thựcUpload, delete, list, và API CRUD meta-link cần xác thực JWT / Basic; đọc object, bundle bản địa hóa, và registry / logo ngân hàng là đọc công khai
i18nTên hiển thị ngân hàng và bundle bản địa hóa dùng chung là nguồn bản địa hóa; entry ngân hàng mang cả tên ngắn lẫn tên đầy đủ

8. UX & Luồng

Bề mặt upload nhận một hoặc nhiều tệp kèm một folder path tùy chọn và một ràng buộc principal, và trả về object name, link, và meta-link (hoặc lỗi meta-link) của mỗi object. Đọc stream theo object name inline hoặc dạng download; một bucket liệt kê được theo prefix. Registry ngân hàng và logo theo từng ngân hàng được lấy thẳng vào UI.

9. Dữ liệu & Miền

Thực thểVai trò
MetaLinkBản ghi bền vững của một object đã lưu - bucket, object name, link, mimetype, size, etag, metadata, storage type, cờ sync - cộng một ràng buộc principal tùy chọn (principalType, principalId, variant)
Stored objectNhị phân trong bucket tương thích S3, định địa chỉ theo object name và tiếp cận qua link của nó
Bank registry entryMột bản ghi tham chiếu chỉ-đọc - tên ngắn, tên đầy đủ, cờ năng lực (VietQR, disburse, NAPAS), và một logo - đóng gói cùng service

Chỉ khái niệm - toàn bộ schema và bất biến sống trong asset domain model. Quan hệ principal là soft reference phân giải theo type + id, không phải khóa ngoại database.

10. Phụ thuộc & Giả định

Phụ thuộc vào

  • Object storage tương thích S3 - một endpoint, access key, secret key, và một bucket mặc định được cấu hình trong môi trường.
  • @nx/core - sở hữu schema / model / repository MetaLink, registry principal-type, và các environment key dùng chung.
  • Một explorer base URL cấu hình - dùng để chiếu các đường dẫn logo ngân hàng tương đối thành URL tuyệt đối cho client.

Giả định

  • Service tạo sự kiện biết principalType / principalId của bản ghi nó đang đính media.
  • Bundle bản địa hóa và các asset logo banks-VN có mặt trong bucket cấu hình / đóng gói cùng service.
  • Một bucket cấu hình duy nhất là đủ cho service chủ; cô lập đa-bucket / theo-từng-tenant ngoài phạm vi ở đây.

11. Rủi ro & Câu hỏi mở

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Object đã lưu nhưng meta-link ghi lỗiObject không bị mất - được trả về kèm lỗi meta-link theo từng tệp và được log để đối soát
Object name không an toàn hoặc trùngTên được tạo duy nhất và an toàn URL; độ sâu thư mục bị giới hạn và segment được kiểm tra; đọc từ chối đường dẫn không hợp lệ
Ủy quyền CRUD meta-link hiện đang dễ dãiFollow-up đã biết - siết API meta-link về tập permission của nó được theo dõi (URD-CON-005)
Path traversal logo ngân hàngTên tệp logo phải khớp mẫu <code>.png nghiêm ngặt; bất cứ gì khác bị từ chối trước khi truy cập đĩa
Registry ngân hàng trôi dạt giữa các appMột registry chỉ-đọc duy nhất phục vụ từ một nguồn; các app ngừng mang bản sao cục bộ

12. Kế hoạch phát hành & Tiêu chí ra mắt

Khía cạnhKế hoạch
PhaseP2 - AST, MTL, BNK trong URD feature catalog
RolloutĐược mount bởi các service chủ cần media; không feature flag
MigrationKhông - store MetaLink và các asset ngân hàng đóng gói ship cùng service
Tiêu chí ra mắtUpload lưu object kèm một meta-link và ràng buộc tùy chọn; object stream inline và tải theo tên; delete dọn cả lưu trữ lẫn meta-link; registry ngân hàng trả về entry kèm logo URL tuyệt đối và logo phục vụ dạng PNG
Giám sátTỷ lệ lỗi upload, tỷ lệ meta-link ghi lỗi, nhất quán object-vs-meta-link, hành vi cache hit registry / logo

13. FAQ

Tệp upload đi đâu? Vào bucket tương thích S3 cấu hình, mỗi cái dưới một object name duy nhất, an toàn URL, với một link định địa chỉ trả về cho caller.

Làm sao tìm media cho một product hoặc variant cụ thể? Ràng buộc object tại lúc upload với principalTypeprincipalId của nó; meta-link khi đó làm nó tìm được theo thực thể đó qua API truy vấn meta-link.

Điều gì xảy ra nếu meta-link không ghi được sau khi một tệp đã lưu? Object không bị mất - kết quả upload báo tệp đó kèm một lỗi meta-link để đối soát; các tệp khác trong cùng upload không bị ảnh hưởng.

Object upload có công khai không? Đọc object, bundle bản địa hóa, và registry / logo ngân hàng là đọc công khai; upload, delete, list, và API CRUD meta-link cần xác thực.

Tôi có sửa được registry ngân hàng không? Không - đây là dữ liệu tham chiếu chỉ-đọc đóng gói cùng service. Mỗi entry được chiếu kèm một logo URL tuyệt đối để client dùng trực tiếp.

Xóa một object có để lại bản ghi của nó không? Không - một delete xóa object khỏi lưu trữ và dọn các bản ghi meta-link của nó cho bucket + object đó.

Trang liên quan

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.