console.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import { domain } from "./stage"
  2. import { EMAILOCTOPUS_API_KEY } from "./app"
  3. ////////////////
  4. // DATABASE
  5. ////////////////
  6. const cluster = planetscale.getDatabaseOutput({
  7. name: "opencode",
  8. organization: "anomalyco",
  9. })
  10. const branch =
  11. $app.stage === "production"
  12. ? planetscale.getBranchOutput({
  13. name: "production",
  14. organization: cluster.organization,
  15. database: cluster.name,
  16. })
  17. : new planetscale.Branch("DatabaseBranch", {
  18. database: cluster.name,
  19. organization: cluster.organization,
  20. name: $app.stage,
  21. parentBranch: "production",
  22. })
  23. const password = new planetscale.Password("DatabasePassword", {
  24. name: $app.stage,
  25. database: cluster.name,
  26. organization: cluster.organization,
  27. branch: branch.name,
  28. })
  29. export const database = new sst.Linkable("Database", {
  30. properties: {
  31. host: password.accessHostUrl,
  32. database: cluster.name,
  33. username: password.username,
  34. password: password.plaintext,
  35. port: 3306,
  36. },
  37. })
  38. new sst.x.DevCommand("Studio", {
  39. link: [database],
  40. dev: {
  41. command: "bun db studio",
  42. directory: "packages/console/core",
  43. autostart: true,
  44. },
  45. })
  46. ////////////////
  47. // AUTH
  48. ////////////////
  49. const GITHUB_CLIENT_ID_CONSOLE = new sst.Secret("GITHUB_CLIENT_ID_CONSOLE")
  50. const GITHUB_CLIENT_SECRET_CONSOLE = new sst.Secret("GITHUB_CLIENT_SECRET_CONSOLE")
  51. const GOOGLE_CLIENT_ID = new sst.Secret("GOOGLE_CLIENT_ID")
  52. const authStorage = new sst.cloudflare.Kv("AuthStorage")
  53. export const auth = new sst.cloudflare.Worker("AuthApi", {
  54. domain: `auth.${domain}`,
  55. handler: "packages/console/function/src/auth.ts",
  56. url: true,
  57. link: [database, authStorage, GITHUB_CLIENT_ID_CONSOLE, GITHUB_CLIENT_SECRET_CONSOLE, GOOGLE_CLIENT_ID],
  58. })
  59. ////////////////
  60. // GATEWAY
  61. ////////////////
  62. export const stripeWebhook = new stripe.WebhookEndpoint("StripeWebhookEndpoint", {
  63. url: $interpolate`https://${domain}/stripe/webhook`,
  64. enabledEvents: [
  65. "checkout.session.async_payment_failed",
  66. "checkout.session.async_payment_succeeded",
  67. "checkout.session.completed",
  68. "checkout.session.expired",
  69. "charge.refunded",
  70. "customer.created",
  71. "customer.deleted",
  72. "customer.updated",
  73. "customer.discount.created",
  74. "customer.discount.deleted",
  75. "customer.discount.updated",
  76. "customer.source.created",
  77. "customer.source.deleted",
  78. "customer.source.expiring",
  79. "customer.source.updated",
  80. "customer.subscription.created",
  81. "customer.subscription.deleted",
  82. "customer.subscription.paused",
  83. "customer.subscription.pending_update_applied",
  84. "customer.subscription.pending_update_expired",
  85. "customer.subscription.resumed",
  86. "customer.subscription.trial_will_end",
  87. "customer.subscription.updated",
  88. ],
  89. })
  90. const ZEN_MODELS = new sst.Secret("ZEN_MODELS")
  91. const STRIPE_SECRET_KEY = new sst.Secret("STRIPE_SECRET_KEY")
  92. const AUTH_API_URL = new sst.Linkable("AUTH_API_URL", {
  93. properties: { value: auth.url.apply((url) => url!) },
  94. })
  95. const STRIPE_WEBHOOK_SECRET = new sst.Linkable("STRIPE_WEBHOOK_SECRET", {
  96. properties: { value: stripeWebhook.secret },
  97. })
  98. ////////////////
  99. // CONSOLE
  100. ////////////////
  101. const AWS_SES_ACCESS_KEY_ID = new sst.Secret("AWS_SES_ACCESS_KEY_ID")
  102. const AWS_SES_SECRET_ACCESS_KEY = new sst.Secret("AWS_SES_SECRET_ACCESS_KEY")
  103. let logProcessor
  104. if ($app.stage === "production" || $app.stage === "frank") {
  105. const HONEYCOMB_API_KEY = new sst.Secret("HONEYCOMB_API_KEY")
  106. logProcessor = new sst.cloudflare.Worker("LogProcessor", {
  107. handler: "packages/console/function/src/log-processor.ts",
  108. link: [HONEYCOMB_API_KEY],
  109. })
  110. }
  111. new sst.cloudflare.x.SolidStart("Console", {
  112. domain,
  113. path: "packages/console/app",
  114. link: [
  115. database,
  116. AUTH_API_URL,
  117. STRIPE_WEBHOOK_SECRET,
  118. STRIPE_SECRET_KEY,
  119. ZEN_MODELS,
  120. EMAILOCTOPUS_API_KEY,
  121. AWS_SES_ACCESS_KEY_ID,
  122. AWS_SES_SECRET_ACCESS_KEY,
  123. ],
  124. environment: {
  125. //VITE_DOCS_URL: web.url.apply((url) => url!),
  126. //VITE_API_URL: gateway.url.apply((url) => url!),
  127. VITE_AUTH_URL: auth.url.apply((url) => url!),
  128. },
  129. transform: {
  130. server: {
  131. transform: {
  132. worker: {
  133. placement: { mode: "smart" },
  134. tailConsumers: logProcessor ? [{ service: logProcessor.nodes.worker.scriptName }] : [],
  135. },
  136. },
  137. },
  138. },
  139. })