Repository navigation
feat(BA-8647): move the default of a dotfile path onto one of the user's dotfiles - #15936
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Concurrent switches can fail without retry, and the action does not follow the required field-owner lookup contract.
2 open issues
What changed in this PR
Adds a service operation to select a user's default dotfile variant, preparing for the user dotfile v2 API. No API endpoint calls it yet.
Changes:
- Adds the action, processor, and service method.
- Clears and sets defaults within one scoped transaction.
- Adds database tests and a changelog entry.
| File | Description |
|---|---|
| tests/unit/manager/repositories/user/test_switch_default_dotfile.py | Tests switching, path isolation, and ownership. |
| src/ai/backend/manager/services/user/service.py | Delegates switching to the repository. |
| src/ai/backend/manager/services/user/processors.py | Registers the switch processor. |
| src/ai/backend/manager/services/user/actions/switch_default_dotfile.py | Defines the action and result. |
| src/ai/backend/manager/repositories/user/repository.py | Coordinates transactional default switching. |
| src/ai/backend/manager/models/dotfile/updaters.py | Adds clear-default and set-default specifications. |
| changes/15936.feature.md | Documents the new service operation. |
Review effort: Balanced
| await ops.batch_update_in_scopes( | ||
| scopes, DotfileDefaultClearUpdater(user_id=user_id, dotfile_id=dotfile_id) | ||
| ) | ||
| switched = await ops.batch_update_in_scopes( | ||
| scopes, DotfileDefaultSetUpdater(dotfile_id=dotfile_id) |
| user_id: UserID | ||
| dotfile_id: DotfileID |
| # Cleared first; the partial unique index allows one default per path. | ||
| await ops.batch_update_in_scopes( | ||
| scopes, DotfileDefaultClearUpdater(user_id=user_id, dotfile_id=dotfile_id) | ||
| ) | ||
| switched = await ops.batch_update_in_scopes( | ||
| scopes, DotfileDefaultSetUpdater(dotfile_id=dotfile_id) |
There was a problem hiding this comment.
Do we have a bulk updater with conditions?
| async with self._v2_ops.write_ops() as ops: | ||
| # Cleared first; the partial unique index allows one default per path. | ||
| await ops.batch_update_in_scopes( | ||
| scopes, DotfileDefaultClearUpdater(user_id=user_id, dotfile_id=dotfile_id) | ||
| ) | ||
| switched = await ops.batch_update_in_scopes( | ||
| scopes, DotfileDefaultSetUpdater(dotfile_id=dotfile_id) |
There was a problem hiding this comment.
If we handle this without row locks, it seems like it will break.
| target.entity_type == user_id.entity_type(), | ||
| target.entity_id == user_id, |
There was a problem hiding this comment.
In future project and domain migration tasks, we plan to change this from user_id to entity_id.
…r's dotfiles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Concurrent switches on one path could both clear nothing and then violate uq_dotfiles_is_default. The clear now locks every dotfile of the user on that path in id order, so a concurrent switch waits and re-reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b52e25b to
0641e97
Compare
HyeockJinKim
left a comment
There was a problem hiding this comment.
I’d like to generalize the “set default” part, but I think I’ll need to create a separate issue for that. The work you’ve done so far is great.

Summary
A dotfile is created as a non-default variant, so a path needs an operation that makes one of its variants the one sessions receive. Groundwork for the user dotfile v2 API (BA-8462); no API calls it yet.
SwitchDefaultDotfileAction(user_id, dotfile_id)onUserProcessors, checked against the user likecreate_dotfileUserRepository.switch_default_dotfileruns twoDataBatchUpdaterspecs in onewrite_ops()transaction, both throughbatch_update_in_scopes([UserDotfileTarget(user_id)], ...):DotfileDefaultClearUpdater: clears the default among the user's other dotfiles on the target's path (first, as the partial unique index allows one default per path)DotfileDefaultSetUpdater: sets the target as the defaultDotfileNotFound; the transaction rolls back the clearTest plan
tests/unit/manager/repositories/user/test_switch_default_dotfile.py(real DB)pants lint/pants check --changed-dependents=directResolves BA-8647
🤖 Generated with Claude Code