Openstatus www.openstatus.dev

feat: add follow redirects option for HTTP requests in checker service (#1331)

* feat: add follow redirects option for HTTP requests in checker service

* feat: add followRedirects option to monitor schema and validation

* ci: apply automated fixes

* fix: tsc

* feat: include form

* feat: add explicit 10 redirect limit when FollowRedirects is enabled

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Maximilian Kaske <maximilian@kaske.org>
Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.Com>

+2649 -16
+16 -1
apps/checker/handlers/checker.go
··· 76 76 requestClient := &http.Client{ 77 77 Timeout: time.Duration(req.Timeout) * time.Millisecond, 78 78 } 79 + 80 + // Configure redirect policy based on FollowRedirects setting 81 + if !req.FollowRedirects { 82 + requestClient.CheckRedirect = func(req *http.Request, via []*http.Request) error { 83 + return http.ErrUseLastResponse 84 + } 85 + } else { 86 + // Explicitly limit the number of redirects to 10 (Go's default) 87 + requestClient.CheckRedirect = func(req *http.Request, via []*http.Request) error { 88 + if len(via) >= 10 { 89 + return http.ErrUseLastResponse 90 + } 91 + return nil 92 + } 93 + } 79 94 defer requestClient.CloseIdleConnections() 80 95 81 96 // Might be a more efficient way to do it ··· 97 112 var result checker.Response 98 113 99 114 var retry int 100 - if req.Retry == 0 { 115 + if req.Retry == 0 { 101 116 retry = int(req.Retry) 102 117 } else { 103 118 retry = 3
+14 -13
apps/checker/request/request.go
··· 50 50 Key string `json:"key"` 51 51 Value string `json:"value"` 52 52 } `json:"headers,omitempty"` 53 - WorkspaceID string `json:"workspaceId"` 54 - URL string `json:"url"` 55 - MonitorID string `json:"monitorId"` 56 - Method string `json:"method"` 57 - Status string `json:"status"` 58 - Body string `json:"body"` 59 - Trigger string `json:"trigger,omitempty"` 60 - RawAssertions []json.RawMessage `json:"assertions,omitempty"` 61 - CronTimestamp int64 `json:"cronTimestamp"` 62 - Timeout int64 `json:"timeout"` 63 - DegradedAfter int64 `json:"degradedAfter,omitempty"` 64 - Retry int64 `json:"retry,omitempty"` 65 - OtelConfig struct { 53 + WorkspaceID string `json:"workspaceId"` 54 + URL string `json:"url"` 55 + MonitorID string `json:"monitorId"` 56 + Method string `json:"method"` 57 + Status string `json:"status"` 58 + Body string `json:"body"` 59 + Trigger string `json:"trigger,omitempty"` 60 + RawAssertions []json.RawMessage `json:"assertions,omitempty"` 61 + CronTimestamp int64 `json:"cronTimestamp"` 62 + Timeout int64 `json:"timeout"` 63 + DegradedAfter int64 `json:"degradedAfter,omitempty"` 64 + Retry int64 `json:"retry,omitempty"` 65 + FollowRedirects bool `json:"followRedirects,omitempty"` 66 + OtelConfig struct { 66 67 Endpoint string `json:"endpoint"` 67 68 Headers map[string]string `json:"headers,omitempty"` 68 69 } `json:"otelConfig,omitempty"`
+4
apps/dashboard/src/app/(dashboard)/monitors/[id]/sidebar.tsx
··· 81 81 }, 82 82 { label: "Public", value: String(monitor.public) }, 83 83 { label: "Active", value: String(monitor.active) }, 84 + { 85 + label: "Follow redirects", 86 + value: String(monitor.followRedirects), 87 + }, 84 88 ], 85 89 }, 86 90 {
+126
apps/dashboard/src/components/forms/monitor/form-follow-redirect.tsx
··· 1 + "use client"; 2 + 3 + import { Link } from "@/components/common/link"; 4 + import { 5 + FormCard, 6 + FormCardContent, 7 + FormCardDescription, 8 + FormCardFooter, 9 + FormCardFooterInfo, 10 + FormCardHeader, 11 + FormCardTitle, 12 + } from "@/components/forms/form-card"; 13 + import { Button } from "@/components/ui/button"; 14 + import { 15 + Form, 16 + FormControl, 17 + FormDescription, 18 + FormField, 19 + FormItem, 20 + FormLabel, 21 + } from "@/components/ui/form"; 22 + import { Switch } from "@/components/ui/switch"; 23 + import { zodResolver } from "@hookform/resolvers/zod"; 24 + import { useTransition } from "react"; 25 + import { useForm } from "react-hook-form"; 26 + import { toast } from "sonner"; 27 + import { z } from "zod"; 28 + 29 + export const FOLLOW_REDIRECTS_DEFAULT = true; 30 + 31 + const schema = z.object({ 32 + followRedirects: z.boolean().default(true), 33 + }); 34 + 35 + type FormValues = z.infer<typeof schema>; 36 + 37 + export function FormFollowRedirect({ 38 + defaultValues, 39 + onSubmit, 40 + ...props 41 + }: Omit<React.ComponentProps<"form">, "onSubmit"> & { 42 + defaultValues?: FormValues; 43 + onSubmit: (values: FormValues) => Promise<void>; 44 + }) { 45 + const form = useForm<FormValues>({ 46 + resolver: zodResolver(schema), 47 + defaultValues: defaultValues ?? { 48 + followRedirects: FOLLOW_REDIRECTS_DEFAULT, 49 + }, 50 + }); 51 + const [isPending, startTransition] = useTransition(); 52 + 53 + function submitAction(values: FormValues) { 54 + if (isPending) return; 55 + 56 + startTransition(async () => { 57 + try { 58 + const promise = onSubmit(values); 59 + toast.promise(promise, { 60 + loading: "Saving...", 61 + success: "Saved", 62 + error: "Failed to save", 63 + }); 64 + await promise; 65 + } catch (error) { 66 + console.error(error); 67 + } 68 + }); 69 + } 70 + 71 + return ( 72 + <Form {...form}> 73 + <form onSubmit={form.handleSubmit(submitAction)} {...props}> 74 + <FormCard> 75 + <FormCardHeader> 76 + <FormCardTitle>Follow Redirects</FormCardTitle> 77 + <FormCardDescription> 78 + Configure whether to follow redirects. 79 + </FormCardDescription> 80 + </FormCardHeader> 81 + <FormCardContent className="grid gap-4"> 82 + <FormField 83 + control={form.control} 84 + name="followRedirects" 85 + render={({ field }) => ( 86 + <FormItem className="flex flex-row items-center justify-between"> 87 + <div className="space-y-0.5"> 88 + <FormLabel>Follow redirects</FormLabel> 89 + <FormDescription> 90 + When enabled, the monitor will automatically follow HTTP 91 + redirects (3xx status codes) to their final destination. 92 + This is useful when monitoring URLs that may redirect to 93 + other locations. 94 + </FormDescription> 95 + </div> 96 + <FormControl> 97 + <Switch 98 + checked={field.value} 99 + onCheckedChange={field.onChange} 100 + /> 101 + </FormControl> 102 + </FormItem> 103 + )} 104 + /> 105 + </FormCardContent> 106 + <FormCardFooter> 107 + <FormCardFooterInfo> 108 + Learn more about{" "} 109 + <Link 110 + href="https://docs.openstatus.dev/monitoring/customization/follow-redirects/" 111 + rel="noreferrer" 112 + target="_blank" 113 + > 114 + follow redirects 115 + </Link> 116 + . 117 + </FormCardFooterInfo> 118 + <Button type="submit" disabled={isPending}> 119 + {isPending ? "Submitting..." : "Submit"} 120 + </Button> 121 + </FormCardFooter> 122 + </FormCard> 123 + </form> 124 + </Form> 125 + ); 126 + }
+17
apps/dashboard/src/components/forms/monitor/update.tsx
··· 6 6 import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; 7 7 import { useParams, useRouter } from "next/navigation"; 8 8 import { FormDangerZone } from "./form-danger-zone"; 9 + import { FormFollowRedirect } from "./form-follow-redirect"; 9 10 import { FormGeneral } from "./form-general"; 10 11 import { FormNotifiers } from "./form-notifiers"; 11 12 import { FormOtel } from "./form-otel"; ··· 56 57 ); 57 58 const updateTagsMutation = useMutation( 58 59 trpc.monitor.updateTags.mutationOptions({ 60 + onSuccess: () => refetch(), 61 + }), 62 + ); 63 + const updateFollowRedirectsMutation = useMutation( 64 + trpc.monitor.updateFollowRedirects.mutationOptions({ 59 65 onSuccess: () => refetch(), 60 66 }), 61 67 ); ··· 208 214 retry: values.retry, 209 215 }) 210 216 } 217 + /> 218 + <FormFollowRedirect 219 + defaultValues={{ 220 + followRedirects: monitor.followRedirects ?? true, 221 + }} 222 + onSubmit={async (values) => { 223 + await updateFollowRedirectsMutation.mutateAsync({ 224 + id: Number.parseInt(id), 225 + followRedirects: values.followRedirects, 226 + }); 227 + }} 211 228 /> 212 229 <FormOtel 213 230 locked={workspace.limits.otel === false}
+4
apps/docs/astro.config.mjs
··· 139 139 label: "Timing", 140 140 slug: "monitoring/customization/timing", 141 141 }, 142 + { 143 + label: "Follow Redirects", 144 + slug: "monitoring/customization/follow-redirects", 145 + }, 142 146 ], 143 147 }, 144 148 ],
+12
apps/docs/src/content/docs/monitoring/customization/follow-redirects.mdx
··· 1 + --- 2 + title: Follow Redirects 3 + description: "What are follow redirects on a monitor in OpenStatus" 4 + --- 5 + 6 + The Follow Redirects option controls whether your monitor should automatically follow HTTP redirects. **By default, we follow the redirects.** 7 + 8 + When enabled, the monitor will follow any `3xx` redirect responses (e.g. `301 Moved Permanently`, `302 Found`) until it reaches the final destination URL. The monitor will then report the status of the final response. 9 + 10 + Enable this option if: 11 + - You are monitoring a URL that often redirects (e.g. from http:// to https://, or from a short link to the final page). 12 + - You want to verify that the final destination is available and returns the expected response.
+3
apps/server/src/routes/v1/monitors/schema.ts
··· 203 203 retry: z.number().default(3).openapi({ 204 204 description: "The number of retries to attempt", 205 205 }), 206 + followRedirects: z.boolean().default(true).openapi({ 207 + description: "If the monitor should follow redirects", 208 + }), 206 209 jobType: z.enum(monitorJobTypes).optional().default("http").openapi({ 207 210 description: "The type of the monitor", 208 211 }),
+1 -1
apps/web/src/app/api/checker/cron/_cron.ts
··· 187 187 } 188 188 : undefined, 189 189 retry: row.retry || 3, 190 - followRedirects: true, 190 + followRedirects: row.followRedirects || true, 191 191 }; 192 192 } 193 193 if (row.jobType === "tcp") {
+2 -1
packages/api/src/router/checker.ts
··· 289 289 } 290 290 : undefined, 291 291 retry: input.retry || 3, 292 - followRedirects: true, 292 + followRedirects: input.followRedirects || true, 293 293 }; 294 294 } 295 295 if (input.jobType === "tcp") { ··· 310 310 headers: transformHeaders(input.otelHeaders), 311 311 } 312 312 : undefined, 313 + followRedirects: input.followRedirects || true, 313 314 }; 314 315 } 315 316 const allResult = [];
+20
packages/api/src/router/monitor.ts
··· 984 984 .run(); 985 985 }), 986 986 987 + updateFollowRedirects: protectedProcedure 988 + .meta({ track: Events.UpdateMonitor }) 989 + .input(z.object({ id: z.number(), followRedirects: z.boolean() })) 990 + .mutation(async ({ ctx, input }) => { 991 + const whereConditions: SQL[] = [ 992 + eq(monitor.id, input.id), 993 + eq(monitor.workspaceId, ctx.workspace.id), 994 + isNull(monitor.deletedAt), 995 + ]; 996 + 997 + await ctx.db 998 + .update(monitor) 999 + .set({ 1000 + followRedirects: input.followRedirects, 1001 + updatedAt: new Date(), 1002 + }) 1003 + .where(and(...whereConditions)) 1004 + .run(); 1005 + }), 1006 + 987 1007 updateOtel: protectedProcedure 988 1008 .meta({ track: Events.UpdateMonitor }) 989 1009 .input(
+1
packages/db/drizzle/0045_little_paladin.sql
··· 1 + ALTER TABLE `monitor` ADD `follow_redirects` integer DEFAULT true;
+2417
packages/db/drizzle/meta/0045_snapshot.json
··· 1 + { 2 + "version": "6", 3 + "dialect": "sqlite", 4 + "id": "c5cd5994-2e75-43ff-b2e0-637f0fe87d88", 5 + "prevId": "731c8921-4489-4e79-965c-e3d292b164dd", 6 + "tables": { 7 + "workspace": { 8 + "name": "workspace", 9 + "columns": { 10 + "id": { 11 + "name": "id", 12 + "type": "integer", 13 + "primaryKey": true, 14 + "notNull": true, 15 + "autoincrement": false 16 + }, 17 + "slug": { 18 + "name": "slug", 19 + "type": "text", 20 + "primaryKey": false, 21 + "notNull": true, 22 + "autoincrement": false 23 + }, 24 + "name": { 25 + "name": "name", 26 + "type": "text", 27 + "primaryKey": false, 28 + "notNull": false, 29 + "autoincrement": false 30 + }, 31 + "stripe_id": { 32 + "name": "stripe_id", 33 + "type": "text(256)", 34 + "primaryKey": false, 35 + "notNull": false, 36 + "autoincrement": false 37 + }, 38 + "subscription_id": { 39 + "name": "subscription_id", 40 + "type": "text", 41 + "primaryKey": false, 42 + "notNull": false, 43 + "autoincrement": false 44 + }, 45 + "plan": { 46 + "name": "plan", 47 + "type": "text", 48 + "primaryKey": false, 49 + "notNull": false, 50 + "autoincrement": false 51 + }, 52 + "ends_at": { 53 + "name": "ends_at", 54 + "type": "integer", 55 + "primaryKey": false, 56 + "notNull": false, 57 + "autoincrement": false 58 + }, 59 + "paid_until": { 60 + "name": "paid_until", 61 + "type": "integer", 62 + "primaryKey": false, 63 + "notNull": false, 64 + "autoincrement": false 65 + }, 66 + "limits": { 67 + "name": "limits", 68 + "type": "text", 69 + "primaryKey": false, 70 + "notNull": true, 71 + "autoincrement": false, 72 + "default": "'{}'" 73 + }, 74 + "created_at": { 75 + "name": "created_at", 76 + "type": "integer", 77 + "primaryKey": false, 78 + "notNull": false, 79 + "autoincrement": false, 80 + "default": "(strftime('%s', 'now'))" 81 + }, 82 + "updated_at": { 83 + "name": "updated_at", 84 + "type": "integer", 85 + "primaryKey": false, 86 + "notNull": false, 87 + "autoincrement": false, 88 + "default": "(strftime('%s', 'now'))" 89 + }, 90 + "dsn": { 91 + "name": "dsn", 92 + "type": "text", 93 + "primaryKey": false, 94 + "notNull": false, 95 + "autoincrement": false 96 + } 97 + }, 98 + "indexes": { 99 + "workspace_slug_unique": { 100 + "name": "workspace_slug_unique", 101 + "columns": [ 102 + "slug" 103 + ], 104 + "isUnique": true 105 + }, 106 + "workspace_stripe_id_unique": { 107 + "name": "workspace_stripe_id_unique", 108 + "columns": [ 109 + "stripe_id" 110 + ], 111 + "isUnique": true 112 + }, 113 + "workspace_id_dsn_unique": { 114 + "name": "workspace_id_dsn_unique", 115 + "columns": [ 116 + "id", 117 + "dsn" 118 + ], 119 + "isUnique": true 120 + } 121 + }, 122 + "foreignKeys": {}, 123 + "compositePrimaryKeys": {}, 124 + "uniqueConstraints": {}, 125 + "checkConstraints": {} 126 + }, 127 + "account": { 128 + "name": "account", 129 + "columns": { 130 + "user_id": { 131 + "name": "user_id", 132 + "type": "integer", 133 + "primaryKey": false, 134 + "notNull": true, 135 + "autoincrement": false 136 + }, 137 + "type": { 138 + "name": "type", 139 + "type": "text", 140 + "primaryKey": false, 141 + "notNull": true, 142 + "autoincrement": false 143 + }, 144 + "provider": { 145 + "name": "provider", 146 + "type": "text", 147 + "primaryKey": false, 148 + "notNull": true, 149 + "autoincrement": false 150 + }, 151 + "provider_account_id": { 152 + "name": "provider_account_id", 153 + "type": "text", 154 + "primaryKey": false, 155 + "notNull": true, 156 + "autoincrement": false 157 + }, 158 + "refresh_token": { 159 + "name": "refresh_token", 160 + "type": "text", 161 + "primaryKey": false, 162 + "notNull": false, 163 + "autoincrement": false 164 + }, 165 + "access_token": { 166 + "name": "access_token", 167 + "type": "text", 168 + "primaryKey": false, 169 + "notNull": false, 170 + "autoincrement": false 171 + }, 172 + "expires_at": { 173 + "name": "expires_at", 174 + "type": "integer", 175 + "primaryKey": false, 176 + "notNull": false, 177 + "autoincrement": false 178 + }, 179 + "token_type": { 180 + "name": "token_type", 181 + "type": "text", 182 + "primaryKey": false, 183 + "notNull": false, 184 + "autoincrement": false 185 + }, 186 + "scope": { 187 + "name": "scope", 188 + "type": "text", 189 + "primaryKey": false, 190 + "notNull": false, 191 + "autoincrement": false 192 + }, 193 + "id_token": { 194 + "name": "id_token", 195 + "type": "text", 196 + "primaryKey": false, 197 + "notNull": false, 198 + "autoincrement": false 199 + }, 200 + "session_state": { 201 + "name": "session_state", 202 + "type": "text", 203 + "primaryKey": false, 204 + "notNull": false, 205 + "autoincrement": false 206 + } 207 + }, 208 + "indexes": {}, 209 + "foreignKeys": { 210 + "account_user_id_user_id_fk": { 211 + "name": "account_user_id_user_id_fk", 212 + "tableFrom": "account", 213 + "tableTo": "user", 214 + "columnsFrom": [ 215 + "user_id" 216 + ], 217 + "columnsTo": [ 218 + "id" 219 + ], 220 + "onDelete": "cascade", 221 + "onUpdate": "no action" 222 + } 223 + }, 224 + "compositePrimaryKeys": { 225 + "account_provider_provider_account_id_pk": { 226 + "columns": [ 227 + "provider", 228 + "provider_account_id" 229 + ], 230 + "name": "account_provider_provider_account_id_pk" 231 + } 232 + }, 233 + "uniqueConstraints": {}, 234 + "checkConstraints": {} 235 + }, 236 + "session": { 237 + "name": "session", 238 + "columns": { 239 + "session_token": { 240 + "name": "session_token", 241 + "type": "text", 242 + "primaryKey": true, 243 + "notNull": true, 244 + "autoincrement": false 245 + }, 246 + "user_id": { 247 + "name": "user_id", 248 + "type": "integer", 249 + "primaryKey": false, 250 + "notNull": true, 251 + "autoincrement": false 252 + }, 253 + "expires": { 254 + "name": "expires", 255 + "type": "integer", 256 + "primaryKey": false, 257 + "notNull": true, 258 + "autoincrement": false 259 + } 260 + }, 261 + "indexes": {}, 262 + "foreignKeys": { 263 + "session_user_id_user_id_fk": { 264 + "name": "session_user_id_user_id_fk", 265 + "tableFrom": "session", 266 + "tableTo": "user", 267 + "columnsFrom": [ 268 + "user_id" 269 + ], 270 + "columnsTo": [ 271 + "id" 272 + ], 273 + "onDelete": "cascade", 274 + "onUpdate": "no action" 275 + } 276 + }, 277 + "compositePrimaryKeys": {}, 278 + "uniqueConstraints": {}, 279 + "checkConstraints": {} 280 + }, 281 + "user": { 282 + "name": "user", 283 + "columns": { 284 + "id": { 285 + "name": "id", 286 + "type": "integer", 287 + "primaryKey": true, 288 + "notNull": true, 289 + "autoincrement": false 290 + }, 291 + "tenant_id": { 292 + "name": "tenant_id", 293 + "type": "text(256)", 294 + "primaryKey": false, 295 + "notNull": false, 296 + "autoincrement": false 297 + }, 298 + "first_name": { 299 + "name": "first_name", 300 + "type": "text", 301 + "primaryKey": false, 302 + "notNull": false, 303 + "autoincrement": false, 304 + "default": "''" 305 + }, 306 + "last_name": { 307 + "name": "last_name", 308 + "type": "text", 309 + "primaryKey": false, 310 + "notNull": false, 311 + "autoincrement": false, 312 + "default": "''" 313 + }, 314 + "photo_url": { 315 + "name": "photo_url", 316 + "type": "text", 317 + "primaryKey": false, 318 + "notNull": false, 319 + "autoincrement": false, 320 + "default": "''" 321 + }, 322 + "name": { 323 + "name": "name", 324 + "type": "text", 325 + "primaryKey": false, 326 + "notNull": false, 327 + "autoincrement": false 328 + }, 329 + "email": { 330 + "name": "email", 331 + "type": "text", 332 + "primaryKey": false, 333 + "notNull": false, 334 + "autoincrement": false, 335 + "default": "''" 336 + }, 337 + "emailVerified": { 338 + "name": "emailVerified", 339 + "type": "integer", 340 + "primaryKey": false, 341 + "notNull": false, 342 + "autoincrement": false 343 + }, 344 + "created_at": { 345 + "name": "created_at", 346 + "type": "integer", 347 + "primaryKey": false, 348 + "notNull": false, 349 + "autoincrement": false, 350 + "default": "(strftime('%s', 'now'))" 351 + }, 352 + "updated_at": { 353 + "name": "updated_at", 354 + "type": "integer", 355 + "primaryKey": false, 356 + "notNull": false, 357 + "autoincrement": false, 358 + "default": "(strftime('%s', 'now'))" 359 + } 360 + }, 361 + "indexes": { 362 + "user_tenant_id_unique": { 363 + "name": "user_tenant_id_unique", 364 + "columns": [ 365 + "tenant_id" 366 + ], 367 + "isUnique": true 368 + } 369 + }, 370 + "foreignKeys": {}, 371 + "compositePrimaryKeys": {}, 372 + "uniqueConstraints": {}, 373 + "checkConstraints": {} 374 + }, 375 + "users_to_workspaces": { 376 + "name": "users_to_workspaces", 377 + "columns": { 378 + "user_id": { 379 + "name": "user_id", 380 + "type": "integer", 381 + "primaryKey": false, 382 + "notNull": true, 383 + "autoincrement": false 384 + }, 385 + "workspace_id": { 386 + "name": "workspace_id", 387 + "type": "integer", 388 + "primaryKey": false, 389 + "notNull": true, 390 + "autoincrement": false 391 + }, 392 + "role": { 393 + "name": "role", 394 + "type": "text", 395 + "primaryKey": false, 396 + "notNull": true, 397 + "autoincrement": false, 398 + "default": "'member'" 399 + }, 400 + "created_at": { 401 + "name": "created_at", 402 + "type": "integer", 403 + "primaryKey": false, 404 + "notNull": false, 405 + "autoincrement": false, 406 + "default": "(strftime('%s', 'now'))" 407 + } 408 + }, 409 + "indexes": {}, 410 + "foreignKeys": { 411 + "users_to_workspaces_user_id_user_id_fk": { 412 + "name": "users_to_workspaces_user_id_user_id_fk", 413 + "tableFrom": "users_to_workspaces", 414 + "tableTo": "user", 415 + "columnsFrom": [ 416 + "user_id" 417 + ], 418 + "columnsTo": [ 419 + "id" 420 + ], 421 + "onDelete": "no action", 422 + "onUpdate": "no action" 423 + }, 424 + "users_to_workspaces_workspace_id_workspace_id_fk": { 425 + "name": "users_to_workspaces_workspace_id_workspace_id_fk", 426 + "tableFrom": "users_to_workspaces", 427 + "tableTo": "workspace", 428 + "columnsFrom": [ 429 + "workspace_id" 430 + ], 431 + "columnsTo": [ 432 + "id" 433 + ], 434 + "onDelete": "no action", 435 + "onUpdate": "no action" 436 + } 437 + }, 438 + "compositePrimaryKeys": { 439 + "users_to_workspaces_user_id_workspace_id_pk": { 440 + "columns": [ 441 + "user_id", 442 + "workspace_id" 443 + ], 444 + "name": "users_to_workspaces_user_id_workspace_id_pk" 445 + } 446 + }, 447 + "uniqueConstraints": {}, 448 + "checkConstraints": {} 449 + }, 450 + "verification_token": { 451 + "name": "verification_token", 452 + "columns": { 453 + "identifier": { 454 + "name": "identifier", 455 + "type": "text", 456 + "primaryKey": false, 457 + "notNull": true, 458 + "autoincrement": false 459 + }, 460 + "token": { 461 + "name": "token", 462 + "type": "text", 463 + "primaryKey": false, 464 + "notNull": true, 465 + "autoincrement": false 466 + }, 467 + "expires": { 468 + "name": "expires", 469 + "type": "integer", 470 + "primaryKey": false, 471 + "notNull": true, 472 + "autoincrement": false 473 + } 474 + }, 475 + "indexes": {}, 476 + "foreignKeys": {}, 477 + "compositePrimaryKeys": { 478 + "verification_token_identifier_token_pk": { 479 + "columns": [ 480 + "identifier", 481 + "token" 482 + ], 483 + "name": "verification_token_identifier_token_pk" 484 + } 485 + }, 486 + "uniqueConstraints": {}, 487 + "checkConstraints": {} 488 + }, 489 + "status_report_to_monitors": { 490 + "name": "status_report_to_monitors", 491 + "columns": { 492 + "monitor_id": { 493 + "name": "monitor_id", 494 + "type": "integer", 495 + "primaryKey": false, 496 + "notNull": true, 497 + "autoincrement": false 498 + }, 499 + "status_report_id": { 500 + "name": "status_report_id", 501 + "type": "integer", 502 + "primaryKey": false, 503 + "notNull": true, 504 + "autoincrement": false 505 + }, 506 + "created_at": { 507 + "name": "created_at", 508 + "type": "integer", 509 + "primaryKey": false, 510 + "notNull": false, 511 + "autoincrement": false, 512 + "default": "(strftime('%s', 'now'))" 513 + } 514 + }, 515 + "indexes": {}, 516 + "foreignKeys": { 517 + "status_report_to_monitors_monitor_id_monitor_id_fk": { 518 + "name": "status_report_to_monitors_monitor_id_monitor_id_fk", 519 + "tableFrom": "status_report_to_monitors", 520 + "tableTo": "monitor", 521 + "columnsFrom": [ 522 + "monitor_id" 523 + ], 524 + "columnsTo": [ 525 + "id" 526 + ], 527 + "onDelete": "cascade", 528 + "onUpdate": "no action" 529 + }, 530 + "status_report_to_monitors_status_report_id_status_report_id_fk": { 531 + "name": "status_report_to_monitors_status_report_id_status_report_id_fk", 532 + "tableFrom": "status_report_to_monitors", 533 + "tableTo": "status_report", 534 + "columnsFrom": [ 535 + "status_report_id" 536 + ], 537 + "columnsTo": [ 538 + "id" 539 + ], 540 + "onDelete": "cascade", 541 + "onUpdate": "no action" 542 + } 543 + }, 544 + "compositePrimaryKeys": { 545 + "status_report_to_monitors_monitor_id_status_report_id_pk": { 546 + "columns": [ 547 + "monitor_id", 548 + "status_report_id" 549 + ], 550 + "name": "status_report_to_monitors_monitor_id_status_report_id_pk" 551 + } 552 + }, 553 + "uniqueConstraints": {}, 554 + "checkConstraints": {} 555 + }, 556 + "status_report": { 557 + "name": "status_report", 558 + "columns": { 559 + "id": { 560 + "name": "id", 561 + "type": "integer", 562 + "primaryKey": true, 563 + "notNull": true, 564 + "autoincrement": false 565 + }, 566 + "status": { 567 + "name": "status", 568 + "type": "text", 569 + "primaryKey": false, 570 + "notNull": true, 571 + "autoincrement": false 572 + }, 573 + "title": { 574 + "name": "title", 575 + "type": "text(256)", 576 + "primaryKey": false, 577 + "notNull": true, 578 + "autoincrement": false 579 + }, 580 + "workspace_id": { 581 + "name": "workspace_id", 582 + "type": "integer", 583 + "primaryKey": false, 584 + "notNull": false, 585 + "autoincrement": false 586 + }, 587 + "page_id": { 588 + "name": "page_id", 589 + "type": "integer", 590 + "primaryKey": false, 591 + "notNull": false, 592 + "autoincrement": false 593 + }, 594 + "created_at": { 595 + "name": "created_at", 596 + "type": "integer", 597 + "primaryKey": false, 598 + "notNull": false, 599 + "autoincrement": false, 600 + "default": "(strftime('%s', 'now'))" 601 + }, 602 + "updated_at": { 603 + "name": "updated_at", 604 + "type": "integer", 605 + "primaryKey": false, 606 + "notNull": false, 607 + "autoincrement": false, 608 + "default": "(strftime('%s', 'now'))" 609 + } 610 + }, 611 + "indexes": {}, 612 + "foreignKeys": { 613 + "status_report_workspace_id_workspace_id_fk": { 614 + "name": "status_report_workspace_id_workspace_id_fk", 615 + "tableFrom": "status_report", 616 + "tableTo": "workspace", 617 + "columnsFrom": [ 618 + "workspace_id" 619 + ], 620 + "columnsTo": [ 621 + "id" 622 + ], 623 + "onDelete": "no action", 624 + "onUpdate": "no action" 625 + }, 626 + "status_report_page_id_page_id_fk": { 627 + "name": "status_report_page_id_page_id_fk", 628 + "tableFrom": "status_report", 629 + "tableTo": "page", 630 + "columnsFrom": [ 631 + "page_id" 632 + ], 633 + "columnsTo": [ 634 + "id" 635 + ], 636 + "onDelete": "cascade", 637 + "onUpdate": "no action" 638 + } 639 + }, 640 + "compositePrimaryKeys": {}, 641 + "uniqueConstraints": {}, 642 + "checkConstraints": {} 643 + }, 644 + "status_report_update": { 645 + "name": "status_report_update", 646 + "columns": { 647 + "id": { 648 + "name": "id", 649 + "type": "integer", 650 + "primaryKey": true, 651 + "notNull": true, 652 + "autoincrement": false 653 + }, 654 + "status": { 655 + "name": "status", 656 + "type": "text", 657 + "primaryKey": false, 658 + "notNull": true, 659 + "autoincrement": false 660 + }, 661 + "date": { 662 + "name": "date", 663 + "type": "integer", 664 + "primaryKey": false, 665 + "notNull": true, 666 + "autoincrement": false 667 + }, 668 + "message": { 669 + "name": "message", 670 + "type": "text", 671 + "primaryKey": false, 672 + "notNull": true, 673 + "autoincrement": false 674 + }, 675 + "status_report_id": { 676 + "name": "status_report_id", 677 + "type": "integer", 678 + "primaryKey": false, 679 + "notNull": true, 680 + "autoincrement": false 681 + }, 682 + "created_at": { 683 + "name": "created_at", 684 + "type": "integer", 685 + "primaryKey": false, 686 + "notNull": false, 687 + "autoincrement": false, 688 + "default": "(strftime('%s', 'now'))" 689 + }, 690 + "updated_at": { 691 + "name": "updated_at", 692 + "type": "integer", 693 + "primaryKey": false, 694 + "notNull": false, 695 + "autoincrement": false, 696 + "default": "(strftime('%s', 'now'))" 697 + } 698 + }, 699 + "indexes": {}, 700 + "foreignKeys": { 701 + "status_report_update_status_report_id_status_report_id_fk": { 702 + "name": "status_report_update_status_report_id_status_report_id_fk", 703 + "tableFrom": "status_report_update", 704 + "tableTo": "status_report", 705 + "columnsFrom": [ 706 + "status_report_id" 707 + ], 708 + "columnsTo": [ 709 + "id" 710 + ], 711 + "onDelete": "cascade", 712 + "onUpdate": "no action" 713 + } 714 + }, 715 + "compositePrimaryKeys": {}, 716 + "uniqueConstraints": {}, 717 + "checkConstraints": {} 718 + }, 719 + "integration": { 720 + "name": "integration", 721 + "columns": { 722 + "id": { 723 + "name": "id", 724 + "type": "integer", 725 + "primaryKey": true, 726 + "notNull": true, 727 + "autoincrement": false 728 + }, 729 + "name": { 730 + "name": "name", 731 + "type": "text(256)", 732 + "primaryKey": false, 733 + "notNull": true, 734 + "autoincrement": false 735 + }, 736 + "workspace_id": { 737 + "name": "workspace_id", 738 + "type": "integer", 739 + "primaryKey": false, 740 + "notNull": false, 741 + "autoincrement": false 742 + }, 743 + "credential": { 744 + "name": "credential", 745 + "type": "text", 746 + "primaryKey": false, 747 + "notNull": false, 748 + "autoincrement": false 749 + }, 750 + "external_id": { 751 + "name": "external_id", 752 + "type": "text", 753 + "primaryKey": false, 754 + "notNull": true, 755 + "autoincrement": false 756 + }, 757 + "created_at": { 758 + "name": "created_at", 759 + "type": "integer", 760 + "primaryKey": false, 761 + "notNull": false, 762 + "autoincrement": false, 763 + "default": "(strftime('%s', 'now'))" 764 + }, 765 + "updated_at": { 766 + "name": "updated_at", 767 + "type": "integer", 768 + "primaryKey": false, 769 + "notNull": false, 770 + "autoincrement": false, 771 + "default": "(strftime('%s', 'now'))" 772 + }, 773 + "data": { 774 + "name": "data", 775 + "type": "text", 776 + "primaryKey": false, 777 + "notNull": true, 778 + "autoincrement": false 779 + } 780 + }, 781 + "indexes": {}, 782 + "foreignKeys": { 783 + "integration_workspace_id_workspace_id_fk": { 784 + "name": "integration_workspace_id_workspace_id_fk", 785 + "tableFrom": "integration", 786 + "tableTo": "workspace", 787 + "columnsFrom": [ 788 + "workspace_id" 789 + ], 790 + "columnsTo": [ 791 + "id" 792 + ], 793 + "onDelete": "no action", 794 + "onUpdate": "no action" 795 + } 796 + }, 797 + "compositePrimaryKeys": {}, 798 + "uniqueConstraints": {}, 799 + "checkConstraints": {} 800 + }, 801 + "page": { 802 + "name": "page", 803 + "columns": { 804 + "id": { 805 + "name": "id", 806 + "type": "integer", 807 + "primaryKey": true, 808 + "notNull": true, 809 + "autoincrement": false 810 + }, 811 + "workspace_id": { 812 + "name": "workspace_id", 813 + "type": "integer", 814 + "primaryKey": false, 815 + "notNull": true, 816 + "autoincrement": false 817 + }, 818 + "title": { 819 + "name": "title", 820 + "type": "text", 821 + "primaryKey": false, 822 + "notNull": true, 823 + "autoincrement": false 824 + }, 825 + "description": { 826 + "name": "description", 827 + "type": "text", 828 + "primaryKey": false, 829 + "notNull": true, 830 + "autoincrement": false 831 + }, 832 + "icon": { 833 + "name": "icon", 834 + "type": "text(256)", 835 + "primaryKey": false, 836 + "notNull": false, 837 + "autoincrement": false, 838 + "default": "''" 839 + }, 840 + "slug": { 841 + "name": "slug", 842 + "type": "text(256)", 843 + "primaryKey": false, 844 + "notNull": true, 845 + "autoincrement": false 846 + }, 847 + "custom_domain": { 848 + "name": "custom_domain", 849 + "type": "text(256)", 850 + "primaryKey": false, 851 + "notNull": true, 852 + "autoincrement": false 853 + }, 854 + "published": { 855 + "name": "published", 856 + "type": "integer", 857 + "primaryKey": false, 858 + "notNull": false, 859 + "autoincrement": false, 860 + "default": false 861 + }, 862 + "force_theme": { 863 + "name": "force_theme", 864 + "type": "text", 865 + "primaryKey": false, 866 + "notNull": true, 867 + "autoincrement": false, 868 + "default": "'system'" 869 + }, 870 + "password": { 871 + "name": "password", 872 + "type": "text(256)", 873 + "primaryKey": false, 874 + "notNull": false, 875 + "autoincrement": false 876 + }, 877 + "password_protected": { 878 + "name": "password_protected", 879 + "type": "integer", 880 + "primaryKey": false, 881 + "notNull": false, 882 + "autoincrement": false, 883 + "default": false 884 + }, 885 + "show_monitor_values": { 886 + "name": "show_monitor_values", 887 + "type": "integer", 888 + "primaryKey": false, 889 + "notNull": false, 890 + "autoincrement": false, 891 + "default": true 892 + }, 893 + "created_at": { 894 + "name": "created_at", 895 + "type": "integer", 896 + "primaryKey": false, 897 + "notNull": false, 898 + "autoincrement": false, 899 + "default": "(strftime('%s', 'now'))" 900 + }, 901 + "updated_at": { 902 + "name": "updated_at", 903 + "type": "integer", 904 + "primaryKey": false, 905 + "notNull": false, 906 + "autoincrement": false, 907 + "default": "(strftime('%s', 'now'))" 908 + } 909 + }, 910 + "indexes": { 911 + "page_slug_unique": { 912 + "name": "page_slug_unique", 913 + "columns": [ 914 + "slug" 915 + ], 916 + "isUnique": true 917 + } 918 + }, 919 + "foreignKeys": { 920 + "page_workspace_id_workspace_id_fk": { 921 + "name": "page_workspace_id_workspace_id_fk", 922 + "tableFrom": "page", 923 + "tableTo": "workspace", 924 + "columnsFrom": [ 925 + "workspace_id" 926 + ], 927 + "columnsTo": [ 928 + "id" 929 + ], 930 + "onDelete": "cascade", 931 + "onUpdate": "no action" 932 + } 933 + }, 934 + "compositePrimaryKeys": {}, 935 + "uniqueConstraints": {}, 936 + "checkConstraints": {} 937 + }, 938 + "monitor": { 939 + "name": "monitor", 940 + "columns": { 941 + "id": { 942 + "name": "id", 943 + "type": "integer", 944 + "primaryKey": true, 945 + "notNull": true, 946 + "autoincrement": false 947 + }, 948 + "job_type": { 949 + "name": "job_type", 950 + "type": "text", 951 + "primaryKey": false, 952 + "notNull": true, 953 + "autoincrement": false, 954 + "default": "'http'" 955 + }, 956 + "periodicity": { 957 + "name": "periodicity", 958 + "type": "text", 959 + "primaryKey": false, 960 + "notNull": true, 961 + "autoincrement": false, 962 + "default": "'other'" 963 + }, 964 + "status": { 965 + "name": "status", 966 + "type": "text", 967 + "primaryKey": false, 968 + "notNull": true, 969 + "autoincrement": false, 970 + "default": "'active'" 971 + }, 972 + "active": { 973 + "name": "active", 974 + "type": "integer", 975 + "primaryKey": false, 976 + "notNull": false, 977 + "autoincrement": false, 978 + "default": false 979 + }, 980 + "regions": { 981 + "name": "regions", 982 + "type": "text", 983 + "primaryKey": false, 984 + "notNull": true, 985 + "autoincrement": false, 986 + "default": "''" 987 + }, 988 + "url": { 989 + "name": "url", 990 + "type": "text(2048)", 991 + "primaryKey": false, 992 + "notNull": true, 993 + "autoincrement": false 994 + }, 995 + "name": { 996 + "name": "name", 997 + "type": "text(256)", 998 + "primaryKey": false, 999 + "notNull": true, 1000 + "autoincrement": false, 1001 + "default": "''" 1002 + }, 1003 + "description": { 1004 + "name": "description", 1005 + "type": "text", 1006 + "primaryKey": false, 1007 + "notNull": true, 1008 + "autoincrement": false, 1009 + "default": "''" 1010 + }, 1011 + "headers": { 1012 + "name": "headers", 1013 + "type": "text", 1014 + "primaryKey": false, 1015 + "notNull": false, 1016 + "autoincrement": false, 1017 + "default": "''" 1018 + }, 1019 + "body": { 1020 + "name": "body", 1021 + "type": "text", 1022 + "primaryKey": false, 1023 + "notNull": false, 1024 + "autoincrement": false, 1025 + "default": "''" 1026 + }, 1027 + "method": { 1028 + "name": "method", 1029 + "type": "text", 1030 + "primaryKey": false, 1031 + "notNull": false, 1032 + "autoincrement": false, 1033 + "default": "'GET'" 1034 + }, 1035 + "workspace_id": { 1036 + "name": "workspace_id", 1037 + "type": "integer", 1038 + "primaryKey": false, 1039 + "notNull": false, 1040 + "autoincrement": false 1041 + }, 1042 + "timeout": { 1043 + "name": "timeout", 1044 + "type": "integer", 1045 + "primaryKey": false, 1046 + "notNull": true, 1047 + "autoincrement": false, 1048 + "default": 45000 1049 + }, 1050 + "degraded_after": { 1051 + "name": "degraded_after", 1052 + "type": "integer", 1053 + "primaryKey": false, 1054 + "notNull": false, 1055 + "autoincrement": false 1056 + }, 1057 + "assertions": { 1058 + "name": "assertions", 1059 + "type": "text", 1060 + "primaryKey": false, 1061 + "notNull": false, 1062 + "autoincrement": false 1063 + }, 1064 + "otel_endpoint": { 1065 + "name": "otel_endpoint", 1066 + "type": "text", 1067 + "primaryKey": false, 1068 + "notNull": false, 1069 + "autoincrement": false 1070 + }, 1071 + "otel_headers": { 1072 + "name": "otel_headers", 1073 + "type": "text", 1074 + "primaryKey": false, 1075 + "notNull": false, 1076 + "autoincrement": false 1077 + }, 1078 + "public": { 1079 + "name": "public", 1080 + "type": "integer", 1081 + "primaryKey": false, 1082 + "notNull": false, 1083 + "autoincrement": false, 1084 + "default": false 1085 + }, 1086 + "retry": { 1087 + "name": "retry", 1088 + "type": "integer", 1089 + "primaryKey": false, 1090 + "notNull": false, 1091 + "autoincrement": false, 1092 + "default": 3 1093 + }, 1094 + "follow_redirects": { 1095 + "name": "follow_redirects", 1096 + "type": "integer", 1097 + "primaryKey": false, 1098 + "notNull": false, 1099 + "autoincrement": false, 1100 + "default": true 1101 + }, 1102 + "created_at": { 1103 + "name": "created_at", 1104 + "type": "integer", 1105 + "primaryKey": false, 1106 + "notNull": false, 1107 + "autoincrement": false, 1108 + "default": "(strftime('%s', 'now'))" 1109 + }, 1110 + "updated_at": { 1111 + "name": "updated_at", 1112 + "type": "integer", 1113 + "primaryKey": false, 1114 + "notNull": false, 1115 + "autoincrement": false, 1116 + "default": "(strftime('%s', 'now'))" 1117 + }, 1118 + "deleted_at": { 1119 + "name": "deleted_at", 1120 + "type": "integer", 1121 + "primaryKey": false, 1122 + "notNull": false, 1123 + "autoincrement": false 1124 + } 1125 + }, 1126 + "indexes": {}, 1127 + "foreignKeys": { 1128 + "monitor_workspace_id_workspace_id_fk": { 1129 + "name": "monitor_workspace_id_workspace_id_fk", 1130 + "tableFrom": "monitor", 1131 + "tableTo": "workspace", 1132 + "columnsFrom": [ 1133 + "workspace_id" 1134 + ], 1135 + "columnsTo": [ 1136 + "id" 1137 + ], 1138 + "onDelete": "no action", 1139 + "onUpdate": "no action" 1140 + } 1141 + }, 1142 + "compositePrimaryKeys": {}, 1143 + "uniqueConstraints": {}, 1144 + "checkConstraints": {} 1145 + }, 1146 + "monitors_to_pages": { 1147 + "name": "monitors_to_pages", 1148 + "columns": { 1149 + "monitor_id": { 1150 + "name": "monitor_id", 1151 + "type": "integer", 1152 + "primaryKey": false, 1153 + "notNull": true, 1154 + "autoincrement": false 1155 + }, 1156 + "page_id": { 1157 + "name": "page_id", 1158 + "type": "integer", 1159 + "primaryKey": false, 1160 + "notNull": true, 1161 + "autoincrement": false 1162 + }, 1163 + "created_at": { 1164 + "name": "created_at", 1165 + "type": "integer", 1166 + "primaryKey": false, 1167 + "notNull": false, 1168 + "autoincrement": false, 1169 + "default": "(strftime('%s', 'now'))" 1170 + }, 1171 + "order": { 1172 + "name": "order", 1173 + "type": "integer", 1174 + "primaryKey": false, 1175 + "notNull": false, 1176 + "autoincrement": false, 1177 + "default": 0 1178 + } 1179 + }, 1180 + "indexes": {}, 1181 + "foreignKeys": { 1182 + "monitors_to_pages_monitor_id_monitor_id_fk": { 1183 + "name": "monitors_to_pages_monitor_id_monitor_id_fk", 1184 + "tableFrom": "monitors_to_pages", 1185 + "tableTo": "monitor", 1186 + "columnsFrom": [ 1187 + "monitor_id" 1188 + ], 1189 + "columnsTo": [ 1190 + "id" 1191 + ], 1192 + "onDelete": "cascade", 1193 + "onUpdate": "no action" 1194 + }, 1195 + "monitors_to_pages_page_id_page_id_fk": { 1196 + "name": "monitors_to_pages_page_id_page_id_fk", 1197 + "tableFrom": "monitors_to_pages", 1198 + "tableTo": "page", 1199 + "columnsFrom": [ 1200 + "page_id" 1201 + ], 1202 + "columnsTo": [ 1203 + "id" 1204 + ], 1205 + "onDelete": "cascade", 1206 + "onUpdate": "no action" 1207 + } 1208 + }, 1209 + "compositePrimaryKeys": { 1210 + "monitors_to_pages_monitor_id_page_id_pk": { 1211 + "columns": [ 1212 + "monitor_id", 1213 + "page_id" 1214 + ], 1215 + "name": "monitors_to_pages_monitor_id_page_id_pk" 1216 + } 1217 + }, 1218 + "uniqueConstraints": {}, 1219 + "checkConstraints": {} 1220 + }, 1221 + "page_subscriber": { 1222 + "name": "page_subscriber", 1223 + "columns": { 1224 + "id": { 1225 + "name": "id", 1226 + "type": "integer", 1227 + "primaryKey": true, 1228 + "notNull": true, 1229 + "autoincrement": false 1230 + }, 1231 + "email": { 1232 + "name": "email", 1233 + "type": "text", 1234 + "primaryKey": false, 1235 + "notNull": true, 1236 + "autoincrement": false 1237 + }, 1238 + "page_id": { 1239 + "name": "page_id", 1240 + "type": "integer", 1241 + "primaryKey": false, 1242 + "notNull": true, 1243 + "autoincrement": false 1244 + }, 1245 + "token": { 1246 + "name": "token", 1247 + "type": "text", 1248 + "primaryKey": false, 1249 + "notNull": false, 1250 + "autoincrement": false 1251 + }, 1252 + "accepted_at": { 1253 + "name": "accepted_at", 1254 + "type": "integer", 1255 + "primaryKey": false, 1256 + "notNull": false, 1257 + "autoincrement": false 1258 + }, 1259 + "expires_at": { 1260 + "name": "expires_at", 1261 + "type": "integer", 1262 + "primaryKey": false, 1263 + "notNull": false, 1264 + "autoincrement": false 1265 + }, 1266 + "created_at": { 1267 + "name": "created_at", 1268 + "type": "integer", 1269 + "primaryKey": false, 1270 + "notNull": false, 1271 + "autoincrement": false, 1272 + "default": "(strftime('%s', 'now'))" 1273 + }, 1274 + "updated_at": { 1275 + "name": "updated_at", 1276 + "type": "integer", 1277 + "primaryKey": false, 1278 + "notNull": false, 1279 + "autoincrement": false, 1280 + "default": "(strftime('%s', 'now'))" 1281 + } 1282 + }, 1283 + "indexes": {}, 1284 + "foreignKeys": { 1285 + "page_subscriber_page_id_page_id_fk": { 1286 + "name": "page_subscriber_page_id_page_id_fk", 1287 + "tableFrom": "page_subscriber", 1288 + "tableTo": "page", 1289 + "columnsFrom": [ 1290 + "page_id" 1291 + ], 1292 + "columnsTo": [ 1293 + "id" 1294 + ], 1295 + "onDelete": "cascade", 1296 + "onUpdate": "no action" 1297 + } 1298 + }, 1299 + "compositePrimaryKeys": {}, 1300 + "uniqueConstraints": {}, 1301 + "checkConstraints": {} 1302 + }, 1303 + "notification": { 1304 + "name": "notification", 1305 + "columns": { 1306 + "id": { 1307 + "name": "id", 1308 + "type": "integer", 1309 + "primaryKey": true, 1310 + "notNull": true, 1311 + "autoincrement": false 1312 + }, 1313 + "name": { 1314 + "name": "name", 1315 + "type": "text", 1316 + "primaryKey": false, 1317 + "notNull": true, 1318 + "autoincrement": false 1319 + }, 1320 + "provider": { 1321 + "name": "provider", 1322 + "type": "text", 1323 + "primaryKey": false, 1324 + "notNull": true, 1325 + "autoincrement": false 1326 + }, 1327 + "data": { 1328 + "name": "data", 1329 + "type": "text", 1330 + "primaryKey": false, 1331 + "notNull": false, 1332 + "autoincrement": false, 1333 + "default": "'{}'" 1334 + }, 1335 + "workspace_id": { 1336 + "name": "workspace_id", 1337 + "type": "integer", 1338 + "primaryKey": false, 1339 + "notNull": false, 1340 + "autoincrement": false 1341 + }, 1342 + "created_at": { 1343 + "name": "created_at", 1344 + "type": "integer", 1345 + "primaryKey": false, 1346 + "notNull": false, 1347 + "autoincrement": false, 1348 + "default": "(strftime('%s', 'now'))" 1349 + }, 1350 + "updated_at": { 1351 + "name": "updated_at", 1352 + "type": "integer", 1353 + "primaryKey": false, 1354 + "notNull": false, 1355 + "autoincrement": false, 1356 + "default": "(strftime('%s', 'now'))" 1357 + } 1358 + }, 1359 + "indexes": {}, 1360 + "foreignKeys": { 1361 + "notification_workspace_id_workspace_id_fk": { 1362 + "name": "notification_workspace_id_workspace_id_fk", 1363 + "tableFrom": "notification", 1364 + "tableTo": "workspace", 1365 + "columnsFrom": [ 1366 + "workspace_id" 1367 + ], 1368 + "columnsTo": [ 1369 + "id" 1370 + ], 1371 + "onDelete": "no action", 1372 + "onUpdate": "no action" 1373 + } 1374 + }, 1375 + "compositePrimaryKeys": {}, 1376 + "uniqueConstraints": {}, 1377 + "checkConstraints": {} 1378 + }, 1379 + "notification_trigger": { 1380 + "name": "notification_trigger", 1381 + "columns": { 1382 + "id": { 1383 + "name": "id", 1384 + "type": "integer", 1385 + "primaryKey": true, 1386 + "notNull": true, 1387 + "autoincrement": false 1388 + }, 1389 + "monitor_id": { 1390 + "name": "monitor_id", 1391 + "type": "integer", 1392 + "primaryKey": false, 1393 + "notNull": false, 1394 + "autoincrement": false 1395 + }, 1396 + "notification_id": { 1397 + "name": "notification_id", 1398 + "type": "integer", 1399 + "primaryKey": false, 1400 + "notNull": false, 1401 + "autoincrement": false 1402 + }, 1403 + "cron_timestamp": { 1404 + "name": "cron_timestamp", 1405 + "type": "integer", 1406 + "primaryKey": false, 1407 + "notNull": true, 1408 + "autoincrement": false 1409 + } 1410 + }, 1411 + "indexes": { 1412 + "notification_id_monitor_id_crontimestampe": { 1413 + "name": "notification_id_monitor_id_crontimestampe", 1414 + "columns": [ 1415 + "notification_id", 1416 + "monitor_id", 1417 + "cron_timestamp" 1418 + ], 1419 + "isUnique": true 1420 + } 1421 + }, 1422 + "foreignKeys": { 1423 + "notification_trigger_monitor_id_monitor_id_fk": { 1424 + "name": "notification_trigger_monitor_id_monitor_id_fk", 1425 + "tableFrom": "notification_trigger", 1426 + "tableTo": "monitor", 1427 + "columnsFrom": [ 1428 + "monitor_id" 1429 + ], 1430 + "columnsTo": [ 1431 + "id" 1432 + ], 1433 + "onDelete": "cascade", 1434 + "onUpdate": "no action" 1435 + }, 1436 + "notification_trigger_notification_id_notification_id_fk": { 1437 + "name": "notification_trigger_notification_id_notification_id_fk", 1438 + "tableFrom": "notification_trigger", 1439 + "tableTo": "notification", 1440 + "columnsFrom": [ 1441 + "notification_id" 1442 + ], 1443 + "columnsTo": [ 1444 + "id" 1445 + ], 1446 + "onDelete": "cascade", 1447 + "onUpdate": "no action" 1448 + } 1449 + }, 1450 + "compositePrimaryKeys": {}, 1451 + "uniqueConstraints": {}, 1452 + "checkConstraints": {} 1453 + }, 1454 + "notifications_to_monitors": { 1455 + "name": "notifications_to_monitors", 1456 + "columns": { 1457 + "monitor_id": { 1458 + "name": "monitor_id", 1459 + "type": "integer", 1460 + "primaryKey": false, 1461 + "notNull": true, 1462 + "autoincrement": false 1463 + }, 1464 + "notification_id": { 1465 + "name": "notification_id", 1466 + "type": "integer", 1467 + "primaryKey": false, 1468 + "notNull": true, 1469 + "autoincrement": false 1470 + }, 1471 + "created_at": { 1472 + "name": "created_at", 1473 + "type": "integer", 1474 + "primaryKey": false, 1475 + "notNull": false, 1476 + "autoincrement": false, 1477 + "default": "(strftime('%s', 'now'))" 1478 + } 1479 + }, 1480 + "indexes": {}, 1481 + "foreignKeys": { 1482 + "notifications_to_monitors_monitor_id_monitor_id_fk": { 1483 + "name": "notifications_to_monitors_monitor_id_monitor_id_fk", 1484 + "tableFrom": "notifications_to_monitors", 1485 + "tableTo": "monitor", 1486 + "columnsFrom": [ 1487 + "monitor_id" 1488 + ], 1489 + "columnsTo": [ 1490 + "id" 1491 + ], 1492 + "onDelete": "cascade", 1493 + "onUpdate": "no action" 1494 + }, 1495 + "notifications_to_monitors_notification_id_notification_id_fk": { 1496 + "name": "notifications_to_monitors_notification_id_notification_id_fk", 1497 + "tableFrom": "notifications_to_monitors", 1498 + "tableTo": "notification", 1499 + "columnsFrom": [ 1500 + "notification_id" 1501 + ], 1502 + "columnsTo": [ 1503 + "id" 1504 + ], 1505 + "onDelete": "cascade", 1506 + "onUpdate": "no action" 1507 + } 1508 + }, 1509 + "compositePrimaryKeys": { 1510 + "notifications_to_monitors_monitor_id_notification_id_pk": { 1511 + "columns": [ 1512 + "monitor_id", 1513 + "notification_id" 1514 + ], 1515 + "name": "notifications_to_monitors_monitor_id_notification_id_pk" 1516 + } 1517 + }, 1518 + "uniqueConstraints": {}, 1519 + "checkConstraints": {} 1520 + }, 1521 + "monitor_status": { 1522 + "name": "monitor_status", 1523 + "columns": { 1524 + "monitor_id": { 1525 + "name": "monitor_id", 1526 + "type": "integer", 1527 + "primaryKey": false, 1528 + "notNull": true, 1529 + "autoincrement": false 1530 + }, 1531 + "region": { 1532 + "name": "region", 1533 + "type": "text", 1534 + "primaryKey": false, 1535 + "notNull": true, 1536 + "autoincrement": false, 1537 + "default": "''" 1538 + }, 1539 + "status": { 1540 + "name": "status", 1541 + "type": "text", 1542 + "primaryKey": false, 1543 + "notNull": true, 1544 + "autoincrement": false, 1545 + "default": "'active'" 1546 + }, 1547 + "created_at": { 1548 + "name": "created_at", 1549 + "type": "integer", 1550 + "primaryKey": false, 1551 + "notNull": false, 1552 + "autoincrement": false, 1553 + "default": "(strftime('%s', 'now'))" 1554 + }, 1555 + "updated_at": { 1556 + "name": "updated_at", 1557 + "type": "integer", 1558 + "primaryKey": false, 1559 + "notNull": false, 1560 + "autoincrement": false, 1561 + "default": "(strftime('%s', 'now'))" 1562 + } 1563 + }, 1564 + "indexes": { 1565 + "monitor_status_idx": { 1566 + "name": "monitor_status_idx", 1567 + "columns": [ 1568 + "monitor_id", 1569 + "region" 1570 + ], 1571 + "isUnique": false 1572 + } 1573 + }, 1574 + "foreignKeys": { 1575 + "monitor_status_monitor_id_monitor_id_fk": { 1576 + "name": "monitor_status_monitor_id_monitor_id_fk", 1577 + "tableFrom": "monitor_status", 1578 + "tableTo": "monitor", 1579 + "columnsFrom": [ 1580 + "monitor_id" 1581 + ], 1582 + "columnsTo": [ 1583 + "id" 1584 + ], 1585 + "onDelete": "cascade", 1586 + "onUpdate": "no action" 1587 + } 1588 + }, 1589 + "compositePrimaryKeys": { 1590 + "monitor_status_monitor_id_region_pk": { 1591 + "columns": [ 1592 + "monitor_id", 1593 + "region" 1594 + ], 1595 + "name": "monitor_status_monitor_id_region_pk" 1596 + } 1597 + }, 1598 + "uniqueConstraints": {}, 1599 + "checkConstraints": {} 1600 + }, 1601 + "invitation": { 1602 + "name": "invitation", 1603 + "columns": { 1604 + "id": { 1605 + "name": "id", 1606 + "type": "integer", 1607 + "primaryKey": true, 1608 + "notNull": true, 1609 + "autoincrement": false 1610 + }, 1611 + "email": { 1612 + "name": "email", 1613 + "type": "text", 1614 + "primaryKey": false, 1615 + "notNull": true, 1616 + "autoincrement": false 1617 + }, 1618 + "role": { 1619 + "name": "role", 1620 + "type": "text", 1621 + "primaryKey": false, 1622 + "notNull": true, 1623 + "autoincrement": false, 1624 + "default": "'member'" 1625 + }, 1626 + "workspace_id": { 1627 + "name": "workspace_id", 1628 + "type": "integer", 1629 + "primaryKey": false, 1630 + "notNull": true, 1631 + "autoincrement": false 1632 + }, 1633 + "token": { 1634 + "name": "token", 1635 + "type": "text", 1636 + "primaryKey": false, 1637 + "notNull": true, 1638 + "autoincrement": false 1639 + }, 1640 + "expires_at": { 1641 + "name": "expires_at", 1642 + "type": "integer", 1643 + "primaryKey": false, 1644 + "notNull": true, 1645 + "autoincrement": false 1646 + }, 1647 + "created_at": { 1648 + "name": "created_at", 1649 + "type": "integer", 1650 + "primaryKey": false, 1651 + "notNull": false, 1652 + "autoincrement": false, 1653 + "default": "(strftime('%s', 'now'))" 1654 + }, 1655 + "accepted_at": { 1656 + "name": "accepted_at", 1657 + "type": "integer", 1658 + "primaryKey": false, 1659 + "notNull": false, 1660 + "autoincrement": false 1661 + } 1662 + }, 1663 + "indexes": {}, 1664 + "foreignKeys": {}, 1665 + "compositePrimaryKeys": {}, 1666 + "uniqueConstraints": {}, 1667 + "checkConstraints": {} 1668 + }, 1669 + "incident": { 1670 + "name": "incident", 1671 + "columns": { 1672 + "id": { 1673 + "name": "id", 1674 + "type": "integer", 1675 + "primaryKey": true, 1676 + "notNull": true, 1677 + "autoincrement": false 1678 + }, 1679 + "title": { 1680 + "name": "title", 1681 + "type": "text", 1682 + "primaryKey": false, 1683 + "notNull": true, 1684 + "autoincrement": false, 1685 + "default": "''" 1686 + }, 1687 + "summary": { 1688 + "name": "summary", 1689 + "type": "text", 1690 + "primaryKey": false, 1691 + "notNull": true, 1692 + "autoincrement": false, 1693 + "default": "''" 1694 + }, 1695 + "status": { 1696 + "name": "status", 1697 + "type": "text", 1698 + "primaryKey": false, 1699 + "notNull": true, 1700 + "autoincrement": false, 1701 + "default": "'triage'" 1702 + }, 1703 + "monitor_id": { 1704 + "name": "monitor_id", 1705 + "type": "integer", 1706 + "primaryKey": false, 1707 + "notNull": false, 1708 + "autoincrement": false 1709 + }, 1710 + "workspace_id": { 1711 + "name": "workspace_id", 1712 + "type": "integer", 1713 + "primaryKey": false, 1714 + "notNull": false, 1715 + "autoincrement": false 1716 + }, 1717 + "started_at": { 1718 + "name": "started_at", 1719 + "type": "integer", 1720 + "primaryKey": false, 1721 + "notNull": true, 1722 + "autoincrement": false, 1723 + "default": "(strftime('%s', 'now'))" 1724 + }, 1725 + "acknowledged_at": { 1726 + "name": "acknowledged_at", 1727 + "type": "integer", 1728 + "primaryKey": false, 1729 + "notNull": false, 1730 + "autoincrement": false 1731 + }, 1732 + "acknowledged_by": { 1733 + "name": "acknowledged_by", 1734 + "type": "integer", 1735 + "primaryKey": false, 1736 + "notNull": false, 1737 + "autoincrement": false 1738 + }, 1739 + "resolved_at": { 1740 + "name": "resolved_at", 1741 + "type": "integer", 1742 + "primaryKey": false, 1743 + "notNull": false, 1744 + "autoincrement": false 1745 + }, 1746 + "resolved_by": { 1747 + "name": "resolved_by", 1748 + "type": "integer", 1749 + "primaryKey": false, 1750 + "notNull": false, 1751 + "autoincrement": false 1752 + }, 1753 + "incident_screenshot_url": { 1754 + "name": "incident_screenshot_url", 1755 + "type": "text", 1756 + "primaryKey": false, 1757 + "notNull": false, 1758 + "autoincrement": false 1759 + }, 1760 + "recovery_screenshot_url": { 1761 + "name": "recovery_screenshot_url", 1762 + "type": "text", 1763 + "primaryKey": false, 1764 + "notNull": false, 1765 + "autoincrement": false 1766 + }, 1767 + "auto_resolved": { 1768 + "name": "auto_resolved", 1769 + "type": "integer", 1770 + "primaryKey": false, 1771 + "notNull": false, 1772 + "autoincrement": false, 1773 + "default": false 1774 + }, 1775 + "created_at": { 1776 + "name": "created_at", 1777 + "type": "integer", 1778 + "primaryKey": false, 1779 + "notNull": false, 1780 + "autoincrement": false, 1781 + "default": "(strftime('%s', 'now'))" 1782 + }, 1783 + "updated_at": { 1784 + "name": "updated_at", 1785 + "type": "integer", 1786 + "primaryKey": false, 1787 + "notNull": false, 1788 + "autoincrement": false, 1789 + "default": "(strftime('%s', 'now'))" 1790 + } 1791 + }, 1792 + "indexes": { 1793 + "incident_monitor_id_started_at_unique": { 1794 + "name": "incident_monitor_id_started_at_unique", 1795 + "columns": [ 1796 + "monitor_id", 1797 + "started_at" 1798 + ], 1799 + "isUnique": true 1800 + } 1801 + }, 1802 + "foreignKeys": { 1803 + "incident_monitor_id_monitor_id_fk": { 1804 + "name": "incident_monitor_id_monitor_id_fk", 1805 + "tableFrom": "incident", 1806 + "tableTo": "monitor", 1807 + "columnsFrom": [ 1808 + "monitor_id" 1809 + ], 1810 + "columnsTo": [ 1811 + "id" 1812 + ], 1813 + "onDelete": "set default", 1814 + "onUpdate": "no action" 1815 + }, 1816 + "incident_workspace_id_workspace_id_fk": { 1817 + "name": "incident_workspace_id_workspace_id_fk", 1818 + "tableFrom": "incident", 1819 + "tableTo": "workspace", 1820 + "columnsFrom": [ 1821 + "workspace_id" 1822 + ], 1823 + "columnsTo": [ 1824 + "id" 1825 + ], 1826 + "onDelete": "no action", 1827 + "onUpdate": "no action" 1828 + }, 1829 + "incident_acknowledged_by_user_id_fk": { 1830 + "name": "incident_acknowledged_by_user_id_fk", 1831 + "tableFrom": "incident", 1832 + "tableTo": "user", 1833 + "columnsFrom": [ 1834 + "acknowledged_by" 1835 + ], 1836 + "columnsTo": [ 1837 + "id" 1838 + ], 1839 + "onDelete": "no action", 1840 + "onUpdate": "no action" 1841 + }, 1842 + "incident_resolved_by_user_id_fk": { 1843 + "name": "incident_resolved_by_user_id_fk", 1844 + "tableFrom": "incident", 1845 + "tableTo": "user", 1846 + "columnsFrom": [ 1847 + "resolved_by" 1848 + ], 1849 + "columnsTo": [ 1850 + "id" 1851 + ], 1852 + "onDelete": "no action", 1853 + "onUpdate": "no action" 1854 + } 1855 + }, 1856 + "compositePrimaryKeys": {}, 1857 + "uniqueConstraints": {}, 1858 + "checkConstraints": {} 1859 + }, 1860 + "monitor_tag": { 1861 + "name": "monitor_tag", 1862 + "columns": { 1863 + "id": { 1864 + "name": "id", 1865 + "type": "integer", 1866 + "primaryKey": true, 1867 + "notNull": true, 1868 + "autoincrement": false 1869 + }, 1870 + "workspace_id": { 1871 + "name": "workspace_id", 1872 + "type": "integer", 1873 + "primaryKey": false, 1874 + "notNull": true, 1875 + "autoincrement": false 1876 + }, 1877 + "name": { 1878 + "name": "name", 1879 + "type": "text", 1880 + "primaryKey": false, 1881 + "notNull": true, 1882 + "autoincrement": false 1883 + }, 1884 + "color": { 1885 + "name": "color", 1886 + "type": "text", 1887 + "primaryKey": false, 1888 + "notNull": true, 1889 + "autoincrement": false 1890 + }, 1891 + "created_at": { 1892 + "name": "created_at", 1893 + "type": "integer", 1894 + "primaryKey": false, 1895 + "notNull": false, 1896 + "autoincrement": false, 1897 + "default": "(strftime('%s', 'now'))" 1898 + }, 1899 + "updated_at": { 1900 + "name": "updated_at", 1901 + "type": "integer", 1902 + "primaryKey": false, 1903 + "notNull": false, 1904 + "autoincrement": false, 1905 + "default": "(strftime('%s', 'now'))" 1906 + } 1907 + }, 1908 + "indexes": {}, 1909 + "foreignKeys": { 1910 + "monitor_tag_workspace_id_workspace_id_fk": { 1911 + "name": "monitor_tag_workspace_id_workspace_id_fk", 1912 + "tableFrom": "monitor_tag", 1913 + "tableTo": "workspace", 1914 + "columnsFrom": [ 1915 + "workspace_id" 1916 + ], 1917 + "columnsTo": [ 1918 + "id" 1919 + ], 1920 + "onDelete": "cascade", 1921 + "onUpdate": "no action" 1922 + } 1923 + }, 1924 + "compositePrimaryKeys": {}, 1925 + "uniqueConstraints": {}, 1926 + "checkConstraints": {} 1927 + }, 1928 + "monitor_tag_to_monitor": { 1929 + "name": "monitor_tag_to_monitor", 1930 + "columns": { 1931 + "monitor_id": { 1932 + "name": "monitor_id", 1933 + "type": "integer", 1934 + "primaryKey": false, 1935 + "notNull": true, 1936 + "autoincrement": false 1937 + }, 1938 + "monitor_tag_id": { 1939 + "name": "monitor_tag_id", 1940 + "type": "integer", 1941 + "primaryKey": false, 1942 + "notNull": true, 1943 + "autoincrement": false 1944 + }, 1945 + "created_at": { 1946 + "name": "created_at", 1947 + "type": "integer", 1948 + "primaryKey": false, 1949 + "notNull": false, 1950 + "autoincrement": false, 1951 + "default": "(strftime('%s', 'now'))" 1952 + } 1953 + }, 1954 + "indexes": {}, 1955 + "foreignKeys": { 1956 + "monitor_tag_to_monitor_monitor_id_monitor_id_fk": { 1957 + "name": "monitor_tag_to_monitor_monitor_id_monitor_id_fk", 1958 + "tableFrom": "monitor_tag_to_monitor", 1959 + "tableTo": "monitor", 1960 + "columnsFrom": [ 1961 + "monitor_id" 1962 + ], 1963 + "columnsTo": [ 1964 + "id" 1965 + ], 1966 + "onDelete": "cascade", 1967 + "onUpdate": "no action" 1968 + }, 1969 + "monitor_tag_to_monitor_monitor_tag_id_monitor_tag_id_fk": { 1970 + "name": "monitor_tag_to_monitor_monitor_tag_id_monitor_tag_id_fk", 1971 + "tableFrom": "monitor_tag_to_monitor", 1972 + "tableTo": "monitor_tag", 1973 + "columnsFrom": [ 1974 + "monitor_tag_id" 1975 + ], 1976 + "columnsTo": [ 1977 + "id" 1978 + ], 1979 + "onDelete": "cascade", 1980 + "onUpdate": "no action" 1981 + } 1982 + }, 1983 + "compositePrimaryKeys": { 1984 + "monitor_tag_to_monitor_monitor_id_monitor_tag_id_pk": { 1985 + "columns": [ 1986 + "monitor_id", 1987 + "monitor_tag_id" 1988 + ], 1989 + "name": "monitor_tag_to_monitor_monitor_id_monitor_tag_id_pk" 1990 + } 1991 + }, 1992 + "uniqueConstraints": {}, 1993 + "checkConstraints": {} 1994 + }, 1995 + "application": { 1996 + "name": "application", 1997 + "columns": { 1998 + "id": { 1999 + "name": "id", 2000 + "type": "integer", 2001 + "primaryKey": true, 2002 + "notNull": true, 2003 + "autoincrement": false 2004 + }, 2005 + "name": { 2006 + "name": "name", 2007 + "type": "text", 2008 + "primaryKey": false, 2009 + "notNull": false, 2010 + "autoincrement": false 2011 + }, 2012 + "dsn": { 2013 + "name": "dsn", 2014 + "type": "text", 2015 + "primaryKey": false, 2016 + "notNull": false, 2017 + "autoincrement": false 2018 + }, 2019 + "workspace_id": { 2020 + "name": "workspace_id", 2021 + "type": "integer", 2022 + "primaryKey": false, 2023 + "notNull": false, 2024 + "autoincrement": false 2025 + }, 2026 + "created_at": { 2027 + "name": "created_at", 2028 + "type": "integer", 2029 + "primaryKey": false, 2030 + "notNull": false, 2031 + "autoincrement": false, 2032 + "default": "(strftime('%s', 'now'))" 2033 + }, 2034 + "updated_at": { 2035 + "name": "updated_at", 2036 + "type": "integer", 2037 + "primaryKey": false, 2038 + "notNull": false, 2039 + "autoincrement": false, 2040 + "default": "(strftime('%s', 'now'))" 2041 + } 2042 + }, 2043 + "indexes": { 2044 + "application_dsn_unique": { 2045 + "name": "application_dsn_unique", 2046 + "columns": [ 2047 + "dsn" 2048 + ], 2049 + "isUnique": true 2050 + } 2051 + }, 2052 + "foreignKeys": { 2053 + "application_workspace_id_workspace_id_fk": { 2054 + "name": "application_workspace_id_workspace_id_fk", 2055 + "tableFrom": "application", 2056 + "tableTo": "workspace", 2057 + "columnsFrom": [ 2058 + "workspace_id" 2059 + ], 2060 + "columnsTo": [ 2061 + "id" 2062 + ], 2063 + "onDelete": "no action", 2064 + "onUpdate": "no action" 2065 + } 2066 + }, 2067 + "compositePrimaryKeys": {}, 2068 + "uniqueConstraints": {}, 2069 + "checkConstraints": {} 2070 + }, 2071 + "maintenance": { 2072 + "name": "maintenance", 2073 + "columns": { 2074 + "id": { 2075 + "name": "id", 2076 + "type": "integer", 2077 + "primaryKey": true, 2078 + "notNull": true, 2079 + "autoincrement": false 2080 + }, 2081 + "title": { 2082 + "name": "title", 2083 + "type": "text(256)", 2084 + "primaryKey": false, 2085 + "notNull": true, 2086 + "autoincrement": false 2087 + }, 2088 + "message": { 2089 + "name": "message", 2090 + "type": "text", 2091 + "primaryKey": false, 2092 + "notNull": true, 2093 + "autoincrement": false 2094 + }, 2095 + "from": { 2096 + "name": "from", 2097 + "type": "integer", 2098 + "primaryKey": false, 2099 + "notNull": true, 2100 + "autoincrement": false 2101 + }, 2102 + "to": { 2103 + "name": "to", 2104 + "type": "integer", 2105 + "primaryKey": false, 2106 + "notNull": true, 2107 + "autoincrement": false 2108 + }, 2109 + "workspace_id": { 2110 + "name": "workspace_id", 2111 + "type": "integer", 2112 + "primaryKey": false, 2113 + "notNull": false, 2114 + "autoincrement": false 2115 + }, 2116 + "page_id": { 2117 + "name": "page_id", 2118 + "type": "integer", 2119 + "primaryKey": false, 2120 + "notNull": false, 2121 + "autoincrement": false 2122 + }, 2123 + "created_at": { 2124 + "name": "created_at", 2125 + "type": "integer", 2126 + "primaryKey": false, 2127 + "notNull": false, 2128 + "autoincrement": false, 2129 + "default": "(strftime('%s', 'now'))" 2130 + }, 2131 + "updated_at": { 2132 + "name": "updated_at", 2133 + "type": "integer", 2134 + "primaryKey": false, 2135 + "notNull": false, 2136 + "autoincrement": false, 2137 + "default": "(strftime('%s', 'now'))" 2138 + } 2139 + }, 2140 + "indexes": {}, 2141 + "foreignKeys": { 2142 + "maintenance_workspace_id_workspace_id_fk": { 2143 + "name": "maintenance_workspace_id_workspace_id_fk", 2144 + "tableFrom": "maintenance", 2145 + "tableTo": "workspace", 2146 + "columnsFrom": [ 2147 + "workspace_id" 2148 + ], 2149 + "columnsTo": [ 2150 + "id" 2151 + ], 2152 + "onDelete": "no action", 2153 + "onUpdate": "no action" 2154 + }, 2155 + "maintenance_page_id_page_id_fk": { 2156 + "name": "maintenance_page_id_page_id_fk", 2157 + "tableFrom": "maintenance", 2158 + "tableTo": "page", 2159 + "columnsFrom": [ 2160 + "page_id" 2161 + ], 2162 + "columnsTo": [ 2163 + "id" 2164 + ], 2165 + "onDelete": "cascade", 2166 + "onUpdate": "no action" 2167 + } 2168 + }, 2169 + "compositePrimaryKeys": {}, 2170 + "uniqueConstraints": {}, 2171 + "checkConstraints": {} 2172 + }, 2173 + "maintenance_to_monitor": { 2174 + "name": "maintenance_to_monitor", 2175 + "columns": { 2176 + "maintenance_id": { 2177 + "name": "maintenance_id", 2178 + "type": "integer", 2179 + "primaryKey": false, 2180 + "notNull": true, 2181 + "autoincrement": false 2182 + }, 2183 + "monitor_id": { 2184 + "name": "monitor_id", 2185 + "type": "integer", 2186 + "primaryKey": false, 2187 + "notNull": true, 2188 + "autoincrement": false 2189 + }, 2190 + "created_at": { 2191 + "name": "created_at", 2192 + "type": "integer", 2193 + "primaryKey": false, 2194 + "notNull": false, 2195 + "autoincrement": false, 2196 + "default": "(strftime('%s', 'now'))" 2197 + } 2198 + }, 2199 + "indexes": {}, 2200 + "foreignKeys": { 2201 + "maintenance_to_monitor_maintenance_id_maintenance_id_fk": { 2202 + "name": "maintenance_to_monitor_maintenance_id_maintenance_id_fk", 2203 + "tableFrom": "maintenance_to_monitor", 2204 + "tableTo": "maintenance", 2205 + "columnsFrom": [ 2206 + "maintenance_id" 2207 + ], 2208 + "columnsTo": [ 2209 + "id" 2210 + ], 2211 + "onDelete": "cascade", 2212 + "onUpdate": "no action" 2213 + }, 2214 + "maintenance_to_monitor_monitor_id_monitor_id_fk": { 2215 + "name": "maintenance_to_monitor_monitor_id_monitor_id_fk", 2216 + "tableFrom": "maintenance_to_monitor", 2217 + "tableTo": "monitor", 2218 + "columnsFrom": [ 2219 + "monitor_id" 2220 + ], 2221 + "columnsTo": [ 2222 + "id" 2223 + ], 2224 + "onDelete": "cascade", 2225 + "onUpdate": "no action" 2226 + } 2227 + }, 2228 + "compositePrimaryKeys": { 2229 + "maintenance_to_monitor_maintenance_id_monitor_id_pk": { 2230 + "columns": [ 2231 + "maintenance_id", 2232 + "monitor_id" 2233 + ], 2234 + "name": "maintenance_to_monitor_maintenance_id_monitor_id_pk" 2235 + } 2236 + }, 2237 + "uniqueConstraints": {}, 2238 + "checkConstraints": {} 2239 + }, 2240 + "check": { 2241 + "name": "check", 2242 + "columns": { 2243 + "id": { 2244 + "name": "id", 2245 + "type": "integer", 2246 + "primaryKey": true, 2247 + "notNull": true, 2248 + "autoincrement": true 2249 + }, 2250 + "regions": { 2251 + "name": "regions", 2252 + "type": "text", 2253 + "primaryKey": false, 2254 + "notNull": true, 2255 + "autoincrement": false, 2256 + "default": "''" 2257 + }, 2258 + "url": { 2259 + "name": "url", 2260 + "type": "text(4096)", 2261 + "primaryKey": false, 2262 + "notNull": true, 2263 + "autoincrement": false 2264 + }, 2265 + "headers": { 2266 + "name": "headers", 2267 + "type": "text", 2268 + "primaryKey": false, 2269 + "notNull": false, 2270 + "autoincrement": false, 2271 + "default": "''" 2272 + }, 2273 + "body": { 2274 + "name": "body", 2275 + "type": "text", 2276 + "primaryKey": false, 2277 + "notNull": false, 2278 + "autoincrement": false, 2279 + "default": "''" 2280 + }, 2281 + "method": { 2282 + "name": "method", 2283 + "type": "text", 2284 + "primaryKey": false, 2285 + "notNull": false, 2286 + "autoincrement": false, 2287 + "default": "'GET'" 2288 + }, 2289 + "count_requests": { 2290 + "name": "count_requests", 2291 + "type": "integer", 2292 + "primaryKey": false, 2293 + "notNull": false, 2294 + "autoincrement": false, 2295 + "default": 1 2296 + }, 2297 + "workspace_id": { 2298 + "name": "workspace_id", 2299 + "type": "integer", 2300 + "primaryKey": false, 2301 + "notNull": false, 2302 + "autoincrement": false 2303 + }, 2304 + "created_at": { 2305 + "name": "created_at", 2306 + "type": "integer", 2307 + "primaryKey": false, 2308 + "notNull": false, 2309 + "autoincrement": false, 2310 + "default": "(strftime('%s', 'now'))" 2311 + } 2312 + }, 2313 + "indexes": {}, 2314 + "foreignKeys": { 2315 + "check_workspace_id_workspace_id_fk": { 2316 + "name": "check_workspace_id_workspace_id_fk", 2317 + "tableFrom": "check", 2318 + "tableTo": "workspace", 2319 + "columnsFrom": [ 2320 + "workspace_id" 2321 + ], 2322 + "columnsTo": [ 2323 + "id" 2324 + ], 2325 + "onDelete": "no action", 2326 + "onUpdate": "no action" 2327 + } 2328 + }, 2329 + "compositePrimaryKeys": {}, 2330 + "uniqueConstraints": {}, 2331 + "checkConstraints": {} 2332 + }, 2333 + "monitor_run": { 2334 + "name": "monitor_run", 2335 + "columns": { 2336 + "id": { 2337 + "name": "id", 2338 + "type": "integer", 2339 + "primaryKey": true, 2340 + "notNull": true, 2341 + "autoincrement": false 2342 + }, 2343 + "workspace_id": { 2344 + "name": "workspace_id", 2345 + "type": "integer", 2346 + "primaryKey": false, 2347 + "notNull": false, 2348 + "autoincrement": false 2349 + }, 2350 + "monitor_id": { 2351 + "name": "monitor_id", 2352 + "type": "integer", 2353 + "primaryKey": false, 2354 + "notNull": false, 2355 + "autoincrement": false 2356 + }, 2357 + "runned_at": { 2358 + "name": "runned_at", 2359 + "type": "integer", 2360 + "primaryKey": false, 2361 + "notNull": false, 2362 + "autoincrement": false 2363 + }, 2364 + "created_at": { 2365 + "name": "created_at", 2366 + "type": "integer", 2367 + "primaryKey": false, 2368 + "notNull": false, 2369 + "autoincrement": false, 2370 + "default": "(strftime('%s', 'now'))" 2371 + } 2372 + }, 2373 + "indexes": {}, 2374 + "foreignKeys": { 2375 + "monitor_run_workspace_id_workspace_id_fk": { 2376 + "name": "monitor_run_workspace_id_workspace_id_fk", 2377 + "tableFrom": "monitor_run", 2378 + "tableTo": "workspace", 2379 + "columnsFrom": [ 2380 + "workspace_id" 2381 + ], 2382 + "columnsTo": [ 2383 + "id" 2384 + ], 2385 + "onDelete": "no action", 2386 + "onUpdate": "no action" 2387 + }, 2388 + "monitor_run_monitor_id_monitor_id_fk": { 2389 + "name": "monitor_run_monitor_id_monitor_id_fk", 2390 + "tableFrom": "monitor_run", 2391 + "tableTo": "monitor", 2392 + "columnsFrom": [ 2393 + "monitor_id" 2394 + ], 2395 + "columnsTo": [ 2396 + "id" 2397 + ], 2398 + "onDelete": "no action", 2399 + "onUpdate": "no action" 2400 + } 2401 + }, 2402 + "compositePrimaryKeys": {}, 2403 + "uniqueConstraints": {}, 2404 + "checkConstraints": {} 2405 + } 2406 + }, 2407 + "views": {}, 2408 + "enums": {}, 2409 + "_meta": { 2410 + "schemas": {}, 2411 + "tables": {}, 2412 + "columns": {} 2413 + }, 2414 + "internal": { 2415 + "indexes": {} 2416 + } 2417 + }
+7
packages/db/drizzle/meta/_journal.json
··· 316 316 "when": 1753730490635, 317 317 "tag": "0044_illegal_turbo", 318 318 "breakpoints": true 319 + }, 320 + { 321 + "idx": 45, 322 + "version": "6", 323 + "when": 1756185045968, 324 + "tag": "0045_little_paladin", 325 + "breakpoints": true 319 326 } 320 327 ] 321 328 }
+4
packages/db/src/schema/monitors/monitor.ts
··· 56 56 57 57 retry: integer("retry").default(3), 58 58 59 + followRedirects: integer("follow_redirects", { mode: "boolean" }).default( 60 + true, 61 + ), 62 + 59 63 createdAt: integer("created_at", { mode: "timestamp" }).default( 60 64 sql`(strftime('%s', 'now'))`, 61 65 ),
+1
packages/db/src/schema/monitors/validation.ts
··· 45 45 status: monitorStatusSchema.default("active"), 46 46 jobType: monitorJobTypesSchema.default("http"), 47 47 timeout: z.number().default(45), 48 + followRedirects: z.boolean().default(true), 48 49 retry: z.number().default(3), 49 50 regions: regionsToArraySchema.default([]), 50 51 }).extend({