Compare commits

..

1 Commits

Author SHA1 Message Date
Owen Schwartz 8ed9adbfae New translations en-us.json (German)
[ci skip]
2026-04-28 16:21:16 -07:00
7 changed files with 41 additions and 70 deletions
+1 -1
View File
@@ -1432,7 +1432,7 @@
"alertingTriggerHcToggle": "Gesundheits-Check-Status ändern",
"alertingTriggerResourceHealthy": "Ressource gesund",
"alertingTriggerResourceUnhealthy": "Ressource ungesund",
"alertingTriggerResourceDegraded": "Resource degraded",
"alertingTriggerResourceDegraded": "Ressource verschlechtert",
"alertingSearchHealthChecks": "Gesundheits-Checks suchen…",
"alertingHealthChecksEmpty": "Keine Gesundheits-Checks verfügbar.",
"alertingTriggerResourceToggle": "Ressourcenstatus ändern",
+15 -21
View File
@@ -1,5 +1,5 @@
import { z } from "zod";
import { db, logsDb, statusHistory } from "@server/db";
import { db, statusHistory } from "@server/db";
import { and, eq, gte, asc } from "drizzle-orm";
import cache from "@server/lib/cache";
@@ -27,7 +27,7 @@ export async function getCachedStatusHistory(
const nowSec = Math.floor(Date.now() / 1000);
const startSec = nowSec - days * 86400;
const events = await logsDb
const events = await db
.select()
.from(statusHistory)
.where(
@@ -74,11 +74,11 @@ export const statusHistoryQuerySchema = z
days: z
.string()
.optional()
.transform((v) => (v ? parseInt(v, 10) : 90))
.transform((v) => (v ? parseInt(v, 10) : 90)),
})
.pipe(
z.object({
days: z.number().int().min(1).max(365)
days: z.number().int().min(1).max(365),
})
);
@@ -99,14 +99,7 @@ export interface StatusHistoryResponse {
}
export function computeBuckets(
events: {
entityType: string;
entityId: number;
orgId: string;
status: string;
timestamp: number;
id: number;
}[],
events: { entityType: string; entityId: number; orgId: string; status: string; timestamp: number; id: number }[],
days: number
): { buckets: StatusHistoryDayBucket[]; totalDowntime: number } {
const nowSec = Math.floor(Date.now() / 1000);
@@ -128,8 +121,7 @@ export function computeBuckets(
const currentStatus = lastBeforeDay?.status ?? null;
const windows: { start: number; end: number | null; status: string }[] =
[];
const windows: { start: number; end: number | null; status: string }[] = [];
let dayDowntime = 0;
let dayDegradedTime = 0;
@@ -140,21 +132,22 @@ export function computeBuckets(
if (windowStatus !== null && windowStatus !== evt.status) {
const windowEnd = evt.timestamp;
const isDown =
windowStatus === "offline" || windowStatus === "unhealthy";
windowStatus === "offline" ||
windowStatus === "unhealthy";
const isDegraded = windowStatus === "degraded";
if (isDown) {
dayDowntime += windowEnd - windowStart;
windows.push({
start: windowStart,
end: windowEnd,
status: windowStatus
status: windowStatus,
});
} else if (isDegraded) {
dayDegradedTime += windowEnd - windowStart;
windows.push({
start: windowStart,
end: windowEnd,
status: windowStatus
status: windowStatus,
});
}
}
@@ -166,21 +159,22 @@ export function computeBuckets(
if (windowStatus !== null) {
const finalEnd = Math.min(dayEndSec, nowSec);
const isDown =
windowStatus === "offline" || windowStatus === "unhealthy";
windowStatus === "offline" ||
windowStatus === "unhealthy";
const isDegraded = windowStatus === "degraded";
if (isDown && finalEnd > windowStart) {
dayDowntime += finalEnd - windowStart;
windows.push({
start: windowStart,
end: finalEnd,
status: windowStatus
status: windowStatus,
});
} else if (isDegraded && finalEnd > windowStart) {
dayDegradedTime += finalEnd - windowStart;
windows.push({
start: windowStart,
end: finalEnd,
status: windowStatus
status: windowStatus,
});
}
}
@@ -231,7 +225,7 @@ export function computeBuckets(
uptimePercent: Math.round(uptimePct * 100) / 100,
totalDowntimeSeconds: dayDowntime,
downtimeWindows: windows,
status
status,
});
}
@@ -19,8 +19,7 @@ import {
targetHealthCheck,
targets,
resources,
Transaction,
logsDb
Transaction
} from "@server/db";
import { eq } from "drizzle-orm";
import { invalidateStatusHistoryCache } from "@server/lib/statusHistory";
@@ -53,10 +52,10 @@ export async function fireHealthCheckHealthyAlert(
healthCheckTargetId?: number | null,
extra?: Record<string, unknown>,
send: boolean = true,
trx: Transaction | typeof db = db
trx: Transaction | typeof db = db,
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "health_check",
entityId: healthCheckId,
orgId: orgId,
@@ -120,7 +119,7 @@ export async function fireHealthCheckUnhealthyAlert(
trx: Transaction | typeof db = db
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "health_check",
entityId: healthCheckId,
orgId: orgId,
@@ -173,7 +172,7 @@ export async function fireHealthCheckUnknownAlert(
trx: Transaction | typeof db = db
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "health_check",
entityId: healthCheckId,
orgId: orgId,
@@ -195,12 +194,7 @@ export async function fireHealthCheckUnknownAlert(
}
}
async function handleResource(
orgId: string,
healthCheckTargetId?: number | null,
send: boolean = true,
trx: Transaction | typeof db = db
) {
async function handleResource(orgId: string, healthCheckTargetId?: number | null, send: boolean = true, trx: Transaction | typeof db = db) {
if (!healthCheckTargetId) {
return;
}
@@ -228,10 +222,7 @@ async function handleResource(
const otherTargets = await trx
.select({ hcHealth: targetHealthCheck.hcHealth })
.from(targets)
.innerJoin(
targetHealthCheck,
eq(targetHealthCheck.targetId, targets.targetId)
)
.innerJoin(targetHealthCheck, eq(targetHealthCheck.targetId, targets.targetId))
.where(eq(targets.resourceId, resource.resourceId));
let health = "healthy";
@@ -13,7 +13,7 @@
import logger from "@server/logger";
import { processAlerts } from "../processAlerts";
import { db, logsDb, statusHistory, Transaction } from "@server/db";
import { db, statusHistory, Transaction } from "@server/db";
import { invalidateStatusHistoryCache } from "@server/lib/statusHistory";
// ---------------------------------------------------------------------------
@@ -40,7 +40,7 @@ export async function fireResourceHealthyAlert(
trx: Transaction | typeof db = db
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "resource",
entityId: resourceId,
orgId: orgId,
@@ -101,7 +101,7 @@ export async function fireResourceUnhealthyAlert(
trx: Transaction | typeof db = db
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "resource",
entityId: resourceId,
orgId: orgId,
@@ -162,7 +162,7 @@ export async function fireResourceDegradedAlert(
trx: Transaction | typeof db = db
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "resource",
entityId: resourceId,
orgId: orgId,
@@ -223,7 +223,7 @@ export async function fireResourceUnknownAlert(
trx: Transaction | typeof db = db
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "resource",
entityId: resourceId,
orgId: orgId,
@@ -13,13 +13,7 @@
import logger from "@server/logger";
import { processAlerts } from "../processAlerts";
import {
db,
logsDb,
statusHistory,
targetHealthCheck,
Transaction
} from "@server/db";
import { db, sites, statusHistory, targetHealthCheck, Transaction } from "@server/db";
import { invalidateStatusHistoryCache } from "@server/lib/statusHistory";
import { and, eq, inArray } from "drizzle-orm";
import { fireHealthCheckUnhealthyAlert } from "./healthCheckEvents";
@@ -47,7 +41,7 @@ export async function fireSiteOnlineAlert(
trx: Transaction | typeof db = db
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "site",
entityId: siteId,
orgId: orgId,
@@ -103,7 +97,7 @@ export async function fireSiteOfflineAlert(
trx: Transaction | typeof db = db
): Promise<void> {
try {
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "site",
entityId: siteId,
orgId: orgId,
+8 -16
View File
@@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db, logsDb, statusHistory } from "@server/db";
import { db, statusHistory } from "@server/db";
import {
siteProvisioningKeys,
siteProvisioningKeyOrg,
@@ -84,7 +84,7 @@ export async function registerNewt(
maxBatchSize: siteProvisioningKeys.maxBatchSize,
numUsed: siteProvisioningKeys.numUsed,
validUntil: siteProvisioningKeys.validUntil,
approveNewSites: siteProvisioningKeys.approveNewSites
approveNewSites: siteProvisioningKeys.approveNewSites,
})
.from(siteProvisioningKeys)
.innerJoin(
@@ -125,10 +125,7 @@ export async function registerNewt(
);
}
if (
keyRecord.maxBatchSize &&
keyRecord.numUsed >= keyRecord.maxBatchSize
) {
if (keyRecord.maxBatchSize && keyRecord.numUsed >= keyRecord.maxBatchSize) {
return next(
createHttpError(
HttpCode.UNAUTHORIZED,
@@ -137,10 +134,7 @@ export async function registerNewt(
);
}
if (
keyRecord.validUntil &&
new Date(keyRecord.validUntil) < new Date()
) {
if (keyRecord.validUntil && new Date(keyRecord.validUntil) < new Date()) {
return next(
createHttpError(
HttpCode.UNAUTHORIZED,
@@ -160,10 +154,7 @@ export async function registerNewt(
}
if (!org.subnet) {
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"Organization subnet not found"
)
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "Organization subnet not found")
);
}
@@ -204,6 +195,7 @@ export async function registerNewt(
let newSiteId: number | undefined;
await db.transaction(async (trx) => {
const newClientAddress = await getNextAvailableClientSubnet(orgId);
if (!newClientAddress) {
return next(
@@ -227,11 +219,11 @@ export async function registerNewt(
address: clientAddress,
type: "newt",
dockerSocketEnabled: true,
status: keyRecord.approveNewSites ? "approved" : "pending"
status: keyRecord.approveNewSites ? "approved" : "pending",
})
.returning();
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "site",
entityId: newSite.siteId,
orgId: orgId,
+2 -2
View File
@@ -1,6 +1,6 @@
import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { clients, db, exitNodes, logsDb, statusHistory } from "@server/db";
import { clients, db, exitNodes, statusHistory } from "@server/db";
import { roles, userSites, sites, roleSites, Site, orgs } from "@server/db";
import response from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
@@ -351,7 +351,7 @@ export async function createSite(
})
.returning();
await logsDb.insert(statusHistory).values({
await trx.insert(statusHistory).values({
entityType: "site",
entityId: newSite.siteId,
orgId: orgId,