Openstatus www.openstatus.dev
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

๐Ÿš€ remove screenshot free user (#1086)

* ๐Ÿš€ remove screenshot free user

* ๐Ÿ”ฅ screenshot

* ๐Ÿ”ฅ pricing table

* ci: apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

authored by

Thibault Le Ouay
autofix-ci[bot]
and committed by
GitHub
aaf3e677 d6301f8b

+78 -21
+34 -17
apps/server/src/checker/index.ts
··· 3 3 import { z } from "zod"; 4 4 5 5 import { and, db, eq, isNull, schema } from "@openstatus/db"; 6 - import { incidentTable } from "@openstatus/db/src/schema"; 6 + import { incidentTable, workspace } from "@openstatus/db/src/schema"; 7 7 import { 8 8 monitorStatusSchema, 9 9 selectMonitorSchema, ··· 189 189 .select({ 190 190 url: schema.monitor.url, 191 191 jobType: schema.monitor.jobType, 192 + workspaceId: schema.monitor.workspaceId, 192 193 }) 193 194 .from(schema.monitor) 194 195 .where(eq(schema.monitor.id, Number(monitorId))) 195 196 .get(); 196 - if (monitor && monitor.jobType === "http") { 197 - await triggerScreenshot({ 198 - data: { 199 - url: monitor.url, 200 - incidentId: newIncident[0].id, 201 - kind: "incident", 202 - }, 203 - }); 197 + if (monitor && monitor.jobType === "http" && monitor.workspaceId) { 198 + const currentWorkspace = await db 199 + .select() 200 + .from(workspace) 201 + .where(eq(workspace.id, monitor.workspaceId)) 202 + .get(); 203 + if (currentWorkspace?.plan !== "free") { 204 + await triggerScreenshot({ 205 + data: { 206 + url: monitor.url, 207 + incidentId: newIncident[0].id, 208 + kind: "incident", 209 + }, 210 + }); 211 + } 204 212 } 205 213 } 206 214 } ··· 282 290 .select({ 283 291 url: schema.monitor.url, 284 292 jobType: schema.monitor.jobType, 293 + workspaceId: schema.monitor.workspaceId, 285 294 }) 286 295 .from(schema.monitor) 287 296 .where(eq(schema.monitor.id, Number(monitorId))) 288 297 .get(); 289 - if (monitor && monitor.jobType === "http") { 290 - await triggerScreenshot({ 291 - data: { 292 - url: monitor.url, 293 - incidentId: incident.id, 294 - kind: "recovery", 295 - }, 296 - }); 298 + if (monitor && monitor.jobType === "http" && monitor.workspaceId) { 299 + const currentWorkspace = await db 300 + .select() 301 + .from(workspace) 302 + .where(eq(workspace.id, monitor.workspaceId)) 303 + .get(); 304 + 305 + if (currentWorkspace?.plan !== "free") { 306 + await triggerScreenshot({ 307 + data: { 308 + url: monitor.url, 309 + incidentId: incident.id, 310 + kind: "recovery", 311 + }, 312 + }); 313 + } 297 314 } 298 315 } 299 316 }
+7 -2
apps/web/src/config/pricing-table.tsx
··· 1 - import type { LimitsV1, LimitsV2 } from "@openstatus/db/src/schema/plan/schema"; 1 + import type { 2 + LimitsV1, 3 + LimitsV2, 4 + LimitsV3, 5 + } from "@openstatus/db/src/schema/plan/schema"; 2 6 import Link from "next/link"; 3 7 import type React from "react"; 4 8 ··· 26 30 { 27 31 label: string; 28 32 features: { 29 - value: keyof LimitsV1 | keyof LimitsV2; 33 + value: keyof LimitsV1 | keyof LimitsV2 | keyof LimitsV3; 30 34 label: string; 31 35 description?: React.ReactNode; // tooltip informations 32 36 badge?: string; ··· 52 56 { value: "max-regions", label: "Number of Regions" }, 53 57 54 58 { value: "data-retention", label: "Data retention" }, 59 + { value: "screenshots", label: "Screenshots upon failure" }, 55 60 ], 56 61 }, 57 62 "synthetic-checks": {
+4
packages/db/src/schema/plan/config.ts
··· 25 25 "status-pages": 1, 26 26 maintenance: true, 27 27 "monitor-values-visibility": true, 28 + screenshots: false, 28 29 "status-subscribers": false, 29 30 "custom-domain": false, 30 31 "password-protection": false, ··· 53 54 "status-pages": 1, 54 55 maintenance: true, 55 56 "monitor-values-visibility": true, 57 + screenshots: true, 56 58 "status-subscribers": true, 57 59 "custom-domain": true, 58 60 "password-protection": true, ··· 117 119 "status-pages": 5, 118 120 maintenance: true, 119 121 "monitor-values-visibility": true, 122 + screenshots: true, 120 123 "status-subscribers": true, 121 124 "custom-domain": true, 122 125 "password-protection": true, ··· 181 184 "status-pages": 20, 182 185 maintenance: true, 183 186 "monitor-values-visibility": true, 187 + screenshots: true, 184 188 "status-subscribers": true, 185 189 "custom-domain": true, 186 190 "password-protection": true,
+33 -2
packages/db/src/schema/plan/schema.ts
··· 36 36 "monitor-values-visibility": z.boolean(), 37 37 }); 38 38 39 + export const limitsV3 = limitsV2.extend({ 40 + version: z.literal("v3"), 41 + screenshots: z.boolean(), 42 + }); 43 + 39 44 export type LimitsV2 = z.infer<typeof limitsV2>; 45 + export type LimitsV3 = z.infer<typeof limitsV3>; 40 46 41 - const unknownLimit = z.discriminatedUnion("version", [limitsV1, limitsV2]); 47 + const unknownLimit = z.discriminatedUnion("version", [ 48 + limitsV1, 49 + limitsV2, 50 + limitsV3, 51 + ]); 42 52 43 53 export function migrateFromV1ToV2({ data }: { data: LimitsV1 }) { 44 54 return { ··· 49 59 }; 50 60 } 51 61 62 + export function migrateFromV2ToV3({ data }: { data: LimitsV2 }) { 63 + return { 64 + ...data, 65 + version: "v3", 66 + screenshots: true, 67 + }; 68 + } 69 + 70 + export function migrateFromV1ToV3({ data }: { data: LimitsV1 }) { 71 + return { 72 + ...data, 73 + version: "v3", 74 + screenshots: true, 75 + "private-locations": true, 76 + "monitor-values-visibility": true, 77 + }; 78 + } 79 + 52 80 export const limitSchema = unknownLimit.transform((val) => { 53 81 if (!val.version) { 54 - return migrateFromV1ToV2({ data: val }); 82 + return migrateFromV1ToV3({ data: val }); 83 + } 84 + if (val.version === "v2") { 85 + return migrateFromV2ToV3({ data: val }); 55 86 } 56 87 return val; 57 88 });