Skip to content

Power BI model: a Workday Department column no longer breaks the refresh; fix the Workday wording - #144

Merged
Keith McGrane (Keithland89) merged 1 commit into
mainfrom
keithmcgrane-microsoft-workday-department-rename-fix
Oct 20, 2026
Merged

Keith McGrane (Keithland89) merged 1 commit into
mainfrom
keithmcgrane-microsoft-workday-department-rename-fix

Conversation

@Keithland89

@Keithland89 Keith McGrane (Keithland89) commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

For 0.6.8. Keith decides the merge.

Summary

This does what Keith decided for the 0.6.8 plan's decision 13: option (a) only, plus the wording.

The bug. The "Chat + Agent Org Data" query renamed the first column whose name normalises to department to Organization, without checking whether Organization already exists. The org table always has Organization, and the Workday org data adds any column the table lacks. So a Workday export with a Department column made the rename collide with Organization, and the refresh failed. On Fabric it cleared once the column left the export. On Azure it didn't, because publish never drops a column. This was found by reading the code; the refresh hasn't been run (see Validation).

The fix (a). The query renames Department to Organization only when there's no Organization column:

-    // Rename Department to Organization (if exists)
+    // Rename Department to Organization only when there's no Organization column: renaming
+    // onto an existing one fails the refresh. The table can have both when a Workday export
+    // adds a Department column, and Organization is then left as it is.
     RenamedColumns =
-        if colDepartment <> null then
+        if colDepartment <> null and not Table.HasColumns(RenamedPersonId, "Organization") then
  • A table with both columns refreshes, and Organization is left untouched. The model doesn't declare a Department column, so it isn't loaded.
  • A table with Department and no Organization still gets it renamed, as today.
  • A blank Organization isn't filled from Department. That's option (a+), which Keith rejected.
  • Patched templates: fabric/ValueLens - Fabric.pbit, fabric/ValueLens - Fabric OneLake.pbit and fabric/Add Agent Evaluator/Agent Evaluator.pbit. The change is in DataModelSchema, plus the Agent Evaluator's UnappliedChanges copy. fabric/Add Credit Consumption/Consumption Central - Fabric.pbit has no such rename.
  • The installer builds the Fabric and Azure models from ValueLens - Fabric.pbit, so Azure gets the fix through the same template. A new installer test checks the query in the built Fabric, Azure and Agent Evaluator models.
  • tests/test_consolidated_release.py pins the DataModelSchema hashes of the two core templates, so the two pins are updated, as Power BI model: faster active-user counts, synced from ValueLens #132 did. Main's templates still give the old pins, so the new ones reflect only this change.
  • Workday standalone mode: when the export has no Organization, the Workday load adds one, from Job_Family_Group or null. That's the notebook on Fabric and its port, valuelens_core.workday, on Azure. So a standalone export with Department failed too. It now refreshes, and Organization keeps the Workday load's value rather than taking Department.

The wording. Workday only adds columns, and nothing suggests it any more to people without a department.

  • Installer: the Workday data source (installer/src/uploads.js) and the Workday pipeline activity (installer/src/transform/pipeline.js) said it "adds or overrides" org fields. They now say it adds the columns the org data doesn't have, and doesn't change or fill in existing ones. The department check after the first load (installer/src/steps/run.js) no longer suggests Workday.
  • Org data load: the low-coverage message in core/valuelens_core/org.py and its copy in fabric/notebooks/Copilot_Org_Data_Direct_Ingester.ipynb no longer suggest Workday. The two stay identical.
  • App: DEPARTMENT_ADVICE and the by-organization empty state (app/src/lib/department-coverage.ts) no longer suggest Workday.
  • Docs: docs/DATA-DICTIONARY.md says the rename happens only without an Organization column, and that Workday doesn't fill in a missing department.
  • CHANGELOG.md: two entries under ## Unreleased.
  • Tests that asserted the old text now assert that the advice doesn't mention Workday: tests/test_valuelens_core_collectors.py, installer/test/steps.test.js and app/src/lib/department-coverage.spec.ts.

Scope

Parts affected (installer / app / Fabric notebooks and pipeline / Azure infra, jobs or web / core / Power BI models): Power BI models (3 templates); installer (wording, plus a test); app (wording); Fabric notebooks and pipeline (one message, one activity description); core (one message); docs.

Source contracts, optional inputs, install record or deployed item names changed: none. The Workday export format, the copilot_org_data columns and every deployed item name are unchanged. Only the description text of the Workday pipeline activity changes.

Validation

  • Ran python -B -m pytest tests -q and recorded results below.
  • Ran npm test (and npm run typecheck for the installer) in each changed Node project.
  • Updated directly related documentation and checked changed links.
  • No credentials, tenant exports, prompts or customer names are included.
  • If .pbit files changed, documented the rebuild method and Desktop refresh / visual checks.

Results, skipped checks and limitations:

  • python -B -m pytest tests -q -p no:cacheprovider at the repo root: 1,068 passed, 1 failed, 5 skipped, 12,168 subtests passed. That took 27 minutes on this shared machine.
    • The run started on the commit before the pin update, and its one failure was that pin check (tests/test_consolidated_release.py), which caught the template change as intended.
    • On a2b45ce, python -B -m pytest tests/test_consolidated_release.py -q -p no:cacheprovider passes (3 passed). So a2b45ce is 1,069 passed, the same as its CI run.
    • The 19 test files that read a template, org data or Workday data also pass on a2b45ce: 317 passed, 12,048 subtests passed.
  • npm test in installer/, on the branch rebased onto b902e58: 941 of 944 passed. None of the 3 failures involves this PR's changes:
    • test/script.test.js:115, the known local failure: this machine's execution policy blocks generate.ps1. I didn't bypass it. CI skips this test, because it needs Windows PowerShell and cmd.exe.
    • The two exitWhenDone tests in test/helpers.test.js (lines 154 and 174) timed out because the CPU was at 100%. They give a child Node process 15 or 20 seconds to exit; run directly, it exits with the expected code in 3 to 5 seconds. They test src/auth.js, which this PR doesn't touch, and they passed here before the rebase onto b902e58 (908 of 909). In CI on fd6187d they pass in 1.8 and 3.3 seconds.
  • npm run typecheck in installer/: passed.
  • app/: npm ci fails on this machine because its npm feed returns E404 for caniuse-lite-1.0.30001816.tgz, and I didn't switch registries.
    • Instead, I ran the real src/lib/department-coverage.spec.ts under Node 24's type stripping with a minimal vitest shim: 7 passed. As a check, the new spec against main's department-coverage.ts fails exactly the 2 changed assertions.
    • The regex in src/screens/executive/attention-stage.spec.tsx:124 still matches the new text.
    • The full app suite, lint, tsc -b and build:fabric weren't run locally. CI's app job runs them all.
  • The local runs above were all made before the rebase onto 0fdad40.
  • CI on fd6187d: all green.
    • pytest: 1,069 passed, 5 skipped, 12,172 subtests passed.
    • installer: 941 of 945 passed, 4 skipped (Windows-only), 0 failed, plus npm run typecheck.
    • app: 3,464 tests in 145 files passed, including department-coverage.spec.ts (7) and attention-stage.spec.tsx (5).
    • app lint: 0 errors. Its 2 warnings were already there, in files this PR doesn't touch.
    • app tsc -b and build:fabric: passed.
    • Also green: arm-drift, valuelens-web, both image builds and the three CodeQL analyses.
  • New tests:
    • tests/test_org_department_rename.py (5 tests, passing). They check that the templates are current, that every copy of the query has the guard, and that the script covers every template with the rename. They also run the rename steps of each template's M through the repo's M evaluator (tests/m_eval.py), with stub Table functions that fail on a rename onto an existing column, as Power Query does:
      • Department only: renamed to Organization;
      • both: both columns and their values left as they are, including a blank Organization;
      • the old query text with both columns: fails with "'Organization' already exists".
    • installer/test/model.test.js: the Fabric, Azure and Agent Evaluator models the installer builds all have the guard (passing).
  • Rebuild method: python scripts/Update-Org-Department-Rename.py patches the templates in place, and --check exits 1 if any is stale. It's idempotent. It edits only the org query, in DataModelSchema and (when the template has one) UnappliedChanges, and it refuses to write if any other model field or ZIP member would change. The Agent Evaluator's lastLoadedAsTableFormulaText already differed from its query, so it's left as it is: the script updates it only when it matched, as scripts/Update-Model-Refresh-Fixes.py does.
  • The refresh itself wasn't run. It needs Power Query or a live model, so it can't be run offline, and I made no cloud or tenant changes. Here is the live check. It needs Keith's approval, and I haven't run it:
    1. In Power BI Desktop, open the patched ValueLens - Fabric.pbit against a lakehouse whose copilot_org_data has both Organization and Department, for example after a pipeline run with a Workday export that has a Department column. Refresh. It succeeds, and Organization matches copilot_org_data.Organization.
    2. Point it at a copilot_org_data with Department and no Organization, and refresh. It succeeds, and the Department values show as Organization.
    3. On Azure, run Repair or change on an install whose org table already has a Department column. The model refresh succeeds.

Compatibility

  • Repair or change redeploys the semantic model from the patched template on both Fabric and Azure. The definition's hash is part of the deployed model's signature (installer/src/steps/model.js), so existing installs pick up the fix with no migration. An Azure org table that already has a Department column refreshes again, without dropping the column.

  • Org data without a Department column, or with Department and no Organization, behaves exactly as before.

  • Existing Fabric pipelines keep the Workday activity's old description until their next pipeline update. That's the installer's Update, which always offers to replace the pipeline, or a Repair or change that changes what the pipeline runs, such as turning Workday on or off. New installs get the new text.

    • pipelineSignature (installer/src/steps/fabric.js) is built from the modules, flags and model IDs, not from activity text, and PIPELINE_VERSION (7) isn't bumped.
    • That's deliberate. A bump would ask every install to replace its pipeline, including any activities added to it by hand, for a text-only change. The activity runs the same notebook either way.
  • Left unchanged on purpose:

    • filling a blank Organization from Department (option a+);
    • the Workday notebook and Azure's Workday load (option b);
    • Consumption Central - Fabric.pbit, which has no rename;
    • the archived templates;
    • the CHANGELOG's history.
  • The ValueLens templates need a matching change. That's a follow-up, not part of this PR. On ValueLens main, the same unguarded rename is in:

    • 1. Fabric/Manual setup/ValueLens - Fabric.pbit, ValueLens - Fabric OneLake.pbit and Add Agent Evaluator/Agent Evaluator.pbit;
    • ValueLens - Power Automate + Dataverse.pbit;
    • ValueLens - SharePoint.pbit;
    • ValueLens - Local CSV.pbit.

    Its Consumption Central templates have none. Those variants have no Workday load, but org data with both columns would fail the same way. The patch script here has this repo's paths only.

Overlaps with open PRs

This branch is rebased onto main 0fdad40, which also has #142, #138, #139 and #143, merged since a2b45ce. Only CHANGELOG.md changed, by main's new entries; the code is byte-identical to a2b45ce. The survey of open PRs below was made at a2b45ce, while those four were still open. Main already had #141 (Azure: Workday org data by CSV) and #126, both merged after this was planned.

I checked every open PR with gh pr diff <n> --name-only. None touches a .pbit file, and the only file any of them shares with this PR is CHANGELOG.md.

Please don't merge. Keith OKs the merge separately, and it lands before rc.1.

Keith McGrane (Keithland89) pushed a commit that referenced this pull request Oct 20, 2026
Without #144, the models rename Department to Organization even when the org data already has Organization, and the refresh fails. On Azure, publish never drops a column, so the core and Agent Evaluator refreshes would keep failing. Section 0 says how to check whether the branch under test has it. It looks for #144's test, because this repo's history reuses PR numbers: an old commit is 'Analytics Hub installer 0.3.5 (#144)'.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ssing; Workday wording

The org query renamed the first department-like column to Organization even
when the org data already had an Organization column, so a Workday export with
a Department column failed the refresh. On Azure, publish never drops a column,
so the refresh kept failing even after Workday was turned off.

The query now renames Department only when there's no Organization column
(option a), and leaves a blank Organization as it is. The new
scripts/Update-Org-Department-Rename.py patches both Fabric templates and the
Agent Evaluator. The installer builds the Fabric and Azure models from
ValueLens - Fabric.pbit, so both get the fix.

Workday org data only adds columns. The installer no longer says it adds or
overrides org fields, and the installer, the org data load, the app and the
docs no longer suggest it to people without a department.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Keithland89
Keith McGrane (Keithland89) force-pushed the keithmcgrane-microsoft-workday-department-rename-fix branch from a2b45ce to fd6187d Compare October 20, 2026 11:05
@Keithland89
Keith McGrane (Keithland89) merged commit accfdd3 into main Oct 20, 2026
12 checks passed
Keith McGrane (Keithland89) pushed a commit that referenced this pull request Oct 20, 2026
Brings in #142, #138 and #139 (the app's first pages load sooner), #143
(the Azure app is told which modules are off) and #144 (the model renames
Department to Organization only when Organization is missing). No
conflicts: CHANGELOG.md is the only file both sides change, and main's
entries merge in around this branch's.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keith McGrane (Keithland89) pushed a commit that referenced this pull request Oct 20, 2026
Without #144, the models rename Department to Organization even when the org data already has Organization, and the refresh fails. On Azure, publish never drops a column, so the core and Agent Evaluator refreshes would keep failing. Section 0 says how to check whether the branch under test has it. It looks for #144's test, because this repo's history reuses PR numbers: an old commit is 'Analytics Hub installer 0.3.5 (#144)'.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keith McGrane (Keithland89) added a commit that referenced this pull request Oct 20, 2026
…ng Dataverse (W2, 3 of 3) (#146)

* Azure: turn on Agent Evaluator in the installer

Adds the environment picker, the jobs' managed identity as a Dataverse
application user with Bot Transcript Viewer, and removal on untick and
uninstall. Gates the model on the module (as Fabric does) and its refresh
on an environment the managed identity can read. The jobs skip the ae
model until agentEvaluator is in VALUELENS_MODULES.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Azure: pass the Dataverse environments to the jobs, and test Agent Evaluator's gates and transcript access

- Bicep and the ARM template: a dataverseEnvironments parameter, set as VALUELENS_DATAVERSE_ENVIRONMENTS on the jobs.
- Tests for the two gate levels (model deployed, and an environment the managed identity can read), the schedule turned off with exactly { value: { enabled: false } }, the ledger of application users and roles, removal with the re-enable fallback, demo mode, re-ticking, a new managed identity, uninstall and status.
- Dataverse client tests for removeRole, disableUser, enableUser and deleteUser.
- Existing tests tick Agent Evaluator where they expect its model, and call azureSemanticModels with the whole config, as #125 does.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Azure: name the Agent Evaluator schedule-off variable apart from Consumption's

#125 adds `const kept` for the Consumption model's schedule-off block in the
same function, so a merge that keeps both blocks would declare it twice.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Docs: Agent Evaluator on Azure

Describe the Azure transcript access step, the jobs' managed identity as a
Dataverse application user with the Bot Transcript Viewer role, the two
gates (pages once the model is deployed, refresh once an environment can be
read), demo mode, update and uninstall, in the Azure, installer and jobs
READMEs, DESIGN, ARCHITECTURE, PERMISSIONS, PREREQUISITES, TROUBLESHOOTING,
UPDATE and the CHANGELOG.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Docs: the Agent Evaluator on Azure live-test runbook

azure/AGENT-EVALUATOR-LIVE-TEST.md is for Keith to approve, not to run yet. It
installs into a new resource group, adds the jobs' managed identity to one
environment through the installer and to a second by hand in the admin center
(by its client ID), and times the run. It then checks Repair or change against
the gates: removing an environment, no environment to read, unticking and
re-ticking the module, demo mode, status and uninstall, including whether
Dataverse's Web API deletes an application user. tests/test_docs.py now checks
its links.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Azure Agent Evaluator: VALUELENS_MODULES follows the tick; the environment list gates the jobs

VALUELENS_MODULES now lists agentEvaluator whenever the module is ticked
outside demo mode, as Fabric's flag does. #143 serves that list to the web
app as app.config.json's modules, and use-source-freshness.ts reads
modules.agentEvaluator for the Agent Evaluation page's data date, so the
flag has to mean "ticked" on Azure too.

The jobs' read and refresh gate moves to VALUELENS_DATAVERSE_ENVIRONMENTS.
The installer sends '[]' until the managed identity can read a chosen
environment, then every chosen environment. The jobs collect, and refresh
ae, only when the module is listed and that list is non-empty; otherwise
they log why and skip, and publish still runs. The installer's refresh,
the Power BI schedule, and the alias, viewer, RLS and pendingReloads gates
are unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Agent Evaluator live-test runbook: rc.2, the uninstall order, the jobs' skip lines

The live test runs on 0.6.8-rc.2, with Keith's approval. The uninstall
steps follow #127's order: transcript access is removed right after the
Teams app, before the Power BI workspace and resource group deletes.
Step 10 expects the jobs' new skip lines while no environment is readable.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Live-test runbook: don't load a Department column without #144

Without #144, the models rename Department to Organization even when the org data already has Organization, and the refresh fails. On Azure, publish never drops a column, so the core and Agent Evaluator refreshes would keep failing. Section 0 says how to check whether the branch under test has it. It looks for #144's test, because this repo's history reuses PR numbers: an old commit is 'Analytics Hub installer 0.3.5 (#144)'.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Azure: every module is supported now, so drop the coming-soon wording

With Agent Evaluator on, every catalog module has azure.supported=true,
so nothing on Azure is coming soon any more.

- planAzure's data prompt drops "Unsupported modules are coming soon on
  Azure." azureModuleChoices keeps its disabled-choice path for future
  modules.
- installer/README.md, azure/README.md and azure/DESIGN.md drop their
  coming-soon and not-started lines.
- planAzure's config.modules line gets back the indent it lost in the
  rebase onto main.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Keith Mcgrane <keithmcgrane@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keith McGrane (Keithland89) pushed a commit to microsoft/ValueLens-for-Microsoft-Copilot that referenced this pull request Oct 24, 2026
… missing

Port of microsoft/AnalyticsHub-Dashboard#144. The org query renamed the
first department-like column to Organization even when the org data
already had one, so a Workday export with a Department column (or an org
CSV with both columns) failed the refresh. The installer's Fabric route
offers Workday org data, so it would hit this.

scripts/Update-Org-Department-Rename.py (from AH 1af87db) now covers all
six live ValueLens templates: Fabric, Fabric OneLake, Agent Evaluator,
Power Automate + Dataverse, SharePoint and Local CSV. Only the
"Chat + Agent Org Data" query changes; ZIP metadata and every other
member are unchanged, and the script is idempotent with --check.

tests/test_org_department_rename.py is AH's test, scanning every live
template outside archive/. The pinned Fabric schema hashes in
test_consolidated_release.py move to the patched templates.

Desktop refresh still needs a live check.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant