Skip to main content

Companies & Users (Admin)

Audience: Support, super-admins, ops · Where in app: /admin/companies, /admin/users, /admin/blocked · Access: Super-admin only (user_type === 'admin'); backend re-checks every endpoint.

These screens are how staff manage tenants. Companies is the primary object (a tenant — owner, subscription, AI credits, feature flags); Users is the people layer (the owner and members, with impersonation); Blocked is the moderation list (block abusive IPs, URLs, or companies). All three reuse the main backend's /company, /user, and /blocked endpoints rather than dedicated admin-only controllers — the admin gate is applied at the route/middleware level.

What it does

  • Companies: search/filter every company, view a company's full profile, edit its fields and feature flags, grant manual AI credits / free periods, inspect its AI credit logs and usage, archive, and permanently delete.
  • Users: search/filter every user, view/edit a user, delete, and impersonate ("login as") to reproduce a customer's exact session.
  • Blocked: create/edit/delete entries that block an IP, URL, or company.

How it works

  • The Companies and Users lists are thin admin wrappers over the same backend list endpoints the rest of the app uses (GET /company, GET /user), passing admin-only filters. Pagination is skip/limit (the FE converts page/pageSize).
  • Impersonation calls POST /user/:id/login, which returns a fresh auth token for the target user. The admin then operates as that user. This is the canonical way to debug "it works for me but not for the customer."
  • Feature flags are toggled via dedicated PUT /company/:id/<flag> endpoints (one per flag). Most are simple toggles; a few set a numeric allowance.
  • AI credits are managed via PUT /company/admin/manual-ai-credits and PUT /company/admin/free-period. The customer-facing credit balance lives on the company's subscription; every change is audit-logged to ai_credit_logs (AICreditLogModel).
  • Company-name resolution for cost-tracking: POST /company/admin/names-by-ids resolves a set of company_ids to names — used by the cost-tracking Company Spend tab, since ms-ai does not store names.

Screens & fields

Companies — list (/admin/companies)

frontend/src/views/admin/companies/List.vue. Search by company name or owner.

Filters:

FilterValuesParam
Status (archived)Active / Archivedarchived
Client typeAll / Agency / DirectclientType
Subscription typeAll / Trial / Active / Canceled (Trial hidden when Agency selected)subscriptionType
Low AI creditstogglelowAiCredits
Agencyby agency idagencyId

Columns: Company, Owner, Agency (hidden for direct), Package, AI Credits, status, and Actions.

Company — detail / edit (/admin/companies/:id, .../edit)

Detail.vue / Edit.vue. View/edit company fields plus feature toggles. Toggle endpoints (frontend/src/repositories/admin/companies.js):

  • Lead Intelligence (/lead-intelligence) + allowed (/lead-intelligence-allowed)
  • RB2B (/rb2b), Snitcher (/snitcher + /snitcher-allowed), Apollo (/apollo)
  • Verified Visitor Badge (/verified-visitor-badge)
  • AI inbound/outbound call allowed (/ai-inbound-call-allowed, /ai-outbound-call-allowed) and per-agent allowances (/ai-inbound-call-agents-allowed, /ai-outbound-call-agents-allowed)
  • WhatsApp agents allowed (/whatsapp-agents-allowed)
  • Webhooks (/webhooks), Affiliate link (/affiliate-link), Widget whitelabel (/widget-whitelabel)
  • Knox/Nox enable/disable (POST /company/:id/knox/{enable|disable}) and Knox memories view/delete (/knox-memories)

Admin-only credit controls:

  • Free period: PUT /company/admin/free-period (free_period_minutes).
  • Manual AI credits: PUT /company/admin/manual-ai-credits (credits_calculation, number_of_credits).

Lifecycle: Archive (GET /company/:id/archive) and permanent delete (DELETE /company/:id — only for archived companies; removes the company and all related data).

Company — AI Credit Logs (/admin/companies/:id/ai-credit-logs)

AICreditLogs.vueGET /ai-credit-logs?company_id=.... The audit trail of every credit change (AICreditLogModel, collection-level audit). Each row has source (e.g. ai_tokens_credit_job, manual_ai_credits_job, subscription_renewal, buy_addon, agency_admin_set, admin_override), action (consume / refill / reset / set / addon / override), before/after/delta for remaining_ai_credits and remaining_purchased_ai_credits, consumed_credits, an optional consumption window, and token_usage/metadata. Filterable by source, action, start_date, end_date.

Note: these are customer-facing AI credits (the balance a customer spends), tracked in the main backend — distinct from the provider spend ledger in cost-tracking, which lives in ms-ai.

Company — AI Usage (/admin/companies/:id/ai-credits-usage)

AiCreditsUsage.vueGET /admin/companies/:id/ai-credits-usage. Detailed super-admin usage breakdown: summary, by_agent, by_model, paginated raw events, and subscription, over a from/to window.

Users — list (/admin/users)

frontend/src/views/admin/users/List.vue. Search by name or email. Filters: user_type, status. Columns: user, Company, Agency, User Type, Status, plus Actions. The Impersonate action (handleImpersonate, "Login as this user") calls POST /user/:id/login.

User — detail / edit (/admin/users/:id, .../edit)

Detail.vue / Edit.vue. View/edit user fields; a Login as User button (impersonation); shows the user's recent AI credit logs (GET /ai-credit-logs?user_id=...). Delete via DELETE /user/:id.

Moderation — Blocked List

/admin/blocked, .../create, .../:id/edit (frontend/src/views/admin/blocked/*, repo blocked.js). Block one of three types (BLOCKED_TYPE): ip, url, company. Endpoints: GET /blocked (filter by type, search), GET /blocked/:id, POST /blocked, PUT /blocked/:id, DELETE /blocked/:id. This is the entry point for shutting down abusive traffic or a bad actor company.

Behaviors & edge cases

  • Impersonation is full takeover. POST /user/:id/login issues a real token for the target user — anything you do is done as them. Use it for support repro, and be deliberate about side effects (do not send messages / change settings as the customer unless intended).
  • Permanent delete is destructive and gated. DELETE /company/:id removes the company and all related data; the flow expects the company to be archived first. DELETE /user/:id removes the user. Neither is reversible.
  • Manual AI credits bypass the normal billing path — they write directly to the subscription's credit balance and are logged with an admin source (admin_override / manual_ai_credits_job / agency_admin_set). Use the AI Credit Logs screen to see who changed what.
  • Feature toggles are per-company and take effect immediately; "allowed" variants set a numeric cap rather than a boolean.
  • Filters interact: selecting Agency client type hides the Trial subscription filter (and clears it if it was set), because agency subscriptions don't model trials the same way.
  • Two different "credits". Customer AI credits (this cluster, main backend) ≠ provider cost credits (cost-tracking, ms-ai, 1 credit = $0.01). Don't conflate them.

Technical implementation

  • Frontend views: frontend/src/views/admin/companies/*, frontend/src/views/admin/users/*, frontend/src/views/admin/blocked/*
  • Frontend repos: frontend/src/repositories/admin/companies.js, users.js, blocked.js
  • Backend endpoints: /company*, /user*, /blocked*, /ai-credit-logs, /admin/companies/:id/ai-credits-usage, /company/admin/{names-by-ids,free-period,manual-ai-credits}
  • Models: AICreditLogModel (ai_credit_logs), plus Company/User/Subscription models
  • Related service: ../services/backend.md