Skip to main content

Modpanel user index — last sign-in column & masked export

Jira: BIF-8736 · Epic: BIF-8695

Overview

Improve the Modpanel billing users index (https://moderator.qontak.com/billing/users) with a "Last Sign-In" (last login) column and a masked export, so internal admins can audit user activity without exposing full user details (email, name, phone).

Scope Changes

  • Backend — last-login data + export generation with field masking.
  • Frontend — new column and Export button on the users index.

8. User Stories + Acceptance Criteria

User StoryImportanceMockup / Technical NotesAcceptance Criteria
[USRIDX-S01] — Last sign-in + masked export

As an internal admin on the Modpanel billing users page, I want a "Last Sign-In" (last login) column and a masked export, so that I can audit user activity without exposing full user details.
Should HavePage: /billing/users. Export format: CSV, current-filter only. Masking example: addo.hernando@mekari.com****.hernando@mekari.com; phone +6281377427042+****377427042.— Happy Path —
• AC-1: Given the users list at /billing/users, when it renders, then a "Last Sign-In" column shows each user's most recent login timestamp (last login, not last activity); show "Never"/empty when there is none. Timezone displayed is GMT+7 (Asia/Jakarta).
• AC-2: Given the users page, when the admin clicks Export, then a CSV file is downloaded containing the user list (respecting the current search/filter) with columns in order: company_id, company_name (masked), user_name (masked), email (masked), phone (masked), exists_in (chat/crm/both), last_login_date_jakarta (YYYY-MM-DD, GMT+7), last_login_hour_jakarta (HH:MM:SS, GMT+7).
• AC-3: Given a masked field (company_name, user_name, email, phone), when it is written to the export, then the first 4 characters are replaced with **** and the remainder is preserved. For email, masking applies to the local part only and the full domain is preserved → addo.hernando@mekari.com becomes ****.hernando@mekari.com. For phone, the leading + is preserved then the first 4 digits are replaced → +6281377427042 becomes +****377427042.
— Edge —
• AC-4: Given a masked value with fewer than 4 characters to mask (e.g. email local part abc@…), when it is written to the export, then the entire value (local part, for email) is masked.

Open questions — resolved

  1. Export format — CSV or XLSX? → CSV
  2. Masking rule → first 4 characters replaced with ****, remainder preserved (email: local part only, domain kept; phone: + kept); values shorter than 4 chars are fully masked.
  3. Timezone used for the Last Sign-In display. → GMT+7 (Asia/Jakarta)
  4. Does Export respect the current search/filter on the page, or export all users? → Current filter only