From f6b14c65af10fad196ebeb8e4f84da1324a625b2 Mon Sep 17 00:00:00 2001 From: Gabriel Adrian Samfira Date: Sat, 21 Mar 2026 11:15:51 +0200 Subject: [PATCH] Send forge type as part of the Delete() op for creds When removing credentials we need to also send forge type, as the ID is uint and may clash if we don't also send the forge type. This was a leftover from when we added additional forges. Signed-off-by: Gabriel Adrian Samfira --- database/sql/gitea.go | 7 +------ database/sql/github.go | 2 +- database/watcher/watcher_store_test.go | 4 ++-- webapp/src/lib/stores/eager-cache.ts | 5 ++++- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/database/sql/gitea.go b/database/sql/gitea.go index 4f9ef13c..c7455d46 100644 --- a/database/sql/gitea.go +++ b/database/sql/gitea.go @@ -18,7 +18,6 @@ import ( "context" "errors" "fmt" - "log/slog" "gorm.io/gorm" @@ -472,14 +471,10 @@ func (s *sqlDatabase) DeleteGiteaCredentials(ctx context.Context, id uint) (err var creds GiteaCredentials defer func() { if err == nil { - forgeCreds, innerErr := s.sqlGiteaToCommonForgeCredentials(creds) - if innerErr != nil { - slog.ErrorContext(ctx, "converting gitea credentials", "error", innerErr) - } if creds.ID == 0 || creds.Name == "" { return } - s.sendNotify(common.GiteaCredentialsEntityType, common.DeleteOperation, forgeCreds) + s.sendNotify(common.GiteaCredentialsEntityType, common.DeleteOperation, params.ForgeCredentials{ID: creds.ID, Name: creds.Name, ForgeType: params.GiteaEndpointType}) } }() err = s.conn.Transaction(func(tx *gorm.DB) error { diff --git a/database/sql/github.go b/database/sql/github.go index c5ceef75..fa587966 100644 --- a/database/sql/github.go +++ b/database/sql/github.go @@ -488,7 +488,7 @@ func (s *sqlDatabase) DeleteGithubCredentials(ctx context.Context, id uint) (err var name string defer func() { if err == nil { - s.sendNotify(common.GithubCredentialsEntityType, common.DeleteOperation, params.ForgeCredentials{ID: id, Name: name}) + s.sendNotify(common.GithubCredentialsEntityType, common.DeleteOperation, params.ForgeCredentials{ID: id, Name: name, ForgeType: params.GithubEndpointType}) } }() err = s.conn.Transaction(func(tx *gorm.DB) error { diff --git a/database/watcher/watcher_store_test.go b/database/watcher/watcher_store_test.go index 799c11cc..708b130d 100644 --- a/database/watcher/watcher_store_test.go +++ b/database/watcher/watcher_store_test.go @@ -919,8 +919,8 @@ func (s *WatcherStoreTestSuite) TestGithubCredentialsWatcher() { s.Require().Equal(common.ChangePayload{ EntityType: common.GithubCredentialsEntityType, Operation: common.DeleteOperation, - // We only get the ID and Name of the deleted entity - Payload: params.ForgeCredentials{ID: ghCred.ID, Name: ghCred.Name}, + // We only get the ID, Name and ForgeType of the deleted entity + Payload: params.ForgeCredentials{ID: ghCred.ID, Name: ghCred.Name, ForgeType: params.GithubEndpointType}, }, event) case <-time.After(1 * time.Second): s.T().Fatal("expected payload not received") diff --git a/webapp/src/lib/stores/eager-cache.ts b/webapp/src/lib/stores/eager-cache.ts index 1b226cd6..b41a428a 100644 --- a/webapp/src/lib/stores/eager-cache.ts +++ b/webapp/src/lib/stores/eager-cache.ts @@ -303,7 +303,10 @@ class EagerCacheManager { const credentials = [...state.credentials]; const cred = event.payload as ForgeCredentials; - const matchCred = (c: ForgeCredentials) => c.id === cred.id && c.forge_type === cred.forge_type; + // Derive forge_type from the WebSocket entity type if missing from payload + // (backend delete events may send sparse payloads without forge_type) + const forgeType = cred.forge_type || (event['entity-type'] === 'github_credentials' ? 'github' : 'gitea'); + const matchCred = (c: ForgeCredentials) => c.id === cred.id && c.forge_type === forgeType; if (event.operation === 'create') { const existingIndex = credentials.findIndex(matchCred);