gabriel / musehub public
feat BREAKING task/musehub-117-phase3-repo-domain-link #1 / 1
AI Agent gabriel · 19 days ago · Jul 2, 2026 · Diff

feat: wire a repo to a real registered marketplace domain (musehub#117 Phase 3)

DOM_12: MusehubDomainInstall turned out to be a user<->domain adoption record, not a repo<->domain link, and the existing MusehubRepo.domain_id column is a plain VCS-plugin category string ('code'/'midi'/'mist') load-bearing for the profile heatmap - musehub_profile.py even actively guards against a real marketplace ID leaking into it from a past incident. Neither was the right mechanism, so added a genuinely new, separate column: MusehubRepo.marketplace_domain_id (migration 0074).

Wired end to end: - PATCH /api/repos/{repo_id}/settings accepts marketplace_domain_id - 404s if the target domain doesn't exist, '' clears the link, owner/ admin-guarded like every other setting on this endpoint. - DOM_13: record_domain_uninstall added (record_domain_install had no counterpart) - install/uninstall bookkeeping fires exactly once per actual link/unlink, never double-counts on a re-sent identical patch, never goes negative, is scoped per-user. - repo_nav.html already had real, dormant logic for a repo_domain badge (documented in its own header comment, never actually populated by any route) - populated it via a new _resolve_repo_domain() in the shared _nav_ctx.py helper, wired into both the main repo home page (ui_repo.py, which builds its nav context inline rather than through the shared helper) and the two insights-dashboard routes already using build_repo_nav_ctx.

19 new tests across test_domains.py (install/uninstall lifecycle, repo home badge E2E) and test_musehub_repos.py (settings patch: link/404/ clear/idempotent). Bumped the migration-count/head golden constants (0073->0074) in test_migrations.py and test_musehub_alembic.py. 171 passed across test_domains.py/test_musehub_repos.py/ test_musehub_ui_repo_home_ssr.py, 49/49 test_migrations.py (full up/ down/re-up cycle), 6/6 test_musehub_alembic.py, zero regressions.

sha256:62dd2e53c948b1f169c6c353b0791b8da11e941895e9fc8d89accddac96778bf sha
+29 ~24 symbols
12 changed · 1003 in snapshot files
sha256:a25e69900e6e8e66074af5fbe7065e55d96a33350697ddc4d83a9c63363ea12b snapshot
+29
symbols added
~24
symbols modified
12
files changed
1003
files in snapshot
0
dead code introduced
Semantic Changes 53 symbols
+ branch_labels variable variable branch_labels L23–23
+ depends_on variable variable depends_on L24–24
+ down_revision variable variable down_revision L22–22
+ downgrade function function downgrade L35–37
+ Sequence import import Sequence L14–14
+ Union import import Union L14–14
+ annotations import import annotations L12–12
+ op import import op L16–16
+ sa import import sa L17–17
+ revision variable variable revision L21–21
+ upgrade function function upgrade L27–32
~ musehub/api/routes/musehub/_nav_ctx.py .py 1 symbol added, 2 symbols modified
+ _resolve_repo_domain function async_function _resolve_repo_domain L37–58
~ musehub/api/routes/musehub/ui_repo.py .py 2 symbols added, 1 symbol modified
+ _resolve_domain_viewer_type import import _resolve_domain_viewer_type L23–23
+ _resolve_repo_domain import import _resolve_repo_domain L23–23
+ record_domain_uninstall function async_function record_domain_uninstall L295–322
~ tests/test_domains.py .py 9 symbols added, 11 symbols modified
+ TestIntegrationRecordDomainUninstall class class TestIntegrationRecordDomainUninstall L424–475
+ test_decrements_install_count method async_method test_decrements_install_count L427–437
+ test_idempotent_when_not_installed method async_method test_idempotent_when_not_installed L439–448
+ test_never_goes_negative method async_method test_never_goes_negative L450–462
+ test_only_affects_the_uninstalling_user method async_method test_only_affects_the_uninstalling_user L464–475
+ TestRepoHomeMarketplaceDomainBadge class class TestRepoHomeMarketplaceDomainBadge L1297–1328
+ test_linked_repo_shows_domain_badge method async_method test_linked_repo_shows_domain_badge L1298–1316
+ test_unlinked_repo_shows_no_domain_badge method async_method test_unlinked_repo_shows_no_domain_badge L1318–1328
+ record_domain_uninstall import import record_domain_uninstall L40–40
~ tests/test_migrations.py .py 2 symbols modified
~ tests/test_musehub_repos.py .py 5 symbols added
+ _make_marketplace_domain function async_function _make_marketplace_domain L1143–1158
+ test_patch_marketplace_domain_id_clear_uninstalls function async_function test_patch_marketplace_domain_id_clear_uninstalls L1207–1238
+ test_patch_marketplace_domain_id_links_and_installs function async_function test_patch_marketplace_domain_id_links_and_installs L1161–1185
+ test_patch_marketplace_domain_id_unchanged_does_not_double_install function async_function test_patch_marketplace_domain_id_unchanged_does_not_double_install L1241–1265
+ test_patch_marketplace_domain_id_unknown_returns_404 function async_function test_patch_marketplace_domain_id_unknown_returns_404 L1188–1204
Files Changed
+1 ~11
1003 in snapshot
← Older Oldest on task/musehub-117-phase3-repo-domain-link
All commits
Newer → Latest on task/musehub-117-phase3-repo-domain-link

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:62dd2e53c948b1f169c6c353b0791b8da11e941895e9fc8d89accddac96778bf --body "your comment"