Help & Manual

Quick-start guides for each kind of user. Pick your role above.

Admin Guide

This guide is for people in the ADMIN role — system owners who manage users, KPI catalog, settings, and oversight.

What you'll do here

  • Provision users + roles (USER / MANAGEMENT / ADMIN / CUSTOMER)
  • Configure the KPI catalog (groups, rule types, KPI types, department-KPI mapping)
  • Manage countries, departments, holidays
  • Assign pending intake tickets
  • Configure global app settings (date format, ticket edit window)
  • Review the audit log

The left sidebar lists every admin area. The order is curated; click to navigate:

SectionWhat's there
CountriesCountry list + working-hours config (timezone, workday window, working days)
DivisionsOrg divisions departments roll up to (parallel to country). Optional; departments without one show as Unassigned in division reports.
DepartmentsDepartment records linked to a country and, optionally, a division
UsersUser accounts, roles, department assignment, active/inactive toggle
KPI GroupsTop-level KPI categories (e.g. Issue, Internal Control, Uptime)
Rule TypesThe formula behind each KPI Type (rr, acr, accuracy, submit, project, ic-*, uptime). Usually only admins of admins touch these.
KPI TypesConcrete metrics tracked. Each KPI Type picks a Rule Type, sets parameters (SLA minutes, weights, targets), and belongs to a KPI Group.
KPI ItemsRaw ticket data with import-from-Excel + manual editing.
Department KPIsWhich KPI Types are valid for which Departments.
Pending TicketsIntake tickets that arrived with no assigned user — assign or delete.
HolidaysPer-country holiday calendar + import-from-Nager-API.
General SettingsGlobal app settings (ticket edit window, date format).
Email TemplatesCustomise the subject + body of the transactional emails (live preview, reset-to-default).
Email LogHistory of every email the system has tried to send (filterable).
ModulesTurn whole feature modules (KPI / Workflow / Asset) on/off at runtime.
Audit LogRead-only history of ticket lifecycle + maintenance events.
Data CleansingExport-then-delete old tickets / pending intake / audit logs / orphaned attachments past a cutoff.
Other KPI SettingsUptime unit configuration (and, historically, the global settings now on General Settings).

User management

Roles:

  • CUSTOMER — auto-created the first time someone signs in with Google. Can submit intake tickets and chat on their own tickets only. No internal pages.
  • USER — agent. Has a Department. Can self-log KPI tickets, handle assigned intake tickets, and view their own profile.
  • MANAGEMENT — supervisors. Can view Performance and Monthly reports. No edit access.
  • ADMIN — full admin access (sidebar + all settings).

Adding an internal user: Add the user via the Users admin BEFORE they try to sign in. Sign-ins from Google accounts not in the Users table are auto-provisioned as CUSTOMER. To make someone an Agent or Admin, either:

  1. Create the user row first with their email and role (recommended), or
  2. Have them sign in, then edit their auto-created CUSTOMER row and change the role.

Department assignment is required for USER role only; MANAGEMENT and ADMIN can be left without one.

Active = false disables sign-in and ticket creation but preserves history. Use this instead of Delete for departing staff.

Join date / End date are the employment span. Setting an End date in the past deactivates the account automatically on save (so you can record a leaver by date instead of flipping the Active toggle); clearing it — or a future date — keeps them active. Join date also drives KPI expectations (e.g. monthly project) from the month they joined.

Delete removes the user and all their tickets — only do this in test environments.


KPI catalog setup

Order matters when bootstrapping a new environment:

  1. Country → set timezone, workday start/end, working days of the week.
  2. Division (optional) → create the org divisions departments will roll up to. Skip if you only report by country.
  3. Department → links to a country; optionally assign a division.
  4. KPI Group → toggle "contributes to uptime" only for groups whose KPIs feed the Uptime calculation.
  5. Rule Type → these are pre-seeded; only edit if you understand the formula.
  6. KPI Type → pick a Rule Type, set parameters:
    • For rr: responseSlaMin, resolutionSlaMin, respWeight, resoWeight.
    • For rr-dynamic (Ad Hoc with an extendable, per-ticket resolution deadline): responseSlaMin, resolutionSlaWorkingDays (the default deadline in holiday-aware working days; the agent can raise it per ticket and extend it later), respWeight, resoWeight. Two differences from rr: the resolution target is a working-day deadline set on each ticket (not a fixed minute SLA), and a ticket is scored in the month it is resolved (closedAt), not the month it was requested — open tickets don't score until they close. Each deadline extension logs a reason and emails the requestor.
    • For submit: submitCutoffMin.
    • For accuracy: respAccTarget, dataAccTarget, respAccWeight, dataAccWeight.
    • For acr: six target percentages + six weights.
    • For ic-*: slaWorkingDays, targetDayOfWeek, minFindings (as relevant).
    • availableForIntake: true exposes the KPI Type on the public intake form.
    • ignoreWorkingDayFilter: true means weekend/holiday tickets count without the override.
  7. Department KPIs → assign each KPI Type to the Departments that should be able to log/select it.
  8. Other KPI Settings → for Uptime KPI Types, configure unit counts per country.

Countries

The Country form sets per-country defaults used in working-hour math:

  • Timezone (IANA name, e.g. Asia/Jakarta).
  • Workday Start / End (local time of day, e.g. 10:00-19:00).
  • Working Days as comma-separated ISO weekday numbers (1=Mon … 7=Sun). Default 1,2,3,4,5 (Mon-Fri).

These settings drive response time, resolution time, uptime windows, and ticket inclusion filters. Change carefully — reports recompute on the next dashboard view but consider the impact on historical scoring.


Divisions

Divisions are an organizational tier parallel to country — both are attributes a department carries, and reports can group departments either way. Use them to mirror your real org chart (e.g. Business Operations, Finance, IT & Business Analytics).

  • A division has a name and an optional abbreviation.
  • Assign a department to a division on the Departments form (the Division field is optional).
  • Set the division's Heads via the Heads button on the division row. A division can have one or more heads. Every head gets manager capabilities over all departments in the division — assign tickets, approve extensions, view performance — exactly like a department manager, but division-wide. (This is independent of the user's role; it works like designating a department manager.)
  • Departments with no division roll up under an Unassigned bucket in the division scorecard.
  • The division score is the average of its departments — the same roll-up the country score uses — so the two views always reconcile for a given month.

You can adopt divisions gradually: create them here, then assign departments at your own pace. Until a department is assigned, only its country reporting is affected (nothing breaks).

The structure you build here (divisions, heads, departments, managers, user assignments) is shown live to management on the Insights → Org Chart page — it updates automatically as you make changes.


Holidays

The Holidays admin lets you:

  • Add/edit/delete holidays for any country.
  • Filter the list by country with the radio group.
  • Import public holidays from Nager.Date by picking a country + year and clicking Import. The country must have a 2-letter abbreviation (e.g. ID, US).

Holidays apply to tickets whose country matches.


Pending tickets

Intake tickets submitted without a specific user appear here.

  • Pick a user from the destination department's dropdown.
  • Click the green check to assign — the user gets an email and the ticket flips to On Progress.
  • Click the trash to discard (e.g. spam) — the ticket is permanently deleted.

Once assigned, the ticket lives on the agent's profile and disappears from this list.


Audit log

Path: Admin → Audit Log.

A read-only log of ticket lifecycle events. Filters: action, actor, date range. Columns: When, Who, Action, Entity, Details.

Events captured (v1):

  • TICKET_INTAKE_SUBMITTED — a customer (or signed-in user) submitted via intake.
  • TICKET_SELF_LOGGED — an agent created via /input.
  • TICKET_ASSIGNED — admin/manager assigned a pending ticket.
  • TICKET_REASSIGNED — a manager/admin moved an already-assigned ticket to a different teammate.
  • TICKET_UPDATED — agent edited a ticket (no status change).
  • TICKET_STATUS_CHANGED — agent moved status forward.
  • TICKET_DELETED — ticket removed (pending-tickets admin or agent's profile).
  • DATA_CLEANSED — an admin ran a Data Cleansing purge (records cutoff + counts removed).

Logs are append-only; nothing here can be edited or deleted from the UI.


Email Templates

Path: Admin → System → Email Templates.

Customise the subject + body of the transactional emails (ticket assigned, closed, rejected, re-opened, deadline-extended, and the verification code) without touching code:

  • Pick a template; edit the Subject and Body (HTML). The branded header/footer is fixed (you only edit the message body).
  • Insert variables like {{kpiName}}, {{statusUrl}}, {{rejectionReason}} from the chips (or type them) — they're highlighted in the body and filled in at send time. Required variables (e.g. {{code}} on the verification email) can't be removed.
  • Format tidies the HTML indentation; the right/top preview renders with sample data live.
  • Save to apply; Reset to default drops your customisation and returns to the built-in template. Templates with no override use the built-in default.

Email Log

Path: Admin → System → Email Log.

A history of every transactional email the system has tried to send: recipient, subject, status (sent / failed, with the error), and time. Filter by status and search by recipient/subject. Shows the latest 200; narrow with the filters for older entries.

Data Cleansing

Path: Admin → System → Data Cleansing. Destructive — read carefully.

Permanently removes old data past a cutoff, after exporting a JSON backup. Choose how many months old, tick the data to remove, Preview (counts only, nothing deleted), then Export & Delete (a JSON backup downloads first):

  • Resolved KPI tickets — aged by resolution date (closedAt); cascade-removes their chat + extension requests and deletes their image attachments. Open tickets are never touched.
  • Pending / unassigned intake tickets — aged by submitted date.
  • Audit log entries — aged by created date.
  • Orphaned chat attachments (GCS) — image blobs whose ticket/message is already gone.

Minimum cutoff is 1 month; the run is itself audit-logged. Removing tickets refreshes KPI reports on next view.


Global settings

Other KPI Settings page has:

  • Ticket Edit Window (days) — USER-role accounts can only modify tickets dated within this window. ADMIN/MANAGEMENT always bypass.
  • Date Format — date-fns format pattern used everywhere in the app (table dates, ticket dates, email dates). Examples: dd/MM/yyyy, MM/dd/yyyy, yyyy-MM-dd.

Both fields save together when you click Save.

This page also hosts the Uptime Unit table — pairing each Uptime KPI Type with its country and unit count (number of units, e.g. number of stores).


Operational tasks

Backfilling closed tickets

If you have closed tickets pre-dating the response/resolution auto-tracking, run:

npx tsx scripts/backfill-intake-metrics.ts

It will fill in metrics.responseTimeMin, metrics.resolutionTimeMin, closedAt, and firstAgentReplyAt for closed tickets that are missing them, using createdAt, the first agent chat message, and closedAt ?? updatedAt as anchors. Then it rebuilds the KPI reports.

Rebuilding reports

The persisted KPI report tables (DashboardSummary, KpiMonthlySummary) rebuild lazily: a ticket change marks the reports dirty, and the next time someone opens the dashboard / Monthly Report, the system recomputes them — but only if tickets actually changed since the last rebuild (otherwise the view is instant). So daily ticket actions (submit, chat, close, reassign…) stay fast; the recompute cost lands on the next report view. Admin-config saves (KPI types, holidays, etc.) and bulk imports still rebuild in place.

If something looks stale, just open the dashboard (it self-heals on view) or force a rebuild:

POST /api/admin/rebuild-reports

Importing KPI items from Excel

The KPI Items admin has an Import button that accepts an Excel file. Preview the rows first, then run. The preview shows: which rows will create, update, skip, or error. Errors usually mean unmatched user / country / department / KPI Type names — make sure those exist before importing.


Frequently asked

A user can sign in but doesn't have admin access. Check Users page — they're probably CUSTOMER (auto-provisioned). Change their role to ADMIN.

Country deletion fails with "Cannot delete country with existing department associations". Move or delete the dependent Departments first.

Holiday import says "Country has no abbreviation". Edit the Country and set a 2-letter abbreviation. Nager.Date uses ISO country codes.

The audit log has no entries before today. Audit logging started recently; pre-existing tickets aren't retroactively logged. Going forward, every ticket action is captured.

An intake ticket appears stuck in "Pending Tickets" forever. Assign it manually here. Auto-assignment only happens when the customer picked a specific user at submission.

Pick a role: CustomerSubmit a ticket and chat with the agent. · AgentHandle tickets, self-log activity, close tickets. · ManagementRead dashboards and monthly reports. · AdminManage users, KPIs, settings, and audit history. · DeveloperPublic intake API reference for external integrations.