Openstatus www.openstatus.dev

๐Ÿ’Œ store user email (#167)

* ๐Ÿ’Œ store user email

* ๐Ÿš€ add photo url

authored by

Thibault Le Ouay and committed by
GitHub
5b2997b1 fbd3f0f5

+621 -6
+1 -1
apps/web/src/env.ts
··· 1 1 import { createEnv } from "@t3-oss/env-nextjs"; 2 2 import { z } from "zod"; 3 3 4 - import "@openstatus/db/env"; 4 + import "@openstatus/db/env.mjs"; 5 5 import "@openstatus/analytics/env"; 6 6 7 7 export const env = createEnv({
+3
packages/api/src/router/clerk/webhook.ts
··· 28 28 const userResult = await opts.ctx.db 29 29 .insert(user) 30 30 .values({ 31 + email: opts.input.data.data.email_addresses[0].email_address, 31 32 tenantId: opts.input.data.data.id, 33 + firstName: opts.input.data.data.first_name, 34 + lastName: opts.input.data.data.last_name || "", 32 35 }) 33 36 .returning() 34 37 .get();
+1 -1
packages/db/drizzle.config.ts
··· 2 2 3 3 import type { Config } from "drizzle-kit"; 4 4 5 - import { env } from "./env"; 5 + import { env } from "./env.mjs"; 6 6 7 7 export default { 8 8 schema: "./src/schema/index.ts",
+4
packages/db/drizzle/0002_luxuriant_ser_duncan.sql
··· 1 + ALTER TABLE user ADD `first_name` text DEFAULT '';--> statement-breakpoint 2 + ALTER TABLE user ADD `last_name` text DEFAULT '';--> statement-breakpoint 3 + ALTER TABLE user ADD `email` text DEFAULT '';--> statement-breakpoint 4 + ALTER TABLE user ADD `photo_url` text DEFAULT '';
+596
packages/db/drizzle/meta/0002_snapshot.json
··· 1 + { 2 + "version": "5", 3 + "dialect": "sqlite", 4 + "id": "84c77cb9-dca1-424b-8929-c31f24ad5144", 5 + "prevId": "762acc59-e72a-4ca4-b3fa-2cfd65cdf49a", 6 + "tables": { 7 + "incident": { 8 + "name": "incident", 9 + "columns": { 10 + "id": { 11 + "name": "id", 12 + "type": "integer", 13 + "primaryKey": true, 14 + "notNull": true, 15 + "autoincrement": false 16 + }, 17 + "status": { 18 + "name": "status", 19 + "type": "text(2)", 20 + "primaryKey": false, 21 + "notNull": true, 22 + "autoincrement": false 23 + }, 24 + "page_id": { 25 + "name": "page_id", 26 + "type": "text", 27 + "primaryKey": false, 28 + "notNull": true, 29 + "autoincrement": false 30 + }, 31 + "updated_at": { 32 + "name": "updated_at", 33 + "type": "integer", 34 + "primaryKey": false, 35 + "notNull": false, 36 + "autoincrement": false, 37 + "default": "(strftime('%s', 'now'))" 38 + } 39 + }, 40 + "indexes": {}, 41 + "foreignKeys": { 42 + "incident_page_id_page_id_fk": { 43 + "name": "incident_page_id_page_id_fk", 44 + "tableFrom": "incident", 45 + "tableTo": "page", 46 + "columnsFrom": [ 47 + "page_id" 48 + ], 49 + "columnsTo": [ 50 + "id" 51 + ], 52 + "onDelete": "cascade", 53 + "onUpdate": "no action" 54 + } 55 + }, 56 + "compositePrimaryKeys": {}, 57 + "uniqueConstraints": {} 58 + }, 59 + "incident_update": { 60 + "name": "incident_update", 61 + "columns": { 62 + "id": { 63 + "name": "id", 64 + "type": "integer", 65 + "primaryKey": true, 66 + "notNull": true, 67 + "autoincrement": false 68 + }, 69 + "uuid": { 70 + "name": "uuid", 71 + "type": "text", 72 + "primaryKey": false, 73 + "notNull": true, 74 + "autoincrement": false 75 + }, 76 + "incident_date": { 77 + "name": "incident_date", 78 + "type": "integer", 79 + "primaryKey": false, 80 + "notNull": false, 81 + "autoincrement": false 82 + }, 83 + "title": { 84 + "name": "title", 85 + "type": "text(256)", 86 + "primaryKey": false, 87 + "notNull": false, 88 + "autoincrement": false 89 + }, 90 + "message": { 91 + "name": "message", 92 + "type": "text", 93 + "primaryKey": false, 94 + "notNull": false, 95 + "autoincrement": false 96 + }, 97 + "incident_id": { 98 + "name": "incident_id", 99 + "type": "integer", 100 + "primaryKey": false, 101 + "notNull": true, 102 + "autoincrement": false 103 + }, 104 + "updated_at": { 105 + "name": "updated_at", 106 + "type": "integer", 107 + "primaryKey": false, 108 + "notNull": false, 109 + "autoincrement": false, 110 + "default": "(strftime('%s', 'now'))" 111 + } 112 + }, 113 + "indexes": { 114 + "incident_update_uuid_unique": { 115 + "name": "incident_update_uuid_unique", 116 + "columns": [ 117 + "uuid" 118 + ], 119 + "isUnique": true 120 + } 121 + }, 122 + "foreignKeys": { 123 + "incident_update_incident_id_incident_id_fk": { 124 + "name": "incident_update_incident_id_incident_id_fk", 125 + "tableFrom": "incident_update", 126 + "tableTo": "incident", 127 + "columnsFrom": [ 128 + "incident_id" 129 + ], 130 + "columnsTo": [ 131 + "id" 132 + ], 133 + "onDelete": "cascade", 134 + "onUpdate": "no action" 135 + } 136 + }, 137 + "compositePrimaryKeys": {}, 138 + "uniqueConstraints": {} 139 + }, 140 + "page": { 141 + "name": "page", 142 + "columns": { 143 + "id": { 144 + "name": "id", 145 + "type": "integer", 146 + "primaryKey": true, 147 + "notNull": true, 148 + "autoincrement": false 149 + }, 150 + "workspace_id": { 151 + "name": "workspace_id", 152 + "type": "integer", 153 + "primaryKey": false, 154 + "notNull": true, 155 + "autoincrement": false 156 + }, 157 + "title": { 158 + "name": "title", 159 + "type": "text", 160 + "primaryKey": false, 161 + "notNull": true, 162 + "autoincrement": false 163 + }, 164 + "description": { 165 + "name": "description", 166 + "type": "text", 167 + "primaryKey": false, 168 + "notNull": true, 169 + "autoincrement": false 170 + }, 171 + "icon": { 172 + "name": "icon", 173 + "type": "text(256)", 174 + "primaryKey": false, 175 + "notNull": false, 176 + "autoincrement": false 177 + }, 178 + "slug": { 179 + "name": "slug", 180 + "type": "text(256)", 181 + "primaryKey": false, 182 + "notNull": true, 183 + "autoincrement": false 184 + }, 185 + "custom_domain": { 186 + "name": "custom_domain", 187 + "type": "text(256)", 188 + "primaryKey": false, 189 + "notNull": true, 190 + "autoincrement": false 191 + }, 192 + "published": { 193 + "name": "published", 194 + "type": "integer", 195 + "primaryKey": false, 196 + "notNull": false, 197 + "autoincrement": false, 198 + "default": false 199 + }, 200 + "updated_at": { 201 + "name": "updated_at", 202 + "type": "integer", 203 + "primaryKey": false, 204 + "notNull": false, 205 + "autoincrement": false, 206 + "default": "(strftime('%s', 'now'))" 207 + } 208 + }, 209 + "indexes": { 210 + "page_slug_unique": { 211 + "name": "page_slug_unique", 212 + "columns": [ 213 + "slug" 214 + ], 215 + "isUnique": true 216 + } 217 + }, 218 + "foreignKeys": { 219 + "page_workspace_id_workspace_id_fk": { 220 + "name": "page_workspace_id_workspace_id_fk", 221 + "tableFrom": "page", 222 + "tableTo": "workspace", 223 + "columnsFrom": [ 224 + "workspace_id" 225 + ], 226 + "columnsTo": [ 227 + "id" 228 + ], 229 + "onDelete": "cascade", 230 + "onUpdate": "no action" 231 + } 232 + }, 233 + "compositePrimaryKeys": {}, 234 + "uniqueConstraints": {} 235 + }, 236 + "monitor": { 237 + "name": "monitor", 238 + "columns": { 239 + "id": { 240 + "name": "id", 241 + "type": "integer", 242 + "primaryKey": true, 243 + "notNull": true, 244 + "autoincrement": false 245 + }, 246 + "job_type": { 247 + "name": "job_type", 248 + "type": "text(3)", 249 + "primaryKey": false, 250 + "notNull": true, 251 + "autoincrement": false, 252 + "default": "'other'" 253 + }, 254 + "periodicity": { 255 + "name": "periodicity", 256 + "type": "text(6)", 257 + "primaryKey": false, 258 + "notNull": true, 259 + "autoincrement": false, 260 + "default": "'other'" 261 + }, 262 + "status": { 263 + "name": "status", 264 + "type": "text(2)", 265 + "primaryKey": false, 266 + "notNull": true, 267 + "autoincrement": false, 268 + "default": "'inactive'" 269 + }, 270 + "active": { 271 + "name": "active", 272 + "type": "integer", 273 + "primaryKey": false, 274 + "notNull": false, 275 + "autoincrement": false, 276 + "default": false 277 + }, 278 + "regions": { 279 + "name": "regions", 280 + "type": "text", 281 + "primaryKey": false, 282 + "notNull": true, 283 + "autoincrement": false, 284 + "default": "''" 285 + }, 286 + "url": { 287 + "name": "url", 288 + "type": "text(512)", 289 + "primaryKey": false, 290 + "notNull": true, 291 + "autoincrement": false 292 + }, 293 + "name": { 294 + "name": "name", 295 + "type": "text(256)", 296 + "primaryKey": false, 297 + "notNull": true, 298 + "autoincrement": false, 299 + "default": "''" 300 + }, 301 + "description": { 302 + "name": "description", 303 + "type": "text", 304 + "primaryKey": false, 305 + "notNull": true, 306 + "autoincrement": false, 307 + "default": "''" 308 + }, 309 + "workspace_id": { 310 + "name": "workspace_id", 311 + "type": "integer", 312 + "primaryKey": false, 313 + "notNull": false, 314 + "autoincrement": false 315 + }, 316 + "updated_at": { 317 + "name": "updated_at", 318 + "type": "integer", 319 + "primaryKey": false, 320 + "notNull": false, 321 + "autoincrement": false, 322 + "default": "(strftime('%s', 'now'))" 323 + } 324 + }, 325 + "indexes": {}, 326 + "foreignKeys": { 327 + "monitor_workspace_id_workspace_id_fk": { 328 + "name": "monitor_workspace_id_workspace_id_fk", 329 + "tableFrom": "monitor", 330 + "tableTo": "workspace", 331 + "columnsFrom": [ 332 + "workspace_id" 333 + ], 334 + "columnsTo": [ 335 + "id" 336 + ], 337 + "onDelete": "no action", 338 + "onUpdate": "no action" 339 + } 340 + }, 341 + "compositePrimaryKeys": {}, 342 + "uniqueConstraints": {} 343 + }, 344 + "monitors_to_pages": { 345 + "name": "monitors_to_pages", 346 + "columns": { 347 + "monitor_id": { 348 + "name": "monitor_id", 349 + "type": "integer", 350 + "primaryKey": false, 351 + "notNull": true, 352 + "autoincrement": false 353 + }, 354 + "page_id": { 355 + "name": "page_id", 356 + "type": "integer", 357 + "primaryKey": false, 358 + "notNull": true, 359 + "autoincrement": false 360 + } 361 + }, 362 + "indexes": {}, 363 + "foreignKeys": { 364 + "monitors_to_pages_monitor_id_monitor_id_fk": { 365 + "name": "monitors_to_pages_monitor_id_monitor_id_fk", 366 + "tableFrom": "monitors_to_pages", 367 + "tableTo": "monitor", 368 + "columnsFrom": [ 369 + "monitor_id" 370 + ], 371 + "columnsTo": [ 372 + "id" 373 + ], 374 + "onDelete": "cascade", 375 + "onUpdate": "no action" 376 + }, 377 + "monitors_to_pages_page_id_page_id_fk": { 378 + "name": "monitors_to_pages_page_id_page_id_fk", 379 + "tableFrom": "monitors_to_pages", 380 + "tableTo": "page", 381 + "columnsFrom": [ 382 + "page_id" 383 + ], 384 + "columnsTo": [ 385 + "id" 386 + ], 387 + "onDelete": "cascade", 388 + "onUpdate": "no action" 389 + } 390 + }, 391 + "compositePrimaryKeys": { 392 + "monitors_to_pages_monitor_id_page_id_pk": { 393 + "columns": [ 394 + "monitor_id", 395 + "page_id" 396 + ] 397 + } 398 + }, 399 + "uniqueConstraints": {} 400 + }, 401 + "user": { 402 + "name": "user", 403 + "columns": { 404 + "id": { 405 + "name": "id", 406 + "type": "integer", 407 + "primaryKey": true, 408 + "notNull": true, 409 + "autoincrement": false 410 + }, 411 + "tenant_id": { 412 + "name": "tenant_id", 413 + "type": "text(256)", 414 + "primaryKey": false, 415 + "notNull": false, 416 + "autoincrement": false 417 + }, 418 + "first_name": { 419 + "name": "first_name", 420 + "type": "text", 421 + "primaryKey": false, 422 + "notNull": false, 423 + "autoincrement": false, 424 + "default": "''" 425 + }, 426 + "last_name": { 427 + "name": "last_name", 428 + "type": "text", 429 + "primaryKey": false, 430 + "notNull": false, 431 + "autoincrement": false, 432 + "default": "''" 433 + }, 434 + "email": { 435 + "name": "email", 436 + "type": "text", 437 + "primaryKey": false, 438 + "notNull": false, 439 + "autoincrement": false, 440 + "default": "''" 441 + }, 442 + "photo_url": { 443 + "name": "photo_url", 444 + "type": "text", 445 + "primaryKey": false, 446 + "notNull": false, 447 + "autoincrement": false, 448 + "default": "''" 449 + }, 450 + "updated_at": { 451 + "name": "updated_at", 452 + "type": "integer", 453 + "primaryKey": false, 454 + "notNull": false, 455 + "autoincrement": false, 456 + "default": "(strftime('%s', 'now'))" 457 + } 458 + }, 459 + "indexes": { 460 + "user_tenant_id_unique": { 461 + "name": "user_tenant_id_unique", 462 + "columns": [ 463 + "tenant_id" 464 + ], 465 + "isUnique": true 466 + } 467 + }, 468 + "foreignKeys": {}, 469 + "compositePrimaryKeys": {}, 470 + "uniqueConstraints": {} 471 + }, 472 + "users_to_workspaces": { 473 + "name": "users_to_workspaces", 474 + "columns": { 475 + "user_id": { 476 + "name": "user_id", 477 + "type": "integer", 478 + "primaryKey": false, 479 + "notNull": true, 480 + "autoincrement": false 481 + }, 482 + "workspace_id": { 483 + "name": "workspace_id", 484 + "type": "integer", 485 + "primaryKey": false, 486 + "notNull": true, 487 + "autoincrement": false 488 + } 489 + }, 490 + "indexes": {}, 491 + "foreignKeys": { 492 + "users_to_workspaces_user_id_user_id_fk": { 493 + "name": "users_to_workspaces_user_id_user_id_fk", 494 + "tableFrom": "users_to_workspaces", 495 + "tableTo": "user", 496 + "columnsFrom": [ 497 + "user_id" 498 + ], 499 + "columnsTo": [ 500 + "id" 501 + ], 502 + "onDelete": "no action", 503 + "onUpdate": "no action" 504 + }, 505 + "users_to_workspaces_workspace_id_workspace_id_fk": { 506 + "name": "users_to_workspaces_workspace_id_workspace_id_fk", 507 + "tableFrom": "users_to_workspaces", 508 + "tableTo": "workspace", 509 + "columnsFrom": [ 510 + "workspace_id" 511 + ], 512 + "columnsTo": [ 513 + "id" 514 + ], 515 + "onDelete": "no action", 516 + "onUpdate": "no action" 517 + } 518 + }, 519 + "compositePrimaryKeys": { 520 + "users_to_workspaces_user_id_workspace_id_pk": { 521 + "columns": [ 522 + "user_id", 523 + "workspace_id" 524 + ] 525 + } 526 + }, 527 + "uniqueConstraints": {} 528 + }, 529 + "workspace": { 530 + "name": "workspace", 531 + "columns": { 532 + "id": { 533 + "name": "id", 534 + "type": "integer", 535 + "primaryKey": true, 536 + "notNull": true, 537 + "autoincrement": false 538 + }, 539 + "slug": { 540 + "name": "slug", 541 + "type": "text", 542 + "primaryKey": false, 543 + "notNull": true, 544 + "autoincrement": false 545 + }, 546 + "stripe_id": { 547 + "name": "stripe_id", 548 + "type": "text(256)", 549 + "primaryKey": false, 550 + "notNull": false, 551 + "autoincrement": false 552 + }, 553 + "name": { 554 + "name": "name", 555 + "type": "text", 556 + "primaryKey": false, 557 + "notNull": false, 558 + "autoincrement": false 559 + }, 560 + "updated_at": { 561 + "name": "updated_at", 562 + "type": "integer", 563 + "primaryKey": false, 564 + "notNull": false, 565 + "autoincrement": false, 566 + "default": "(strftime('%s', 'now'))" 567 + } 568 + }, 569 + "indexes": { 570 + "workspace_slug_unique": { 571 + "name": "workspace_slug_unique", 572 + "columns": [ 573 + "slug" 574 + ], 575 + "isUnique": true 576 + }, 577 + "workspace_stripe_id_unique": { 578 + "name": "workspace_stripe_id_unique", 579 + "columns": [ 580 + "stripe_id" 581 + ], 582 + "isUnique": true 583 + } 584 + }, 585 + "foreignKeys": {}, 586 + "compositePrimaryKeys": {}, 587 + "uniqueConstraints": {} 588 + } 589 + }, 590 + "enums": {}, 591 + "_meta": { 592 + "schemas": {}, 593 + "tables": {}, 594 + "columns": {} 595 + } 596 + }
+7
packages/db/drizzle/meta/_journal.json
··· 15 15 "when": 1690892003254, 16 16 "tag": "0001_brainy_beast", 17 17 "breakpoints": true 18 + }, 19 + { 20 + "idx": 2, 21 + "version": "5", 22 + "when": 1691573899721, 23 + "tag": "0002_luxuriant_ser_duncan", 24 + "breakpoints": true 18 25 } 19 26 ] 20 27 }
packages/db/env.ts packages/db/env.mjs
+1 -1
packages/db/package.json
··· 6 6 "scripts": { 7 7 "generate": "drizzle-kit generate:sqlite", 8 8 "push": "drizzle-kit push:sqlite", 9 - "migrate": "ts-node --esm src/migrate.mts ", 9 + "migrate": "ts-node --esm src/migrate.mts", 10 10 "studio": "drizzle-kit studio" 11 11 }, 12 12 "dependencies": {
+1 -1
packages/db/src/db.ts
··· 1 1 import { createClient } from "@libsql/client/http"; 2 2 import { drizzle } from "drizzle-orm/libsql"; 3 3 4 - import { env } from "../env"; 4 + import { env } from "../env.mjs"; 5 5 import * as schema from "./schema"; 6 6 7 7 const client = createClient({
+1 -1
packages/db/src/migrate.mts
··· 4 4 import { drizzle } from "drizzle-orm/libsql"; 5 5 import { migrate } from "drizzle-orm/libsql/migrator"; 6 6 7 - import { env } from "../env"; 7 + import { env } from "../env.mjs"; 8 8 9 9 async function main() { 10 10 const db = drizzle(
+5
packages/db/src/schema/user.ts
··· 12 12 id: integer("id").primaryKey(), 13 13 tenantId: text("tenant_id", { length: 256 }).unique(), // the clerk User Id 14 14 15 + firstName: text("first_name").default(""), 16 + lastName: text("last_name").default(""), 17 + email: text("email").default(""), 18 + photoUrl: text("photo_url").default(""), 19 + 15 20 createdAt: integer("updated_at", { mode: "timestamp" }).default( 16 21 sql`(strftime('%s', 'now'))`, 17 22 ),
+1 -1
packages/db/tsconfig.json
··· 18 18 "resolveJsonModule": true, 19 19 "noUncheckedIndexedAccess": true 20 20 }, 21 - "include": ["src", "*.ts", "env.ts"] 21 + "include": ["src", "*.ts", "env.mjs", "**/*.ts"] 22 22 }