Skip to content

fix(issue-33): account restore on restart + sync rules store folder paths not Graph IDs#34

Merged
jbarden merged 2 commits into
mainfrom
bug/account-restore-and-sync-rule-paths-33
May 27, 2026
Merged

fix(issue-33): account restore on restart + sync rules store folder paths not Graph IDs#34
jbarden merged 2 commits into
mainfrom
bug/account-restore-and-sync-rule-paths-33

Conversation

@jaybarden1

Copy link
Copy Markdown
Contributor

Closes #33

Summary

Two bugs introduced by #26 (persistence layer). Both relate to unimplemented acceptance criteria.


Bug 1 — Accounts not visible in UI after app restart

Root cause

WorkspaceViewModel.Accounts was always populated from the static BuildAccounts() method (hard-coded design-time data). No code ever read IAccountRepository at startup — App.axaml.cs only ran migrations.

Fix

  • WorkspaceViewModel gains a new runtime constructor (IServiceProvider, IAccountRepository) that starts with an empty Accounts collection (no design-time data on the DI path).
  • New LoadPersistedAccountsAsync(CancellationToken) method loads all rows from IAccountRepository, maps them to AccountViewModel, adds to Accounts, and auto-selects the first account.
  • App.axaml.cs resolves WorkspaceViewModel from DI (which now auto-injects IAccountRepository) and fires LoadPersistedAccountsAsync after the main window is created.
  • The parameterless constructor retains BuildAccounts() fake data for design-time and test use — all existing tests unaffected.

Bug 2 — Sync rules stored Graph item IDs not folder paths

Root cause

AddAccountWizardViewModel.ExecuteAddAccountAsync put raw Graph drive item IDs (e.g. 01ABCDEF…) into OneDriveAccount.SelectedFolderIds. AccountOnboardingService then wrote those IDs as SyncRuleEntity.RemotePath. The sync rule evaluator and pipeline expect slash-prefixed path strings (e.g. /Documents), not Graph IDs.

Fix

  • New SelectedFolder(string Id, string Name)readonly record struct in the Domain layer carrying both the Graph item ID and the display name.
  • OneDriveAccount.SelectedFolderIds removed; replaced by SelectedFolders: IReadOnlyList<SelectedFolder>.
  • AddAccountWizardViewModel now builds SelectedFolder instances from WizardFolderItem.FolderId + Name.
  • AccountOnboardingService.UpsertSyncRulesAsync writes RemotePath = $"/{folder.Name}" (e.g. /Documents).

Tests

Suite Before After
Unit 171 pass 174 pass (+3 new)
Integration 21 pass 23 pass (+2 new)

New tests:

  • when_load_persisted_accounts_is_called_then_stored_account_appears_in_accounts
  • when_load_persisted_accounts_is_called_with_no_accounts_then_accounts_collection_is_empty
  • when_load_persisted_accounts_is_called_then_first_account_is_auto_selected
  • when_complete_onboarding_is_called_then_sync_rule_remote_path_is_slash_prefixed_folder_name
  • when_complete_onboarding_is_called_then_sync_rule_remote_path_does_not_contain_graph_item_id

dotnet build — 0 errors, 0 warnings
dotnet test — 197 pass, 0 fail


🤖 Generated with Claude Code

jaybarden1 and others added 2 commits May 27, 2026 12:13
… restore

- GivenAnAccountOnboardingServiceIntegration: two tests asserting RemotePath
  is slash-prefixed folder name (e.g. /Documents), not a Graph item ID
- GivenAWorkspaceViewModel: three tests asserting LoadPersistedAccountsAsync
  populates Accounts from repository, auto-selects first account, and
  leaves collection empty when repository returns no rows

Supporting stubs (not yet implemented):
- SelectedFolder readonly record struct added to Domain
- OneDriveAccount.SelectedFolders property alongside SelectedFolderIds
- WorkspaceViewModel(IServiceProvider, IAccountRepository) constructor overload
- WorkspaceViewModel.LoadPersistedAccountsAsync stub (throws NotImplementedException)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bug 1 — accounts not restored on app restart:
- WorkspaceViewModel now has a two-arg constructor
  (IServiceProvider, IAccountRepository) that starts with an empty
  Accounts collection (no design-time data on the runtime path)
- LoadPersistedAccountsAsync loads all AccountEntity rows from
  IAccountRepository, maps them to AccountViewModel, adds to Accounts,
  and auto-selects the first account
- App.axaml.cs resolves the WorkspaceViewModel (DI now injects
  IAccountRepository) and fires LoadPersistedAccountsAsync after
  the main window is created
- Design-time / single-IServiceProvider constructor retains
  BuildAccounts() fake data unchanged

Bug 2 — sync rules storing Graph item IDs not folder paths:
- OneDriveAccount.SelectedFolderIds removed; replaced by
  SelectedFolders: IReadOnlyList<SelectedFolder>
- SelectedFolder is a new readonly record struct(string Id, string Name)
  carrying both the Graph drive item ID and the display name
- AddAccountWizardViewModel.ExecuteAddAccountAsync now builds
  SelectedFolder instances from WizardFolderItem.FolderId + Name
- AccountOnboardingService.UpsertSyncRulesAsync now writes
  RemotePath = "/\{folder.Name}" (e.g. "/Documents") instead of the
  raw Graph item ID
- WorkspaceViewModel.OnWizardCompleted uses SelectedFolders.Count

All existing tests updated to use SelectedFolders. 197 tests green.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jaybarden1 jaybarden1 requested a review from a team May 27, 2026 11:36
@jbarden jbarden enabled auto-merge (squash) May 27, 2026 11:37
@github-actions

Copy link
Copy Markdown

Test results

0 tests  ±0   0 ✅ ±0   0s ⏱️ ±0s
0 suites ±0   0 💤 ±0 
0 files   ±0   0 ❌ ±0 

Results for commit 07db7f4. ± Comparison against base commit f2000bf.

@jbarden jbarden left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking forward to the rewrite...

@jbarden jbarden merged commit 22f9fb2 into main May 27, 2026
5 of 6 checks passed
@jbarden jbarden deleted the bug/account-restore-and-sync-rule-paths-33 branch May 27, 2026 11:40
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.

bug: persisted accounts not restored on restart; sync rules store Graph IDs not folder paths

2 participants