fix(git): stop invisible connections from blocking provider deletion - #553
Conversation
A git provider could not be deleted whenever a connection row existed for
it, even when that row was invisible to the caller: the provider detail
page lists connections from the per-user endpoint (user_id = caller) and
filters to active ones, while the delete guard counted every active
connection for the provider regardless of owner. The result was a dead
end — "Cannot delete provider GitLab because it has 1 connection(s)" next
to "No connections found", with no way to reach the offending row.
- delete_provider now blocks only on projects that actually deploy from
the provider (naming them), and cascades its connections + repositories,
matching the existing safe-delete path.
- Deletion checks read every connection, including deactivated ones, so a
hidden row can no longer be left orphaned by the cascade.
- GET /git-providers/{id}/connections returns all of the provider's
connections, so the list can no longer contradict the delete error.
- delete_connection names the blocking projects, and the UI surfaces the
server's detail instead of a bare "Failed to delete connection".
📓 Changelog previewThis is what your commits will add to the generated ## [Unreleased]
### Fixed
- **git:** Stop invisible connections from blocking provider deletion
- **git:** Surface connection deletion for every provider type |
Follow-up from verifying the previous commit against a real GitLab PAT
provider in the UI. Two dead ends were left:
- "Delete connection" only rendered for GitHub App providers, so a
PAT/OAuth connection could not be removed at all — including the ones
that block deleting their provider. DELETE /git-connections/{id} is
generic and the server-side project guard still applies, so show it for
every provider type.
- Naming the blocking projects loaded whole project models, which fails
with "Database Error: unexpected value for Preset enum" if any of them
carries a column value this build's enums can't decode — replacing the
actionable reason with an opaque one. Select id/name/slug only.
UI verification (GitLab PAT provider, slot 11)Ran the real console against a seeded GitLab PAT provider with an ownerless connection ( 1. Visibility (the contradiction) — provider page now lists the connection, while the per-user endpoint it used to read still returns nothing: 2. Delete with no project usage — dialog states the cascade, delete succeeds, DB confirms: 3. Delete blocked by a project — actionable, names it: 4. Connection delete — blocked, then succeeds once the project is unlinked: Two problems this run caught (fixed in 1981629)
Re-verified after the follow-up: |
Problem
Deleting a git provider failed with "Cannot delete provider GitLab because it has 1 connection(s)" while the same page rendered "No connections found" — a dead end with nothing to act on.
Root cause is a mismatch between two queries:
get_user_connections_paginated,user_id = caller+is_active = true) and filtered client-side by provider.delete_providercounted every active connection of the provider, regardless of owner.So any connection owned by another user — or with
user_id = NULL— made the provider permanently undeletable and permanently un-findable. Connection deletes hit the same wall: the blocking row was invisible, and the UI'sonErrorthrew away the server's explanation.Fix
delete_providernow blocks only on projects that actually deploy from the provider (naming them), and cascades the provider's connections + repositories — the same semantics as the existing/safe-deleteroute.get_all_provider_connections(no owner/active filter), so a deactivated connection used by a project is no longer skipped by the safety check while still being cascaded away.GET /git-providers/{id}/connectionsreturns all of the provider's connections, and the detail page uses it instead of the per-user list — the list can no longer contradict the delete error. Inactive rows already render an "Inactive" badge.delete_connectionnames the blocking projects; the UI now shows the Problem Detailsdetailinstead of a bare "Failed to delete connection".Evidence
New regression test
delete_provider_removes_connections_the_caller_cannot_seeseeds a provider with an ownerless active connection + a deactivated one and deletes it.Against the old guard it reproduces the reported error verbatim:
```
provider with no project usage should delete: InvalidConfiguration("Cannot delete provider GitLab because it has 1 connection(s)")
test result: FAILED. 0 passed; 1 failed
```
With the fix:
```
$ cargo test -p temps-git --lib
test result: ok. 299 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
```
```
$ cargo clippy -p temps-git --all-targets -- -D warnings
Finished
devprofile ... (no warnings)$ bunx tsc --noEmit -p tsconfig.json # web/
(clean)
```
Note: one earlier full-suite run failed at
TestDatabase::with_migrations()(testcontainer startup), green on rerun — unrelated to this change.No API shape change, so no SDK regen or CLI parity work is required.