Skip to main content

Signal — Employees

Written by Schae Lilley

The Employees view (route /employees in Signal, Power Digital's internal BI web app) is the people-performance roster: every active Power Digital employee with their attributed gross profit (RPE), book value (MRR), client retention, seat/client counts, and standing against role-based KPI targets, drillable into a per-person profile, account list, Pulse hours, and month-by-month history. It is visible to every signed-in Signal user; base-tier "Members" see only their own row ("Your Record"), while Team Leads and above get the full filterable roster, leaderboards, and KPI Rollup. It answers "who is carrying how much revenue, and are they at target?" Data originates from Nova (roster, org structure, staffing history, Pulse hours), Vena (client gross profit — finance's system of record), ADP (employment type), Deel is NOT used on this view, Google Sheets (KPI target definitions, job-description links), and Signal's own records in Supabase (saved team assignments, allocation % overrides, on-leave flags, VABO tags).

Field

Value

Route

/employees

Access

All signed-in users. Members (base tier) see a single-row "Your Record" version; Team Lead / Admin / Gandalf / Sauron tiers see the full view. Extra affordances for Admin+ (FT badge, Mark On Leave, Adjust Allocation, Avg Client Hrs/Wk data).

Nav section

"People" (first link), sidebar accordion. Also one of the two destinations Members keep in their nav (with Summary).

Primary data sources

Nova (roster/org/job titles/manager/hire date, staffing history, Pulse hours, client churn dates; team saves via Nova GraphQL API since 2026-07-01), Vena (gross profit per client × department × month), ADP (employment type), Google Sheets (KPI targets sheet, JD links sheet), Signal's own records in Supabase (team_assignments, revenue_split_overrides, employee_flags, client_flags, signal_roles)

Writes

One: admin-only "Mark On Leave / Remove Leave" → Supabase employee_flags (flag on_leave). Everything else is read-only or links out.

Key code refs

src/views/EmployeeView.tsx, src/context/DataContext.tsx (getEmployeeMetrics, getEmployeeHistory, computeEmployeeRpe via src/utils), src/App.tsx (nav/guards), server/index.ts (/api/employees, /api/employees/nova-org, /api/employee-profile/:id, /api/employee-hours/:id, /api/pulse-coverage, /api/employee-kpi-targets, /api/jd-links), server/vena-kpi-engine.ts (getAssignmentsData), server/snowflake-only-queries.ts (seat detection), server/nova-api.ts / server/nova-history.ts (Nova GraphQL cutover), src/services/transform.ts (retention/active flags)

Last verified

staging @ 98df0c4, verified 2026-07-07

Purpose

The Employees view in Signal exists so leadership does not have to stitch together Vena finance exports, Nova org data, and Pulse check-ins to answer "who is carrying how much revenue, and are they at target?" It attributes each client's gross profit (from Vena, finance's system of record) to the people actually staffed on the account — using the same team and allocation rules as Signal's Manage Leads view — and compares each person against role-based KPI targets maintained in a Google Sheet: RPE (revenue per employee) for delivery roles, MRR book value for Account Director / Account Manager roles, and retention for both. Results roll up by department + role or by division in the KPI Rollup tab. Performance conversations, capacity decisions, promotion cases, and target-setting all start from this screen. A secondary purpose: every individual employee (Member tier) can log in and see their own attributed record.

Access & visibility

  • Route guard: none. /employees is mounted in src/App.tsx with no wrapper (<Route path="/employees" element={<EmployeeView />} />), so any authenticated Signal user can load it. Authentication itself is Google OAuth restricted to authorized Power Digital and Cardinal email domains (the three-domain ALLOWED_DOMAINS allowlist in src/context/AuthContext.tsx: powerdigitalmarketinginc.com, external.powerdigitalmarketinginc.com, cardinaldigitalmarketing.com — see the Access Model page).

  • Role tiers (resolved in src/context/AuthContext.tsx from the Supabase app_users table columns is_team_lead, is_admin, is_gandalf; "Sauron" is a hardcoded super-admin list in code): Member (no elevated role) → Team Lead → Admin → Gandalf → Sauron. Roles are granted by editing app_users via Signal's General Access screen (/users, Gandalf-only). is_team_lead is also auto-granted at login when the user is an Executive Sponsor (Account Director) or Group Director on any active Nova client (the ensureUserProvisioned step provisions/upgrades the app_users row).

  • Member experience: the Employees view itself checks isMember and strips the page down to a table titled "Your Record" containing only the member's own row, matched by login email against the Nova roster (an unfiltered roster call, so the default hide-unassigned / hide-Unknown-org gates cannot drop the member's own record). Filters, averages, leaderboards, tabs, and the KPI Rollup are all hidden. The sidebar for Members keeps exactly two links: Summary and Employees. Global Search and the Iris assistant are also hidden for Members.

  • Nav flag: the "Employees" link sits in the "People" accordion section of the sidebar with no per-link flag (visible to everyone). Sibling links in the same section carry flags: Manage Leads (teamLeadOnly), Employee Pulse and KPI Targets (adminOnly, which also passes for Gandalf).

  • Admin-and-above extras inside the view: the "FT" confirmed-full-time badge on names (canSeeFtTag = isAdmin || isGandalf), the "Mark On Leave / Remove Leave" toggle in the drawer (isAdmin), the "Adjust Allocation" button in the drawer (isAdmin), and the data behind the hidden-by-default "Avg Client Hrs/Wk" column (its endpoint /api/pulse-coverage is requireAuth + requireAdmin; non-admins silently see em-dashes because the fetch failure is swallowed).

Data sources & lineage

Origin legend: "Nova" = Power Digital's Nova platform (org + staffing system); "Vena" = finance's planning system (writes revenue tables Signal reads); "Signal's own records" = the Supabase database written by users inside Signal; "ADP" = the HR/payroll platform; "Google Sheets" = curated sheets maintained by ops/data. Intermediate transport (warehouse replicas, caches) is not a source.

On-screen element

Origin system

Code path

Refresh

Caveat

Roster rows: name, email, job title, division, department, is_fulltime

Nova (users, job titles, divisions, department bridge)

GET /api/employees in server/index.ts

1-hour server cache; ?refresh=1 busts it

Roster = active (non-terminated) people with a company email domain (@powerdigitalmarketinginc.com, @powerdigital.com, @cardinaldigitalmarketing…, @external.powerdigitalmarketinginc.com) plus a test-name denylist. Nova data reaches Signal via a warehouse replica, so a Nova org edit can lag the replica sync in addition to the 1-hour cache.

Employment type (Full Time / Part Time / Apprentice) on roster

ADP (workerType field)

Enrichment step inside GET /api/employees (server/adp.ts fetchWorkers)

Same 1-hour cache

Best-effort name matching (ADP "Last, First" flipped, middle names dropped); null when ADP is unreachable or the name doesn't match.

Per-person division/department pills and org filtering

Nova (complete org lookup, including terminated/partial-org users)

GET /api/employees/nova-org; applied via novaProfile: true in getEmployeeMetrics (src/context/DataContext.tsx)

1-hour server cache

The view drops anyone whose department OR division resolves to "Unknown" (hideUnknownOrgUnit).

Gross profit per account (drives RPE, MRR, averages, leaderboards)

Vena (client gross profit per blueprint × department × month; Vena writes, Signal reads)

GET /api/assignments and /api/assignments/batch → getAssignmentsData() in server/vena-kpi-engine.ts

Master contracts cache per year on the server; frontend refetches per selected months

Current-calendar-month VABO is substituted from a separate latest-VABO field because the contracts table's VABO lags for the in-flight month.

Who is staffed on each account (detected "seats")

Nova (client account assignment history)

Same /api/assignments path → getSeatAssignmentsQuery() in server/snowflake-only-queries.ts; seat↔month matching in TypeScript

Fetched with assignments

Excludes people terminated before 2025-01-01; date-range overlap logic determines which month a seat counts in.

Saved team overrides (which people actually split an account's revenue)

Signal's own records (entered by users in Signal's Manage Leads) — Supabase team_assignments

GET /api/team-assignments?month= (service-role proxy in server/index.ts); merged in DataContext.fetchData — saved teams always win over the Nova-detected team for managed clients

Per month-selection load; Render in-memory backups (/api/assignments/backup/:month) are the fallback during Supabase outages

Since the 2026-07-01 Nova cutover (server/nova-history.ts), AD/Sr-AD chip writes go directly to Nova (POST /api/nova/assignments → Nova updateClient mutation) and point-in-time team lookups for dates ≥ 2026-07-01 read Nova's own assignment history; dates before the cutover still read Supabase team_assignments.

Account Director / Senior AD credit on accounts

Nova (live GraphQL API) with Supabase client_account_directors as cache/fallback

refreshClientAccountDirectors in DataContext.tsx; GET /api/nova/assignments (5-min server cache, server/nova-assignments-cache.ts)

5-minute Nova cache

For non-consulting, single-division clients live Nova now WINS over a stale Supabase cache row; consulting and multi-division clients keep their Signal-side assignment logic.

Allocation % overrides (per-account revenue split)

Signal's own records — Supabase revenue_split_overrides

Direct Supabase read from the frontend (src/services/supabase.ts), applied in every RPE/share calculation

Reloaded when months/accounts change

Overrides are keyed by (client, department, month, employee).

KPI targets (target chips, KPI cards, Rollup targets, Hit Rate)

Google Sheets (curated KPI targets sheet) → Supabase signal_roles → server memory

GET /api/employee-kpi-targets serving cachedTitleTargets (server/index.ts); sheet sync in server/google-sheets.ts

Sync runs automatically on every server startup and manually via the KPI Targets admin view (POST /api/kpi-targets/sync); no scheduled interval found in the repo

Matching is by Nova job title (lowercased); if a title has no comma suffix, a division-specific variant ("title, division") is tried. Titles absent from the sheet get no targets ("unclassified").

"On Leave" badge / aggregate exclusion

Signal's own records — Supabase employee_flags (flag on_leave)

Direct Supabase read/write from the frontend; toggleOnLeave in DataContext.tsx

Immediate (optimistic UI)

Global flag, not month-scoped — an on-leave person is excluded from aggregates in every period until unflagged.

VABO client tag + VABO Allocations table in drawer

Signal's own records — Supabase client_flags (flag vabo) for the tag; Vena for VABO dollars; Manage Leads → People for who gets credit

getVaboAllocationsForEmployee in DataContext.tsx

With main data load

VABO leads are assigned manually in Manage Leads; clients with no VABO leads are unattributed.

Drawer profile block: hire date, manager, employment type, contractor flag

Nova (users table: start_date, employment_type, is_contractor, manager self-join)

GET /api/employee-profile/:employeeId

Per drawer open

Returns graceful nulls if columns are missing.

Job-title link to the job description doc

Google Sheets (live JD map) over a static snapshot (server/jd-data.ts, generated from a curated Excel)

GET /api/jd-links; live sheet pulled at server startup and via Gandalf-only POST /api/jd-sheet/sync

Startup + manual sync

Name match first (including a first+last fallback for middle names), then title match; no link if the person/title isn't in the curated sheet.

"Hours Reported (Pulse)" section in drawer

Nova (employees' weekly Pulse time submissions, question id 1006; Laravel-encrypted, decrypted server-side with NOVA_APP_KEY)

GET /api/employee-hours/:employeeId

Per drawer open

Benchmark = average weekly hours across all reporters over the last 13 weeks; per-entry hours capped at 250 (code constant as of Jul 2026).

"Avg Client Hrs/Wk" table column (hidden by default)

Nova (same Pulse submissions)

GET /api/pulse-coverage — requireAuth + requireAdmin

Per page load

Admin-gated endpoint; non-admins silently see em-dashes.

Month-by-month history overlay

Derived client-side from the same per-month Vena + Nova + Supabase inputs

DataContext.getEmployeeHistory()

Recomputed from months already loaded (all available months load in the background)

No separate backend call.

Averages strip (Total Gross Profit etc.)

Same inputs as the Summary view

DataContext.getSummaryMetrics() client-side

With main data load

Deliberately identical computation to the Summary view so the two screens never disagree.

"Nova Profile" link

Nova app (external)

Hardcoded URL pattern app.novapower.io/our-team/{id}

n/a

Not Signal data.

"Request Title / Dept / Division Change" link

Asana intake form (external)

Hardcoded URL in EmployeeView.tsx (SYSTEM_CHANGE_BOARD_URL)

n/a

Org-data corrections flow through Asana/Nova, not Signal.

Metrics & definitions

All metrics on the Signal Employees view are computed client-side in src/context/DataContext.tsx (getEmployeeMetrics, getEmployeeHistory) from Vena gross-profit rows, Nova staffing, and Signal's own Supabase records. VABO accounts are excluded from revenue/MRR/seat rollups and handled as a separate metric.

  • RPE (Revenue Per Employee) — the employee's allocated share of gross profit from their ACTIVE accounts, divided by the number of selected months, PLUS their monthly-averaged VABO allocation. Allocation merges blueprint slices per (client, department), applies Signal's saved team and any revenue_split_overrides percentages, and uses consulting-role weighting for Consulting accounts. Computed by the shared computeEmployeeRpe helper (also used by the Staffing view's simulator, so the two views cannot drift). Origin: Vena revenue × Nova/Signal staffing.

  • Total Gross Profit (attributedRevenue) — same allocated share summed across all selected months (not averaged). With a single month selected this equals RPE, so the column is labeled "RPE" and the separate Avg RPE column is hidden.

  • MRR (Book Value) — total monthly client value of the employee's active clients, counted once per client (full client revenue across departments, not just their line), averaged per selected month. This is the primary KPI for titles containing "account director" or "account manager". Origin: Vena revenue.

  • Retention — percentage of the employee's assigned clients that are retained. A client is retained in a month if its Nova churn_date is empty or falls after that month's end (src/services/transform.ts); a client counts as retained for the employee if ANY of its accounts are retained. An employee with zero assigned clients shows 100%. Cell color: green ≥ 90%, yellow ≥ 80%, red below (code constants as of Jul 2026). Origin: Nova client churn dates.

  • Seats — number of unique active (client, department) pairs the employee is on (blueprint slices collapsed so a Retainer + Project split is one seat).

  • Active Clients — distinct client names among the employee's active accounts (active = the account has revenue > 0).

  • VABO — the employee's allocated share of VABO revenue (performance-based revenue tracked by Finance in Vena; the acronym's expansion is unconfirmed — see the Glossary entry), lead-based: only people set as VABO leads in Manage Leads → People get credit. Shown as a "+VABO" pill and included in RPE.

  • Performance status / target chips — actual vs target for the employee's primary KPI (MRR for AD/AM titles, RPE otherwise; when a role has only one target set, that one is primary). Targets come from the Google Sheets → signal_roles sync; default retention target is 90% when the sheet doesn't set one (code constant as of Jul 2026, data-team-tunable via the sheet).

  • Hit Rate (KPI Rollup) — percentage of classified employees in a group at or above their primary KPI target. Badge: green ≥ 75%, amber ≥ 50%, red below (code constants as of Jul 2026).

  • KPI Rollup grouping — "By Department & Role" uses the same single-role classification (getCapacityRole) as the Role Capacity view; "By Division" pulls avg RPE / MRR from the centralized getGroupedSummary so numbers match the Summary view.

  • Avg Client Hrs/Wk — total client hours from Pulse submissions divided by distinct weeks submitted, per employee (admin-only data).

  • Hours benchmark badge (drawer) — the person's weekly hours as % of the company benchmark (average weekly hours of all Pulse reporters, last 13 weeks). Badge: green ≥ 90%, amber ≥ 70%, red below (code constants as of Jul 2026).

  • Averages strip — Total Employees, Total Gross Profit (identical to Summary view when no account-level filters are set), Avg Gross Profit / Employee, Avg Clients / Employee, Avg Seats / Employee, all over the currently filtered roster.

How it's used

  1. Monthly performance review of a team: filter the Employees view to a Division/Department, sort by Avg RPE or Retention, scan the target chips. Anyone showing "Below" gets a drawer click: thin book (few Assigned Accounts)? churn (Retention card)? or an allocation problem (shares look wrong → Adjust Allocation into Manage Leads)? Outcome: coaching conversation vs staffing change vs data fix.

  2. Target attainment for leadership readouts: switch to the KPI Rollup tab, group By Department & Role, read Hit Rate per role group (e.g. "Paid Media Account Managers: 62% at/above target"), and export kpi_rollup.csv for the deck. Outcome: reset targets (via the KPI Targets admin view) or intervene on capacity.

  3. Preparing a 1:1 or promotion case: filter to the person's name, open their drawer, then History — is RPE trending up, is the book growing (Seats / Active Clients), did retention hold? Cross-check Pulse hours against the company benchmark to see if output is sustainable. Outcome: a promotion/comp case grounded in attributed numbers.

  4. Load balancing / capacity checks: use the Most Seats and Most Clients leaderboards to spot overloaded people, then compare their hours (drawer, or Avg Client Hrs/Wk for admins) against the benchmark. Outcome: rebalance accounts in Manage Leads.

  5. Keeping aggregates honest during leaves (admin): open the person's drawer and Mark On Leave — they drop out of every aggregate metric in Signal until the flag is removed, so team averages and rollups aren't dragged down by absences.

  6. An individual checking their own record (Member): log in, open Employees, see "Your Record" — attributed gross profit, retention, seats, targets — and click the row for the account list, VABO allocations, hours, and history. If title/department is wrong, use the drawer's "Request Title / Dept / Division Change" Asana link.

What users can change here

The Signal Employees view is almost entirely read-only. Writes and write-adjacent actions:

  • Mark On Leave / Remove Leave (admin-only, in the employee drawer): writes the on_leave flag to Signal's own records (Supabase employee_flags, direct from the browser with optimistic update/rollback). Side effect: the person is excluded from all aggregate metrics across every Signal view (a global, not month-scoped, flag).

  • Adjust Allocation (admin-only, in the drawer) writes nothing on this view — it navigates to Manage Leads (/leads?employee=<name>), where team changes and % splits land in Signal's own records (Supabase team_assignments, revenue_split_overrides) and, since the 2026-07-01 cutover, AD/Sr-AD changes are pushed to Nova itself. Those changes then feed back into every RPE/share number on the Employees view.

  • Request Title / Dept / Division Change opens an external Asana intake form — org-data corrections happen in Nova via Asana, not in Signal.

  • Column show/hide preferences and CSV exports (employees.csv, kpi_rollup.csv) are local to the user's browser; no shared state changes.

Caveats & data quality

  • Avg Client Hrs/Wk is effectively admin-only: the column is offered to all users in the column picker but its endpoint (/api/pulse-coverage) requires admin; non-admins get silent em-dashes. Whether that gate is intentional for this column is not defined in the app repo.

  • Column labels change with month selection: single month → the Gross Profit column is labeled "RPE", the Avg RPE column and the "Avg Monthly" leaderboard tab disappear (they'd duplicate the gross-profit numbers).

  • Unassigned people are hidden by default: the roster only shows people leading at least one account with revenue activity (VABO counts). The "Show unassigned" checkbox reveals everyone; searching a person by name always surfaces them even when unassigned.

  • People with Unknown org are dropped: anyone whose Nova department OR division resolves to "Unknown" is excluded from the Employees view roster (hideUnknownOrgUnit in DataContext.getEmployeeMetrics).

  • Employment type is best-effort ADP name matching — expect blanks when names differ between Nova and ADP or ADP is unreachable.

  • JD links are curated, not automatic: a title links to its job description only if the person/title is in the manually maintained Excel/Google Sheet (re-synced at server startup or by a Gandalf user). Unlinked titles show a dashed-underline fallback.

  • KPI targets depend on a manual sheet + title match: targets sync from a Google Sheet into Supabase signal_roles on server startup and on manual sync; there is no scheduled re-sync in the repo. Employees whose Nova job title doesn't match a sheet row are "unclassified" (no chips, excluded from Hit Rate).

  • Caching: roster and org lookups are cached 1 hour server-side (plus warehouse replica lag from Nova); Nova live assignments cache 5 minutes. A just-made Nova org change can take up to ~1 hour (or ?refresh=1 on the API) to appear.

  • Code constants (as of Jul 2026, changeable without notice): retention colors 90/80, hit-rate badges 75/50, hours badge 90/70, default retention target 90%, Pulse question id 1006, 250h per-entry hours cap, 13-week benchmark window, the Asana form URL, and the Nova profile URL pattern.

  • On Leave is global: the flag applies to all historical months, not just the current selection.

  • Nova cutover transition (2026-07-01): team-assignment history for dates on/after 2026-07-01 reads Nova's own assignment history; earlier dates read Signal's Supabase records. During this transition, discrepancies between Manage Leads saves and Nova's state resolve in Nova's favor for AD/Sr-AD on non-consulting single-division clients.

  • Precise business definition of "Retained": in code, a client is retained for a month when its Nova churn_date is empty or after that month-end. Whether this matches finance's external retention definition is not defined in the app repo.

  • Whether "Seats" matches finance/ops vocabulary outside Signal is not defined in the app repo.

Related views

  • Summary (/summary): the Employees averages strip reuses the Summary view's revenue computation so totals match; Division/Department filters are shared state between the two views (a filter set on Employees follows you to Summary).

  • Manage Leads (/leads, Team Lead+): the biggest upstream dependency — saved teams (Supabase team_assignments), % overrides (revenue_split_overrides), VABO leads, and (post-cutover) Nova-direct AD/Sr-AD writes directly change every RPE, "Your Share", and VABO number on the Employees view. The drawer's "Adjust Allocation" deep-links there pre-filtered to the employee.

  • Staffing (/staffing, non-members): uses the same canonical computeEmployeeRpe helper, so simulated RPE matches this view.

  • KPI Targets (/kpi-targets, Admin+): where the Google Sheet → signal_roles target sync is run and managed; the Employees view consumes the resulting title→target map for chips, KPI cards, and Hit Rate.

  • Employee Pulse (/pulse-coverage, Admin+): audits who submitted Pulse hours; the Employees view consumes the same submissions for hours per person.

  • Role Capacity (/capacity, Admin+): shares the single-role classification (getCapacityRole) used by the KPI Rollup's role grouping.

  • Nova (external, app.novapower.io): origin of the roster, org structure, titles, managers, hire dates, staffing history, and Pulse hours; drawer links out to Nova profiles.

FAQ

Q: Why doesn't the gross profit here match Vena exactly? A: The numbers originate from Vena (finance writes them; Signal only reads), but the Employees view shows each person's ALLOCATED share after Signal's team-split rules and any percentage overrides saved in Manage Leads, averaged or summed over the months you selected. Also, current-month VABO is substituted from a fresher latest-VABO field because Vena's contract rows lag for the in-flight month. Compare totals (not per-person splits) against Vena, and check the selected month range first.

Q: Why can I only see my own row on the Employees page? A: You're on the base "Member" tier — a signed-in user with no elevated Signal role. Members see a "Your Record" version with only their own row (matched by login email) and can navigate only to Summary and Employees. Team Lead, Admin, Gandalf, and Sauron tiers see the full roster. Roles live in Signal's app_users records and are managed by Signal admins via the General Access screen; Executive Sponsors (Account Directors) and Group Directors on active Nova clients are auto-upgraded to Team Lead at login.

Q: Why is an employee missing from the Employees view? A: Four common reasons: (1) they lead no account with revenue activity — check the "Show unassigned" box or search their name directly; (2) their Nova department or division is "Unknown" — the view drops those rows (fix org data in Nova via the Asana change form); (3) they were marked On Leave by an admin — they're excluded from aggregates but still visible in their drawer state; (4) their Nova account doesn't have a company email domain or is terminated, so they're not on the roster at all.

Q: What exactly is RPE and does it include VABO? A: RPE = the employee's allocated share of gross profit from their active accounts, averaged per selected month, PLUS their monthly-averaged VABO allocation. Yes — VABO is included in RPE (rows with VABO show a "+VABO" pill). VABO credit only goes to people manually set as VABO leads in Manage Leads → People.

Q: Why does the column say "RPE" sometimes and "Total Gross Profit" other times? A: With one month selected, total attributed gross profit and monthly RPE are the same number, so Signal shows a single column labeled "RPE" and hides the separate Avg RPE column and the "Avg Monthly" leaderboard tab. Select multiple months to see both "Total Gross Profit" (sum) and "Avg RPE" (per-month average).

Q: Where do the KPI targets come from and how do I change one? A: Targets are maintained in a curated Google Sheet, synced into Signal's signal_roles records (sync runs at server startup or manually from the KPI Targets admin view), and matched to people by Nova job title. To change a target, update the sheet and re-run the sync from the KPI Targets view (Admin+). If someone shows no target chips at all, their Nova title isn't matched in the sheet.

Q: Why is the Avg Client Hrs/Wk column empty (just dashes) for me? A: The data behind that column comes from an admin-gated endpoint (/api/pulse-coverage). Non-admin users get no data and the view silently shows em-dashes. The per-person "Hours Reported (Pulse)" section inside the employee drawer is available to everyone.

Q: What does "Retained" vs "Churned" mean on someone's accounts? A: A client counts as retained in a month if its churn date in Nova is empty or falls after that month's end; otherwise it's churned for that month (so a client that churns in August still shows retained for July). An employee's Retention % is the share of their assigned clients that are retained; a person with zero clients shows 100%.

Q: How do I fix someone's wrong title, department, or division? A: Not in Signal — that data originates in Nova. Open the person's drawer on the Employees view and click "Request Title / Dept / Division Change", which opens the Asana intake form. After the change lands in Nova, allow up to about an hour (replica sync + Signal's 1-hour roster cache) for it to appear.

Q: What does "Mark On Leave" actually do, and who can use it? A: Admins (and above) see the toggle in the employee drawer. It writes an on_leave flag to Signal's own records and excludes the person from every aggregate metric across Signal (averages, rollups, leaderboards) until removed. It is a single global flag — it affects all months, not just the current selection.

Q: Why did a person's RPE change after someone edited teams in Manage Leads? A: The Employees view recomputes allocation from the same team data Manage Leads saves: saved teams (Signal's own records) always win over the Nova-detected team, percentage overrides re-split the account's revenue, and since 2026-07-01 AD/Senior-AD assignments are written to and read live from Nova. Any of those edits immediately changes "Your Share" on the affected accounts and therefore the person's RPE, MRR, and leaderboard position.

Did this answer your question?