Files
anouma/lib/analytics/session.ts
T

30 lines
1.1 KiB
TypeScript

import type { Payload } from "payload";
import { randomUUID } from "node:crypto";
const SESSION_IDLE_WINDOW_MS = 30 * 60 * 1000;
/**
* Groups events into sessions without any client-side identifier: looks up
* the most recent event from the same `visitorHash` within the last 30
* minutes and reuses its sessionId, or mints a new one. One extra indexed
* read per tracked request - acceptable at this site's traffic volume, and
* simpler/safer than trying to hold a lock across an unauthenticated,
* high-frequency public endpoint (unlike lib/booking/lock.ts's advisory
* lock, an occasional extra spurious session here has no correctness
* consequences worth the added complexity).
*/
export async function resolveSessionId(payload: Payload, visitorHash: string): Promise<string> {
const since = new Date(Date.now() - SESSION_IDLE_WINDOW_MS).toISOString();
const { docs } = await payload.find({
collection: "analytics-events",
where: {
and: [{ visitorHash: { equals: visitorHash } }, { createdAt: { greater_than_equal: since } }],
},
sort: "-createdAt",
limit: 1,
depth: 0,
});
return docs[0]?.sessionId ?? randomUUID();
}