Skip to content

Commit b2915f4

Browse files
committed
refactor: Simplify click URL resolution logic
1 parent cf3d312 commit b2915f4

2 files changed

Lines changed: 26 additions & 26 deletions

File tree

apps/server/src/services/event-hook-service.ts

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -588,29 +588,26 @@ export class EventHookService {
588588
eventType: context.eventType,
589589
};
590590

591-
// Build click URL with deep-link if project context is available
592-
let clickUrl = action.clickUrl;
593-
if (!clickUrl && endpoint.defaultClickUrl) {
594-
clickUrl = endpoint.defaultClickUrl;
595-
// If we have a project path and the click URL looks like the server URL,
596-
// append deep-link path
597-
if (context.projectPath && clickUrl) {
598-
try {
599-
const url = new URL(clickUrl);
600-
// Add featureId as query param for deep linking to board with feature output modal
601-
if (context.featureId) {
602-
url.pathname = '/board';
603-
url.searchParams.set('featureId', context.featureId);
604-
} else if (context.projectPath) {
605-
url.pathname = '/board';
606-
}
607-
clickUrl = url.toString();
608-
} catch (error) {
609-
// If URL parsing fails, log warning and use as-is
610-
logger.warn(
611-
`Failed to parse defaultClickUrl "${clickUrl}" for deep linking: ${error instanceof Error ? error.message : String(error)}`
612-
);
591+
// Resolve click URL: action-level overrides endpoint default
592+
let clickUrl = action.clickUrl || endpoint.defaultClickUrl;
593+
594+
// Apply deep-link parameters to the resolved click URL
595+
if (clickUrl && context.projectPath) {
596+
try {
597+
const url = new URL(clickUrl);
598+
// Add featureId as query param for deep linking to board with feature output modal
599+
if (context.featureId) {
600+
url.pathname = '/board';
601+
url.searchParams.set('featureId', context.featureId);
602+
} else {
603+
url.pathname = '/board';
613604
}
605+
clickUrl = url.toString();
606+
} catch (error) {
607+
// If URL parsing fails, log warning and use as-is
608+
logger.warn(
609+
`Failed to parse click URL "${clickUrl}" for deep linking: ${error instanceof Error ? error.message : String(error)}`
610+
);
614611
}
615612
}
616613

apps/server/tests/unit/services/event-hook-service.test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,9 @@ describe('EventHookService', () => {
12461246
const options = mockFetch.mock.calls[0][1];
12471247
// Hook values should override endpoint defaults
12481248
expect(options.headers['Tags']).toBe('override-emoji,override-tag');
1249-
expect(options.headers['Click']).toBe('https://override.example.com');
1249+
// Click URL uses hook-specific base URL with deep link params applied
1250+
expect(options.headers['Click']).toContain('https://override.example.com/board');
1251+
expect(options.headers['Click']).toContain('featureId=feat-1');
12501252
expect(options.headers['Priority']).toBe('5');
12511253
});
12521254

@@ -1359,7 +1361,7 @@ describe('EventHookService', () => {
13591361
expect(clickUrl).not.toContain('featureId=');
13601362
});
13611363

1362-
it('should use hook-specific click URL overriding default with featureId', async () => {
1364+
it('should apply deep link params to hook-specific click URL', async () => {
13631365
mockFetch.mockResolvedValueOnce({
13641366
ok: true,
13651367
status: 200,
@@ -1409,8 +1411,9 @@ describe('EventHookService', () => {
14091411
const options = mockFetch.mock.calls[0][1];
14101412
const clickUrl = options.headers['Click'];
14111413

1412-
// Should use the hook-specific click URL (not modified with featureId since it's a custom URL)
1413-
expect(clickUrl).toBe('https://custom.example.com/custom-page');
1414+
// Should use the hook-specific click URL with deep link params applied
1415+
expect(clickUrl).toContain('https://custom.example.com/board');
1416+
expect(clickUrl).toContain('featureId=feat-789');
14141417
});
14151418

14161419
it('should preserve existing query params when adding featureId', async () => {

0 commit comments

Comments
 (0)