Employee Pulse (route /pulse-coverage, admin-and-above only) is Signal's compliance and wellbeing dashboard for the weekly employee "Pulse" check-in that Power Digital delivery employees submit in the Nova platform. It answers two questions: "Who submitted their weekly Pulse and who didn't?" (Coverage tab) and "How is each person's sentiment and bandwidth trending?" (Sentiment & Bandwidth tab). Every number on the screen originates in the Nova platform — the application where employees actually fill out the Pulse — with employee roster metadata also coming from Nova platform user records. The view is strictly read-only; the only outputs are client-side Excel exports. Do not confuse Employee Pulse with Signal's "Client Pulse" section (Submit Pulse Data / My Submissions / Pulse Summary), which is a separate workflow where account directors record client sentiment into Signal's own records.
Field | Value |
Route | /pulse-coverage |
Access | Admin+ (Admin, Gandalf, and Sauron tiers; route guard AdminRoute) |
Nav section | People → "Employee Pulse" (nav link flagged adminOnly) |
Primary data sources | Nova platform (employee Pulse check-ins: submissions, per-client hours, sentiment, bandwidth; plus user/role/department/job-title roster) |
Writes | None — read-only view; Excel export is client-side only |
Key code refs | src/views/PulseCoverageView.tsx; server/index.ts — GET /api/pulse-coverage (~line 3601), GET /api/pulse-coverage/sentiment (~line 3929), GET /api/pulse-coverage/diagnose (~line 4045), GET /api/debug/pulse-answers (~line 4170), GET /api/employees (~line 1538); src/App.tsx (route ~line 1161, nav ~line 390) |
Last verified | staging @ 98df0c4, verified 2026-07-07 |
Purpose
Every week, Power Digital delivery employees are expected to submit a "Pulse" in the Nova platform: how they are feeling (sentiment), how stretched they are (bandwidth), and how many hours they spent on each client. That self-reported data feeds downstream uses — client profitability math, capacity planning, and people-health monitoring — and it is only trustworthy if people actually submit. The Employee Pulse view (/pulse-coverage) gives leadership:
Compliance visibility — who submitted this week, who didn't, and the coverage percentage against a carefully-defined denominator of "active delivery employees" (executives, Revenue/Sales, Accounting/Finance, Corporate, and the Nova product team are excluded because they are not expected to pulse).
People-health signal — each person's rolling 4-week sentiment and bandwidth averages next to their most recent completed week, so managers can spot burnout risk or morale dips early.
The Pulse week runs Tuesday through Monday (submission deadline Monday evening), so the natural usage rhythm is checking Tuesday/Wednesday for the just-completed week.
Access & visibility
The Employee Pulse view at /pulse-coverage is visible and reachable only to Signal's admin tier and above:
Route guard: the route is wrapped in AdminRoute (src/App.tsx), which admits users whose isAdmin or isGandalf flag is true and redirects everyone else to /summary. Signal's role ladder here is: Member (base) → Team Lead → Admin → Gandalf → Sauron (Sauron auto-sets both isAdmin and isGandalf).
Nav flag: the "Employee Pulse" link sits in the People nav section with adminOnly: true; the sidebar shows adminOnly links only when the user is Admin or Gandalf.
How the flag is granted: admin status comes from Signal's own records — the app_users table (columns is_admin, is_gandalf), managed by existing admins in Signal's user-management screens. Separately, a short hardcoded super-admin ("Sauron") email list in server/index.ts always passes, regardless of database state.
Backend enforcement: the API endpoints GET /api/pulse-coverage, GET /api/pulse-coverage/sentiment, and GET /api/pulse-coverage/diagnose all require a valid login token (requireAuth, verified against Signal's auth provider) plus requireAdmin, which re-checks app_users server-side (result cached 5 minutes per user, a code constant as of Jul 2026). So even a direct API call without the UI is blocked for non-admins.
Exception: the engineering diagnostic endpoint GET /api/debug/pulse-answers has no auth middleware at the route level (code as of staging 98df0c4). It is not linked from the Employee Pulse screen and is intended for engineers only.
Data sources & lineage
Every number in the Employee Pulse view originates in the Nova platform — the internal application where employees fill out the weekly Pulse. Data reaches Signal via a replication pipeline with a lag of roughly 15 minutes to 6 hours (an engineering estimate in a code comment, not a confirmed SLA), so a Pulse submitted minutes ago may not appear immediately. Signal queries this data live on each request (no server-side cache for pulse data itself).
On-screen element | Origin system | Code path | Refresh | Caveat |
Coverage tab: Submitted / Not Submitted panels, week pills, coverage KPI cards | Nova platform (Pulse submission records) | GET /api/pulse-coverage → server/index.ts ~line 3601; view src/views/PulseCoverageView.tsx | Live per page load; replication lag 15 min–6 h | Any Pulse record counts as "submitted" for its Tuesday→Monday week, even with zero hours |
Hours column + client chips in the Submitted panel; "Client Breakdown" in the export | Nova platform (Pulse question 1006, per-client hours; stored encrypted, decrypted server-side with the NOVA_APP_KEY secret) | Same endpoint, second query | Live per page load | Total hours = client hours (each client entry capped at 250 h, code constant as of Jul 2026) + non-client hours from the same answer |
"Active Employees" denominator + fine-grained department labels | Nova platform (user, role, department, and job-title records) | Same endpoint, roster query | Live per page load | Applies exclusion rules (departments, exec titles, 23 test/system accounts, 3 named individuals) and dedupes duplicate Nova accounts per person |
Sentiment & Bandwidth tab: table + KPI cards | Nova platform (Pulse question 1001 = sentiment 0–5, question 1002 = bandwidth 0–10; plain numeric answers, not encrypted) | GET /api/pulse-coverage/sentiment → server/index.ts ~line 3929 | Fetched lazily the first time the tab is opened | Rolling 4-week window is anchored to the current date; "last week" is the previous completed Tuesday→Monday week |
Employee names, divisions, coarse fallback departments (both tabs, filter dropdowns) | Nova platform (user records) | DataContext → GET /api/employees → server/index.ts ~line 1538 | Server-cached 1 hour (code constant as of Jul 2026) | This shared roster is also enriched with employment type from the ADP payroll system, but employment type is not displayed on this view; the view prefers the finer Nova department from the pulse-coverage roster over this coarser one |
Excel export button (both tabs) | Browser-local (data already loaded on the page) | ExportButton component, client-side | On click | Reflects the filters active at the moment of export |
Access gate (who can open the page) | Signal's own records (entered by users in Signal) — app_users admin flags | AdminRoute in src/App.tsx; requireAdmin in server/index.ts | Admin check cached 5 min server-side, session-cached client-side | Not data shown on screen; controls visibility only |
(Not in the UI) "Why isn't X counted?" diagnostics | Nova platform, raw records | GET /api/pulse-coverage/diagnose?name=... (admin-gated) and GET /api/debug/pulse-answers (no route-level auth) | Live | Engineer-only endpoints, not linked from the screen |
The Employee Pulse module does not read revenue/contract data (Vena), Signal's team-assignment records, Google Sheets, or Deel.
Metrics & definitions
All metrics below are computed for the currently filtered population (Division and Department dropdowns, plus the employee name search). "Active employees" means active (non-terminated) Power Digital delivery employees, excluding the Revenue, Sales, Accounting, Finance, Corporate, and Nova departments, leadership titles (VP/SVP, Head, Executive, Chief, President, Group/Managing/Senior Director), test/system accounts, and a small manually-maintained People Ops exclusion list.
This Week Coverage (%) — employees who submitted a Pulse in the selected Tuesday→Monday week ÷ active employees under the current filters, rounded to a whole percent. Origin: Nova platform Pulse submission records. Card color: red below 50%, amber below 75%, green at/above 75% (code constants as of Jul 2026, not official targets).
Monthly Avg Coverage (%) — the plain average of each week's coverage percentage across all weeks in the selected month (each week weighted equally). Same origin and color thresholds as This Week Coverage.
Submitted / Not Submitted / Active Employees (counts) — raw counts under the current filters for the selected week. "Submitted" = at least one Pulse record that week; "Not Submitted" = active employee with no Pulse record that week.
Hours (Submitted panel) — the employee's total self-reported hours for that week's Pulse: sum of per-client hours (each client entry capped at 250 hours, a typo guard; code constant as of Jul 2026) plus reported non-client hours. Origin: Nova platform Pulse question 1006 (decrypted server-side).
Client chips (Submitted panel) — up to three per-client hour entries (e.g. "Acme 12h") with a "+N more" overflow. Same origin as Hours.
Sentiment (4w) — per employee: the average of all sentiment answers (Nova platform Pulse question 1001, scale 0–5, higher is better) in the trailing 4 weeks from today. The KPI card shows the mean across filtered employees who have data. Color: green ≥ 4, amber ≥ 3, red below 3 (code constants as of Jul 2026).
Sentiment (last wk) — the same sentiment average restricted to the previous completed Tuesday→Monday week.
Bandwidth (4w) — per employee: the average of all bandwidth answers (Nova platform Pulse question 1002, scale 0–10, higher = more stretched, i.e. worse) in the trailing 4 weeks. Color: red ≥ 7, amber ≥ 5, green below 5 (code constants as of Jul 2026).
Bandwidth (last wk) — the same bandwidth average restricted to the previous completed Tuesday→Monday week.
Pulsed Last Week (count) — filtered employees with at least one Pulse in the previous completed Tuesday→Monday week.
Pulses (4w) — per employee: number of distinct Pulse submissions in the trailing 4 weeks (max meaningful value is 4–5).
Last Submitted — the date of the employee's most recent Pulse within the trailing 4-week window; shows "—" if none.
Week convention for everything above: a Pulse belongs to the Tuesday→Monday week containing its submission timestamp — a Monday-evening submission counts for the week that is just ending, not the next one.
How it's used
Weekly compliance chase (Tuesday/Wednesday). Open Employee Pulse; the Coverage tab defaults to the most recent completed week (technically: the latest week with more than 10 submissions, a code heuristic). Check "This Week Coverage", sort the Not Submitted panel by department or division, and send reminders — or export the list for a manager follow-up thread. Business goal: keep the self-reported hours that feed profitability and capacity numbers complete.
Division/department accountability review. Pick a Division, then a Department, and compare "Monthly Avg Coverage" across teams to find chronically low-compliance groups that need a process change rather than individual reminders.
Burnout / capacity scan. Switch to the Sentiment & Bandwidth tab; sort "BW (last wk)" descending to find people redlining (bandwidth ≥ 7 of 10), or "Sent. (4w)" ascending for sustained morale problems; compare last week against the 4-week average to catch sudden deteriorations. Feeds workload rebalancing and manager check-ins.
Monthly people-health reporting. Select a month, note Monthly Avg Coverage plus the sentiment/bandwidth aggregate cards for the filtered population, and export both tabs to Excel as the evidence pack for a leadership or People Ops readout.
"Why isn't this person counted?" investigation. Search the employee by name. If they claim they pulsed but show as Not Submitted, the usual causes are: replication lag from the Nova platform (15 minutes–6 hours), the Tuesday→Monday week boundary, or a duplicate Nova account. Engineers can confirm with the admin-only GET /api/pulse-coverage/diagnose?name= endpoint.
Data-quality spot check. Scan the Submitted panel's Hours column for implausible values (each client entry is capped at 250 h) — these same question-1006 hours drive labor-cost allocation in Signal's Client Profitability module.
What users can change here
Nothing — the Employee Pulse (Pulse Coverage) view is read-only. It performs no writes to Signal's own records or to any upstream system. The only outputs are client-side Excel downloads (Coverage export: one row per employee for the selected week with Submitted/Not Submitted status, hours, and client breakdown; Sentiment export: one row per employee with 4-week and last-week sentiment/bandwidth values). Pulse submissions themselves are created in the Nova platform, not in Signal. Signal's separate "Client Pulse → Submit Pulse Data" screen does write data, but that is a different module about client sentiment, not employee check-ins.
Caveats & data quality
Freshness. Pulse data reaches Signal from the Nova platform with a replication lag of roughly 15 minutes to 6 hours (engineering estimate in a code comment; the exact sync schedule is not defined in the app repo). The shared employee roster is additionally server-cached for 1 hour. The screen is near-real-time, not live.
Who counts as "active" is a hardcoded policy, duplicated in two places. The denominator excludes: terminated/deleted users; non-Power-Digital email domains; 23 named test/system accounts; three individually-named employees excluded "per Jenna" (People Ops); the Revenue, Sales, Accounting, Finance, Corporate, and Nova departments; and leadership titles (VP, SVP, Vice President, Head, Executive, Chief, President, Group/Managing/Senior Director). These lists live in backend SQL (server/index.ts ~lines 3737–3814) and are mirrored in the frontend (src/views/PulseCoverageView.tsx ~lines 44–47); they can change without notice and are code constants, not a documented policy. The two mirrors are close but not byte-identical (e.g. the frontend excludes any department containing the substring "nova"; the backend excludes the department named exactly "Nova").
Duplicate Nova accounts are deduped by normalized name. Some people have two Nova accounts (e.g. a Cardinal email and a Power Digital email); the backend picks the account with the most recent submission as canonical and merges the rest, so one person is never double-counted.
Week convention is Tuesday→Monday, not calendar weeks. A Monday submission belongs to the week that is ending.
Default-week heuristic: on load, the Coverage tab selects the most recent week with more than 10 submissions (code constant as of Jul 2026) so a just-started week doesn't look misleadingly empty.
Color thresholds are UI guides, not official targets: coverage red < 50% / amber < 75%; sentiment green ≥ 4 / amber ≥ 3 (of 5); bandwidth red ≥ 7 / amber ≥ 5 (of 10). All are code constants as of Jul 2026; whether they match any official People Ops target is not defined in the app repo.
Hours cap: per-client hours in one Pulse are capped at 250 to guard against typos (code constant as of Jul 2026). Undecryptable hour answers are silently skipped.
Sentiment "4w" window is anchored to today (trailing 4 weeks from the current date), while "last wk" is the previous completed Tuesday→Monday week — the two windows overlap by design.
Unauthenticated debug endpoint: GET /api/debug/pulse-answers has no route-level auth middleware as of staging 98df0c4; it is an engineering diagnostic, not part of the UI.
Not defined in the app repo: whether the weekly Pulse is formally mandated and who owns the exclusion policy; the full Nova Pulse questionnaire (only question IDs 1001 sentiment, 1002 bandwidth, and 1006 client hours are surfaced); the exact replication sync schedule.
Related views
Client Profitability (/profitability, Admin+) — consumes the same Nova platform question-1006 hours to allocate employee time and cost across clients. Low pulse coverage in Employee Pulse directly degrades profitability accuracy there.
Employees view (/employees) — its per-person detail calls GET /api/employee-hours/:employeeId, a per-employee pulse-hours breakdown with an all-company benchmark from the same Nova platform tables.
Growth → People tab — shows the same sentiment (0–5) and bandwidth (0–10) badges with deliberately matched color thresholds, plus a rolling 4-week self-reported hours column (GET /api/growth/weekly-hours). Gated separately by per-user Growth capabilities.
Manager bandwidth digest (server/managerDigest.ts + server/pulseMetrics.ts) — a weekly Slack digest for managers built on the same Tuesday→Monday window and sentiment/bandwidth queries. Controlled by env flags (MANAGER_DIGEST_ENABLED kill switch; dry-run unless MANAGER_DIGEST_LIVE=true plus a Slack token). As of Jul 2026 it is deployed but not activated.
Client Pulse section (/pulse/submit, /pulse/my-submissions, /predictions/pulse-summary) — a different feature despite the similar name: account directors record client sentiment and pacing into Signal's own records. Employee Pulse is about employees' Nova check-ins.
FAQ
Q: Who can see the Employee Pulse page? A: Signal admins and above (Admin, Gandalf, and Sauron tiers). The nav link under People → "Employee Pulse" only appears for those roles, the /pulse-coverage route redirects everyone else to the Summary page, and the backend endpoints independently reject non-admins. Admin status is stored in Signal's own records (app_users table) and is granted by an existing Signal admin; if you need access, ask a Signal admin (Signal is owned by the AI/ML team).
Q: An employee says they submitted their Pulse but they show as "Not Submitted" — why? A: Three usual causes. (1) Replication lag: pulse data flows from the Nova platform into Signal with a delay of roughly 15 minutes to 6 hours, so very recent submissions haven't arrived yet. (2) Week boundary: the Pulse week runs Tuesday→Monday, so a submission made Monday evening counts for the week that just ended — check the adjacent week pill. (3) Duplicate Nova accounts: Signal merges duplicate accounts by name, but an unusual name variant can slip through. Engineers can run the admin-only diagnostic GET /api/pulse-coverage/diagnose?name=<name> to see the exact reason.
Q: Why is a specific person (e.g. a VP, or someone in Finance) missing from the Active Employees count? A: The denominator intentionally excludes people not expected to pulse: the Revenue, Sales, Accounting, Finance, Corporate, and Nova (product team) departments; leadership titles (VP, SVP, Head, Executive, Chief, President, Group/Managing/Senior Director); test/system accounts; and a small manually-maintained exclusion list from People Ops. These rules are hardcoded in Signal's code and can change; the current lists are in server/index.ts (~lines 3737–3814).
Q: What do the sentiment and bandwidth numbers mean, and which direction is bad? A: Sentiment comes from the weekly Nova Pulse (question 1001) on a 0–5 scale where higher is better (green ≥ 4, amber ≥ 3, red below 3). Bandwidth (question 1002) is on a 0–10 scale where higher means more stretched — worse (red ≥ 7, amber ≥ 5, green below 5). The color cutoffs are code constants as of Jul 2026, not official People Ops targets.
Q: What's the difference between the "(4w)" and "(last wk)" columns on the Sentiment & Bandwidth tab? A: "(4w)" is the average of all of that person's Pulse answers in the trailing 4 weeks counted back from today. "(last wk)" is the average from the previous completed Tuesday→Monday Pulse week only (the exact date range is shown in the panel header). Comparing the two shows whether last week was better or worse than the person's recent norm.
Q: Why does the page default to a week that isn't the current one? A: The current Tuesday→Monday week is usually still in progress and would look misleadingly empty. On load the Coverage tab auto-selects the most recent week with more than 10 submissions — in practice, the last completed week. You can pick any week with the week pills or switch months with the month dropdown.
Q: Is the coverage percentage an official compliance target? What is "good"? A: The card turns red below 50% and amber below 75%, green at 75% or above — but those are UI code constants as of Jul 2026, not documented official targets. Whether there is a formal mandated coverage goal is not defined in the app repo; ask People Ops.
Q: Can I fix or enter Pulse data from this screen? A: No. Employee Pulse is entirely read-only. Pulse submissions are created by employees in the Nova platform itself; Signal only reports on them. The only action available is exporting the current tab to Excel. (To change client or team information more broadly, use the Nova platform.)
Q: Why don't the hours shown here match what an employee remembers entering? A: Two mechanics: each per-client hours entry is capped at 250 hours per Pulse (a typo guard, code constant as of Jul 2026), and the Hours column is the sum of all client hours plus non-client hours for every Pulse the person submitted in that Tuesday→Monday week (multiple submissions in one week are merged). Also note the hours answers are stored encrypted; rows that fail decryption are skipped silently.
Q: Is "Employee Pulse" the same as the "Client Pulse" section in the nav? A: No. Employee Pulse (/pulse-coverage, this page) tracks employees' weekly check-ins made in the Nova platform — submission compliance, sentiment, bandwidth, and self-reported hours. The "Client Pulse" nav section (Submit Pulse Data, My Submissions, Pulse Summary) is where Signal account directors record client sentiment and pacing into Signal's own records. They share the word "Pulse" but have different data, different sources, and different audiences.
Q: Where does this data ultimately come from, and how fresh is it? A: Everything originates in the Nova platform — the internal app where employees fill out the weekly Pulse. Signal reads a replicated copy with a lag of roughly 15 minutes to 6 hours (engineering estimate; exact schedule not defined in the app repo), and the shared employee roster is cached for 1 hour on Signal's server. Treat the page as near-real-time, not live.
