Problem
Onboarding/AccountOnboardingService.cs has three defects:
1. MatchAsync used to re-wrap a Result (banned)
MatchAsync must collapse to a concrete final value. Lines 25–35 use it to return Result<OneDriveAccount, PersistenceError> — a Result is not a concrete value. Use BindAsync + MapAsync instead:
return await accountRepository.UpsertAsync(entity, cancellationToken)
.BindAsync(_ => UpsertSyncRulesAsync(account, cancellationToken))
.MapAsync(_ => account)
.ConfigureAwait(false);
2. Default sync path always overwrites existing config
ComputeDefaultSyncPath is called unconditionally (line 65). onboarding.md says: "if no LocalSyncPath is configured, compute the default." Any pre-configured path on the incoming account is silently discarded.
Fix: Make it conditional:
LocalSyncPath = new LocalSyncPath(
string.IsNullOrEmpty(account.SyncConfig?.LocalSyncPath.Value)
? ComputeDefaultSyncPath(account.Profile.Email)
: account.SyncConfig.LocalSyncPath.Value)
3. DriveId ?? string.Empty silently produces invalid entity
Line 62: DriveId = new DriveId(account.DriveId ?? string.Empty). An empty DriveId causes all downstream Graph operations to fail with an opaque error. Fail fast instead:
if (string.IsNullOrEmpty(account.DriveId?.Value))
return new Fail<OneDriveAccount, PersistenceError>(
PersistenceErrorFactory.Unexpected("Cannot onboard account: DriveId is missing."));
Rule reference
@.claude/rules/functional-usage.md — Match/MatchAsync usage; @.claude/rules/onedrive-onboarding.md
Problem
Onboarding/AccountOnboardingService.cshas three defects:1.
MatchAsyncused to re-wrap aResult(banned)MatchAsyncmust collapse to a concrete final value. Lines 25–35 use it to returnResult<OneDriveAccount, PersistenceError>— aResultis not a concrete value. UseBindAsync+MapAsyncinstead:2. Default sync path always overwrites existing config
ComputeDefaultSyncPathis called unconditionally (line 65).onboarding.mdsays: "if noLocalSyncPathis configured, compute the default." Any pre-configured path on the incoming account is silently discarded.Fix: Make it conditional:
3.
DriveId ?? string.Emptysilently produces invalid entityLine 62:
DriveId = new DriveId(account.DriveId ?? string.Empty). An emptyDriveIdcauses all downstream Graph operations to fail with an opaque error. Fail fast instead:Rule reference
@.claude/rules/functional-usage.md— Match/MatchAsync usage;@.claude/rules/onedrive-onboarding.md