tighten types, remove duplicate calls
This commit is contained in:
1 parent
ff2e1fd648
commit
7b1d6c763f
8 files changed
+23
-13
No files matched your search
+1
-1
@@ -1648,7 +1648,7 @@
|
||||
},
|
||||
"range": {
|
||||
"type": "string",
|
||||
"enum": ["latest", "30d", "60d", "90d"]
|
||||
"enum": ["30d", "60d", "90d"]
|
||||
},
|
||||
"bucketTimezone": {
|
||||
"type": "string"
|
||||
|
||||
@@ -69,7 +69,6 @@ class StatusPageController implements IStatusPageController {
|
||||
|
||||
getStatusPageByUrl = catchAsync(async (req: Request, res: Response) => {
|
||||
getStatusPageParamValidation.parse(req.params);
|
||||
getStatusPageQueryValidation.parse(req.query);
|
||||
const { range } = getStatusPageQueryValidation.parse(req.query);
|
||||
|
||||
if (!req.params.url) {
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { z } from "zod";
|
||||
import { booleanCoercion, dnsHostnameRegex, timezoneValidation } from "./shared.js";
|
||||
import { StatusPageTypes, StatusPageThemes, StatusPageThemeModes, StatusPageRanges } from "@/domain/status-pages/status-page.type.js";
|
||||
import {
|
||||
StatusPageTypes,
|
||||
StatusPageThemes,
|
||||
StatusPageThemeModes,
|
||||
StatusPageRanges,
|
||||
StatusPageDayRanges,
|
||||
} from "@/domain/status-pages/status-page.type.js";
|
||||
import { MonitorTypes, MonitorStatuses } from "@/domain/monitors/monitor.type.js";
|
||||
import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js";
|
||||
import { cssReferencesExternalResource } from "@/utils/customCss.js";
|
||||
@@ -156,7 +162,7 @@ export const publicStatusPageMonitorResponseSchema = z.object({
|
||||
export const publicStatusPagePayloadResponseSchema = z.object({
|
||||
statusPage: statusPageResponseSchema,
|
||||
monitors: z.array(publicStatusPageMonitorResponseSchema),
|
||||
range: z.enum(StatusPageRanges).optional(),
|
||||
range: z.enum(StatusPageDayRanges).optional(),
|
||||
bucketTimezone: z.string().optional(),
|
||||
checkTTLDays: z.number().optional(),
|
||||
});
|
||||
@@ -41,7 +41,7 @@ export interface IChecksRepository {
|
||||
): Promise<UptimeChecksResult | HardwareChecksResult | PageSpeedChecksResult>;
|
||||
findSummaryByTeamId(teamId: string, dateRange: DateRange): Promise<ChecksSummary>;
|
||||
findUnevaluatedByMonitorId(monitorId: string, since: number): Promise<Check[]>;
|
||||
getDailyStatusBuckets(monitorIds: string[], days: number, timezone: string | undefined): Promise<DailyCheckBucket[]>;
|
||||
getDailyStatusBuckets(monitorIds: string[], days: number, timezone: string): Promise<DailyCheckBucket[]>;
|
||||
|
||||
// update
|
||||
//delete
|
||||
|
||||
@@ -329,7 +329,7 @@ class MongoChecksRepository implements IChecksRepository {
|
||||
return docs.map(this.toEntity);
|
||||
};
|
||||
|
||||
getDailyStatusBuckets = async (monitorIds: string[], days: number, timezone: string | undefined) => {
|
||||
getDailyStatusBuckets = async (monitorIds: string[], days: number, timezone: string) => {
|
||||
const objectIds = monitorIds.map((id) => new mongoose.Types.ObjectId(id));
|
||||
// One extra day so the oldest rendered day is complete; the client enumerates exactly `days` days and ignores the partial extra bucket
|
||||
const windowStart = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
|
||||
|
||||
@@ -132,8 +132,9 @@ export class StatusPageService implements IStatusPageService {
|
||||
}
|
||||
}
|
||||
|
||||
const showURL = (await this.settingsService.getDBSettings()).showURL;
|
||||
const monitors = await this.monitorsRepository.findByIds(statusPage.monitors);
|
||||
const dbSettings = await this.settingsService.getDBSettings();
|
||||
const showURL = dbSettings.showURL;
|
||||
const monitors = await this.monitorsRepository.findByIds(statusPage.monitors, { includeRecentChecks: range === "latest" });
|
||||
const order = new Map(statusPage.monitors.map((id, i) => [id, i]));
|
||||
const sorted = [...monitors].sort((a, b) => (order.get(a.id) ?? Number.MAX_SAFE_INTEGER) - (order.get(b.id) ?? Number.MAX_SAFE_INTEGER));
|
||||
|
||||
@@ -158,7 +159,7 @@ export class StatusPageService implements IStatusPageService {
|
||||
statusPage,
|
||||
range,
|
||||
bucketTimezone,
|
||||
checkTTLDays: (await this.settingsService.getDBSettings()).checkTTL,
|
||||
checkTTLDays: dbSettings.checkTTL,
|
||||
monitors: sorted.map((monitor) => ({
|
||||
...this.toPublicMonitor(monitor, showURL),
|
||||
recentChecks: [],
|
||||
|
||||
@@ -11,9 +11,11 @@ export const StatusPageThemeModes = ["auto", "light", "dark"] as const;
|
||||
export type StatusPageThemeMode = (typeof StatusPageThemeModes)[number];
|
||||
export const DEFAULT_STATUS_PAGE_THEME_MODE: StatusPageThemeMode = "auto";
|
||||
|
||||
export const StatusPageRanges = ["latest", "30d", "60d", "90d"] as const;
|
||||
export const StatusPageDayRanges = ["30d", "60d", "90d"] as const;
|
||||
export type StatusPageDayRange = (typeof StatusPageDayRanges)[number];
|
||||
export const StatusPageRanges = ["latest", ...StatusPageDayRanges] as const;
|
||||
export type StatusPageRange = (typeof StatusPageRanges)[number];
|
||||
export const STATUS_PAGE_RANGE_DAYS: Record<Exclude<StatusPageRange, "latest">, number> = {
|
||||
export const STATUS_PAGE_RANGE_DAYS: Record<StatusPageDayRange, number> = {
|
||||
"30d": 30,
|
||||
"60d": 60,
|
||||
"90d": 90,
|
||||
@@ -63,7 +65,7 @@ export type PublicStatusPageMonitor = Pick<Monitor, "id" | "name" | "type" | "st
|
||||
export interface PublicStatusPagePayload {
|
||||
statusPage: StatusPage;
|
||||
monitors: PublicStatusPageMonitor[];
|
||||
range?: StatusPageRange;
|
||||
range?: StatusPageDayRange;
|
||||
bucketTimezone?: string;
|
||||
checkTTLDays?: number;
|
||||
}
|
||||
@@ -364,7 +364,7 @@ describe("StatusPageService", () => {
|
||||
|
||||
describe("range", () => {
|
||||
it("omits range-mode fields and never queries buckets for the default (latest) range", async () => {
|
||||
const { service, checksRepo } = createService();
|
||||
const { service, checksRepo, monitorsRepo } = createService();
|
||||
|
||||
const implicitLatest = await service.getPublicStatusPagePayload(publishedPage(), undefined);
|
||||
const explicitLatest = await service.getPublicStatusPagePayload(publishedPage(), undefined, "latest");
|
||||
@@ -376,6 +376,7 @@ describe("StatusPageService", () => {
|
||||
expect(payload.monitors[0]).not.toHaveProperty("dailyChecks");
|
||||
}
|
||||
expect(checksRepo.getDailyStatusBuckets).not.toHaveBeenCalled();
|
||||
expect(monitorsRepo.findByIds).toHaveBeenCalledWith(["mon-1"], { includeRecentChecks: true });
|
||||
});
|
||||
|
||||
it("attaches dailyChecks, empties recentChecks, and echoes range metadata for a day range", async () => {
|
||||
@@ -388,6 +389,7 @@ describe("StatusPageService", () => {
|
||||
const payload = await service.getPublicStatusPagePayload(page, undefined, "30d");
|
||||
|
||||
expect(checksRepo.getDailyStatusBuckets).toHaveBeenCalledWith(["mon-1"], 30, "America/Toronto");
|
||||
expect(monitorsRepo.findByIds).toHaveBeenCalledWith(["mon-1"], { includeRecentChecks: false });
|
||||
expect(payload).toMatchObject({ range: "30d", bucketTimezone: "America/Toronto", checkTTLDays: 30 });
|
||||
expect(payload.monitors[0].recentChecks).toEqual([]);
|
||||
expect(payload.monitors[0].dailyChecks).toEqual([bucket]);
|
||||
|
||||
Reference in new issue
Block a user