Rebuild employee projections

Rebuild employee projections

Recomputes per-employee projections from scratch. Use this when a read-model looks out of sync with the underlying events.

What is a projection?

The app pre-computes several read-models per employee — the data the UI reads when you open a page. Each projection is built from events (time-off requests, timesheet submissions, terms changes…) and kept in sync as new events arrive. If a projection ever drifts (after a bad migration, a manual data fix, or a deploy that introduced a bug), rebuilding it from the source events restores it to a known good state.

Projections this job rebuilds

ProjectionWhat it backs
Employee searchThe employee directory and search bar
Employment periodsEach employee’s resolved current and historical terms
Time-off employee projectionPlanned, active, and used absences per employee
Time-bank balanceAccount balances per employee
Accrual forecastForecasted upcoming accruals
Timesheet weekly projectionPer-week timesheet aggregates
Timesheet statementsEach employee’s pending/ready/submitted statements
Policy activityResolved activity per time-off policy per employee
Approvals inboxThe manager’s “to approve” list
Notification user viewThe notifications feed per user

How it works

  1. Loads the scope — by default, every employee in the workspace
  2. For each employee, runs each builder in turn — most builders simply replay the relevant events through the same handlers used in production
  3. For some projections, a second pass runs after every employee is rebuilt — e.g. the IsManager flag, which depends on every direct-report row being settled

Parameters

ParameterDescription
ProjectionThe projection to rebuild. Defaults to all. Picking a single projection narrows the work — useful when you know which read-model is off
Employee IDOptional. Rebuild only this employee’s projections
Org Unit IDOptional. Rebuild every employee in this org unit and its descendants. Ignored when Employee ID is set

When the scope is restricted (single employee or org unit), the post-rebuild-all step is skipped — those steps assume every employee was just refreshed.

Job results

MetricDescription
projectionThe target that was rebuilt (all or a specific key)
scopeall, employee:<id>, or org_unit:<id>
success_countEmployees rebuilt without error
error_countEmployees the rebuild failed on (see the run details for the per-employee errors)

When to run

  • After importing data from another system
  • After fixing a malformed event with a migration
  • When a single employee’s UI looks wrong (use Employee ID to scope to one)
  • After an incident report that mentions one of the projections by name

Auto-trigger on backfill

When the worker starts up and finds any registered projection completely empty but employees exist, it schedules this job automatically. That’s an operational safety net for fresh deployments and restored backups.

Troubleshooting

IssueSolution
Run takes a long timeRebuilding all projections for every employee is the most expensive option. Scope down to a single projection or a single org unit when you know what you’re trying to fix
Errors on a few employeesOpen the job run details to see the per-employee errors. Often it’s a stale reference to a deleted entity that can be fixed with a targeted edit, then re-rebuild that single employee
Projection still looks wrong after rebuildThe rebuild replays events through the live handlers. If the handler itself has a bug, rebuilding won’t fix it — escalate to the developers