workspace.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import { z } from "zod"
  2. import { fn } from "./util/fn"
  3. import { Actor } from "./actor"
  4. import { Database } from "./drizzle"
  5. import { Identifier } from "./identifier"
  6. import { UserTable } from "./schema/user.sql"
  7. import { BillingTable } from "./schema/billing.sql"
  8. import { WorkspaceTable } from "./schema/workspace.sql"
  9. import { AccountTable } from "./schema/account.sql"
  10. import { Key } from "./key"
  11. import { and, eq, isNull, sql } from "drizzle-orm"
  12. export namespace Workspace {
  13. export const create = fn(
  14. z.object({
  15. name: z.string().min(1),
  16. }),
  17. async ({ name }) => {
  18. const account = Actor.assert("account")
  19. const workspaceID = Identifier.create("workspace")
  20. const userID = Identifier.create("user")
  21. await Database.transaction(async (tx) => {
  22. const active = await tx
  23. .select({ id: AccountTable.id })
  24. .from(AccountTable)
  25. .where(and(eq(AccountTable.id, account.properties.accountID), isNull(AccountTable.timeDeleted)))
  26. .then((rows) => rows[0])
  27. if (!active) throw new Error("Account is not active")
  28. await tx.insert(WorkspaceTable).values({
  29. id: workspaceID,
  30. name,
  31. })
  32. await tx.insert(UserTable).values({
  33. workspaceID,
  34. id: userID,
  35. accountID: account.properties.accountID,
  36. name: "",
  37. role: "admin",
  38. })
  39. await tx.insert(BillingTable).values({
  40. workspaceID,
  41. id: Identifier.create("billing"),
  42. balance: 0,
  43. })
  44. })
  45. await Actor.provide(
  46. "system",
  47. {
  48. workspaceID,
  49. },
  50. () => Key.create({ userID, name: "Default API Key" }),
  51. )
  52. return workspaceID
  53. },
  54. )
  55. export const update = fn(
  56. z.object({
  57. name: z.string().min(1).max(255),
  58. }),
  59. async ({ name }) => {
  60. Actor.assertAdmin()
  61. const workspaceID = Actor.workspace()
  62. return await Database.use((tx) =>
  63. tx
  64. .update(WorkspaceTable)
  65. .set({
  66. name,
  67. })
  68. .where(eq(WorkspaceTable.id, workspaceID)),
  69. )
  70. },
  71. )
  72. export const remove = fn(z.void(), async () => {
  73. await Database.use((tx) =>
  74. tx
  75. .update(WorkspaceTable)
  76. .set({ timeDeleted: sql`now()` })
  77. .where(eq(WorkspaceTable.id, Actor.workspace())),
  78. )
  79. })
  80. }