Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,36 @@ import type { WebsocketsError } from "~/features/shared/errors.js";
import { WebsocketServiceError } from "~/features/shared/errors.js";
import { ConnectionRegistry } from "~/features/ConnectionRegistry/abstractions.js";

const RECENT_CONNECTION_WINDOW_MS = 3 * 60 * 60 * 1000;

/**
* Parse a stored `connectedOn` value to a UTC epoch (ms).
*
* `connectedOn` is written as a UTC ISO string, but SQL `datetime` columns hand it back in a
* driver-specific shape: a `Date` object (mysql2) or a `T`/`Z`-less string like "2026-08-04 17:02:06".
* We normalize the string form back to UTC (safe — the stored wall-clock is UTC) so recency checks
* don't depend on the driver's formatting. Returns NaN for anything unparseable.
*/
const connectedOnToEpoch = (value: unknown): number => {
if (value instanceof Date) {
return value.getTime();
}
if (typeof value === "string") {
const normalized =
value.includes(" ") && !value.includes("T") ? `${value.replace(" ", "T")}Z` : value;
return new Date(normalized).getTime();
}
return NaN;
};

const isRecentConnection = (
connection: WebsocketsListConnectionsUseCase.RegistryData,
cutoff: number
): boolean => {
const epoch = connectedOnToEpoch(connection.connectedOn);
return Number.isFinite(epoch) && epoch >= cutoff;
};

class ListConnectionsUseCaseImpl implements WebsocketsListConnectionsUseCase.Interface {
public constructor(private readonly registry: ConnectionRegistry.Interface) {}

Expand All @@ -27,8 +57,9 @@ class ListConnectionsUseCaseImpl implements WebsocketsListConnectionsUseCase.Int
return Result.fail(new WebsocketServiceError(error as Error));
}

const threeHoursAgo = new Date(Date.now() - 3 * 60 * 60 * 1000).toISOString();
connections = connections.filter(c => c.connectedOn >= threeHoursAgo);
// Keep only connections seen within the recency window.
const cutoff = Date.now() - RECENT_CONNECTION_WINDOW_MS;
connections = connections.filter(c => isRecentConnection(c, cutoff));

return Result.ok(connections);
}
Expand Down
Loading