diff --git a/src/__tests__/e2e/support/page-objects/DashboardPage.ts b/src/__tests__/e2e/support/page-objects/DashboardPage.ts index 758c7dd010..1a4110e1bd 100644 --- a/src/__tests__/e2e/support/page-objects/DashboardPage.ts +++ b/src/__tests__/e2e/support/page-objects/DashboardPage.ts @@ -36,11 +36,11 @@ export class DashboardPage { const isTasksVisible = await tasksLink.isVisible().catch(() => false); if (!isTasksVisible) { await buildButton.click(); - await tasksLink.waitFor({ state: 'visible', timeout: 5000 }); + await tasksLink.waitFor({ state: 'visible', timeout: 10000 }); } await tasksLink.click(); - await this.page.waitForURL(/\/w\/.*\/tasks/, { timeout: 10000 }); + await this.page.waitForURL(/\/w\/.*\/tasks/, { timeout: 30000 }); } /** @@ -55,11 +55,11 @@ export class DashboardPage { const isPlanVisible = await planLink.isVisible().catch(() => false); if (!isPlanVisible) { await buildButton.click(); - await planLink.waitFor({ state: 'visible', timeout: 5000 }); + await planLink.waitFor({ state: 'visible', timeout: 10000 }); } await planLink.click(); - await this.page.waitForURL(/\/w\/.*\/plan/, { timeout: 10000 }); + await this.page.waitForURL(/\/w\/.*\/plan/, { timeout: 30000 }); } /** @@ -78,7 +78,7 @@ export class DashboardPage { } await recommendationsLink.click(); - await this.page.waitForURL(/\/w\/.*\/recommendations/, { timeout: 10000 }); + await this.page.waitForURL(/\/w\/.*\/recommendations/, { timeout: 30000 }); } /** @@ -97,7 +97,7 @@ export class DashboardPage { } await janitorsLink.click(); - await this.page.waitForURL(/\/w\/.*\/janitors/, { timeout: 10000 }); + await this.page.waitForURL(/\/w\/.*\/janitors/, { timeout: 30000 }); } /** @@ -122,7 +122,7 @@ export class DashboardPage { */ async goToCapacity(): Promise { await this.page.locator(selectors.navigation.capacityLink).click(); - await this.page.waitForURL(/\/w\/.*\/capacity/, { timeout: 10000 }); + await this.page.waitForURL(/\/w\/.*\/capacity/, { timeout: 30000 }); } /** diff --git a/src/__tests__/integration/api/chat-response-notifications.test.ts b/src/__tests__/integration/api/chat-response-notifications.test.ts index 683f6c5bb9..4f09e91687 100644 --- a/src/__tests__/integration/api/chat-response-notifications.test.ts +++ b/src/__tests__/integration/api/chat-response-notifications.test.ts @@ -73,6 +73,7 @@ describe("POST /api/chat/response — plan artifact notifications", () => { ownerId: owner.id, name: "Test Workspace", slug: "test-ws-chat-notif", + sphinxEnabled: true, }); feature = await db.feature.create({ data: { diff --git a/src/__tests__/integration/api/stakwork/webhook-halted-notification.test.ts b/src/__tests__/integration/api/stakwork/webhook-halted-notification.test.ts index 44cb228173..57dd639111 100644 --- a/src/__tests__/integration/api/stakwork/webhook-halted-notification.test.ts +++ b/src/__tests__/integration/api/stakwork/webhook-halted-notification.test.ts @@ -74,6 +74,7 @@ describe("POST /api/stakwork/webhook — WORKFLOW_HALTED notification", () => { workspace = await createTestWorkspace({ ownerId: user.id, slug: generateUniqueSlug("ws-halted"), + sphinxEnabled: true, }); await db.workspaceMember.create({ diff --git a/src/__tests__/integration/services/feature-assignment-notification.test.ts b/src/__tests__/integration/services/feature-assignment-notification.test.ts index 5c422b2186..a9812bb917 100644 --- a/src/__tests__/integration/services/feature-assignment-notification.test.ts +++ b/src/__tests__/integration/services/feature-assignment-notification.test.ts @@ -51,6 +51,7 @@ describe("FEATURE_ASSIGNED notification", () => { ownerId: owner.id, name: "Test Workspace", slug: "test-ws-feat-assign", + sphinxEnabled: true, }); await db.workspaceMember.create({ diff --git a/src/__tests__/integration/services/feature-completed-notification.test.ts b/src/__tests__/integration/services/feature-completed-notification.test.ts index 2fcf4dde79..fca8cf1d78 100644 --- a/src/__tests__/integration/services/feature-completed-notification.test.ts +++ b/src/__tests__/integration/services/feature-completed-notification.test.ts @@ -49,6 +49,7 @@ describe("FEATURE_COMPLETED notification", () => { ownerId: owner.id, name: "Test Workspace", slug: "test-ws-feat-complete", + sphinxEnabled: true, }); await db.workspaceMember.create({ diff --git a/src/__tests__/integration/services/task-assignment-notification.test.ts b/src/__tests__/integration/services/task-assignment-notification.test.ts index 13c7db48a7..81e875f6f1 100644 --- a/src/__tests__/integration/services/task-assignment-notification.test.ts +++ b/src/__tests__/integration/services/task-assignment-notification.test.ts @@ -45,11 +45,13 @@ describe("TASK_ASSIGNED notification", () => { data: { email: "assignee@test.com", name: "Assignee", lightningPubkey: "test-pubkey-assignee" }, }); - const { createTestWorkspace } = await import("@/__tests__/support/factories/workspace.factory"); - workspace = await createTestWorkspace({ - ownerId: owner.id, - name: "Test Workspace", - slug: "test-ws-task-assign", + workspace = await db.workspace.create({ + data: { + name: "Test Workspace", + slug: "test-ws-task-assign", + ownerId: owner.id, + sphinxEnabled: true, + }, }); await db.workspaceMember.create({ diff --git a/src/__tests__/support/factories/github-webhook.factory.ts b/src/__tests__/support/factories/github-webhook.factory.ts index 1cc95590cb..22b805f1d6 100644 --- a/src/__tests__/support/factories/github-webhook.factory.ts +++ b/src/__tests__/support/factories/github-webhook.factory.ts @@ -52,6 +52,7 @@ export async function createWebhookTestScenario(options?: CreateWebhookTestScena name: `Test Workspace ${workspaceId}`, slug: `test-workspace-${workspaceId.toLowerCase()}`, ownerId: user.id, + sphinxEnabled: true, }, }); diff --git a/src/__tests__/support/factories/workspace.factory.ts b/src/__tests__/support/factories/workspace.factory.ts index 90e6d0f90a..a606f3a4f3 100644 --- a/src/__tests__/support/factories/workspace.factory.ts +++ b/src/__tests__/support/factories/workspace.factory.ts @@ -31,6 +31,7 @@ export interface CreateTestWorkspaceOptions { stakworkApiKey?: string | null; sourceControlOrgId?: string | null; repositoryDraft?: string | null; + sphinxEnabled?: boolean; /** If true, return existing workspace if slug matches */ idempotent?: boolean; } @@ -73,6 +74,7 @@ export async function createTestWorkspace( stakworkApiKey: options.stakworkApiKey ?? null, sourceControlOrgId: options.sourceControlOrgId ?? null, repositoryDraft: options.repositoryDraft ?? null, + sphinxEnabled: options.sphinxEnabled ?? false, }, }); } diff --git a/src/__tests__/unit/services/notifications.test.ts b/src/__tests__/unit/services/notifications.test.ts index 548f245a01..9b93c3b96c 100644 --- a/src/__tests__/unit/services/notifications.test.ts +++ b/src/__tests__/unit/services/notifications.test.ts @@ -43,7 +43,7 @@ const baseInput = { const userWithPubkey = { lightningPubkey: "alice-pubkey", sphinxRouteHint: null, iosDeviceToken: null }; const userWithPubkeyAndToken = { lightningPubkey: "alice-pubkey", sphinxRouteHint: null, iosDeviceToken: "device-token-abc" }; const userWithoutPubkey = { lightningPubkey: null, sphinxRouteHint: null, iosDeviceToken: null }; -const mockWorkspace = { slug: "test-workspace" }; +const mockWorkspace = { slug: "test-workspace", sphinxEnabled: true }; const mockRecord = { id: "notif-1", diff --git a/src/services/notifications.ts b/src/services/notifications.ts index eeb3c6bb4e..e02c55b740 100644 --- a/src/services/notifications.ts +++ b/src/services/notifications.ts @@ -42,7 +42,7 @@ export async function createAndSendNotification(input: { }), db.workspace.findUnique({ where: { id: input.workspaceId }, - select: { slug: true }, + select: { slug: true, sphinxEnabled: true }, }), ]); @@ -73,7 +73,7 @@ export async function createAndSendNotification(input: { const decryptedPubkey = targetUser?.lightningPubkey ? encryptionService.decryptField("lightningPubkey", targetUser.lightningPubkey) : null; - const dmReady = isDirectMessageConfigured() && !!decryptedPubkey; + const dmReady = isDirectMessageConfigured() && !!decryptedPubkey && (workspace?.sphinxEnabled ?? false); // 4. Always insert a row — use SKIPPED when DM is not ready const record = await db.notificationTrigger.create({