review fixes

This commit is contained in:
x032205
2025-10-10 14:37:52 -04:00
parent e752391dbf
commit 2f01d096c6
7 changed files with 36 additions and 22 deletions

View File

@@ -31,6 +31,7 @@ export const gatewayV2DalFactory = (db: TDbClient) => {
if (isHeartbeatStale) {
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
void query.whereNotNull(`${TableName.GatewayV2}.heartbeat`);
void query.where(`${TableName.GatewayV2}.heartbeat`, "<", oneHourAgo);
void query.where((v) => {
void v

View File

@@ -9,6 +9,7 @@ import { PgSqlLock } from "@app/keystore/keystore";
import { crypto } from "@app/lib/crypto";
import { DatabaseErrorCode } from "@app/lib/error-codes";
import { BadRequestError, DatabaseError, NotFoundError } from "@app/lib/errors";
import { groupBy } from "@app/lib/fn";
import { GatewayProxyProtocol } from "@app/lib/gateway/types";
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
import { logger } from "@app/lib/logger";
@@ -902,13 +903,7 @@ export const gatewayV2ServiceFactory = ({
"Found gateways with last heartbeat over an hour ago. Sending notifications."
);
const gatewaysByOrg = unhealthyGateways.reduce<Record<string, (typeof unhealthyGateways)[number][]>>((acc, gw) => {
if (!acc[gw.orgId]) {
acc[gw.orgId] = [];
}
acc[gw.orgId].push(gw);
return acc;
}, {});
const gatewaysByOrg = groupBy(unhealthyGateways, (gw) => gw.orgId);
for await (const [orgId, gateways] of Object.entries(gatewaysByOrg)) {
try {

View File

@@ -21,6 +21,7 @@ export const relayDalFactory = (db: TDbClient) => {
if (isHeartbeatStale) {
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
void query.whereNotNull(`${TableName.Relay}.heartbeat`);
void query.where(`${TableName.Relay}.heartbeat`, "<", oneHourAgo);
void query.where((v) => {
void v

View File

@@ -8,6 +8,7 @@ import { OrgMembershipRole, TRelays } from "@app/db/schemas";
import { PgSqlLock } from "@app/keystore/keystore";
import { crypto } from "@app/lib/crypto";
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { groupBy } from "@app/lib/fn";
import { createRelayConnection } from "@app/lib/gateway-v2/gateway-v2";
import { logger } from "@app/lib/logger";
import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
@@ -1220,14 +1221,7 @@ export const relayServiceFactory = ({
"Found relays with last heartbeat over an hour ago. Sending notifications."
);
const relaysByOrg = unhealthyRelays.reduce<Record<string, TRelays[]>>((acc, r) => {
const key = r.orgId ?? "instance";
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(r);
return acc;
}, {});
const relaysByOrg = groupBy(unhealthyRelays, (r) => r.orgId ?? "instance");
for await (const [orgId, relays] of Object.entries(relaysByOrg)) {
try {
@@ -1244,7 +1238,7 @@ export const relayServiceFactory = ({
recipients,
subjectLine: "Relay Health Alert",
substitutions: {
type: "relay",
type: "instance-relay",
names: relayNames
},
template: SmtpTemplates.HealthAlert

View File

@@ -4,7 +4,7 @@ import { BaseEmailWrapper, BaseEmailWrapperProps } from "./BaseEmailWrapper";
import { BaseLink } from "./BaseLink";
interface HealthAlertTemplateProps extends Omit<BaseEmailWrapperProps, "title" | "preview" | "children"> {
type: "gateway" | "relay";
type: "gateway" | "relay" | "instance-relay";
names: string;
}
@@ -24,8 +24,14 @@ export const HealthAlertTemplate = ({ siteUrl, names, type }: HealthAlertTemplat
heartbeat in over an hour: <strong>{names}</strong>.
</Text>
<Text className="text-black text-[14px] leading-[24px]">
If your issue persists, you can contact the Infisical team at{" "}
<BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>.
{type === "instance-relay" && (
<>
If your issue persists, you can contact the Infisical team at{" "}
<BaseLink href="mailto:support@infisical.com">support@infisical.com</BaseLink>.
</>
)}
{type === "relay" && <>Please contact your relay administrators.</>}
{type === "gateway" && <>Please contact your gateway administrators.</>}
</Text>
</Section>
</BaseEmailWrapper>

View File

@@ -48,7 +48,7 @@ import { useDeleteGatewayV2ById } from "@app/hooks/api/gateways-v2";
import { EditGatewayDetailsModal } from "./components/EditGatewayDetailsModal";
export const GatewayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => {
const GatewayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => {
const heartbeatDate = heartbeat ? new Date(heartbeat) : null;
const now = new Date();
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);

View File

@@ -42,7 +42,24 @@ import { withPermission } from "@app/hoc";
import { usePopUp } from "@app/hooks";
import { useDeleteRelayById, useGetRelays } from "@app/hooks/api/relays";
import { GatewayHealthStatus } from "../GatewayTab/GatewayTab";
const RelayHealthStatus = ({ heartbeat }: { heartbeat?: string }) => {
const heartbeatDate = heartbeat ? new Date(heartbeat) : null;
const now = new Date();
const oneHourAgo = new Date(now.getTime() - 60 * 60 * 1000);
const isHealthy = heartbeatDate && heartbeatDate >= oneHourAgo;
const tooltipContent = heartbeatDate
? `Last heartbeat: ${heartbeatDate.toLocaleString()}`
: "No heartbeat data available";
return (
<Tooltip content={tooltipContent}>
<span className={`cursor-default ${isHealthy ? "text-green-400" : "text-red-400"}`}>
{isHealthy ? "Healthy" : "Unreachable"}
</span>
</Tooltip>
);
};
export const RelayTab = withPermission(
() => {
@@ -143,7 +160,7 @@ export const RelayTab = withPermission(
<Td>{el.host}</Td>
<Td>{formatRelative(new Date(el.createdAt), new Date())}</Td>
<Td>
<GatewayHealthStatus heartbeat={el.heartbeat} />
<RelayHealthStatus heartbeat={el.heartbeat} />
</Td>
<Td className="w-5">
<Tooltip className="max-w-sm text-center" content="Options">