Skip to content

Commit 0223f5e

Browse files
committed
perf(analytics): pre-fetch video data once and gate first-view email on firstViewEmailSentAt
1 parent c37ec53 commit 0223f5e

File tree

1 file changed

+67
-45
lines changed
  • apps/web/app/api/analytics/track

1 file changed

+67
-45
lines changed

apps/web/app/api/analytics/track/route.ts

Lines changed: 67 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,34 @@ export async function POST(request: NextRequest) {
100100
},
101101
});
102102

103-
if (userId && (!body.ownerId || userId === body.ownerId)) {
104-
const [videoRecord] = yield* Effect.tryPromise(() =>
105-
db()
106-
.select({ ownerId: videos.ownerId })
107-
.from(videos)
108-
.where(eq(videos.id, Video.VideoId.make(body.videoId)))
109-
.limit(1),
110-
).pipe(Effect.orElseSucceed(() => [] as { ownerId: string }[]));
111-
112-
if (videoRecord && userId === videoRecord.ownerId) {
113-
return;
114-
}
103+
const [videoRecord] = yield* Effect.tryPromise(() =>
104+
db()
105+
.select({
106+
ownerId: videos.ownerId,
107+
firstViewEmailSentAt: videos.firstViewEmailSentAt,
108+
videoName: videos.name,
109+
})
110+
.from(videos)
111+
.where(eq(videos.id, Video.VideoId.make(body.videoId)))
112+
.limit(1),
113+
).pipe(
114+
Effect.orElseSucceed(
115+
() =>
116+
[] as {
117+
ownerId: string;
118+
firstViewEmailSentAt: Date | null;
119+
videoName: string;
120+
}[],
121+
),
122+
);
123+
124+
if (videoRecord && userId === videoRecord.ownerId) {
125+
return;
115126
}
116127

117128
const tenantId =
118129
body.orgId ||
130+
videoRecord?.ownerId ||
119131
body.ownerId ||
120132
(hostname ? `domain:${hostname}` : "public");
121133

@@ -139,46 +151,54 @@ export async function POST(request: NextRequest) {
139151
},
140152
]);
141153

154+
const shouldSendFirstViewEmail =
155+
videoRecord && !videoRecord.firstViewEmailSentAt;
156+
142157
if (userId) {
143-
yield* Effect.forkDaemon(
158+
if (shouldSendFirstViewEmail) {
159+
yield* Effect.forkDaemon(
160+
Effect.tryPromise(() =>
161+
sendFirstViewEmail({
162+
videoId: body.videoId,
163+
viewerUserId: userId,
164+
isAnonymous: false,
165+
}),
166+
).pipe(
167+
Effect.catchAll((error) => {
168+
console.error("Failed to send first view email:", error);
169+
return Effect.void;
170+
}),
171+
),
172+
);
173+
}
174+
}
175+
176+
if (!userId && sessionId) {
177+
const anonName = getAnonymousName(sessionId);
178+
const location =
179+
city && country ? `${city}, ${country}` : city || country || null;
180+
181+
const effects: Effect.Effect<void, never, never>[] = [
144182
Effect.tryPromise(() =>
145-
sendFirstViewEmail({
183+
createAnonymousViewNotification({
146184
videoId: body.videoId,
147-
viewerUserId: userId,
148-
isAnonymous: false,
185+
sessionId,
186+
anonName,
187+
location,
149188
}),
150189
).pipe(
151190
Effect.catchAll((error) => {
152-
console.error("Failed to send first view email:", error);
191+
console.error(
192+
"Failed to create anonymous view notification:",
193+
error,
194+
);
153195
return Effect.void;
154196
}),
155197
),
156-
);
157-
}
198+
];
158199

159-
if (!userId && sessionId) {
160-
const anonName = getAnonymousName(sessionId);
161-
const location =
162-
city && country ? `${city}, ${country}` : city || country || null;
163-
164-
yield* Effect.forkDaemon(
165-
Effect.all([
166-
Effect.tryPromise(() =>
167-
createAnonymousViewNotification({
168-
videoId: body.videoId,
169-
sessionId,
170-
anonName,
171-
location,
172-
}),
173-
).pipe(
174-
Effect.catchAll((error) => {
175-
console.error(
176-
"Failed to create anonymous view notification:",
177-
error,
178-
);
179-
return Effect.void;
180-
}),
181-
),
200+
if (shouldSendFirstViewEmail) {
201+
effects.push(
182202
Effect.tryPromise(() =>
183203
sendFirstViewEmail({
184204
videoId: body.videoId,
@@ -191,11 +211,13 @@ export async function POST(request: NextRequest) {
191211
return Effect.void;
192212
}),
193213
),
194-
]),
195-
);
214+
);
215+
}
216+
217+
yield* Effect.forkDaemon(Effect.all(effects));
196218
}
197219

198-
if (!userId && !sessionId) {
220+
if (!userId && !sessionId && shouldSendFirstViewEmail) {
199221
yield* Effect.forkDaemon(
200222
Effect.tryPromise(() =>
201223
sendFirstViewEmail({

0 commit comments

Comments
 (0)