Skip to Content
ChangelogUnreleasedUnreleased · Zalo Mini App

Unreleased · Zalo Mini App

Các thay đổi dưới đây chưa được gán phiên bản hoặc ngày phát hành.

Fixed

  • Biên lai bảng lương lưu bằng path media tương đối được chuyển thành URL ảnh khi Worker mở lịch sử thanh toán; URL cũ vẫn hiển thị.

  • Form bán hàng kiểm tra request và response verify-contact-otp bằng contract chung với Hire Workspace trước khi cập nhật trạng thái xác thực số điện thoại.

  • Form bán hàng kiểm tra request và response send-contact-otp bằng contract chung với Hire Workspace trước khi hiển thị mã OTP thử nghiệm.

  • Form bán hàng kiểm tra request và response apply-promotion bằng contract chung với Hire Workspace; dữ liệu scheme hoặc quà tặng sai kiểu được chặn trước khi ánh xạ.

  • Chi tiết đơn chỉ tải bốn cột khách hàng và năm cột sản phẩm cần hiển thị; chi tiết và lịch sử kiểm tra hai join theo contract chung, kể cả giá trị null.

  • Lịch sử đơn hàng nhận đủ sale_id và product_id của từng sale_items; chi tiết và lịch sử kiểm tra đầy đủ bảy cột item theo contract chung với Hire Workspace.

  • Danh sách, chi tiết và lịch sử đơn hàng kiểm tra hàng sales theo contract chung với Hire Workspace; lịch sử sai kiểu dữ liệu không còn bị hiển thị thành danh sách rỗng.

  • Cấu hình bán hàng ở folder và workspace kiểm tra các trường JSONB trước khi hiển thị và tạo đơn; dữ liệu sai kiểu không còn đi vào mặc định âm thầm.

  • Ứng tuyển Job kiểm tra payload ghi job_applications theo contract chung với Hire Workspace trước khi gửi Supabase.

  • Màn hình thu nhập kiểm tra đầy đủ hàng payrolls theo contract chung với Hire Workspace trước khi hiển thị trạng thái và số tiền.

  • Tiến độ task bán hàng đọc sales qua datasource và kiểm tra cùng projection với Hire Workspace trước khi cập nhật danh sách đơn trong bằng chứng ca.

  • Tạo đơn bán hàng kiểm tra payload và hàng sales của create_sale_with_validation theo contract chung; không còn tạo mã đơn tạm vốn bị datasource bỏ trước khi gọi RPC.

  • Cấu hình bán hàng kiểm tra JSONB resolve_sale_stock_context theo contract chung với Hire Workspace; dữ liệu sai cấu trúc không còn bị thay bằng cấu hình mặc định.

  • Tìm việc kiểm tra toàn bộ hàng search_jobs bằng contract chung với Hire Workspace; bộ lọc người thuê dùng tên đúng với tham số SQL p_hirer_name.

  • Kiểm tra request, response và hàng đánh giá ca từ Supabase theo contract chung với Hire Workspace, giữ dữ liệu join reviewer/hirer cho giao diện.

  • Kiểm tra payload RPC thông báo, cài đặt và theo dõi người dùng trước khi ánh xạ vào màn hình; kết quả đánh dấu/xóa được kiểm tra là số dòng và theo dõi là boolean.

  • Xác thực payload Membership và mọi luồng Invitation từ Supabase; lời mời không còn đi qua JSON thô, tên folder lấy từ project.name, và kết quả nhận lời mời được kiểm tra là membership UUID.

Added

  • Báo cáo ca không phát sinh đơn: Task bán hàng hỗ trợ chỉ tiêu tối thiểu 0 đơn; Worker thấy số đơn đã ghi nhận và vẫn có thể hoàn tất ca khi không phát sinh đơn, nếu các bằng chứng khác hợp lệ.

  • Avatar mặc định nhất quán với Web Dashboard: Dùng API DiceBear Critters preset Bare theo profile ID khi ảnh hồ sơ/Zalo còn trống. Ảnh đã lưu được ưu tiên; giao diện dùng chữ viết tắt nếu ảnh không tải được. URL API lấy từ VITE_APP_URL khi build.

  • Chuẩn Hoá Clean Architecture & Nâng Cấp Nghiệp Vụ Kho Phía Worker (Zalo Mini App):

    • Tái Cấu Trúc Clean Architecture Toàn Diện cho task_stock_transaction: Tách biệt hoàn toàn tầng Presentation khỏi việc gọi trực tiếp Supabase SDK bằng TaskStockTransactionRemoteDataSource, TaskStockTransactionRepositoryImpl, các usecases (GetTaskStockTransactionContextUseCase, CreateTaskStockTransactionUseCase) và custom hook useStockTransactionForm.
    • Nhận Diện 8 Phân Loại Tài Sản & Cờ Thu Hồi: AssetPickerSheet nâng cấp hỗ trợ đầy đủ 8 loại tài sản (product, premium, sampling, posm, uniform, equipment, consumable, other), bổ sung badge cảnh báo “Thu hồi sau ca” đối với tài sản có is_returnable = true (Đồng phục, POSM, Thiết bị).
    • Tìm Kiếm Đa Năng (Tên, SKU, Barcode) & Bộ Lọc Phân Nhóm: Hỗ trợ tìm kiếm theo cả Barcode, SKU và tên hàng hoá, kèm bộ lọc chip theo từng loại tài sản.
    • Khép Kín Vòng Lặp Vận Hành Worker: Hỗ trợ đầy đủ luồng: Nhận vật tư đầu ca (outbound / staff_dispatch) ➡️ Bán hàng & phát quà tặng trong ca (sales) ➡️ Hoàn trả tài sản hoàn lại cuối ca (inbound / return).
  • Nâng Cấp Task Giao Dịch Kho Trong Job Builder Phù Hợp Nghiệp Vụ (StockTransactionValidator.tsx, StockTransactionProofView.tsx):

    • 4 Workflow Presets Tự Động & Chống Tràn Chữ: Bổ sung thanh công cụ chọn nhanh 4 kịch bản chuẩn: (1) Cấp phát / Nhận vật tư đầu ca, (2) Thu hồi / Hoàn trả cuối ca, (3) Điều chuyển quầy/kho, (4) Kiểm đếm tại quầy, thiết kế dạng pill chips co giãn thông minh không tràn chữ.
    • Quy Định Ảnh Chứng Từ Tối Thiểu (min_photos), Không Chặn Tối Đa: Chuyển đổi toàn diện từ chặn số lượng ảnh tối đa sang quy định số ảnh tối thiểu cần nộp trên cả Database RPCs, Job Builder và Zalo Mini App, cho phép Worker chụp thêm nhiều trang chứng từ bàn giao.
    • Nhận Diện 8 Asset Types & Lọc Danh Mục: Hiển thị badge phân loại, nhãn cảnh báo “Thu hồi sau ca”, bộ lọc chip theo từng loại tài sản và nút “Chọn tất cả tài sản cần thu hồi”.
    • Giao Diện Định Tuyến Kho Trực Quan & Xem Bằng Chứng (Proof View): Nâng cấp card định tuyến [Kho Xuất] ➔ [Kho Nhập] và màn hình xem bằng chứng chi tiết kèm thư viện ảnh chứng từ.
  • Kiểm Tra Điều Kiện Cấu Hình & Lưu Đơn Hàng Phía RPC (create_sale_with_validation) (Backend & Zalo Mini App):

    • Stored Procedure Backend An Toàn & Nguyên Tử (ACID): Khởi tạo migration 20260910000000_func_create_sale_with_validation.sql xử lý kiểm tra toàn diện cấu hình bán hàng (configurations) trực tiếp trong cơ sở dữ liệu:
      • Kiểm tra trạng thái enable của tính năng bán hàng.
      • Kiểm tra enable_consumer: Bắt buộc cung cấp Số điện thoại hợp lệ ($\ge 9$ số) và Họ tên khách hàng.
      • Kiểm tra require_otp_verification: Bắt buộc số điện thoại đã được xác thực OTP / Zalo QR (is_phone_verify = true).
      • Tự động tạo hoặc cập nhật hồ sơ khách hàng (contacts), lưu bản ghi sales và toàn bộ chi tiết sale_items trong 1 Transaction duy nhất.
    • Single Network Round-Trip: Cập nhật sales_remote_datasource.ts gọi trực tiếp supabase.rpc('create_sale_with_validation'), tối ưu hiệu năng và ngăn chặn triệt để hành vi bypass từ client.
    • pgTAP Test Suite: Bổ sung bộ kiểm thử 043_create_sale_with_validation_test.sql bao phủ toàn bộ các trường hợp ngoại lệ và luồng tạo đơn thành công.
  • Ràng Buộc Bắt Buộc Nhập Thông Tin Khách Hàng Khi Bật Thu Thập Consumer (Zalo Mini App):

    • Kiểm soát tính hợp lệ của khách hàng: Khi cấu hình Bán hàng (POS) kích hoạt mục “2. Thu thập Thông tin Khách hàng (Consumer)”, hệ thống bắt buộc nhân viên phải nhập Số điện thoại hợp lệ (từ 9 số trở lên) và Họ tên khách hàng trước khi bấm Hoàn tất đơn hàng.
    • Bắt buộc Xác thực OTP / Zalo QR: Nếu đồng thời bật “Yêu cầu xác thực OTP”, đơn hàng chỉ được lưu khi khách hàng đã hoàn tất xác thực số điện thoại.
    • Chỉ báo trực quan UI: Bổ sung ký hiệu bắt buộc (*) màu đỏ tại nhãn Số điện thoại và Họ tên trong ContactSection.tsx, kèm thông báo cảnh báo kịp thời qua Snackbar.
  • Lọc Danh Sách Sản Phẩm Bán Chỉ Lấy Tài Sản Thương Mại (type = 'product') (Zalo Mini App):

    • Loại bỏ Asset không phải hàng bán: Bổ sung bộ lọc điều kiện type = 'product' ở cả 3 tầng (Remote DataSource, Repository Implementation, và ProductPickerSheet UI) giúp loại trừ hoàn toàn các loại tài sản không dùng để bán thương mại như Quà tặng khuyến mãi (premium), Mẫu thử (sampling), Vật phẩm quảng cáo (posm), Công cụ dụng cụ (tool) khỏi Bottom Sheet chọn sản phẩm bán hàng.
  • Chọn Hàng Loạt Sản Phẩm (Batch Product Selection) trong Bottom Sheet Chọn Sản Phẩm (Zalo Mini App):

    • Tối ưu trải nghiệm chọn món: Bỏ nút “Thêm” riêng lẻ ở từng dòng sản phẩm, mặc định khởi tạo số lượng bằng 0 (hoặc giữ nguyên số lượng đang có trong giỏ hàng). Nút - cho phép giảm số lượng về 0.
    • Thanh tác vụ cố định (Sticky Action Bar): Bổ sung thanh tác vụ ở đáy Bottom Sheet hiển thị tổng số món đã chọn (qty > 0), tổng số đơn vị và tổng giá trị tiền hàng dự kiến theo thời gian thực.
    • Xác nhận 1 lần (1-Tap Batch Sync): Người dùng chỉ cần bấm nút “Xác nhận (X món)” 1 lần để áp dụng toàn bộ danh sách sản phẩm vào giỏ hàng. Các sản phẩm giảm về 0 sẽ tự động bị loại khỏi giỏ hàng.
  • Bộ Chuyển Đổi Đơn Vị Đóng Gói (Multi-Unit Converter - Thùng / Lốc / Lẻ) trong Form Bán Hàng Zalo Mini App:

    • Quy đổi Tự động & Phân rã Đơn vị: Khởi tạo usecase ConvertProductUnitQuantityUseCase.ts hỗ trợ quy đổi đa chiều giữa số lượng đóng gói (Thùng pack, Lốc bundle, Lẻ unit) và đơn vị cơ sở nhỏ nhất.
    • Modal Nhập Nhanh Đa Quy Cách: Xây dựng component ProductUnitQuantityModal.tsx cho phép nhân viên bán hàng/PG điều chỉnh số lượng Thùng, Lốc và Lẻ kèm tính toán tạm tính (VND) và chuỗi diễn giải trực quan (ví dụ: 1 thùng + 2 lốc + 3 lon).
    • Tích hợp Vào Giỏ Hàng & Danh Sách Chọn Sản Phẩm: Cập nhật ProductSelectionSection.tsx và ProductPickerSheet.tsx hiển thị huy hiệu quy cách phân rã và hỗ trợ 1-chạm mở modal quy đổi.
    • Đồng bộ DTO & Truy vấn Kho: Mở rộng câu truy vấn stock_assets trong sales_remote_datasource.ts và CartItem trong use_sale_form.ts lấy đầy đủ thông tin pack, bundle, unit_per_pack, unit_per_bundle.
  • Xác thực Số điện thoại Khách hàng qua Quét mã Zalo QR (Zalo Mini App 1-Touch Verification):

    • Cơ chế Xác thực 1-Chạm qua Zalo QR: Khi cấu hình hình thức xác thực otp_method = "zalo_miniapp" (hoặc chọn Quét mã QR), Form Bán hàng POS hiển thị nút “Quét Zalo QR”. Nhân viên POS mở mã QR động kèm sessionId và đồng hồ đếm ngược 3 phút.
    • Màn hình Người tiêu dùng (/consumer/verify): Khách hàng quét mã QR bằng ứng dụng Zalo để mở màn hình xác thực quyền lợi ConsumerVerifyPhonePage.tsx. Khách hàng bấm “Xác thực bằng số Zalo chính chủ” và cấp quyền qua ZMP SDK getPhoneNumber() mà không cần nhận/gõ mã SMS OTP thủ công.
    • Edge Function verify-consumer-phone: Tiếp nhận Zalo token / số điện thoại giải mã, tự động đồng bộ & tạo/cập nhật hồ sơ khách hàng contacts (is_phone_verify: true), đồng thời phát sự kiện Realtime qua kênh pos_session_{sessionId}.
    • Đồng bộ Tức thì qua Supabase Realtime: Màn hình bán hàng của nhân viên nhận sự kiện Realtime, tự động điền số điện thoại, họ tên, xác nhận trạng thái Đã xác thực và tự động đóng modal QR mà không cần bất kỳ thao tác thủ công nào.
  • Tra cứu Khách hàng cũ & Xem Lịch sử Mua hàng trong Form Bán hàng Zalo Mini App:

    • Tự động kiểm tra và nhận diện khách hàng qua Số điện thoại: Tại ContactSection.tsx, khi nhập số điện thoại (từ 9 số trở lên), hệ thống tự động tra cứu danh bạ khách hàng (contacts). Nếu khách hàng đã từng mua sắm, tự động điền họ tên, gắn mã hồ sơ (customerId), kế thừa trạng thái xác thực OTP và hiển thị huy hiệu nhận diện “Khách quen”.
    • Xem Lịch sử Mua hàng đa cấp độ (Folder / Org): Bổ sung nút bấm “Lịch sử mua hàng” và modal chuyên dụng CustomerPurchaseHistoryModal.tsx cho phép lọc danh sách đơn hàng theo “Thư mục này (Điểm bán)” hoặc “Toàn Tổ chức (Hệ thống)”. Thống kê tổng số đơn, tổng chi tiêu, danh sách sản phẩm, quà tặng và hình ảnh hóa đơn của các lần mua trước.
    • Tự động lưu và liên kết khách hàng mới khi tạo đơn: Cập nhật phương thức createSale tại sales_remote_datasource.ts tự động khởi tạo hồ sơ contacts và gắn customer_id vào đơn hàng đối với khách hàng mới.
    • Bổ sung Function & Phân quyền RLS cho Worker thực địa: Bổ sung hàm is_workspace_worker(p_workspace_id) (20260909223000_func_is_workspace_worker.sql) và cập nhật các chính sách RLS trên bảng contacts (20260909223100_contacts_rls_allow_worker_access.sql), sales, sale_items (20260909223200_sales_rls_allow_worker_access.sql), đảm bảo worker phụ trách ca làm việc có toàn quyền tra cứu khách hàng và lịch sử đơn hàng trong phạm vi dự án.
  • Xem Chi tiết Điều khoản Thu thập & Xử lý Dữ liệu Cá nhân trong Form Bán hàng Zalo Mini App:

    • Tại ContactSection.tsx, bổ sung liên kết "Xem nội dung" bên cạnh mục “Đồng ý thu thập và xử lý dữ liệu cá nhân cho mục đích khuyến mãi.”.
    • Tạo mới component ConsumerAgreementModal.tsx hiển thị chi tiết điều khoản bảo vệ dữ liệu cá nhân (tuân thủ Nghị định 13/2023/NĐ-CP).
    • Cho phép tùy chỉnh toàn bộ nội dung hiển thị thông qua trường consumer_agreement_content trong Cấu hình Bán hàng (POS) trên Web Dashboard, tự động áp dụng chính sách chuẩn khi dùng thiết lập mặc định.
    • Bổ sung xác thực kiểm tra khách hàng/nhân viên xác nhận đồng ý điều khoản tại SaleFormPage.tsx trước khi lưu đơn hàng.
    • Tinh chỉnh mô tả hướng dẫn tại SaleConfigTab.tsx để người quản trị dễ dàng nhập điều khoản riêng của thương hiệu.
  • Đồng bộ Dữ liệu Danh mục Sản phẩm & Cấu hình Bán hàng trong Task Plugin (task_sale):

    • Zalo Mini App Task Plugin (task_sale):
    • Web Dashboard Task Builder (task_sale):
      • Nâng cấp SaleValidator.tsx hỗ trợ chọn danh mục sản phẩm cụ thể từ kho (stock_assets) hoặc áp dụng cho toàn bộ sản phẩm, kèm tùy chọn cho phép bán hàng Offline.
  • Cấu hình Bán hàng (Sale Configuration Tab) trong Phân hệ Khuyến mãi (?tab=promotions):

    • Bổ sung sub-tab “Cấu hình Bán hàng (POS)” bên cạnh tab “Danh sách khuyến mãi” trên trang PromotionPage.tsx.
    • Triển khai component SaleConfigTab.tsx theo chuẩn thiết kế Shadcn UI & Tailwind CSS v4, đồng bộ trực tiếp với bảng public.configurations (feature: 'sale'):
      • Thiết lập Điểm bán & Kho hàng (POS): Bật/tắt tính năng POS, chọn kho xuất hàng mặc định qua LocationSelect.
      • Thu thập Khách hàng (Consumer): Bật/tắt form khách hàng và tùy chỉnh nội dung cam kết điều khoản thu thập dữ liệu cá nhân.
      • Xác thực OTP: Bật/tắt OTP, chọn phương thức (SMS, Zalo ZNS, Zalo Mini App), mẫu tin nhắn / Template ID, và quản lý danh sách mã OTP trắng (Whitelist OTP) cho môi trường test/sự kiện offline.
      • Cấu hình Ảnh Chứng từ Hoá đơn (Upload Settings): Bật/tắt tải ảnh, chọn nguồn (Camera, Thư viện, Bất kỳ), cho phép chọn nhiều ảnh, nén ảnh tự động, đóng dấu Watermark thời gian & GPS, quy định số lượng file tối thiểu/tối đa, và xác thực mã QR trên hóa đơn.
      • Raw JSON Tab: Hỗ trợ xem trực tiếp payload cấu hình kỹ thuật từ cơ sở dữ liệu.
  • Phân hệ Bán hàng Thực địa (Sales & POS) và Task Plugin (task_sale):

    • Supabase Backend Migrations:
      • 20260909211000_sales_schema.sql: Khởi tạo schema public.sales, public.sale_items hỗ trợ lưu trữ đơn hàng, chiết khấu, khuyến mãi, phương thức thanh toán, ảnh hóa đơn, cùng các trigger tính doanh thu và chính sách bảo mật RLS toàn diện theo Workspace & Folder. Bổ sung seed cấu hình Master Data task.sale và tài nguyên phân quyền iam_resource (sales:*) vào public.system_configurations.
      • 20260909212000_add_sale_task_enum.sql: Bổ sung giá trị 'sale' vào Postgres enum public.task_type_enum.
      • 20260909212100_add_sale_task_storage.sql: Tạo bảng lưu trữ metric nhiệm vụ public.task_metric_sale (min_sales, min_amount, warehouse_id, product_ids, allow_offline), thiết lập RLS qua fn_can_manage_task_metric, cập nhật hàm default_task_contract cho 'sale', và cập nhật hàm xuất bản nguyên tử publish_job_revision_base để tự động lưu cấu hình task bán hàng khi lưu/xuất bản ca làm.
    • Zalo Mini App Standalone Feature (apps/worker_zalo/src/features/sales):
      • Xây dựng hoàn chỉnh theo chuẩn Clean Architecture (data, domain, presentation) với Jotai state management (use_sale_form.ts).
      • Giao diện POS / Checkout: chọn sản phẩm từ kho hàng (ProductPickerSheet), kiểm tra điều kiện khách hàng & xác thực OTP số điện thoại (OtpVerificationModal), chọn áp dụng khuyến mãi (PromotionSection), vòng quay may mắn Canvas tương tác (LuckyWheelModal), tải ảnh hóa đơn chứng từ (UploadGridWidget), nhập tiền khách đưa và tính tiền thối tự động.
      • Trang danh sách đơn hàng (SaleListPage), tạo đơn mới (SaleFormPage), và xem chi tiết đơn bán hàng (SaleDetailPage) có liên kết điều hướng thông suốt.
    • Zalo Mini App Task Plugin (apps/worker_zalo/src/features/task/tasks/task_sale):
      • Triển khai SaleExecutionComponent theo chuẩn Task Contract v2 (type: "sale", domainGroup: "stock"), tự động theo dõi tiến độ hoàn thành chỉ tiêu doanh thu và số đơn bán theo ca thực thi, cung cấp nút mở màn hình POS với ngữ cảnh thực thi (job_id, execution_id, task_key).
      • Đăng ký SaleExecutionModule vào TaskExecutionRegistry.
    • Web Dashboard Task Plugin (apps/hire_workspace/src/features/task/tasks/task_sale):
      • Triển khai SaleValidator cho TaskBuilder: thiết lập số đơn tối thiểu (min_sales), doanh thu tối thiểu (min_amount), xử lý khi không đạt chỉ tiêu (failure_action) và quyền cho phép worker chỉnh sửa.
      • Triển khai SaleProofView cho Live Monitor: kiểm tra danh sách đơn bán hàng kèm mã đơn, khách hàng, tổng tiền và ảnh chụp hóa đơn theo từng lượt nộp.
      • Đăng ký SaleModule vào taskRegistry (setup.ts) và bổ sung bộ unit test TaskSale.test.ts kiểm thử toàn diện DTO schemas, mappers và module contract v2.
  • Hoàn thiện Phân hệ Thông báo & Cấu hình trên Zalo Mini App (apps/worker_zalo):

    • Tối ưu vị trí Thông báo vào Bottom Navigation: Di chuyển thông báo từ góc trên phải (tránh trùng khớp với nút Đóng/Tuỳ chọn mặc định của Zalo Mini App) thành tab “Thông báo” chính thức trên thanh điều hướng dưới cùng (BottomNavigation.tsx) kèm huy hiệu số lượng chưa đọc realtime (9+).
    • Realtime Sync: Bổ sung cơ chế lắng nghe Realtime (supabase.channel) trên bảng public.notifies trong useNotifications và BottomNavigation, tự động cập nhật danh sách và badge count tức thì.
    • Deep Navigation & Action Handling: Tích hợp điều hướng sâu trực tiếp từ NotificationsPage tới các phân hệ đích tương ứng (/execution/:id, /jobs/:id, /payroll-history, /invitation/:code).
    • Toolbar Đánh dấu đã đọc: Tích hợp nút “Đánh dấu đã đọc tất cả” ngay dưới thanh tiêu đề trang thông báo.
    • Kiểm tra & Chuẩn hoá Cấu hình Môi trường: Cập nhật src/core/supabase.ts hỗ trợ tự động fallback giữa VITE_SUPABASE_PUBLISHABLE_KEY và VITE_SUPABASE_ANON_KEY.
  • Refactor & Chuẩn hoá 3 Phân hệ (contacts, notification, promotion) trên Web Dashboard:

    • Contacts (apps/hire_workspace/src/features/contacts): Tái cấu trúc hoàn chỉnh theo chuẩn Clean Architecture và kiến trúc đa người thuê (Multi-Tenancy workspace_id, folder_id). Hỗ trợ quản lý thông tin đối tác/khách hàng, tích hợp danh bạ ngân hàng Việt Nam (VIETNAM_BANKS), tải ảnh chứng từ qua UploadGridWidget, bảo vệ thao tác bằng IamButton và thiết kế UI chuẩn Tailwind CSS v4 & Radix primitives.
    • Notification (apps/hire_workspace/src/features/notification): Tái cấu trúc phân hệ Thông báo Dashboard và hạ tầng FCM Web Push, chuẩn hoá DTOs và routing về hệ thống tài nguyên Gigee (/issues, /jobs, /folders, /payroll, /formx). Bổ sung bảng cài đặt thông báo NotificationSettingsPanel và trang trung tâm thông báo NotificationPage.
    • Promotion (apps/hire_workspace/src/features/promotion): Loại bỏ hoàn toàn Ant Design (antd, @ant-design/icons), viết lại toàn bộ PromotionWizard và các bước thiết lập (Thông tin chung, Điều kiện áp dụng, Cơ cấu phần thưởng, Xác nhận) sang Shadcn UI & Tailwind CSS v4 tokens. Tích hợp liên kết tài sản từ stock feature và hỗ trợ các cơ chế Nhận ngay (Instant), Vòng quay may mắn (Lucky Wheel), Tự chọn quà (Selective).
      • Tích hợp Folder Explorer: Bổ sung 3 Tabs mới (contacts - Khách hàng, promotions - Khuyến mãi, notifications - Thông báo) vào trang Folder Explorer (FolderExplorerPage.tsx) với giao diện chuẩn hoá FolderTabLayout và cơ chế đồng bộ tham số URL (folderExplorerNavigation.ts).
      • Supabase Backend Migrations & Edge Functions:
        • Thêm migration 20260909204000_contacts_schema.sql khởi tạo bảng public.contacts, index, triggers và đầy đủ chính sách bảo mật RLS.
        • Thêm migration 20260909204100_promotion_schemes_schema.sql khởi tạo bảng public.promotion_schemes, index, triggers và chính sách bảo mật RLS.
        • Thêm migration 20260909204200_user_notification_settings_add_inactivity_columns.sql bổ sung các cột cài đặt cảnh báo bất hoạt (follow_inactivity_push, inactivity_scope, inactivity_threshold_minutes) vào bảng public.user_notification_settings.
        • Tái cấu trúc 4 Edge Functions:
          • apply-promotion: Cập nhật schema repository và premium repository tương thích với các cột workspace_id, folder_id của promotion_schemes và stock_assets, hỗ trợ tính toán khuyến mãi đa tầng theo scope folder/workspace.
          • send-contact-otp: Cập nhật truy vấn cấu hình whitelist OTP theo workspace_id và folder_id.
          • verify-contact-otp: Cập nhật xác thực OTP, kiểm tra whitelist và tự động cập nhật trạng thái is_phone_verify = true trên bảng public.contacts.
          • send-zalo-sms-hook: Nâng cấp sang chuẩn Deno.serve, sửa cấu trúc truy vấn configurations và chuẩn hoá tracking ID gigee_otp_*.
    • DI Container Composition Root: Đăng ký đầy đủ các DataSources, Repositories và UseCases của contacts, notification, promotion vào src/shared/di/container.ts.
    • Unit Testing: Bổ sung bộ test mapper 2 chiều DTO <-> Entity cho ContactsRepository, NotificationRepository, PromotionRepository, test điều hướng folderExplorerNavigation.test.ts, pgTAP schema tests, và Deno test suite cho apply-promotion (18 steps) đảm bảo 100% pass.
  • Hỗ trợ Trường Số điện thoại FormX (apps/hire_workspace/src/features/formx):

    • Bổ sung loại trường phone (“Số điện thoại”) vào FormX Builder module (phone.tsx), entity FormxFieldType, schema validation formxBoundary.ts và registry module registry.ts.
    • Hiển thị giá trị số điện thoại dưới dạng liên kết tel: bấm trực tiếp trên web dashboard.
    • Đồng bộ hoàn toàn với backend RPC Supabase create_formx_task_submission và Zalo Mini App task FormX.
  • Location Search UI Components (apps/hire_workspace/ & apps/worker_zalo/):

    • Xây dựng component LocationSelect (apps/hire_workspace/src/features/location/presentation/components/LocationSelect.tsx) dựa trên Shadcn UI (Popover, Command, Badge). Hỗ trợ tìm kiếm theo mọi scopes (auto, folder, workspace, global, vn_geo, suggestions), chế độ chọn đơn (single) và chọn nhiều (multiple với badges xoá nhanh). Hỗ trợ nút tạo mới inline (+ Tạo địa điểm mới "[từ khóa]") và click chọn đơn vị hành chính (vn_ward/vn_province) để mở form tạo nhanh với dữ liệu điền sẵn.
    • Tích hợp LocationSelect vào bước chọn địa điểm trong JobFormModal với phạm vi rộng nhất (scope="suggestions"), kết nối callback onSuccess để tự động chọn ngay địa điểm vừa tạo/đăng ký vào công việc.
    • Xây dựng component LocationSearchSelect (apps/worker_zalo/src/features/auth/presentation/components/LocationSearchSelect.tsx) dựa trên ZaUI và Tailwind CSS cho thiết bị di động. Hỗ trợ tìm kiếm địa chính theo debounce, loading spinner, chọn đơn (nơi ở hiện tại) và chọn nhiều (khu vực nhận việc mong muốn). Tích hợp vào PreferencesStep.
    • Bổ sung bộ kiểm thử đơn vị LocationSelect.test.tsx (100% test pass).
  • Web Dashboard Auth & User Profile (apps/hire_workspace/src/features/user/presentation/components/UserLinkedAccountsTab.tsx):

    • Bổ sung tab “Liên kết tài khoản” (Linked Accounts) tại trang chi tiết hồ sơ người dùng (/users/:id/accounts).
    • Cho phép người dùng liên kết thêm hoặc hủy liên kết các phương thức OAuth providers (Google, Facebook, Zalo, GitHub, Email/Mật khẩu) với tài khoản Supabase Auth.
    • Tích hợp helper mapAuthError chuẩn hóa thông báo lỗi kỹ thuật từ Supabase SDK sang Tiếng Việt thân thiện.
    • Hỗ trợ cơ chế bảo vệ ngăn hủy phương thức đăng nhập duy nhất (single_identity) và hiển thị Hộp thoại xác nhận an toàn (AlertDialog).
  • Single-Time Onboarding Flow & Navigation UI Polish cho Zalo Mini App (apps/worker_zalo):

    • Bổ sung thuộc tính isOnboarded?: boolean vào entity UserProfile và cập nhật AuthRemoteDataSource (getCurrentUser và saveProfile) để đọc/ghi giá trị is_onboarded từ Supabase.
    • Cập nhật OnboardingPage: tự động gọi saveProfile với isOnboarded: true khi người dùng bấm Hoàn tất hoặc bấm Bỏ qua (Skip).
    • Tinh chỉnh giao diện thanh điều hướng dưới (bottom navigation bar) của OnboardingPage: Đặt nút “Bỏ qua” (w-1/3, variant="secondary") cùng dòng với nút “Tiếp theo” (w-2/3, variant="primary") ở Bước 1.
    • Sửa lỗi thiếu thuộc tính province_name trong dữ liệu các cột khu vực (home_address_region và preferred_working_regions) khi lưu hồ sơ tại PreferencesStep và EditProfilePage bằng cách kết hợp cột trả về từ RPC và cơ chế fallback tự động parse tỉnh/thành từ full_name.
    • Cập nhật điều kiện phân luồng chuyển hướng tại AppInitializer (layout.tsx) và LoginPage để kiểm tra profile?.isOnboarded giúp đảm bảo Worker chỉ thực hiện Onboarding 1 lần duy nhất.
  • Nâng cấp Multi-step Onboarding quy trình 3 bước cho Zalo Mini App (apps/worker_zalo):

    • Toàn bộ quy trình thiết lập thông tin (CCCD, khu vực, chuyên môn, ngân hàng) là không bắt buộc. Worker có thể bấm nút “Bỏ qua” trên header để vào thẳng danh sách việc làm /jobs bất kỳ lúc nào hoặc bổ sung sau trong trang Profile.
    • Bước 1 (Xác thực & CCCD): Hỗ trợ nút quét mã QR trên CCCD chip Việt Nam qua ZMP SDK (scanQRCode), tự động parse số CCCD, họ tên, ngày sinh, giới tính, ngày cấp; tích hợp component UploadGridWidget từ upload feature cho phép chọn ảnh từ máy ảnh/thư viện (album), nén ảnh client-side và upload lên bucket media/id_cards.
    • Bước 2 (Chuyên môn, Thời gian rảnh & Khu vực): Chuẩn hóa kiểu dữ liệu VnGeoRegion (province_code, province_name, ward_code, ward_name, full_name) cho địa chỉ thường trú và nhiều khu vực mong muốn nhận việc (preferredWorkingRegions); lựa chọn kỹ năng chuyên môn và lịch rảnh theo tuần.
    • Cập nhật màn hình Hồ sơ cá nhân (ProfilePage.tsx & EditProfilePage.tsx): Bổ sung thẻ hiển thị thông tin CCCD (Họ tên, Số CCCD, Ngày sinh, Giới tính Nam/Nữ/Khác, Ngày cấp, ảnh CCCD) và danh sách tài khoản ngân hàng VietQR. Tái cấu trúc EditProfilePage.tsx tái sử dụng 100% các sub-components chuẩn (CccdStep, PreferencesStep, BankStep) từ OnboardingPage, xóa bỏ hoàn toàn code trùng lặp và rút gọn từ 743 dòng xuống 140 dòng.
    • Tích hợp thanh tiến trình StepIndicator Wizard Navigation mượt mà.
  • Hỗ trợ đăng nhập Zalo Mini App không bắt buộc số điện thoại (getPhoneNumber) khi người dùng từ chối hoặc gặp lỗi.

Fixed

  • Khắc Phục Lỗi Truy Vấn Cột code Không Tồn Tại & Hiển Thị Chi Tiết Giao Dịch Kho Trên Zalo App (StockTransactionExecutionComponent.tsx):

    • Loại bỏ cột code không tồn tại khỏi câu truy vấn stock_transactions, trích xuất mã phiếu giao dịch từ 8 ký tự đầu của UUID (#XXXXXXXX).
    • Hiển thị đầy đủ danh sách giao dịch kho đã tạo kèm trạng thái, định tuyến kho xuất/nhập, danh sách hàng hoá và ảnh chứng từ biên bản.
  • Khắc Phục Lỗi 403 Forbidden (“Active worker execution required”), Vô Hiệu Hoá Nút Khi Đạt Giới Hạn & Việt Hoá Thông Báo Lỗi (StockTransactionExecutionComponent.tsx, 20260921024500_fix_create_task_stock_transaction_step_lookup.sql):

    • Cập nhật hàm PostgreSQL RPC create_task_stock_transaction hỗ trợ linh hoạt cả p_step_id = es.step_id (ID template bước gửi từ client Zalo App) lẫn p_step_id = es.id (ID bản ghi thực thi bước).
    • Chuyển mệnh đề folder_contents từ INNER JOIN sang LEFT JOIN kèm FOR UPDATE OF er, es để hỗ trợ cả các công việc không có folder.
    • Việt hoá toàn bộ các thông báo lỗi trả về từ backend PostgreSQL sang tiếng Việt rõ ràng, thân thiện với người dùng.
    • Tự động vô hiệu hoá (disabled) nút hành động + Tạo giao dịch kho và hiển thị trạng thái Đã đủ số lần giao dịch (X/X) khi Worker đã hoàn thành đủ số lượng giao dịch tối đa được chỉ định trong task.
  • Ngăn Chặn Worker Nộp Lại Báo Cáo & Bằng Chứng Khi Ca Làm Việc Bị Từ Chối (rejected):

    • Cập nhật database function submit_execution: Chặn nghiêm ngặt việc nộp lại báo cáo khi ca làm việc đã kết thúc hoặc bị từ chối (status IN ('submitted', 'approved', 'rejected')).
    • Cập nhật database function submit_step_proof_legacy & submit_step_proof: Chặn nộp mới hoặc chỉnh sửa bằng chứng nhiệm vụ khi toàn bộ ca làm việc đã ở trạng thái rejected, submitted, approved, hoặc paid.
    • Cập nhật Zalo Mini App (ExecutionControllerPage.tsx, StepProofPage.tsx): Khóa toàn bộ các trường nhập liệu (isTaskLocked), hiển thị badge/nút cảnh báo Ca làm việc đã bị từ chối (disabled) và thông báo lý do từ chối từ người thuê.
    • Bổ sung bộ test tự động pgTAP execution_reject_resubmit_guard.test.sql xác minh toàn diện chu trình bảo vệ và xử lý lỗi khi ca làm việc bị từ chối.
  • Khắc Phục Điều Hướng Lỗi Cho Thông Báo Sửa Nhiệm Vụ (task_needs_revision) & Từ Chối (task_rejected):

    • Cập nhật trigger function handle_task_rejection_notification và handle_execution_submission_notification để gán đúng execution_record_id vào resource_id và metadata.executionRecordId trong bảng public.notifies (thay vì gán proof_id hoặc step_id).
    • Nâng cấp ExecutionRemoteDataSource.getExecutionStatus trên Zalo Mini App với cơ chế fallback phân giải đa tầng (Multi-strategy ID resolution: execution_record_id $\rightarrow$ proof_id $\rightarrow$ step_id $\rightarrow$ job_id), đảm bảo tương thích ngược 100% với cả các thông báo cũ đã lưu trong database.
    • Cập nhật routeResolver trong default_registrations.ts và NotificationsPage.tsx ưu tiên metadata.executionRecordId || resourceId khi điều hướng đến /execution/:id.
    • Cập nhật ExecutionControllerPage.tsx và StepProofPage.tsx truyền đúng session.id khi chuyển bước và nộp lại bằng chứng đã bị từ chối.
  • Khắc Phục Toàn Diện Luồng Tải Ảnh & Giải Mã Vị Trí Khi Nộp Bằng Chứng (StepProofPage & Upload Module Zalo Mini App):

    • Bộ Giải Mã Ảnh Đa Tầng (Multi-tier Image Decoding): Cập nhật UploadPickerButton.tsx trích xuất an toàn mọi định dạng đường dẫn từ Zalo SDK (filePaths, tempFiles) qua 3 tầng (Data URL $\rightarrow$ Blob Fetch $\rightarrow$ Canvas Fallback), ngăn chặn triệt để lỗi Failed to fetch khi lấy ảnh từ camera Zalo trên thiết bị thực.
    • Khử Nghẽn Hàng Đợi Tải Lên (Non-blocking Upload Queue): Cập nhật useUploadController.ts đưa ảnh vào trạng thái ADD ngay lập tức khi người dùng chọn/chụp ảnh, giúp hiển thị thẻ ảnh và thanh tiến trình tức thì.
    • Tích Hợp Giải Mã Tọa Độ Zalo Token Exchange Không Gây Treo: Thay thế hoàn toàn hàm navigator.geolocation bị chặn trên Webview bằng DeviceLocationDataSource (kết hợp zalo-location-exchange Edge Function) kèm cơ chế timeout 2.5 giây, đảm bảo quá trình tải ảnh luôn tiếp tục mượt mà ngay cả khi định vị bị từ chối hoặc mạng chậm.
    • Dự Phòng Tải Ảnh Trực Tiếp & Nén An Toàn: Thiết lập useWebWorker: false trong browser-image-compression để tránh crash trong Webview, đồng thời tự động dự phòng sang Supabase Storage (media bucket) khi Edge Function xử lý ảnh gặp sự cố.
    • Mở Khóa Nhiệm Vụ Pending: Cập nhật PhotoProofExecutionComponent.tsx và GeofenceExecutionComponent.tsx loại bỏ điều kiện khóa sai khi status === "pending".
    • Ổn Định Trạng Thái Bước Thực Thi: Cập nhật StepProofPage.tsx cố định hook khởi tạo giá trị nhiệm vụ theo stepId.
  • Khắc Phục Lỗi Nộp Bằng Chứng Ảnh (RPC submit_step_proof failed: 42501 Photo evidence not found or unauthorized) (Zalo Mini App & Edge Functions):

    • Khắc phục lỗi lệch workspace_id: Cập nhật PhotoProofExecutionComponent.tsx nhận và truyền đầy đủ các thuộc tính workspaceId, folderId, executionId vào UploadConfig.
    • Tự động đối soát execution_id trên Edge Function: Cập nhật Edge Function process-photo tiếp nhận execution_id từ metadata và tự động tra cứu chính xác workspace_id của công việc (job_execution_records -> job_revisions -> jobs -> workspace_id), loại bỏ hoàn toàn việc fallback sai sang workspace ngẫu nhiên (workspaces LIMIT 1).
    • Tối ưu trích xuất dữ liệu phiên làm việc: Cập nhật execution_remote_datasource.ts và StepProofPage.tsx xử lý an toàn kiểu dữ liệu mảng/đối tượng từ PostgREST, đảm bảo workspaceId luôn được truyền chính xác tới toàn bộ các component thực thi nhiệm vụ.
  • Sửa Lỗi Cuộn Trang Form Bán Hàng & Hiển Thị Quà Lucky Wheel (Zalo Mini App):

    • Khắc phục lỗi cuộn trang: Cập nhật container <Page> trong SaleFormPage.tsx với overflow-y-auto pb-36 và WebkitOverflowScrolling: "touch", đảm bảo cuộn mượt mà toàn bộ các khối nội dung trên thiết bị di động.
    • Cập nhật hiển thị quà Lucky Wheel: Bổ sung danh sách các phần quà may mắn đã quay trúng và số lượt quay còn lại trực tiếp trong card chương trình tại PromotionSection.tsx.
    • Khắc phục lỗi ép kiểu bill_photos is type text[]: Cập nhật Stored Procedure create_sale_with_validation chuyển đổi mảng ảnh JSON sang mảng TEXT[] của Postgres trước khi insert vào bảng sales.
  • Khắc phục lỗi Xác thực OTP Người tiêu dùng với Whitelist OTP (Edge Function HTTP Error):

    • Đồng bộ Tham số và Alias OTP: Trong verify-contact-otp/index.ts, bổ sung hỗ trợ đa dạng tham số đầu vào (otp, otp_code, otpCode, code) tránh lỗi Missing required parameters khi client gửi mã otp_code.
    • Xử lý Dummy UUID & Truy vấn Cấu hình Linh hoạt: Chuẩn hoá kiểm tra UUID mặc định (00000000-0000-0000-0000-000000000000), tự động tra cứu workspace_id từ folders nếu thiếu, đảm bảo nạp chính xác cấu hình whitelist OTP (settings.whitelist_otp).
    • Chuẩn hoá Response Code & Thân thiện với Client SDK: Trả về HTTP 200 kèm payload { success, verified, message } thay vì HTTP 400 khi sai mã OTP, ngăn chặn việc Supabase Client SDK ném biệt lệ FunctionsHttpError: Edge Function returned a non-2xx status code.
    • Tuân thủ Tuyệt đối Cấu hình Whitelist trong public.configurations: Cả hai hàm send-contact-otp và verify-contact-otp đọc trực tiếp danh sách mã OTP thử nghiệm (whitelist_otp) và danh sách số điện thoại thử nghiệm (whitelist_phones) từ bảng public.configurations theo thứ tự ưu tiên phân cấp (cấp Điểm bán folder_id ghi đè cấp Tổ chức workspace_id). Loại bỏ hoàn toàn mã hardcode 123456, chỉ cho phép bypass OTP khi khớp chính xác thiết lập trong configurations.
    • Hỗ trợ Quản lý Whitelist Phones trên Web Dashboard: Cập nhật SaleConfigTab.tsx cho phép quản trị viên thêm/xóa linh hoạt cả danh sách mã OTP (whitelist_otp) và danh sách số điện thoại thử nghiệm (whitelist_phones).
    • Tương thích Độ dài Mã OTP Whitelist: Cập nhật modal xác thực OtpVerificationModal.tsx cho phép nhập mã OTP có độ dài từ 3 ký tự (hỗ trợ các mã whitelist ngắn như 123, 234), đồng thời hiển thị gợi ý mã whitelist khi số điện thoại thuộc diện thử nghiệm.
    • Cập nhật Giao diện ContactSection.tsx: Trích xuất và thông báo chính xác mã whitelist OTP trả về từ Edge Function send-contact-otp.
    • Tự động Reset Trạng thái Xác thực khi Thay đổi Số điện thoại: Trong ContactSection.tsx, khi người dùng chỉnh sửa hoặc thay đổi bất kỳ ký tự nào của số điện thoại, hệ thống lập tức đặt lại cờ isPhoneVerify = false và chuyển trạng thái nút bấm về “Gửi OTP”, ngăn chặn việc sử dụng trạng thái xác thực của số điện thoại cũ cho số điện thoại mới.
  • Sửa Lỗi Tải Ảnh Hóa đơn Bán hàng (Storage RLS Policy Error):

    • Khắc phục vi phạm RLS storage.objects khi upload ảnh: Bổ sung migration 20260909222500_fix_media_storage_worker_upload_rls.sql khôi phục cờ public = true cho bucket media, cập nhật các chính sách RLS INSERT, UPDATE, SELECT trên storage.objects hỗ trợ đầy đủ quyền upload ảnh cho nhân viên/worker thực địa và tương thích với cơ chế upsert: true.
    • Cấu hình Đường dẫn Lưu trữ Ảnh Hóa đơn theo Không gian làm việc (workspace_id): Cập nhật ExtraInfoSection.tsx và SaleFormPage.tsx truyền workspaceId, folderId vào UploadConfig, chuẩn hoá tiền tố đường dẫn lưu trữ ${workspaceId}/sales/bills theo đúng chuẩn kiến trúc nền tảng.
    • Ưu tiên Public URL Dài hạn: Cập nhật SupabaseUploadRemoteDataSource.ts ưu tiên lấy getPublicUrl để ảnh hoá đơn đính kèm đơn hàng tồn tại lâu dài, không bị hết hạn sau 300 giây.
  • Tải Danh mục Hàng hoá (Stock Assets) trong Form Bán hàng Zalo Mini App:

    • Khắc phục xung đột thư mục (Folder Mismatch) giữa Ca làm việc và Kho hàng: Trong sales_remote_datasource.ts, loại bỏ điều kiện thắt chặt folder_id khi đã có danh sách productIds chỉ định; bổ sung cơ chế tự động fallback về cấp workspace_id khi thư mục của ca làm việc không chứa sản phẩm bán hàng, giúp nhân viên hiện trường luôn chọn được sản phẩm để bán.
    • Ánh xạ thuộc tính workspaceId & folderId vào thực thể CartItem: Cập nhật sales_repository_impl.ts để lưu giữ thông tin xuất xứ kho hàng của sản phẩm, đảm bảo tính toán CTKM và lưu đơn chính xác.
    • Nâng cấp RLS Policy stock_assets_select: Bổ sung migration 20260909221500_stock_assets_rls_allow_worker_access.sql mở rộng quyền đọc stock_assets (available = true) cho các worker được phân công thực hiện ca làm việc (job_execution_records) hoặc đã ứng tuyển (job_applications) trong Workspace tương ứng.
  • Edge Function apply-promotion & Tính toán Khuyến mãi Bán hàng (POS):

    • Tự động phục hồi workspaceId & folderId: Bổ sung cơ chế tự động tra cứu phạm vi dự án từ stock_assets khi client truyền thiếu hoặc truyền giá trị rỗng/mặc định (00000000-0000-0000-0000-000000000000), khắc phục triệt để lỗi không tìm thấy CTKM (0 schemes, 0 premiums loaded).
    • Bỏ qua dummy UUIDs trong Repository: SchemeRepository.ts và PremiumRepository.ts lọc bỏ 00000000-0000-0000-0000-000000000000 khỏi mệnh đề WHERE để không chặn các chương trình khuyến mãi đang hoạt động.
    • Ánh xạ kết quả trả về từ Edge Function: sales_remote_datasource.ts trích xuất chính xác payload { appliedPromotions: [...] } từ hàm apply-promotion.
    • Đồng bộ xuyên suốt Context ca làm việc trong Zalo Mini App:
  • Zalo Mini App Onboarding (apps/worker_zalo/src/features/auth/presentation/pages/OnboardingPage.tsx):

    • Sửa lỗi không cuộn được trang trên OnboardingPage bằng cách cấu trúc lại Page container và khu vực nội dung với flex-1 overflow-y-auto min-h-0, cố định thanh điều hướng hành động phía dưới kèm safe-area insets.

UI Polish

  • Fallback Mock Tọa Độ Vị Trí Trong Local Dev Cho Zalo Mini App:

    • Bổ sung cơ chế fallback tự động trong DeviceLocationDataSource khi chạy môi trường development (import.meta.env.DEV), trả về tọa độ trung tâm TP.HCM hoặc tùy chỉnh qua VITE_MOCK_LOCATION_LAT / VITE_MOCK_LOCATION_LNG nếu cả Zalo SDK và Browser Geolocation đều không khả dụng.
  • Thông Báo Khi Có Người Theo Dõi Mới (follow_new):

    • Thêm loại thông báo mới mặc định kích hoạt: Khi người dùng được ai đó theo dõi, hệ thống tự động tạo thông báo follow_new với tiêu đề “Người theo dõi mới” và liên kết đến trang hồ sơ cá nhân.
    • Thiết lập PostgreSQL trigger trg_notify_on_user_followed chạy AFTER INSERT trên bảng public.user_follows gọi hàm handle_user_followed_notification().
    • Hỗ trợ cài đặt bật/tắt nhận thông báo người theo dõi mới (newFollowerPush, mặc định true) trong preferences JSONB của user_notification_settings.
    • Đăng ký hiển thị loại thông báo follow_new trên cả Zalo Mini App và Web Dashboard.
  • Trang Hồ Sơ Chi Tiết Nhà Tuyển Dụng Cho Worker (/hirer/:id trên Zalo Mini App):

    • Bổ sung PostgreSQL RPC rpc_get_hirer_public_profile trả về thông tin định danh, điểm uy tín, huy hiệu xác thực, thống kê công việc, danh sách việc đang tuyển và nhận xét từ thợ.
    • Triển khai Clean Architecture Vertical Slice (features/hirer) gồm domain, data và presentation (useHirerProfile, HirerProfilePage).
    • Hỗ trợ xem điểm uy tín (Reliability Score / 5.0), huy hiệu đã xác thực, danh sách công việc đang hoạt động và đánh giá/nhận xét thực tế từ cộng đồng thợ.
    • Tích hợp nút theo dõi / hủy theo dõi nhanh 1-chạm (Follow / Unfollow) trực tiếp trên trang hồ sơ kèm cập nhật tức thì.
    • Liên kết chuyển hướng trực tiếp từ phần thông tin Nhà tuyển dụng trên trang chi tiết công việc (JobDetailPage.tsx) sang /hirer/:id.
  • Trung Tâm Thông Báo Toàn Diện & Đa Năng Cho Zalo Mini App (NotificationsPage):

    • Triển khai kiến trúc NotificationTypeRegistry cho phép đăng ký, huỷ đăng ký và mở rộng các loại thông báo linh hoạt (không hardcode if/else).
    • Hỗ trợ thanh công cụ đa năng: Bộ lọc danh mục dạng thẻ cuộn (Tất cả, Công việc, Sự cố, Lương & Thưởng, Theo dõi, Hệ thống), ô tìm kiếm toàn văn có debounce, và công tắc lọc tin “Chưa đọc”.
    • Bổ sung các thao tác nâng cao: “Đọc tất cả” (markAllAsRead), “Đánh dấu đã đọc” (markAsRead), và “Xóa đã đọc” (deleteRead kèm hộp thoại xác nhận).
    • Tích hợp modal Cài đặt thông báo theo nhóm nguồn gửi (NotificationSettingsModal trên Zalo Mini App và NotificationSettingsPanel trên Web Dashboard) với 4 nhóm trực quan: Từ Quản lý & Nhà tuyển dụng (Hirer), Từ Người theo dõi & Đội ngũ (Followers), Nhắc đến bạn & Tương tác (Mentions), Hệ thống & An toàn (System).
    • Tích hợp modal Quản lý Theo dõi (FollowManagementModal) hỗ trợ xem danh sách “Đang theo dõi” & “Người theo dõi”, cùng thao tác theo dõi / bỏ theo dõi trực tiếp.
    • Hỗ trợ tự động phân trang “Tải thêm thông báo” và đồng bộ tức thì qua Supabase Realtime Channel.
  • Bộ PostgreSQL RPCs Dùng Chung Cho Cả Web Dashboard, Zalo App và Mobile App:

    • rpc_list_notifications: Lấy danh sách thông báo kèm bộ lọc đa tiêu chí, đếm số tin chưa đọc và phân trang trong 1 truy vấn duy nhất.
    • rpc_get_user_notification_settings & rpc_upsert_user_notification_settings: Truy xuất và lưu cài đặt thông báo (hỗ trợ tự động tạo mặc định và mở rộng preferences JSONB).
    • rpc_list_user_follows & rpc_toggle_follow_user: Truy xuất danh sách theo dõi kèm thông tin profile và bật/tắt theo dõi người dùng.
    • rpc_mark_notifications_read & rpc_delete_read_notifications: Xử lý đánh dấu đã đọc và xóa thông báo đã đọc an toàn theo auth.uid().
    • Trigger tr_execution_submission_notification: Tự động gửi thông báo đến người theo dõi khi nhân sự nộp báo cáo / bằng chứng ca làm việc.
  • Chuẩn Hóa Typography & Cải Thiện UI/UX Trang Hồ Sơ (ProfilePage - Zalo Mini App):

    • Chuẩn hóa toàn bộ hệ thống kích thước font chữ (font-display cho tiêu đề/số liệu thống kê, font-body cho nội dung, loại bỏ kích thước không đồng nhất 10px).
    • Bổ sung khối Hero Profile Card ở đầu trang với Avatar lớn, Tên người dùng rõ nét, số điện thoại, nhãn vai trò, huy hiệu xác thực CCCD và nút chỉnh sửa hồ sơ nhanh.
    • Tinh chỉnh các thẻ Card (Đánh giá uy tín, Chỉ số thống kê nhanh, Thông tin CCCD, Hồ sơ công việc, Tài khoản ngân hàng, Hồ sơ người thuê, Đơn vị đã tham gia) với cấu trúc phân cấp thị giác rõ ràng, nhãn trường đồng bộ và icon nhận diện trực quan.
    • Thay thế toàn bộ layout space-y-* sang flex flex-col gap-* theo chuẩn thiết kế repo.
  • Tối Ưu Kích Thước & Bổ Sung Nút Về Hôm Nay Cho Thanh Chọn Ngày (HorizontalCalendar - SchedulePage - Zalo Mini App):

    • Thu gọn kích thước thẻ ngày từ w-14 h-20 (80px) xuống w-11 h-[52px] (52px), tinh chỉnh padding container từ py-3 xuống py-2 và khoảng cách giữa các thẻ sang gap-2.
    • Tinh chỉnh typography (thứ ngày text-[10px], ngày text-sm font-bold), thanh tiêu đề tháng text-sm và bộ chuyển đổi Tuần/Tháng nhỏ gọn, tiết kiệm ~32% chiều cao dọc màn hình.
    • Bổ sung nút bấm nhanh “Hôm nay” trên thanh tiêu đề Calendar Filter giúp người dùng đặt lại ngày và tự động cuộn nhanh về ngày hiện tại một cách tiện lợi.
  • Đồng Bộ Header Chuẩn Ứng Dụng Cho Trang Thông Báo (NotificationsPage - Zalo Mini App):

    • Thay thế header tĩnh của trang thông báo (PageHeader với nút back) bằng Header chuẩn ứng dụng hiển thị Avatar/Tên người dùng và ngày giờ hiện tại (showBack={false}) tương tự các tab chính khác (SchedulePage, JobMarketPage, ProfilePage, PayrollHistoryPage).
  • Tối Ưu Hiển Thị Nhãn Thanh Điều Hướng Dưới Cùng (Bottom Navigation - Zalo Mini App):

    • Tái cấu trúc BottomNavigation.tsx sang mô hình khai báo mảng danh sách (NAV_ITEMS) nhất quán và chặt chẽ về mặt kiểu dữ liệu (IconProps["icon"]).
    • Loại bỏ hiệu ứng chữ in hoa toàn bộ (uppercase) và khoảng cách chữ (tracking-wider), chuyển sang dạng Sentence/Title Case chuẩn thanh điều hướng di động (“Việc mới”, “Lịch làm”, “Thông báo”, “Bảng lương”, “Cá nhân”).
    • Thêm whitespace-nowrap, truncate, flex-1, min-w-0 đảm bảo nhãn của toàn bộ 5 tab luôn nằm trên một dòng duy nhất, không bị rớt dòng trên các màn hình kích thước nhỏ (như iPhone X, iPhone 12/13 mini hay màn hình 360px-375px).
  • Khóa Ô Số Điện Thoại khi Quét Zalo QR & Khách Hàng Cũ, Hỗ trợ Xác thực Khách Chưa Xác minh:

    • Tại component ContactSection.tsx, tự động khóa ô nhập Số điện thoại (disabled / readOnly) khi khách hàng xác thực qua Quét mã Zalo QR hoặc khi nhận diện là Khách quen trong danh bạ, ngăn chặn việc sửa nhầm hoặc giả mạo số điện thoại.
    • Trường hợp Khách quen chưa từng xác thực (is_phone_verify = false), hệ thống vẫn khóa ô SĐT nhưng cung cấp đầy đủ nút hành động “Gửi OTP” hoặc “Quét QR Zalo” để worker xác thực nâng cấp hồ sơ khách hàng.
    • Bổ sung nút tiện ích “Đổi khách khác” (Reset) giúp xóa trắng dữ liệu và mở khóa lại ô SĐT khi phục vụ khách hàng mới.
  • Linh hoạt Lựa chọn Phương thức Xác thực Khách hàng tại Form Bán Hàng POS (Quét QR hoặc Gửi OTP):

    • Tại component ContactSection.tsx, bổ sung bộ chuyển đổi phương thức (Segmented Toggle) cho phép nhân viên bán hàng linh hoạt lựa chọn:
      1. ⚡ Quét Zalo QR (Nhanh): Mở mã QR ngay lập tức cho khách hàng quét mà không cần nhập số điện thoại trước. Sau khi khách cấp quyền Zalo, số điện thoại và họ tên tự động điền vào form và đánh dấu đã xác thực.
      2. 📩 Gửi mã OTP (SMS/ZNS): Dành cho trường hợp khách hàng không tiện quét QR. Worker nhập số điện thoại ➡️ Tự động nhận diện hồ sơ khách cũ ➡️ Gửi mã OTP xác nhận.
    • Tinh chỉnh giao diện thẻ khách hàng gọn gàng, hiển thị huy hiệu trạng thái xác thực rõ ràng, và tự động reset trạng thái bảo mật khi có chỉnh sửa số điện thoại.
  • Thu gọn Diễn giải Tính toán Khuyến mãi trong Zalo Mini App:

    • Tại component PromotionSection.tsx, chuyển đổi khối diễn giải chi tiết tính toán CTKM (scheme.notes) sang dạng collapsible có thể đóng/mở theo nhu cầu bằng nút bấm "Diễn giải tính toán" / "Ẩn diễn giải". Giữ giao diện thẻ chương trình khuyến mãi luôn ngắn gọn, tinh giản và tránh tràn màn hình khi đơn hàng có nhiều công thức tính phức tạp.
  • Web Dashboard Auth (apps/hire_workspace/src/features/authentication/presentation/components/SocialAuthButtons.tsx):

    • Update Zalo login button icon to use /assets/zalo-logo.svg.

Changed

  • Metadata task validator từ system_configurations được kiểm tra bằng contract bốn cột dùng chung với Hire Workspace trước khi dùng trong luồng thực thi.

  • Mọi nhánh tải sản phẩm bán hàng kiểm tra cùng contract stock_assets 16 cột với Hire Workspace trước khi tính tồn kho.

  • Bộ lọc sản phẩm bán hàng kiểm tra projection stock_balances ba cột bằng contract chung với Hire Workspace trước khi tính tồn khả dụng.

  • Tra cứu tỉnh/phường lúc onboarding kiểm tra tham số và hàng search_locations bằng contract chung với Hire Workspace, bao gồm các trường nullable của hàng hành chính.

  • Chuẩn Hóa Thuật Ngữ Vòng Đời Ca Làm (Execution Lifecycle) & Tinh Chỉnh Bộ Thông Báo:

    • Loại bỏ hoàn toàn các thuật ngữ cũ checkIn, checkOut, activity trên toàn bộ hệ thống (supabase, apps/hire_workspace, apps/worker_zalo).
    • Thay thế bằng các sự kiện thực thi ca làm: execution_submitted (follow_execution_submit_push), execution_rejected / task_needs_revision (follow_execution_reject_push), execution_approved (follow_execution_approve_push), execution_assigned.
    • Tạm thời loại bỏ các loại thông báo time-based chưa có background cron daemon: “Cảnh báo không có hoạt động trong ca làm việc” (execution_inactivity) và “Nhắc nhở trước giờ vào ca” (reminderPush / reminder) khỏi Supabase DB migrations, RPCs, Zalo Mini App và Web Dashboard.
    • Củng cố và đăng ký toàn diện 2 loại thông báo sự kiện cốt lõi: “Nhắc đến bạn (@mention)” (mention, user_mention) và “Cảnh báo hệ thống” (system_alert, system) trong PostgreSQL RPC category mapping (rpc_list_notifications), Zalo NotificationTypeRegistry và Web Dashboard TYPE_META.
    • Cập nhật entity, repository mapper, và giao diện cài đặt trên Web Dashboard (NotificationSettingsPanel) và Zalo Mini App (NotificationSettingsModal).
    • Tối ưu Điều hướng Web Dashboard: Chuyển “Trung tâm Thông báo” (/notifications) từ danh mục tab con của từng Folder (FolderExplorerPage) thành mục Menu cấp cao độc lập trong nhóm WORKSPACE trên thanh điều hướng Sidebar (AppRouter & AppSidebar), phản ánh chính xác phạm vi thông báo theo User & Workspace.
    • Tích hợp Tab Theo dõi trực tiếp trong Zalo Mini App (NotificationsPage): Tách danh sách “Đang theo dõi” và “Người theo dõi” thành các Tab chính độc lập, bổ sung thanh tìm kiếm người dùng toàn diện, bộ lọc theo vai trò (Tất cả / Thợ / Chủ ca & Quản lý) và nút thao tác theo dõi / hủy theo dõi nhanh.
  • Sửa Lỗi Nộp Lại Bước Chứa Nhiều FormX Khi Có Task Bị Từ Chối (apps/worker_zalo/src/features/execution):

    • Khắc phục lỗi P0001: Submitted FormX tasks cannot be edited khi Worker nộp lại bước công việc có nhiều nhiệm vụ (ví dụ: 2 FormX trong 1 bước) mà chỉ 1 nhiệm vụ bị Hirer từ chối yêu cầu bổ sung (needs_revision).
    • Cập nhật hàm khóa nhiệm vụ isTaskLocked và vòng lặp handleSubmit trong StepProofPage.tsx: khi bước có nhiệm vụ cần chỉnh sửa (needs_revision), các nhiệm vụ đã nộp hợp lệ trước đó (status === 'submitted') sẽ được giữ nguyên trạng thái khóa và không bị gửi lại RPC submit_step_proof.
    • Thiết lập giá trị chuẩn allowEdit: false cho nhiệm vụ kiểu formx tại ExecutionRemoteDataSource.ts nhằm đồng bộ tuyệt đối với ràng buộc chống sửa đè của Database.
  • Cho Phép Worker Chỉnh Sửa Phản Hồi FormX Khi Trong Trạng Thái Nháp (apps/worker_zalo/src/features/task/tasks/task_formx):

    • Khắc phục hạn chế mở modal phản hồi FormX nháp. Hỗ trợ Worker xem và chỉnh sửa (Xem & Sửa ✏️) các phản hồi FormX khi nhiệm vụ đang ở trạng thái nháp (isFormxDisabled = false).
    • Khóa quyền sửa/xoá (Xem chi tiết 🔍) đối với các phản hồi FormX đã được nộp báo cáo (status === "submitted" | "approved" | "paid"), phù hợp với quy định bảo toàn dữ liệu bằng chứng của PostgreSQL backend (P0001: Submitted FormX response cannot be deleted), đồng thời thêm thông báo lỗi thân thiện nếu gặp vi phạm.
  • Khắc Phục Lỗi Gửi Trùng Lặp Yêu Cầu searchJobs Trên JobMarketPage (apps/worker_zalo):

    • Thêm isFirstRender ref guard cho debounce search effect trên JobMarketPage.tsx, loại bỏ cuộc gọi API thứ hai dư thừa khi trang vừa tải do điều kiện undefined !== "" kích hoạt timeout không cần thiết.
  • Sửa Lỗi Trạng Thái Nút “Bắt đầu làm” & Sai Lệch Múi Giờ Ngày Thực Hiện (apps/worker_zalo):

    • Khắc phục lỗi ngày sai lệch (Timezone Mismatch Bug): Loại bỏ việc dùng new Date().toISOString().split('T')[0] (sinh ngày theo UTC gây lệch lùi 1 ngày tại Việt Nam vào khung giờ 00:00 - 07:00 AM). Bổ sung bộ tiện ích dateUtils.ts chuẩn hóa định dạng theo múi giờ Asia/Ho_Chi_Minh, loại bỏ triệt để lỗi “Chỉ có thể bắt đầu công việc vào đúng ngày đã lên lịch”.
    • Đồng bộ hóa vòng đời thực thi ca làm việc trên Job Detail Page: Cập nhật JobDetailPage.tsx đồng bộ cả trạng thái ứng tuyển (job_applications) lẫn trạng thái ca làm việc trong ngày (job_execution_records). Nút bấm tự động cập nhật chính xác theo tiến trình: “Bắt đầu làm” (chưa bắt đầu), “Tiếp tục làm việc” (started), “Đã nộp báo cáo” (submitted), “Đã hoàn thành (Đã duyệt)” (approved), “Đã thanh toán” (paid), hoặc “Chưa đến ca làm việc” nếu ngoài ngày làm việc đã lên lịch.
  • Task Validator Metadata qua System Configuration (supabase/, apps/hire_workspace/, apps/worker_zalo/):

    • Seed các khóa task.photo_proof và task.geofence trong public.system_configurations; tên, mô tả và trạng thái kích hoạt được quản lý tập trung tại /system-configurations.
    • Giữ Registry trong mã nguồn làm nguồn xác thực cho component, schema và logic validation; Web Dashboard và Zalo Mini App dùng TaskValidatorEntity riêng trong feature task để đọc metadata cấu hình.
    • StepProofPage ưu tiên metadata hệ thống, fallback về module đăng ký khi tải cấu hình thất bại và loại task không hoạt động khỏi hiển thị, validation, tiến độ và submission.
    • Loại bỏ route/page legacy /validators cùng navigation và API aliases không còn sử dụng.
  • Loại bỏ Trạng thái assigned & Chuyển thẳng sang approved khi Gán/Nhập Lời mời (supabase/migrations/, apps/hire_workspace/, apps/worker_zalo/):

    • Tự động Phê duyệt (Direct Approval): Khi Người thuê (Hirer) chỉ định trực tiếp thành viên Workspace/Folder vào công việc hoặc khi Worker quét mã mời/nhập link (redeem_invitation), đơn ứng tuyển trong job_applications được thiết lập trực tiếp ở trạng thái approved (thay vì assigned), không cần qua bước phê duyệt trung gian.
    • Đơn giản hóa Vòng đời Đơn ứng tuyển: Loại bỏ trạng thái assigned khỏi enum application_status_type (pending, approved, rejected, cancelled).
    • Tối ưu hóa RPCs Thực thi: Cập nhật các RPC backend start_job_execution, reset_job_execution và get_worker_schedule kiểm tra chặt chẽ điều kiện status = 'approved'.
    • Làm sạch Giao diện & Bộ lọc: Dọn dẹp các bộ lọc, huy hiệu và logic kiểm tra assigned trên Web Dashboard (WorkerSourcingBoard, CandidateProfilesTable, JobAssignMemberModal) và Zalo Mini App (JobDetailPage).
  • Hợp nhất get_nearby_jobs vào search_jobs() (supabase/migrations/, apps/worker_zalo/):

    • Tối ưu hóa public.search_jobs(...) hỗ trợ p_keyword nhận NULL hoặc chuỗi rỗng '' để đóng vai trò khám phá việc làm xung quanh theo khu vực (p_working_regions).
    • Chuyển đổi public.get_nearby_jobs thành wrapper tương thích ngược gọi trực tiếp public.search_jobs.
    • Cập nhật JobsRemoteDataSource.fetchNearbyJobs trong Zalo Mini App ủy quyền trực tiếp qua searchJobs({ workingRegions }).
  • Location Search RPC Unified (supabase/migrations/ & apps/hire_workspace & apps/worker_zalo):

    • Hợp nhất toàn bộ 100% các RPC functions tìm kiếm địa điểm (search_locations, search_locations_batch, autocomplete_location_suggestions, search_vn_geo) thành một hàm duy nhất: public.search_locations(p_workspace_id?, search_query?, p_folder_id?, p_scope?, row_limit?, row_offset?, p_names?).
    • Loại bỏ hoàn toàn tình trạng hàm nạp chồng (overloaded duplicate functions), drop toàn bộ các RPC cũ (search_locations_batch, search_vn_geo, autocomplete_location_suggestions).
    • Hỗ trợ đa dạng các scope tìm kiếm: 'folder', 'workspace', 'global', 'vn_geo', 'suggestions', 'batch', và 'auto'.
    • Tự động kế thừa và merge các custom overrides (custom_name, custom_code, custom_category, metadata) của workspace/folder.
    • Refactor LocationRemoteDataSource (searchLocations, searchLocationsBatch, autocompleteAdminSuggestions) và GlobalSearch trên apps/hire_workspace cùng auth_remote_datasource trên apps/worker_zalo sử dụng chung hàm RPC search_locations mới.
    • Bổ sung bộ pgTAP test 030_search_locations_unified_test.sql bao phủ 100% các scopes, batch matching và xác nhận chỉ có đúng 1 hàm search_locations tồn tại trong schema.
  • Web Dashboard Zalo User Display (apps/hire_workspace/src/router/AppRouter.tsx & apps/hire_workspace/src/features/user/presentation/pages/UserDetailPage.tsx):

    • Đối với người dùng xác thực qua Zalo Provider (email chứa từ khóa zalo), ẩn email kỹ thuật tự sinh và thay thế bằng nhãn “Zalo” (trên Topbar Menu) hoặc “Tài khoản Zalo” (trên trang Hồ sơ cá nhân).
  • Web Dashboard Auth (apps/hire_workspace/src/features/user/presentation/components/UserLinkedAccountsTab.tsx):

    • Loại bỏ hoàn toàn option email (Email & Mật khẩu) và github khỏi danh sách các nhà cung cấp định danh liên kết.
    • Danh sách Provider liên kết hiện tại tập trung vào 3 dịch vụ phổ biến: Google, Facebook, và Zalo.
  • Supabase Edge Function Config (supabase/config.toml & supabase/functions/zalo-oauth-proxy/index.ts):

    • Prioritize LOCAL_PROXY_BASE_URL environment variable for local redirect URI generation in zalo-oauth-proxy.
    • Disable JWT verification (verify_jwt = false) for zalo-oauth-proxy, auth-zalo-exchange, and server-time functions to prevent UNAUTHORIZED_NO_AUTH_HEADER errors when accessed publicly via browser OAuth redirects.
  • Cập nhật Supabase Edge Function auth-zalo-exchange chấp nhận tham số token tùy chọn (optional) miễn là có zaloId, bỏ qua bước giải mã SĐT Zalo khi không có token và tự động fallback về số điện thoại đã lưu trong bảng profiles nếu người dùng đã đăng ký SĐT trước đó.

  • Nâng cấp cơ chế bảo mật cho auth-zalo-exchange: Tự động truyền và đối soát Zalo Access Token (getAccessToken()) với Zalo Graph API (https://graph.zalo.me/v2.0/me) để xác thực danh tính người dùng và ngăn chặn tấn công giả mạo zaloId.

  • Zalo Mini App Photo Proof Integration:

    • Cập nhật module upload trong Zalo Mini App tích hợp phương thức processAndStampPhoto gọi Server Edge Function process-photo.
    • Cập nhật TaskPhotoProofProofMapper, DTO, Entity và RPC submitTaskProof trong Zalo App hỗ trợ cấu trúc photos JSONB đầy đủ.
  • Zalo Mini App Photo Proof Persistence:

    • Khắc phục lỗi mất ảnh minh chứng sau khi nộp thành công trên Zalo Mini App (ExecutionRemoteDataSource): cập nhật trích xuất danh sách ảnh từ cấu trúc mới task_proof_photo.photos (JSONB Array) thay vì chỉ đọc photo_urls, và chuẩn hóa payload gửi lên RPC submit_step_proof.

Performance

  • Client-Side Photo Compression Optimization:
    • Tối ưu hóa bộ tiền xử lý applyCompression tại Client (useUploadController.ts): Tự động nén chất lượng ảnh (tương ứng % cấu hình từ UploadConfig.compressionQuality hoặc 0.6 mặc định) và giới hạn kích thước tối đa 1600px trước khi gửi dữ liệu lên Edge Function. Giúp giảm 70-85% dung lượng truyền tải mạng và tăng tốc độ đóng dấu watermark trên server.