| 1 |
Pre-Work |
Export GL SL semantic model to recover external DAX BLOCKER |
All 116 of the 118 measures in Fee Flash V3 are EXTERNALMEASURE references delegated to the upstream GL SL Analysis Services model. The DAX bodies are not stored in the Fee Flash project files. This export must be completed before any measure rebuild can begin. |
- GL SL model exported from
powerbi://api.powerbi.com/v1.0/myorg/D365%20TT%20Production as TMDL or BIM format
- All 116 EXTERNALMEASURE DAX bodies recovered and documented
- DAX formulas saved to D365-Fabric-PowerBI repo (or equivalent documentation location)
- Measure names confirmed to align with Fee Flash V3 measure inventory in this spec
- Unblocks PBI 22 (measure rebuild)
|
- Export GL SL model from
powerbi://api.powerbi.com/v1.0/myorg/D365%20TT%20Production as TMDL or BIM format
- Recover and document all 116 EXTERNALMEASURE DAX bodies
- Save DAX formulas to D365-Fabric-PowerBI repo (or equivalent documentation location)
- Confirm measure names align with Fee Flash V3 measure inventory in this spec
|
2d |
| 2 |
Bronze |
Identify missing D365 source tables and add to Bronze ingest |
Bronze ingests D365 tables exactly as-is via a tables_to_run set in nb_d365_bronze_ingest. Any D365 table needed by a Gold notebook that is not already in that list must be added here before Gold development can begin. Review all Fee Flash Gold output requirements against the existing table list and add any gaps. |
- All D365 source tables required for Fee Flash Gold outputs identified
- Each missing table added to the
tables_to_run set in nb_d365_bronze_ingest
- Bronze ingest runs successfully and all new tables land in the Bronze Lakehouse
- Changes committed to D365-Fabric-Bronze repo and deployed via pipeline
|
- Identify all D365 source tables required for Fee Flash Gold outputs
- Add each missing table to the
tables_to_run set in nb_d365_bronze_ingest
- Run Bronze ingest and verify all new tables land in the Bronze Lakehouse
- Commit changes to D365-Fabric-Bronze repo and deploy via pipeline
|
1d |
| 3 |
Silver |
Add Silver config entries for any new Bronze tables |
Silver runs the same D365 table set as Bronze through silver_config — a JSON config that defines column renames, the select statement, and quality checks for each table. Any table added to Bronze in PBI 2 must also have a full config entry added to silver_config before it will be processed in Silver. |
- Full config entry added to
silver_config.Notebook for each table introduced in PBI 2
- Each entry includes:
name, description, select statement with renamed columns, column descriptions, and quality_checks — following the pattern of existing entries
- Silver ingest runs successfully and all new tables land in the Silver Lakehouse
- Changes committed to D365-Fabric-Silver repo and deployed via pipeline
- Depends on PBI 2
|
- Add a full config entry to
silver_config.Notebook for each table introduced in PBI 2
- Ensure each entry includes:
name, description, select statement with renamed columns, column descriptions, and quality_checks — following the pattern of existing entries
- Run Silver ingest and verify all new tables land in the Silver Lakehouse
- Commit changes to D365-Fabric-Silver repo and deploy via pipeline
|
1d |
| 4 |
Gold Tables |
Create nb_dim_currency |
New Gold notebook to produce gold.dim_currency from Silver source. Used as the transaction and reporting currency dimension across all facts. Not currently in the MA notebook set. |
- Notebook committed to D365-Fabric-Gold under Notebooks/Dimensions/
- Output table:
gold.dim_currency
- Natural key: Currency code (Currency column)
- Surrogate key generated: CurrencyKey
- Columns include: currency code, currency name, additional attributes per Silver source
- Idempotent — truncate and reload each run
- Added to Gold Orchestration pipeline
|
- Create notebook and commit to D365-Fabric-Gold under Notebooks/Dimensions/
- Produce output table:
gold.dim_currency
- Set natural key to Currency code (Currency column)
- Generate surrogate key: CurrencyKey
- Include columns: currency code, currency name, additional attributes per Silver source
- Implement truncate and reload pattern (idempotent)
- Add to Gold Orchestration pipeline
|
0.5d |
| 5 |
Gold Tables |
Create nb_dim_currency_display |
Disconnected slicer table with the currency display option values used to drive the SWITCH currency selection pattern. Not sourced from Silver — static reference values defined in the notebook. |
- Notebook committed to D365-Fabric-Gold under Notebooks/Dimensions/
- Output table:
gold.dim_currency_display
- Single column: CurrencyDisplayed
- Rows: "Global", "Accounting", "Transaction", "GBP", "USD", "Regional", "Reporting"
- No relationship to any fact table — used as a disconnected slicer in the semantic model
- Added to Gold Orchestration pipeline
|
- Create notebook and commit to D365-Fabric-Gold under Notebooks/Dimensions/
- Produce output table:
gold.dim_currency_display
- Define single column: CurrencyDisplayed
- Populate rows: "Global", "Accounting", "Transaction", "GBP", "USD", "Regional", "Reporting"
- Confirm no relationship to any fact table — used as a disconnected slicer in the semantic model
- Add to Gold Orchestration pipeline
|
0.5d |
| 6 |
Gold Tables |
Create nb_dim_posting_layer |
New Gold notebook for the posting layer dimension. Note: this is different from the existing gold.dim_postingtype (migrated from MA). Posting Layer is shared by GL and Budget facts. |
- Notebook committed to D365-Fabric-Gold under Notebooks/Dimensions/
- Output table:
gold.dim_posting_layer
- Natural key: PostingLayerID
- Surrogate key generated: PostingLayerKey
- Columns: PostingLayerKey, PostingLayerID, PostingLayer name
- Added to Gold Orchestration pipeline
|
- Create notebook and commit to D365-Fabric-Gold under Notebooks/Dimensions/
- Produce output table:
gold.dim_posting_layer
- Set natural key: PostingLayerID
- Generate surrogate key: PostingLayerKey
- Include columns: PostingLayerKey, PostingLayerID, PostingLayer name
- Add to Gold Orchestration pipeline
|
0.5d |
| 7 |
Gold Tables |
Add period type to nb_dim_date or create standalone nb_dim_period_type |
Period type (Operating, Closing, Opening etc.) is shared by GL and Budget facts. Investigate whether it can be included as an attribute on gold.dim_accountingdate — if the period type classification aligns to a date key, adding it to the date dim is the preferred approach and avoids a separate table. Only create a standalone dim if period type is a transaction-level classification that does not align to date. |
- Review whether period type values align to specific dates in
gold.dim_accountingdate
- Preferred outcome: PeriodType added as a column to
gold.dim_accountingdate via nb_dim_date — no separate table needed
- If period type does not align to date: create nb_dim_period_type in D365-Fabric-Gold under Notebooks/Dimensions/, output
gold.dim_period_type, natural key PeriodTypeID, surrogate key PeriodTypeKey
- Fact notebooks updated to reference PeriodType via DateKey (preferred) or PeriodTypeKey (standalone)
- Added to Gold Orchestration pipeline if standalone table is required
|
- Review whether period type values align to specific dates in
gold.dim_accountingdate
- Preferred outcome: add PeriodType as a column to
gold.dim_accountingdate via nb_dim_date — no separate table needed
- If period type does not align to date: create nb_dim_period_type in D365-Fabric-Gold under Notebooks/Dimensions/, producing
gold.dim_period_type with natural key PeriodTypeID and surrogate key PeriodTypeKey
- Update fact notebooks to reference PeriodType via DateKey (preferred) or PeriodTypeKey (standalone)
- Add to Gold Orchestration pipeline if standalone table is created
|
1d |
| 8 |
Gold Tables |
Create nb_dim_type_a_transaction_type |
New Gold notebook for the Type A transaction type dimension. A small lookup table classifying Type A transactions by type. Joined to gold.fact_type_a_value on TypeATransactionTypeKey. |
- Notebook committed to D365-Fabric-Gold under Notebooks/Dimensions/
- Output table:
gold.dim_type_a_transaction_type
- Natural key: TypeATransID
- Surrogate key generated: TypeATransactionTypeKey
- Columns: TypeATransactionTypeKey, TypeATransID, TypeATransactionType name
- Added to Gold Orchestration pipeline
|
- Create notebook and commit to D365-Fabric-Gold under Notebooks/Dimensions/
- Produce output table:
gold.dim_type_a_transaction_type
- Set natural key: TypeATransID
- Generate surrogate key: TypeATransactionTypeKey
- Include columns: TypeATransactionTypeKey, TypeATransID, TypeATransactionType name
- Add to Gold Orchestration pipeline
|
0.5d |
| 9 |
Gold Tables |
Update nb_fact_gl_transaction — absorb GL Information |
GL Information is a 1:1 helper table currently kept separate in the semantic model. Before adding its columns to the fact, review each attribute — some may belong on an existing dimension rather than the fact. Only genuinely fact-level attributes should be added to gold.fct_generalledger. |
- Each GL Information column reviewed: assign to an existing dim, add to fact, or discard
- Columns that belong on an existing dim are not duplicated on the fact — they are accessed via the existing dim relationship
- Remaining attributes that do not belong on an existing dim are added as degenerate dimensions directly on
gold.fct_generalledger
- GL Information is not produced as a standalone Gold table
- Row grain unchanged: one row per GL.RECID
- No bidirectional relationship required in the semantic model for this fact
|
- Review each GL Information column: assign to an existing dim, add to fact, or discard
- For columns that belong on an existing dim, do not duplicate on the fact — access via the existing dim relationship
- Add remaining attributes that do not belong on an existing dim as degenerate dimensions directly on
gold.fct_generalledger
- Do not produce GL Information as a standalone Gold table
- Confirm row grain is unchanged: one row per GL.RECID
- Confirm no bidirectional relationship is required in the semantic model for this fact
|
2d |
| 10 |
Gold Tables |
Update nb_fact_budget — absorb Budget Information |
Budget Information is a 1:1 helper currently joined with bidirectional filtering in the semantic model. Before adding its columns to the fact, review each attribute — some may belong on an existing dimension rather than the fact. Only genuinely fact-level attributes should be added to gold.fct_generalledgerbudget. |
- Each Budget Information column reviewed: assign to an existing dim, add to fact, or discard
- Columns that belong on an existing dim are not duplicated on the fact — they are accessed via the existing dim relationship
- Remaining attributes that do not belong on an existing dim are added as degenerate dimensions directly on
gold.fct_generalledgerbudget
- Budget Information is not produced as a standalone Gold table
- Row grain unchanged: one row per Budget.RECID
- No bidirectional relationship required in the semantic model for this fact
|
- Review each Budget Information column: assign to an existing dim, add to fact, or discard
- For columns that belong on an existing dim, do not duplicate on the fact — access via the existing dim relationship
- Add remaining attributes that do not belong on an existing dim as degenerate dimensions directly on
gold.fct_generalledgerbudget
- Do not produce Budget Information as a standalone Gold table
- Confirm row grain is unchanged: one row per Budget.RECID
- Confirm no bidirectional relationship is required in the semantic model for this fact
|
2d |
| 11 |
Gold Tables |
Create nb_fact_proposal |
New Gold notebook for Proposal. Proposal Information attributes are absorbed into the fact — columns assigned to existing dims, added as degenerate dimensions, or discarded. Proposal Information is not produced as a standalone Gold table. |
- Notebook committed to D365-Fabric-Gold under Notebooks/Facts/
- Output table:
gold.fact_proposal
- Grain: one row per Proposal.RECID
- Surrogate key generated: ProposalKey
- Foreign keys: CompanyKey, InvoiceDateKey, CurrencyKey, AccountKey, CostCenterKey, ProjectKey, DepartmentKey, OfficeKey, LeadProjectKey, CounterPartKey
- Amount columns sufficient to support semantic model measure creation
- Each Proposal Information column reviewed: assign to an existing dim, add to fact, or discard
- Columns that belong on an existing dim are not duplicated on the fact — they are accessed via the existing dim relationship
- Remaining attributes that do not belong on an existing dim are added as degenerate dimensions directly on
gold.fact_proposal
- Proposal Information is not produced as a standalone Gold table
- Added to Gold Orchestration pipeline
|
- Create notebook and commit to D365-Fabric-Gold under Notebooks/Facts/
- Produce output table:
gold.fact_proposal
- Set grain to one row per Proposal.RECID
- Generate surrogate key: ProposalKey
- Include foreign keys: CompanyKey, InvoiceDateKey, CurrencyKey, AccountKey, CostCenterKey, ProjectKey, DepartmentKey, OfficeKey, LeadProjectKey, CounterPartKey
- Include amount columns from D365 source — currency conversion variants are derived in the semantic model via exchange rate measures, not pre-calculated on the fact
- Review each Proposal Information column: assign to an existing dim, add to fact, or discard
- For columns that belong on an existing dim, do not duplicate on the fact — access via the existing dim relationship
- Add remaining attributes that do not belong on an existing dim as degenerate dimensions directly on
gold.fact_proposal
- Do not produce Proposal Information as a standalone Gold table
- Add to Gold Orchestration pipeline
|
3d |
| 12 |
Gold Tables |
Create nb_fact_project_transaction |
New Gold notebook combining Project Transactions and Project Transactions Information into a single fact table. |
- Notebook committed to D365-Fabric-Gold under Notebooks/Facts/
- Output table:
gold.fact_project_transaction
- Grain: one row per Project Transactions.RECID
- Surrogate key generated: ProjectTransKey
- Foreign keys: CompanyKey, TransactionDateKey, CurrencyKey, AccountKey, CostCenterKey, ProjectKey, DepartmentKey, OfficeKey, LeadProjectKey, CounterPartKey
- Amount and quantity columns sufficient to support semantic model measure creation
- Each Project Transactions Information column reviewed: assign to an existing dim, add to fact, or discard
- Columns that belong on an existing dim are not duplicated on the fact — they are accessed via the existing dim relationship
- Remaining attributes that do not belong on an existing dim are added as degenerate dimensions directly on
gold.fact_project_transaction
- Project Transactions Information is not produced as a standalone Gold table
- Added to Gold Orchestration pipeline
|
- Create notebook and commit to D365-Fabric-Gold under Notebooks/Facts/
- Produce output table:
gold.fact_project_transaction
- Set grain to one row per Project Transactions.RECID
- Generate surrogate key: ProjectTransKey
- Include foreign keys: CompanyKey, TransactionDateKey, CurrencyKey, AccountKey, CostCenterKey, ProjectKey, DepartmentKey, OfficeKey, LeadProjectKey, CounterPartKey
- Include amount and quantity columns from D365 source — currency conversion variants are derived in the semantic model via exchange rate measures, not pre-calculated on the fact
- Review each Project Transactions Information column: assign to an existing dim, add to fact, or discard
- For columns that belong on an existing dim, do not duplicate on the fact — access via the existing dim relationship
- Add remaining attributes that do not belong on an existing dim as degenerate dimensions directly on
gold.fact_project_transaction
- Do not produce Project Transactions Information as a standalone Gold table
- Add to Gold Orchestration pipeline
|
3d |
| 13 |
Gold Tables |
Create nb_fact_type_a_value |
New Gold notebook for Type A Values. GL Information attributes are absorbed into the fact following the same pattern as PBI 9 — columns assigned to existing dims, added as degenerate dimensions, or discarded. GL Information is not produced as a standalone Gold table. |
- Notebook committed to D365-Fabric-Gold under Notebooks/Facts/
- Output table:
gold.fact_type_a_value
- Grain: one row per Type A Values.RECID
- Surrogate key generated: TypeAValueKey
- Foreign keys: CompanyKey, TransactionDateKey, AccountKey, CurrencyKey, CostCenterKey, ProjectKey, DepartmentKey, OfficeKey, LeadProjectKey, CounterPartKey, TypeATransactionTypeKey
- Amount and quantity columns sufficient to support semantic model measure creation
- Each GL Information column reviewed: assign to an existing dim, add to fact, or discard
- Columns that belong on an existing dim are not duplicated on the fact — they are accessed via the existing dim relationship
- Remaining attributes that do not belong on an existing dim are added as degenerate dimensions directly on
gold.fact_type_a_value
- GL Information is not produced as a standalone Gold table
- Added to Gold Orchestration pipeline
|
- Create notebook and commit to D365-Fabric-Gold under Notebooks/Facts/
- Produce output table:
gold.fact_type_a_value
- Set grain to one row per Type A Values.RECID
- Generate surrogate key: TypeAValueKey
- Include foreign keys: CompanyKey, TransactionDateKey, AccountKey, CurrencyKey, CostCenterKey, ProjectKey, DepartmentKey, OfficeKey, LeadProjectKey, CounterPartKey, TypeATransactionTypeKey
- Include amount and quantity columns from D365 source — currency conversion variants are derived in the semantic model via exchange rate measures, not pre-calculated on the fact
- Review each GL Information column: assign to an existing dim, add to fact, or discard
- For columns that belong on an existing dim, do not duplicate on the fact — access via the existing dim relationship
- Add remaining attributes that do not belong on an existing dim as degenerate dimensions directly on
gold.fact_type_a_value
- Do not produce GL Information as a standalone Gold table
- Add to Gold Orchestration pipeline
|
2d |
| 14 |
Infrastructure |
Create Azure DevOps repo: D365-Fabric-FeeFlash |
Create a new Azure DevOps Git repository named D365-Fabric-FeeFlash to hold all artefacts for the Fee Flash Fabric workspace — Lakehouse definition, shortcuts config, nb_create_shortcuts, semantic model, reports, and CI/CD pipeline. |
- Repo exists in turntownd365 / D365 BI - Kerv DevOps project
- Default branch is main
|
- Create repo in turntownd365 / D365 BI - Kerv DevOps project
- Set default branch to main
|
0.5d |
| 15 |
Infrastructure |
Provision Fee Flash Fabric workspaces — Dev, UAT, and Prod |
Create three Fabric workspaces for the Fee Flash layer: Dev, UAT, and Prod. These host the Fee Flash Lakehouse, shortcuts to Gold tables, and the Direct Lake semantic model. |
- Three workspaces created: D365-Fabric-Dev-FeeFlash, D365-Fabric-UAT-FeeFlash, D365-Fabric-Prod-FeeFlash
- Appropriate capacity assigned to each
- Workspace Identity has PBI Access
- Workspaces visible in Fabric portal
|
- Create three workspaces: D365-Fabric-Dev-FeeFlash, D365-Fabric-UAT-FeeFlash, D365-Fabric-Prod-FeeFlash
- Assign appropriate capacity to each
- Grant Workspace Identity PBI Access
- Verify workspaces are visible in Fabric portal
|
0.5d |
| 16 |
Infrastructure |
Create Fee Flash Lakehouse in Dev workspace |
Create a Fabric Lakehouse in the Fee Flash Dev workspace. UAT and Prod Lakehouses are provisioned via CI/CD pipeline deployment from the repo definition. |
- Fee Flash Lakehouse exists in D365-Fabric-Dev-FeeFlash workspace
- SQL analytics endpoint accessible
- Lakehouse definition committed to D365-Fabric-FeeFlash repo
|
- Create Fee Flash Lakehouse in D365-Fabric-Dev-FeeFlash workspace
- Verify SQL analytics endpoint is accessible
- Commit Lakehouse definition to D365-Fabric-FeeFlash repo
|
0.5d |
| 17 |
Infrastructure |
Set up VariableLibrary in D365-Fabric-FeeFlash repo |
Add a VariableLibrary item to D365-Fabric-FeeFlash with value sets for Dev, UAT, and Prod. Must include the Fee Flash Lakehouse IDs and the Gold workspace and Lakehouse IDs required by nb_create_shortcuts. |
- VariableLibrary committed to repo
- Value sets exist for Dev, UAT, and Prod
- Variables include Fee Flash Lakehouse workspace ID and item ID per environment
- Variables include Gold workspace ID and Gold Lakehouse ID per environment (required by nb_create_shortcuts)
- Naming conventions match existing repos
|
- Commit VariableLibrary to repo
- Add value sets for Dev, UAT, and Prod
- Include Fee Flash Lakehouse workspace ID and item ID per environment
- Include Gold workspace ID and Gold Lakehouse ID per environment (required by nb_create_shortcuts)
- Follow naming conventions from existing repos
|
0.5d |
| 18 |
Infrastructure |
Set up azure-pipelines.yaml and CI/CD in D365-Fabric-FeeFlash |
Configure the Azure DevOps CI/CD pipeline for D365-Fabric-FeeFlash, using the deployment script pattern from existing repos. Connects the repo to all three workspaces so Lakehouse, semantic model, and report artefacts deploy via pipeline. |
- azure-pipelines.yaml committed and pipeline registered in DevOps
- Pipeline deploys successfully to Dev on merge to main
- Auth scripts (SPN + user) in place
- Environment gates match existing repos
- Repo connected (Git sync) to D365-Fabric-Dev-FeeFlash, D365-Fabric-UAT-FeeFlash, and D365-Fabric-Prod-FeeFlash workspaces
- Fee Flash Lakehouse deploys successfully to UAT and Prod via pipeline
|
- Commit azure-pipelines.yaml and register pipeline in DevOps
- Confirm pipeline deploys successfully to Dev on merge to main
- Add auth scripts (SPN + user)
- Match environment gates to existing repos
- Connect repo (Git sync) to D365-Fabric-Dev-FeeFlash, D365-Fabric-UAT-FeeFlash, and D365-Fabric-Prod-FeeFlash workspaces
- Deploy Fee Flash Lakehouse to UAT and Prod via pipeline
|
1d |
| 19 |
Fee Flash WS |
Create shortcuts_config.json for Fee Flash workspace |
Create a JSON config file mapping each required Gold table to a shortcut in the Fee Flash Lakehouse. Using VariableLibrary variable names for source workspace and Lakehouse IDs makes the config environment-aware across Dev, UAT, and Prod. |
- shortcuts_config.json committed to the Fee Flash workspace repo under Config/
- File includes
source_workspace_variable and source_lakehouse_variable fields referencing the Gold VariableLibrary variable names (e.g. Gold_Workspace_ID, Gold_Lakehouse_ID)
- One entry per table with
source_table and shortcut_name fields:
-
| source_table (Gold) | shortcut_name (Fee Flash Lakehouse) |
| gold.dim_accountingdate | fee_flash.dim_accountingdate |
| gold.dim_chartofaccount | fee_flash.dim_chartofaccount |
| gold.dim_company | fee_flash.dim_company |
| gold.dim_costcenter | fee_flash.dim_costcenter |
| gold.dim_project | fee_flash.dim_project |
| gold.dim_department | fee_flash.dim_department |
| gold.dim_office | fee_flash.dim_office |
| gold.dim_leadproject | fee_flash.dim_leadproject |
| gold.dim_counterpart | fee_flash.dim_counterpart |
| gold.dim_posting_layer | fee_flash.dim_posting_layer |
| gold.dim_period_type | fee_flash.dim_period_type (if standalone per PBI 7) |
| gold.dim_currency | fee_flash.dim_currency |
| gold.dim_currency_display | fee_flash.dim_currency_display |
| gold.dim_type_a_transaction_type | fee_flash.dim_type_a_transaction_type |
| gold.fct_generalledger | fee_flash.fct_generalledger |
| gold.fct_generalledgerbudget | fee_flash.fct_generalledgerbudget |
| gold.fact_proposal | fee_flash.fact_proposal |
| gold.fact_project_transaction | fee_flash.fact_project_transaction |
| gold.fact_type_a_value | fee_flash.fact_type_a_value |
|
- Create and commit shortcuts_config.json to the Fee Flash workspace repo under Config/
- Add
source_workspace_variable and source_lakehouse_variable fields referencing the Gold VariableLibrary variable names (e.g. Gold_Workspace_ID, Gold_Lakehouse_ID)
- Add one mapping entry per table with
source_table and shortcut_name fields (see AC for full mapping)
|
0.5d |
| 20 |
Fee Flash WS |
Create nb_create_shortcuts utility notebook |
Create a generic utility notebook that reads shortcuts_config.json, resolves the source workspace and Lakehouse IDs from VariableLibrary using the variable names in the config, and creates shortcuts in the target Lakehouse. Designed to work with any source by changing only the config file. |
- Notebook committed to D365-Fabric-FeeFlash under Notebooks/Utility/
- Reads shortcuts_config.json from Config/
- Resolves source_workspace_variable and source_lakehouse_variable names against VariableLibrary to get environment-specific IDs at runtime
- Creates or updates each shortcut in the target Lakehouse using the shortcut_name from config
- Idempotent — re-running does not duplicate or error on existing shortcuts
- Notebook runs successfully in Dev and all shortcuts visible in Fee Flash Lakehouse
|
- Create notebook and commit to D365-Fabric-FeeFlash under Notebooks/Utility/
- Implement logic to read shortcuts_config.json from Config/
- Resolve source_workspace_variable and source_lakehouse_variable names against VariableLibrary at runtime to get environment-specific IDs
- Create or update each shortcut in the target Lakehouse using the shortcut_name from config
- Ensure idempotency — re-running must not duplicate or error on existing shortcuts
- Run notebook in Dev and verify all shortcuts are visible in Fee Flash Lakehouse
|
0.5d |
| 21 |
Fee Flash WS |
Create Lakehouse shortcuts in Fee Flash Lakehouse pointing to Gold tables |
Run nb_create_shortcuts (PBI 20) against the Fee Flash workspace using shortcuts_config.json from PBI 19. Creates shortcuts in the Fee Flash Lakehouse pointing to the corresponding Gold Lakehouse tables across Dev, UAT, and Prod. |
- nb_create_shortcuts run in the Fee Flash workspace using shortcuts_config.json from PBI 19
- All 19 shortcuts created in the Fee Flash Lakehouse (Dev, UAT, and Prod)
- Data visible via SQL endpoint for each shortcut in all three environments
- Idempotent — re-running does not duplicate or error on existing shortcuts
- Shortcuts committed to repo via shortcuts.metadata.json
- A Fabric pipeline created to run nb_create_shortcuts, committed to the Fee Flash workspace repo — triggered manually after deployment to each environment to create or refresh shortcuts
- Depends on PBI 19
|
- Run nb_create_shortcuts in the Fee Flash workspace using shortcuts_config.json from PBI 19
- Verify all 19 shortcuts are created in the Fee Flash Lakehouse (Dev, UAT, and Prod)
- Confirm data is visible via SQL endpoint for each shortcut in all three environments
- Verify idempotency — re-running must not duplicate or error on existing shortcuts
- Commit shortcuts to repo via shortcuts.metadata.json
- Create a Fabric pipeline to run nb_create_shortcuts, commit to the Fee Flash workspace repo, and trigger manually after deployment to UAT and Prod
|
1d |
| 22 |
Semantic Model |
Build new Fee Flash V3 semantic model |
Create a new semantic model in the Fee Flash workspace using Direct Lake over shortcuts to Gold Lakehouse tables. Replaces the current thin composite model that delegates to GL SL. |
- New semantic model created in the Fee Flash workspace
- Direct Lake mode over shortcuts to Gold tables in the Fee Flash Lakehouse
- All relationships one-to-many, single direction (dim to fact)
- No bidirectional filtering (helper 1:1 tables eliminated per PBIs 9–10)
- DimCurrencyDisplay defined with no fact relationships (disconnected slicer)
- All surrogate keys, RECID columns, source lineage fields, and raw technical columns marked hidden
- DimDate marked as date table with fiscal hierarchies: FY-FP-D, FY-FQ-FP-D, Y-M-D, Y-M
- Account hierarchy and cost centre hierarchy preserved
- Refresh metadata exposed as a semantic measure or single-row calculated table (Last Refreshed Date)
- Model deploys successfully in the Fee Flash Dev workspace
|
- Create new semantic model in the Fee Flash workspace
- Set Direct Lake mode over shortcuts to Gold tables in the Fee Flash Lakehouse
- Define all relationships as one-to-many, single direction (dim to fact)
- Confirm no bidirectional filtering is needed (helper 1:1 tables eliminated per PBIs 9–10)
- Define DimCurrencyDisplay with no fact relationships (disconnected slicer)
- Mark all surrogate keys, RECID columns, source lineage fields, and raw technical columns as hidden
- Mark DimDate as date table and define fiscal hierarchies: FY-FP-D, FY-FQ-FP-D, Y-M-D, Y-M
- Preserve account hierarchy and cost centre hierarchy
- Expose refresh metadata as a semantic measure or single-row calculated table (Last Refreshed Date)
- Deploy model and confirm it deploys successfully in the Fee Flash Dev workspace
|
3d |
| 23 |
Semantic Model |
Rebuild all 118 measures DEPENDS ON PBI 1 |
Port all 116 external measures (previously EXTERNALMEASURE references to GL SL) and 2 local DAX measures into the new semantic model. EXTERNALMEASURE references are replaced with direct DAX sourced from the GL SL export (PBI 1). |
- All 118 measures present in the new semantic model
- EXTERNALMEASURE references replaced with direct DAX — model no longer references GL SL
- 2 local measures ported as-is:
FD Cost Center[Project Cost Centre Selected] (CONCATENATEX/FILTERS pattern) and GL[Legal Entity Selected] (CONCATENATEX/FILTERS pattern)
- Display folders match spec: Budget, FD Cost Center, GL, Fee Flash, Fee Flash Proposal, Project Transactions, Proposal
- Formats match spec:
#,0.00 for amounts, 0.00%;-0.00%;0.00% for percentages, #,0 for OV/count variants
- Measure values validated against current Fee Flash V3 report for at least one closed month (see PBI 26)
|
- Port all 118 measures into the new semantic model
- Replace EXTERNALMEASURE references with direct DAX — model must no longer reference GL SL
- Port 2 local measures as-is:
FD Cost Center[Project Cost Centre Selected] and GL[Legal Entity Selected] (CONCATENATEX/FILTERS pattern)
- Set display folders to match spec: Budget, FD Cost Center, GL, Fee Flash, Fee Flash Proposal, Project Transactions, Proposal
- Set formats to match spec:
#,0.00 for amounts, 0.00%;-0.00%;0.00% for percentages, #,0 for OV/count variants
- Validate measure values against current Fee Flash V3 report for at least one closed month (see PBI 26)
|
5d |
| 24 |
Semantic Model |
Implement currency selection pattern |
Rebuild the currency selection pattern using DimCurrencyDisplay as a disconnected slicer and a SWITCH measure family to return the correct currency amount variant based on the user's selection. |
- DimCurrencyDisplay table in model with no fact relationships
- Selected Currency Amount measure implemented for each relevant fact table using the SELECTEDVALUE/SWITCH pattern
- SWITCH covers: "Accounting" → Acc CCY, "Transaction" → Tx CCY, "Regional" → Reg CCY, "Reporting" → Rep CCY, "USD" → USD CCY, default → GBP CCY ("Global")
- Report-level hidden filter (Currency Displayed = "Global") replaced by semantic default in the measure — no hidden filter required in the report
- Formula matches spec:
VAR currency_type = SELECTEDVALUE('Dim Currency Display'[CurrencyDisplayed], "Global") RETURN SWITCH(currency_type, "Accounting", [Acc CCY Amount], ...)
|
- Confirm DimCurrencyDisplay is in model with no fact relationships
- Implement Selected Currency Amount measure for each relevant fact table using the SELECTEDVALUE/SWITCH pattern
- Cover all SWITCH cases: "Accounting" → Acc CCY, "Transaction" → Tx CCY, "Regional" → Reg CCY, "Reporting" → Rep CCY, "USD" → USD CCY, default → GBP CCY ("Global")
- Replace report-level hidden filter (Currency Displayed = "Global") with a semantic default in the measure — no hidden filter required in the report
- Implement formula matching spec:
VAR currency_type = SELECTEDVALUE('Dim Currency Display'[CurrencyDisplayed], "Global") RETURN SWITCH(currency_type, "Accounting", [Acc CCY Amount], ...)
|
1d |
| 25 |
Semantic Model |
Implement Row-Level Security |
Define RLS roles in the semantic model on legal entity and cost centre dimensions. RLS is applied in the model, not as report-level page filters, so security travels with the semantic model regardless of which report consumes it. |
- RLS role defined on DimCompany for legal entity (Entity column) filtering
- RLS role defined on DimFinancialCostCenter for cost centre filtering
- RLS implemented in semantic model, not as report-level filters
- Roles defined in TMDL and committed to repo
- Tested with at least one user per role in Dev workspace — filtered user sees only permitted entities/cost centres
- Mapping of D365 security groups or user accounts to RLS roles documented
|
- Define RLS role on DimCompany for legal entity (Entity column) filtering
- Define RLS role on DimFinancialCostCenter for cost centre filtering
- Implement RLS in semantic model, not as report-level filters
- Define roles in TMDL and commit to repo
- Test with at least one user per role in Dev workspace — verify filtered user sees only permitted entities/cost centres
- Document mapping of D365 security groups or user accounts to RLS roles
|
1d |
| 26 |
Manual System Test |
Manual System Test |
Manually compare current Fee Flash V3 report output against the new Gold semantic model output to confirm figures match before sign-off. Comparison is conducted by a tester across at least one closed fiscal month. |
- Test conducted for at least one closed fiscal month
- Key measures compared across: company, fiscal period, cost centre, account category, and currency type
- Financial amounts for closed months match to currency precision
- Any variances investigated, explained, and signed off
- Open month variances documented with a named operational explanation
- Stakeholder sign-off obtained before Prod deployment
|
- Select at least one closed fiscal month for comparison
- Compare key measures across: company, fiscal period, cost centre, account category, and currency type
- Investigate and sign off any variances
- Document open month variances with a named operational explanation
- Obtain stakeholder sign-off before Prod deployment
|
2d |
| 27 |
Operations |
Set up Fabric Deployment Pipeline for Fee Flash workspace |
Create the Fabric Deployment Pipeline connecting the Fee Flash Dev, UAT, and Prod workspaces. This promotes all workspace items — Lakehouse, semantic model, reports, and Fabric Data Pipelines — through environments. Must be in place before DevOps can trigger promotions. |
- Fabric Deployment Pipeline created with three stages: D365-Fabric-Dev-FeeFlash → D365-Fabric-UAT-FeeFlash → D365-Fabric-Prod-FeeFlash
- All workspace items visible in the pipeline: Fee Flash Lakehouse, semantic model, reports, and Fabric Data Pipelines (including Post Deployment pipeline from PBI 20)
- Successful deployment from Dev to UAT
- Successful deployment from UAT to Prod
|
- Create Fabric Deployment Pipeline with three stages: D365-Fabric-Dev-FeeFlash → D365-Fabric-UAT-FeeFlash → D365-Fabric-Prod-FeeFlash
- Verify all workspace items are visible in the pipeline: Lakehouse, semantic model, reports, and Fabric Data Pipelines
- Set deployment rules for each workspace item to handle environment-specific configuration (e.g. Lakehouse connections, data source references)
- Deploy from Dev to UAT and confirm success
- Deploy from UAT to Prod and confirm success
|
1d |
| 28 |
Operations |
Configure Azure DevOps to trigger Fabric Deployment Pipeline |
Configure Azure DevOps CI/CD to trigger the Fabric Deployment Pipeline promotions for the Fee Flash workspace. DevOps orchestrates the promotion sequence; the Fabric Deployment Pipeline (PBI 26) does the actual item deployment. |
- azure-pipelines.yaml configured in the Fee Flash workspace repo
- Pipeline triggers Fabric Deployment Pipeline promotion from Dev to UAT on merge to main
- UAT to Prod gate matches existing MA pipeline pattern
- Service principal or user auth matches existing pipeline pattern
- End-to-end run completes successfully in Dev and UAT
|
- Configure azure-pipelines.yaml in the Fee Flash workspace repo
- Set pipeline to trigger Fabric Deployment Pipeline promotion Dev to UAT on merge to main
- Match UAT to Prod gate to the existing MA pipeline pattern
- Match service principal or user auth to the existing pipeline pattern
- Run end-to-end in Dev and UAT and confirm success
|
1d |