Skip to content

Commit aeaa751

Browse files
authored
fix: dashboard subscribers notification runtime (#2316)
* fix: runtime * fix: nullish
1 parent 3a8ab6b commit aeaa751

11 files changed

Lines changed: 58 additions & 42 deletions

File tree

apps/dashboard/src/app/(dashboard)/status-pages/[id]/maintenances/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export default function Page() {
3232
}),
3333
);
3434
const sendMaintenanceUpdateMutation = useMutation(
35-
trpc.maintenance.notify.mutationOptions(),
35+
trpc.subscriberNotification.maintenance.mutationOptions(),
3636
);
3737
const createMaintenanceMutation = useMutation(
3838
trpc.maintenance.new.mutationOptions({

apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/[reportId]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export default function Page() {
4242
);
4343

4444
const sendStatusReportUpdateMutation = useMutation(
45-
trpc.statusReport.notify.mutationOptions(),
45+
trpc.subscriberNotification.statusReport.mutationOptions(),
4646
);
4747

4848
const createStatusReportUpdateMutation = useMutation(

apps/dashboard/src/app/(dashboard)/status-pages/[id]/status-reports/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default function Page() {
3434
trpc.statusReport.list.queryOptions({ pageId: Number.parseInt(id) }),
3535
);
3636
const sendStatusReportUpdateMutation = useMutation(
37-
trpc.statusReport.notify.mutationOptions(),
37+
trpc.subscriberNotification.statusReport.mutationOptions(),
3838
);
3939
const createStatusReportMutation = useMutation(
4040
trpc.statusReport.create.mutationOptions({

apps/dashboard/src/components/data-table/status-report-updates/data-table.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export function DataTable({
4949
const { id } = useParams<{ id: string }>();
5050
const queryClient = useQueryClient();
5151
const sendStatusReportUpdateMutation = useMutation(
52-
trpc.statusReport.notify.mutationOptions(),
52+
trpc.subscriberNotification.statusReport.mutationOptions(),
5353
);
5454
const createStatusReportUpdateMutation = useMutation(
5555
trpc.statusReport.createStatusReportUpdate.mutationOptions({

apps/dashboard/src/components/data-table/status-reports/data-table-row-actions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function DataTableRowActions({ row }: DataTableRowActionsProps) {
5555
const currentImpacts = currentImpactsFromUpdates(row.original.updates);
5656
const nextStatus = getNextStatus(row.original.status);
5757
const sendStatusReportUpdateMutation = useMutation(
58-
trpc.statusReport.notify.mutationOptions(),
58+
trpc.subscriberNotification.statusReport.mutationOptions(),
5959
);
6060
const updateStatusReportMutation = useMutation(
6161
trpc.statusReport.updateStatus.mutationOptions({

apps/dashboard/src/lib/trpc/shared.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const lambdas = [
4040
"apiKeyRouter",
4141
"integrationRouter",
4242
"blob",
43+
"subscriberNotification",
4344
];
4445

4546
export const endingLink = (opts?: {

packages/api/src/lambda.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { blobRouter } from "./router/blob";
33
import { emailRouter } from "./router/email";
44
import { integrationRouter } from "./router/integration";
55
import { stripeRouter } from "./router/stripe";
6+
import { subscriberNotificationRouter } from "./router/subscriber-notification";
67
import { createTRPCRouter } from "./trpc";
78
// Deployed to /trpc/lambda/**
89
export const lambdaRouter = createTRPCRouter({
@@ -11,6 +12,7 @@ export const lambdaRouter = createTRPCRouter({
1112
apiKeyRouter: apiKeyRouter,
1213
integrationRouter: integrationRouter,
1314
blob: blobRouter,
15+
subscriberNotification: subscriberNotificationRouter,
1416
});
1517

1618
export { stripe } from "./router/stripe/shared";

packages/api/src/router/maintenance.ts

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
createMaintenance,
55
deleteMaintenance,
66
listMaintenances,
7-
notifyMaintenance,
87
updateMaintenance,
98
} from "@openstatus/services/maintenance";
109
import { z } from "zod";
@@ -66,21 +65,6 @@ export const maintenanceRouter = createTRPCRouter({
6665
}
6766
}),
6867

69-
notify: protectedProcedure
70-
.meta({ track: Events.NotifyMaintenance })
71-
.input(z.object({ id: z.number() }))
72-
.mutation(async ({ ctx, input }) => {
73-
try {
74-
await notifyMaintenance({
75-
ctx: toServiceCtx(ctx),
76-
input: { maintenanceId: input.id },
77-
});
78-
return { success: true };
79-
} catch (err) {
80-
toTRPCError(err);
81-
}
82-
}),
83-
8468
new: protectedProcedure
8569
.meta({ track: Events.CreateMaintenance })
8670
.input(

packages/api/src/router/statusReport.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
deleteStatusReportUpdate,
1111
getStatusReport,
1212
listStatusReports,
13-
notifyStatusReport,
1413
updateStatusReport,
1514
updateStatusReportUpdate,
1615
} from "@openstatus/services/status-report";
@@ -80,8 +79,9 @@ export const statusReportRouter = createTRPCRouter({
8079
message: input.message,
8180
},
8281
});
83-
// Notification is a separate, client-driven step (statusReport.notify)
84-
// so creation and dispatch stay split.
82+
// Notification is a separate, client-driven step
83+
// (subscriberNotification.statusReport) so creation and dispatch stay
84+
// split — dispatch must run on lambda, this router is Edge-served.
8585
return { ...initialUpdate, notifySubscribers: input.notifySubscribers };
8686
} catch (err) {
8787
toTRPCError(err);
@@ -113,21 +113,6 @@ export const statusReportRouter = createTRPCRouter({
113113
}
114114
}),
115115

116-
notify: protectedProcedure
117-
.meta({ track: Events.NotifyReport })
118-
.input(z.object({ id: z.number() }))
119-
.mutation(async ({ ctx, input }) => {
120-
try {
121-
await notifyStatusReport({
122-
ctx: toServiceCtx(ctx),
123-
input: { statusReportUpdateId: input.id },
124-
});
125-
return { success: true };
126-
} catch (err) {
127-
toTRPCError(err);
128-
}
129-
}),
130-
131116
updateStatusReportUpdate: protectedProcedure
132117
.meta({ track: Events.UpdateReportUpdate })
133118
.input(updateStatusReportUpdateTRPCInput)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Events } from "@openstatus/analytics";
2+
import { notifyMaintenance } from "@openstatus/services/maintenance";
3+
import { notifyStatusReport } from "@openstatus/services/status-report";
4+
import { z } from "zod";
5+
6+
import { toServiceCtx, toTRPCError } from "../service-adapter";
7+
import { createTRPCRouter, protectedProcedure } from "../trpc";
8+
9+
// Subscriber dispatch fans out across every channel (email + webhook), so it
10+
// must run on the lambda runtime: the email channel (Resend + react-email
11+
// render) can't run on Edge and would silently drop emails while webhooks
12+
// still go out. Kept off the statusReport/maintenance routers, which are
13+
// Edge-served — see the `lambdas` list in the dashboard tRPC client.
14+
export const subscriberNotificationRouter = createTRPCRouter({
15+
statusReport: protectedProcedure
16+
.meta({ track: Events.NotifyReport })
17+
.input(z.object({ id: z.number() }))
18+
.mutation(async ({ ctx, input }) => {
19+
try {
20+
await notifyStatusReport({
21+
ctx: toServiceCtx(ctx),
22+
input: { statusReportUpdateId: input.id },
23+
});
24+
return { success: true };
25+
} catch (err) {
26+
toTRPCError(err);
27+
}
28+
}),
29+
30+
maintenance: protectedProcedure
31+
.meta({ track: Events.NotifyMaintenance })
32+
.input(z.object({ id: z.number() }))
33+
.mutation(async ({ ctx, input }) => {
34+
try {
35+
await notifyMaintenance({
36+
ctx: toServiceCtx(ctx),
37+
input: { maintenanceId: input.id },
38+
});
39+
return { success: true };
40+
} catch (err) {
41+
toTRPCError(err);
42+
}
43+
}),
44+
});

0 commit comments

Comments
 (0)