Skip to content

bug(onboarding): AccountOnboardingService — wrong MatchAsync usage, unconditional sync path override, missing DriveId guard #46

@jaybarden1

Description

@jaybarden1

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions