@@ -5,6 +5,7 @@ import { githubIntegration } from '~/server/database/schema/feedback'
55import { createErrorResponse , createSuccessResponse , ErrorCode } from '~/server/utils/response'
66import { requireProjectCategoryAccess } from '~/server/utils/project-categories'
77import { validateBody } from '~/server/utils/validation'
8+ import { registerGitHubWebhook , deleteGitHubWebhook } from '~/server/utils/github'
89
910const updateGithubIntegrationSchema = z . object ( {
1011 repoFullName : z
@@ -46,6 +47,8 @@ export default defineEventHandler(async (event) => {
4647
4748 const now = new Date ( )
4849
50+ const webhookUrl = `${ getRequestURL ( event ) . origin } /api/github/webhook`
51+
4952 if ( existing ) {
5053 const [ conflict ] = await db
5154 . select ( )
@@ -61,12 +64,26 @@ export default defineEventHandler(async (event) => {
6164 } )
6265 }
6366
67+ // Re-register webhook if the repo has changed
68+ const repoChanged = existing . owner !== owner || existing . repo !== repo
69+ const tokenForWebhook = ( accessToken !== null ? accessToken : existing . accessToken ) as string | null
70+ let webhookFields : { webhookId : string ; webhookSecret : string } | null = null
71+
72+ if ( repoChanged && tokenForWebhook ) {
73+ // Delete webhook from old repo (best-effort)
74+ if ( existing . webhookId && existing . accessToken ) {
75+ await deleteGitHubWebhook ( existing . owner , existing . repo , existing . webhookId , existing . accessToken )
76+ }
77+ webhookFields = await registerGitHubWebhook ( owner , repo , tokenForWebhook , webhookUrl )
78+ }
79+
6480 const [ updated ] = await db
6581 . update ( githubIntegration )
6682 . set ( {
6783 owner,
6884 repo,
6985 ...( accessToken !== null && { accessToken } ) ,
86+ ...( webhookFields && { webhookId : webhookFields . webhookId , webhookSecret : webhookFields . webhookSecret } ) ,
7087 ...( body . syncEnabled !== undefined && { syncEnabled : body . syncEnabled } ) ,
7188 ...( body . autoCreateIssues !== undefined && { autoCreateIssues : body . autoCreateIssues } ) ,
7289 ...( body . autoSyncStatus !== undefined && { autoSyncStatus : body . autoSyncStatus } ) ,
@@ -91,6 +108,7 @@ export default defineEventHandler(async (event) => {
91108 autoCreateIssues : updated . autoCreateIssues ,
92109 autoSyncStatus : updated . autoSyncStatus ,
93110 hasAccessToken : Boolean ( updated . accessToken ) ,
111+ webhookRegistered : Boolean ( updated . webhookId ) ,
94112 updatedAt : updated . updatedAt ,
95113 } )
96114 }
@@ -109,6 +127,8 @@ export default defineEventHandler(async (event) => {
109127 } )
110128 }
111129
130+ const webhook = await registerGitHubWebhook ( owner , repo , accessToken ! , webhookUrl )
131+
112132 const [ created ] = await db
113133 . insert ( githubIntegration )
114134 . values ( {
@@ -117,6 +137,8 @@ export default defineEventHandler(async (event) => {
117137 owner,
118138 repo,
119139 accessToken : accessToken ! ,
140+ webhookId : webhook . webhookId ,
141+ webhookSecret : webhook . webhookSecret ,
120142 syncEnabled : body . syncEnabled ?? true ,
121143 autoCreateIssues : body . autoCreateIssues ?? false ,
122144 autoSyncStatus : body . autoSyncStatus ?? true ,
@@ -142,6 +164,7 @@ export default defineEventHandler(async (event) => {
142164 autoCreateIssues : created . autoCreateIssues ,
143165 autoSyncStatus : created . autoSyncStatus ,
144166 hasAccessToken : Boolean ( created . accessToken ) ,
167+ webhookRegistered : Boolean ( created . webhookId ) ,
145168 updatedAt : created . updatedAt ,
146169 } )
147170} )
0 commit comments