Hệ thống mã nguồn (Bookmarks v3) là một ứng dụng Web App toàn diện (Full-stack) thu nhỏ chạy hoàn toàn trên hệ sinh thái của Google. Ứng dụng sử dụng Google Sheets làm Cơ sở dữ liệu (Database), Google Apps Script làm Backend xử lý logic và HTML/CSS/JS làm Frontend hiển thị giao diện kéo thả thuận tiện.

Dưới đây là phân tích chuyên sâu về kiến trúc, cơ chế hoạt động và các điểm sáng công nghệ trong 2 file code của ứng dụng.

1. Phân tích File Backend (Code.gs)

File này đóng vai trò như một máy chủ (Server-side), chịu trách nhiệm xử lý toàn bộ logic nghiệp vụ bảo mật, truy vấn dữ liệu và tương tác trực tiếp với Google Sheets.

🛡️ Cơ chế Phân quyền (Role-based Access Control)

Hệ thống quản lý nghiêm ngặt qua 3 cấp độ quyền bằng hàm checkDataPermission(role) trước khi thực thi bất kỳ thao tác thay đổi dữ liệu nào:

  • Admin: Toàn quyền tối cao. Là cấp duy nhất có thể gọi hàm renameSheetServer (Đổi tên trang tính) và deleteSheetServer (Xóa trang tính).

  • User (Nhân viên): Có quyền thêm, sửa, xóa các liên kết (Bookmarks) và kéo thả đổi danh mục, nhưng không được can thiệp vào cấu trúc Sheet.

  • Xem (Khách): Bị chặn ngay từ tầng Server. Nếu cố tình gọi các hàm ghi dữ liệu, Server sẽ trả về lỗi "Bạn không có quyền...".

🔑 Tính năng Khôi phục Mật khẩu bằng OTP qua Email

Đây là logic nâng cao rất hay, hoạt động dựa trên hai dịch vụ lõi của Google:

  1. CacheService.getScriptCache(): Khi khách bấm quên mật khẩu, hệ thống tạo ra một chuỗi ngẫu nhiên 6 chữ số và nạp vào bộ nhớ đệm (Cache) của Google Script với thời gian sống là 300 giây (5 phút). Thiết kế này giúp kiểm tra mã OTP cực nhanh mà không cần ghi bừa bãi vào file Excel gây rác dữ liệu.

  2. MailApp.sendEmail(): Tự động lấy Email cấu hình tương ứng với tài khoản đó trong Sheet để gửi mã xác thực đi.

  3. Mã hóa hiển thị (Masking Email): Trước khi trả phản hồi về giao diện, hàm sendOtpEmailServer tự động ẩn ký tự Email (Ví dụ: gu***@example.com) giúp bảo mật danh tính người dùng.

📊 Quản trị Dữ liệu (CRUD) và Tự động hóa

  • Khởi tạo thông minh (getSheetSafely): Cơ chế phòng vệ lỗi (Error-handling) tuyệt vời. Nếu vô tình ai đó xóa mất trang tính, hàm này sẽ tự động tái tạo lại cấu trúc chuẩn, nạp sẵn dữ liệu 3 tài khoản mẫu cùng các cột tiêu đề được định dạng in đậm, đổ nền xám tự động.

  • Tự sinh ID tăng dần (generateNextAppId): Quét toàn bộ cột A, tìm mã lớn nhất (ví dụ APP002) rồi tự động tính toán cắt chuỗi, cộng thêm 1 để sinh ra mã tiếp theo (APP03), đồng thời chuẩn hóa chuỗi bằng hàm padStart(3, '0').

2. Phân tích File Frontend (Index.html)

Giao diện được thiết kế theo phong cách hiện đại, tối giản, chú trọng vào trải nghiệm người dùng (UX) và tối ưu hóa hiệu năng tải trang.

🎨 Thiết kế Giao diện (UI/UX)

  • Tailwind CSS: Toàn bộ giao diện sử dụng các class tiện ích của Tailwind giúp tốc độ render cực nhanh, không bị nặng trang. Hệ thống màu sắc phân tách rõ ràng theo trạng thái quyền (Admin màu đỏ, User màu xanh dương, Khách màu hổ phách).

  • Trạng thái Form Đăng nhập đa năng: Gói gọn 3 màn hình (Đăng nhập chính, Nhập tài khoản nhận OTP, Nhập OTP đổi mật khẩu) trong cùng một khung Overlay bằng cách ẩn/hiện class hidden.

  • Menu Thu Gọn <details>: Phần hướng dẫn tạo app từ số 0 được bọc trong thẻ HTML5 nguyên bản, kết hợp hiệu ứng xoay mũi tên group-open:rotate-180 giúp giao diện gọn gàng, chỉ mở ra khi người dùng cần xem.

⚡ Xử lý Logic phía Client (Javascript)

  • Kéo thả trực quan (Drag & Drop): Tích hợp thư viện SortableJS. Điểm đặc biệt là hệ thống sẽ kiểm tra quyền trước; nếu là tài khoản "Xem", tính năng kéo thả sẽ bị khóa cứng. Nếu có quyền ghi, khi thả icon vào nhóm mới, trình duyệt lập tức gọi ngầm lệnh updateCategoryServer để đồng bộ trực tiếp lên Google Sheets theo thời gian thực.

  • Hệ thống thông báo tạm thời (Toast Notification): Hàm showToast() tự động sinh ra các thẻ thông báo động ở góc màn hình (Thành công, Thất bại, Đang xử lý) và tự hủy sau 4 giây để không làm rác bộ nhớ DOM.

  • Cơ chế Nhúng Iframe an toàn: Khi click vào một liên kết, ứng dụng sẽ mở một modal popup chứa thẻ <iframe>. Do một số trang web lớn (như Facebook, Google) bật tính năng bảo mật chặn nhúng (X-Frame-Options), mã nguồn của bạn đã có sẵn một banner cảnh báo thông minh kèm nút "Mở trực tiếp ứng dụng" làm phương án dự phòng hoàn hảo.

🔄 Luồng Đi của Dữ liệu (Data Flow)

[Người dùng click kéo thả/Đăng nhập] 
              │
              ▼ (Frontend - Index.html)
   Gửi yêu cầu qua lệnh: google.script.run
              │
              ▼ (Môi trường Cloud của Google)
   Xử lý logic, kiểm tra phân quyền (Backend - Code.gs)
              │
              ▼ 
   Đọc/Ghi dữ liệu vào Google Sheets hoặc gửi Email OTP
              │
              ▼ (Phản hồi về)
   withSuccessHandler() cập nhật lại giao diện không cần load lại trang!

📝 Nhận xét chung & Đánh giá

  • Điểm cộng xuất sắc: Code viết rất sạch, chia module rõ ràng. Cơ chế phân quyền chạy song song ở cả Frontend (ẩn nút bấm) lẫn Backend (chặn hàm thực thi) giúp ứng dụng đạt độ bảo mật rất tốt đối với một app chạy trên Google Apps Script.

  • Một lưu ý nhỏ cho bạn: ...

Các bước cài đặt từ số 0:

B1: Tạo một file Google Sheets trống hoàn toàn.

B2: Trên thanh menu Sheet, chọn Tiện ích mở rộngApps Script.

B3: Trong giao diện code, tạo đúng 2 file là Code.gsIndex.html rồi dán mã nguồn vào.

B4: Nhấn nút Triển khai (Deploy)Tùy chọn triển khai mới → Chọn loại Ứng ứng dụng Web.

B5: Tại phần "Quyền truy cập", chọn cấu hình Bất kỳ ai (Anyone) → Bấm Triển khai và Xác thực cấp quyền Google là chạy!