Skip to content

feat(BA-8647): move the default of a dotfile path onto one of the user's dotfiles - #15936

Merged
HyeockJinKim merged 3 commits into
mainfrom
feat/BA-8647
Oct 22, 2026
Merged

HyeockJinKim merged 3 commits into
mainfrom
feat/BA-8647

Conversation

@seedspirit

Copy link
Copy Markdown
Contributor

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) on UserProcessors, checked against the user like create_dotfile
  • UserRepository.switch_default_dotfile runs two DataBatchUpdater specs in one write_ops() transaction, both through batch_update_in_scopes([UserDotfileTarget(user_id)], ...):
    1. 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)
    2. DotfileDefaultSetUpdater: sets the target as the default
  • A dotfile id the user does not own updates nothing and raises DotfileNotFound; the transaction rolls back the clear

Test plan

  • tests/unit/manager/repositories/user/test_switch_default_dotfile.py (real DB)
    • the default moves onto a variant and the previous one is cleared
    • a path without a default gets one
    • other paths keep their default
    • another user's dotfile is not found and stays unchanged
  • pants lint / pants check --changed-dependents=direct

Resolves BA-8647

🤖 Generated with Claude Code

@github-actions github-actions Bot added size:L 100~500 LoC comp:manager Related to Manager component labels Oct 21, 2026
seedspirit added a commit that referenced this pull request Oct 21, 2026
@seedspirit
seedspirit marked this pull request as ready for review October 21, 2026 04:33
@seedspirit
seedspirit requested a review from a team as a code owner October 21, 2026 04:33
Copilot AI balanced review requested due to automatic review settings October 21, 2026 04:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 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

Comment on lines +384 to +388
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)
Comment on lines +18 to +19
user_id: UserID
dotfile_id: DotfileID
Comment on lines +383 to +388
# 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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we have a bulk updater with conditions?

jopemachine
jopemachine previously approved these changes Oct 21, 2026
Comment on lines +382 to +388
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)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If we handle this without row locks, it seems like it will break.

Comment on lines +74 to +75
target.entity_type == user_id.entity_type(),
target.entity_id == user_id,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

In future project and domain migration tasks, we plan to change this from user_id to entity_id.

seedspirit and others added 3 commits October 22, 2026 13:23
…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>

@HyeockJinKim HyeockJinKim left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

@HyeockJinKim
HyeockJinKim merged commit 1fc7c10 into main Oct 22, 2026
41 checks passed
@HyeockJinKim
HyeockJinKim deleted the feat/BA-8647 branch October 22, 2026 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp:manager Related to Manager component size:L 100~500 LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants