vibecarbon 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (495) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +188 -0
  3. package/carbon/.claude/hooks/task-completed-gate.sh +19 -0
  4. package/carbon/.claude/hooks/teammate-idle-gate.sh +29 -0
  5. package/carbon/.claude/settings.json +29 -0
  6. package/carbon/.cursor/rules/vibecarbon.mdc +6 -0
  7. package/carbon/.dockerignore +57 -0
  8. package/carbon/.env.example +219 -0
  9. package/carbon/.github/copilot-instructions.md +3 -0
  10. package/carbon/.github/workflows/deploy.yml +346 -0
  11. package/carbon/.github/workflows/vibecarbon-build.yml +81 -0
  12. package/carbon/.windsurfrules +74 -0
  13. package/carbon/AGENTS.md +422 -0
  14. package/carbon/CLAUDE.md +3 -0
  15. package/carbon/DEVELOPMENT.md +187 -0
  16. package/carbon/Dockerfile +98 -0
  17. package/carbon/LICENSE +21 -0
  18. package/carbon/PRODUCTION.md +364 -0
  19. package/carbon/README.md +193 -0
  20. package/carbon/TESTING.md +138 -0
  21. package/carbon/backup/Dockerfile +75 -0
  22. package/carbon/backup/backup.sh +95 -0
  23. package/carbon/backup/compose-backup.sh +140 -0
  24. package/carbon/biome.json +83 -0
  25. package/carbon/cloud-init/docker-ce-setup.yaml +55 -0
  26. package/carbon/cloud-init/k3s/master-init.sh +215 -0
  27. package/carbon/cloud-init/k3s/supabase-init.sh +167 -0
  28. package/carbon/cloud-init/k3s/worker-init.sh +147 -0
  29. package/carbon/components.json +24 -0
  30. package/carbon/content/blog/authentication-guide.mdx +34 -0
  31. package/carbon/content/blog/getting-started.mdx +41 -0
  32. package/carbon/content/changelog/v0-1-0.mdx +40 -0
  33. package/carbon/content/docs/analytics.mdx +90 -0
  34. package/carbon/content/docs/authentication.mdx +231 -0
  35. package/carbon/content/docs/background-jobs.mdx +116 -0
  36. package/carbon/content/docs/cli.mdx +630 -0
  37. package/carbon/content/docs/database.mdx +236 -0
  38. package/carbon/content/docs/deployment.mdx +227 -0
  39. package/carbon/content/docs/development.mdx +238 -0
  40. package/carbon/content/docs/environments.mdx +84 -0
  41. package/carbon/content/docs/getting-started.mdx +112 -0
  42. package/carbon/content/docs/legal/privacy-policy.mdx +89 -0
  43. package/carbon/content/docs/legal/terms-of-service.mdx +99 -0
  44. package/carbon/content/docs/optional-services.mdx +160 -0
  45. package/carbon/db/Dockerfile +23 -0
  46. package/carbon/docker-compose.dev-init.yml +5 -0
  47. package/carbon/docker-compose.metabase.override.yml +14 -0
  48. package/carbon/docker-compose.metabase.prod.yml +28 -0
  49. package/carbon/docker-compose.metabase.yml +84 -0
  50. package/carbon/docker-compose.n8n.override.yml +14 -0
  51. package/carbon/docker-compose.n8n.prod.yml +31 -0
  52. package/carbon/docker-compose.n8n.yml +97 -0
  53. package/carbon/docker-compose.observability.override.yml +18 -0
  54. package/carbon/docker-compose.observability.prod.yml +28 -0
  55. package/carbon/docker-compose.observability.yml +125 -0
  56. package/carbon/docker-compose.override.yml +28 -0
  57. package/carbon/docker-compose.prod.yml +294 -0
  58. package/carbon/docker-compose.yml +508 -0
  59. package/carbon/docker-entrypoint.sh +12 -0
  60. package/carbon/ha/activate-standby.sh +52 -0
  61. package/carbon/ha/primary-init.sql +36 -0
  62. package/carbon/ha/standby-init.sh +74 -0
  63. package/carbon/k8s/LICENSE +99 -0
  64. package/carbon/k8s/README.md +272 -0
  65. package/carbon/k8s/base/app/deployment.yaml +130 -0
  66. package/carbon/k8s/base/app/hpa.yaml +44 -0
  67. package/carbon/k8s/base/app/kustomization.yaml +10 -0
  68. package/carbon/k8s/base/app/network-policy.yaml +124 -0
  69. package/carbon/k8s/base/app/pdb.yaml +14 -0
  70. package/carbon/k8s/base/app/rbac.yaml +36 -0
  71. package/carbon/k8s/base/app/service.yaml +16 -0
  72. package/carbon/k8s/base/backup/cronjob.yaml +120 -0
  73. package/carbon/k8s/base/backup/kustomization.yaml +7 -0
  74. package/carbon/k8s/base/backup/network-policy.yaml +31 -0
  75. package/carbon/k8s/base/backup/rbac.yaml +7 -0
  76. package/carbon/k8s/base/cluster-autoscaler/deployment.yaml +103 -0
  77. package/carbon/k8s/base/cluster-autoscaler/kustomization.yaml +17 -0
  78. package/carbon/k8s/base/cluster-autoscaler/rbac.yaml +109 -0
  79. package/carbon/k8s/base/config/configmap.yaml +48 -0
  80. package/carbon/k8s/base/config/kustomization.yaml +8 -0
  81. package/carbon/k8s/base/hetzner-ccm/kustomization.yaml +9 -0
  82. package/carbon/k8s/base/hetzner-csi/kustomization.yaml +9 -0
  83. package/carbon/k8s/base/kustomization.yaml +43 -0
  84. package/carbon/k8s/base/namespace.yaml +7 -0
  85. package/carbon/k8s/base/network-policies.yaml +95 -0
  86. package/carbon/k8s/base/registry/kustomization.yaml +5 -0
  87. package/carbon/k8s/base/registry/local-registry.yaml +193 -0
  88. package/carbon/k8s/base/traefik/certificate.yaml +21 -0
  89. package/carbon/k8s/base/traefik/configmap.yaml +13 -0
  90. package/carbon/k8s/base/traefik/deployment.yaml +165 -0
  91. package/carbon/k8s/base/traefik/ingressroute.yaml +141 -0
  92. package/carbon/k8s/base/traefik/kustomization.yaml +11 -0
  93. package/carbon/k8s/base/traefik/middleware.yaml +109 -0
  94. package/carbon/k8s/base/traefik/network-policy.yaml +92 -0
  95. package/carbon/k8s/base/traefik/service.yaml +38 -0
  96. package/carbon/k8s/flux/README.md +49 -0
  97. package/carbon/k8s/flux/clusters/primary/vibecarbon.yaml +128 -0
  98. package/carbon/k8s/flux/clusters/standby/vibecarbon.yaml +83 -0
  99. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-release.yaml +38 -0
  100. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-repository.yaml +16 -0
  101. package/carbon/k8s/gitops/cert-manager-webhook-hetzner/kustomization.yaml +10 -0
  102. package/carbon/k8s/gitops/supabase/helm-release.yaml +66 -0
  103. package/carbon/k8s/gitops/supabase/helm-repository.yaml +18 -0
  104. package/carbon/k8s/gitops/supabase/kustomization.yaml +33 -0
  105. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-cloudflare.yaml +51 -0
  106. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-hetzner.yaml +59 -0
  107. package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-manual.yaml +43 -0
  108. package/carbon/k8s/infra/cert-manager-resources/kustomization.yaml +15 -0
  109. package/carbon/k8s/infra/kustomization.yaml +21 -0
  110. package/carbon/k8s/infra/traefik-crds/kustomization.yaml +10 -0
  111. package/carbon/k8s/overlays/local/configmap.yaml +23 -0
  112. package/carbon/k8s/overlays/local/ingressroute-studio.yaml +104 -0
  113. package/carbon/k8s/overlays/local/kustomization.yaml +215 -0
  114. package/carbon/k8s/overlays/local/namespace.yaml +8 -0
  115. package/carbon/k8s/overlays/local/secrets.yaml +32 -0
  116. package/carbon/k8s/overlays/production/kustomization.yaml +34 -0
  117. package/carbon/k8s/test-local.sh +318 -0
  118. package/carbon/k8s/values/supabase.values.yaml +133 -0
  119. package/carbon/package.json +154 -0
  120. package/carbon/runtime.Dockerfile +17 -0
  121. package/carbon/scripts/_dev-jwt.mjs +45 -0
  122. package/carbon/scripts/check-rls.ts +53 -0
  123. package/carbon/scripts/dev-init.js +191 -0
  124. package/carbon/scripts/dev.js +191 -0
  125. package/carbon/scripts/docker-down.js +63 -0
  126. package/carbon/scripts/docker-logs.js +59 -0
  127. package/carbon/scripts/docker-up.js +222 -0
  128. package/carbon/scripts/generate-dev-configs.sh +131 -0
  129. package/carbon/scripts/generate-rss.ts +116 -0
  130. package/carbon/scripts/generate-sitemap.ts +102 -0
  131. package/carbon/scripts/k8s-apply.js +71 -0
  132. package/carbon/scripts/k8s-delete.js +75 -0
  133. package/carbon/scripts/lib/manifest.js +176 -0
  134. package/carbon/scripts/secret-scan.mjs +278 -0
  135. package/carbon/scripts/validate-dev-configs.sh +101 -0
  136. package/carbon/src/client/App.tsx +202 -0
  137. package/carbon/src/client/assets/hyperformant-dark.svg +29 -0
  138. package/carbon/src/client/assets/hyperformant-light.svg +29 -0
  139. package/carbon/src/client/assets/logos/aider.svg +1 -0
  140. package/carbon/src/client/assets/logos/antigravity.svg +1 -0
  141. package/carbon/src/client/assets/logos/bolt.svg +1 -0
  142. package/carbon/src/client/assets/logos/claude-code.svg +1 -0
  143. package/carbon/src/client/assets/logos/copilot.svg +1 -0
  144. package/carbon/src/client/assets/logos/cursor.svg +1 -0
  145. package/carbon/src/client/assets/logos/gemini-cli.svg +1 -0
  146. package/carbon/src/client/assets/logos/lovable.svg +1 -0
  147. package/carbon/src/client/assets/logos/openai-codex.svg +1 -0
  148. package/carbon/src/client/assets/logos/v0.svg +1 -0
  149. package/carbon/src/client/assets/logos/windsurf.svg +1 -0
  150. package/carbon/src/client/assets/vibecarbon-icon.svg +19 -0
  151. package/carbon/src/client/assets/vibecarbon-logo-dark.svg +29 -0
  152. package/carbon/src/client/assets/vibecarbon-logo-light.svg +29 -0
  153. package/carbon/src/client/components/AIIntegrationSection.tsx +120 -0
  154. package/carbon/src/client/components/AppSidebar.tsx +760 -0
  155. package/carbon/src/client/components/ArchitectureSection.tsx +46 -0
  156. package/carbon/src/client/components/CTAFooter.tsx +59 -0
  157. package/carbon/src/client/components/ComparisonSection.tsx +132 -0
  158. package/carbon/src/client/components/ContentPanel.tsx +66 -0
  159. package/carbon/src/client/components/ContentSkeleton.tsx +21 -0
  160. package/carbon/src/client/components/ErrorBoundary.tsx +46 -0
  161. package/carbon/src/client/components/FAQSection.tsx +76 -0
  162. package/carbon/src/client/components/FileUpload.tsx +210 -0
  163. package/carbon/src/client/components/HeaderActions.tsx +17 -0
  164. package/carbon/src/client/components/Hero.tsx +608 -0
  165. package/carbon/src/client/components/ImpersonationBanner.tsx +31 -0
  166. package/carbon/src/client/components/LanguageSwitcher.tsx +67 -0
  167. package/carbon/src/client/components/Logo.tsx +87 -0
  168. package/carbon/src/client/components/LogoStrip.tsx +76 -0
  169. package/carbon/src/client/components/MetricsStrip.tsx +48 -0
  170. package/carbon/src/client/components/Nav.tsx +195 -0
  171. package/carbon/src/client/components/NewsletterSignup.tsx +147 -0
  172. package/carbon/src/client/components/NotificationDrawer.tsx +171 -0
  173. package/carbon/src/client/components/PageHeader.tsx +24 -0
  174. package/carbon/src/client/components/PlanGate.tsx +36 -0
  175. package/carbon/src/client/components/PricingSection.tsx +371 -0
  176. package/carbon/src/client/components/SEO.tsx +34 -0
  177. package/carbon/src/client/components/SmoothScroll.tsx +45 -0
  178. package/carbon/src/client/components/TechStackSection.tsx +165 -0
  179. package/carbon/src/client/components/WorkflowSection.tsx +604 -0
  180. package/carbon/src/client/components/admin/DockerLogs.tsx +276 -0
  181. package/carbon/src/client/components/admin/PerformanceMetrics.tsx +230 -0
  182. package/carbon/src/client/components/admin/ServiceCard.tsx +45 -0
  183. package/carbon/src/client/components/admin/ServicesStatus.tsx +296 -0
  184. package/carbon/src/client/components/architecture/ArchitectureDiagram.tsx +413 -0
  185. package/carbon/src/client/components/auth/AuthProvider.tsx +466 -0
  186. package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +35 -0
  187. package/carbon/src/client/components/effects/FresnelEdge.tsx +49 -0
  188. package/carbon/src/client/components/effects/GlowTracker.tsx +46 -0
  189. package/carbon/src/client/components/effects/SparkBurst.tsx +145 -0
  190. package/carbon/src/client/components/effects/VGlowEffect.tsx +83 -0
  191. package/carbon/src/client/components/effects/index.ts +2 -0
  192. package/carbon/src/client/components/layouts/SidebarLayout.tsx +20 -0
  193. package/carbon/src/client/components/scroll/ScrollSection.tsx +76 -0
  194. package/carbon/src/client/components/scroll/ScrollytellingProvider.tsx +81 -0
  195. package/carbon/src/client/components/scroll/index.ts +2 -0
  196. package/carbon/src/client/components/ui/accordion.tsx +71 -0
  197. package/carbon/src/client/components/ui/alert-dialog.tsx +162 -0
  198. package/carbon/src/client/components/ui/alert.tsx +73 -0
  199. package/carbon/src/client/components/ui/aspect-ratio.tsx +22 -0
  200. package/carbon/src/client/components/ui/avatar.tsx +91 -0
  201. package/carbon/src/client/components/ui/badge.tsx +50 -0
  202. package/carbon/src/client/components/ui/breadcrumb.tsx +100 -0
  203. package/carbon/src/client/components/ui/button-group.tsx +78 -0
  204. package/carbon/src/client/components/ui/button.tsx +120 -0
  205. package/carbon/src/client/components/ui/calendar.tsx +182 -0
  206. package/carbon/src/client/components/ui/card.tsx +85 -0
  207. package/carbon/src/client/components/ui/carousel.tsx +227 -0
  208. package/carbon/src/client/components/ui/chart.tsx +357 -0
  209. package/carbon/src/client/components/ui/checkbox.tsx +27 -0
  210. package/carbon/src/client/components/ui/collapsible.tsx +15 -0
  211. package/carbon/src/client/components/ui/command.tsx +178 -0
  212. package/carbon/src/client/components/ui/context-menu.tsx +233 -0
  213. package/carbon/src/client/components/ui/dialog.tsx +132 -0
  214. package/carbon/src/client/components/ui/drawer.tsx +118 -0
  215. package/carbon/src/client/components/ui/dropdown-menu.tsx +242 -0
  216. package/carbon/src/client/components/ui/empty.tsx +94 -0
  217. package/carbon/src/client/components/ui/field.tsx +226 -0
  218. package/carbon/src/client/components/ui/hover-card.tsx +44 -0
  219. package/carbon/src/client/components/ui/input-group.tsx +146 -0
  220. package/carbon/src/client/components/ui/input-otp.tsx +83 -0
  221. package/carbon/src/client/components/ui/input.tsx +20 -0
  222. package/carbon/src/client/components/ui/item.tsx +188 -0
  223. package/carbon/src/client/components/ui/kbd.tsx +26 -0
  224. package/carbon/src/client/components/ui/label.tsx +21 -0
  225. package/carbon/src/client/components/ui/menubar.tsx +250 -0
  226. package/carbon/src/client/components/ui/navigation-menu.tsx +155 -0
  227. package/carbon/src/client/components/ui/pagination.tsx +102 -0
  228. package/carbon/src/client/components/ui/popover.tsx +75 -0
  229. package/carbon/src/client/components/ui/progress.tsx +66 -0
  230. package/carbon/src/client/components/ui/radio-group.tsx +36 -0
  231. package/carbon/src/client/components/ui/resizable.tsx +46 -0
  232. package/carbon/src/client/components/ui/scroll-area.tsx +48 -0
  233. package/carbon/src/client/components/ui/select.tsx +186 -0
  234. package/carbon/src/client/components/ui/separator.tsx +21 -0
  235. package/carbon/src/client/components/ui/sheet.tsx +124 -0
  236. package/carbon/src/client/components/ui/sidebar.tsx +702 -0
  237. package/carbon/src/client/components/ui/skeleton.tsx +13 -0
  238. package/carbon/src/client/components/ui/slider.tsx +57 -0
  239. package/carbon/src/client/components/ui/sonner.tsx +45 -0
  240. package/carbon/src/client/components/ui/spinner.tsx +15 -0
  241. package/carbon/src/client/components/ui/switch.tsx +30 -0
  242. package/carbon/src/client/components/ui/table.tsx +89 -0
  243. package/carbon/src/client/components/ui/tabs.tsx +73 -0
  244. package/carbon/src/client/components/ui/textarea.tsx +18 -0
  245. package/carbon/src/client/components/ui/toggle-group.tsx +87 -0
  246. package/carbon/src/client/components/ui/toggle.tsx +44 -0
  247. package/carbon/src/client/components/ui/tooltip.tsx +56 -0
  248. package/carbon/src/client/hooks/api/index.ts +14 -0
  249. package/carbon/src/client/hooks/api/useAuthSettings.ts +80 -0
  250. package/carbon/src/client/hooks/api/useSubscription.ts +87 -0
  251. package/carbon/src/client/hooks/use-mobile.ts +21 -0
  252. package/carbon/src/client/hooks/useMousePosition.ts +91 -0
  253. package/carbon/src/client/hooks/useNotifications.tsx +124 -0
  254. package/carbon/src/client/hooks/useOrganizationMembers.ts +127 -0
  255. package/carbon/src/client/hooks/useOrganizations.tsx +230 -0
  256. package/carbon/src/client/hooks/usePackageManager.ts +69 -0
  257. package/carbon/src/client/hooks/useReducedMotion.ts +20 -0
  258. package/carbon/src/client/hooks/useRunningServices.ts +114 -0
  259. package/carbon/src/client/hooks/useScrollProgress.ts +56 -0
  260. package/carbon/src/client/index.css +467 -0
  261. package/carbon/src/client/index.html +56 -0
  262. package/carbon/src/client/lib/admin-services.ts +151 -0
  263. package/carbon/src/client/lib/api.ts +32 -0
  264. package/carbon/src/client/lib/blog.ts +35 -0
  265. package/carbon/src/client/lib/changelog.ts +33 -0
  266. package/carbon/src/client/lib/docs-search.ts +101 -0
  267. package/carbon/src/client/lib/docs.ts +37 -0
  268. package/carbon/src/client/lib/i18n.ts +32 -0
  269. package/carbon/src/client/lib/supabase.ts +72 -0
  270. package/carbon/src/client/lib/tailwind-colors.ts +357 -0
  271. package/carbon/src/client/lib/theme.ts +117 -0
  272. package/carbon/src/client/lib/utils.ts +22 -0
  273. package/carbon/src/client/locales/de.json +529 -0
  274. package/carbon/src/client/locales/en.json +461 -0
  275. package/carbon/src/client/locales/es.json +529 -0
  276. package/carbon/src/client/locales/fr.json +529 -0
  277. package/carbon/src/client/locales/pt.json +529 -0
  278. package/carbon/src/client/main.tsx +56 -0
  279. package/carbon/src/client/mdx.d.ts +13 -0
  280. package/carbon/src/client/pages/ApiDocs.tsx +76 -0
  281. package/carbon/src/client/pages/AuthCallback.tsx +34 -0
  282. package/carbon/src/client/pages/Blog.tsx +167 -0
  283. package/carbon/src/client/pages/Changelog.tsx +171 -0
  284. package/carbon/src/client/pages/Charts.tsx +388 -0
  285. package/carbon/src/client/pages/Checkout.tsx +227 -0
  286. package/carbon/src/client/pages/Contact.tsx +174 -0
  287. package/carbon/src/client/pages/Dashboard.tsx +368 -0
  288. package/carbon/src/client/pages/Docs.tsx +372 -0
  289. package/carbon/src/client/pages/ForgotPassword.tsx +111 -0
  290. package/carbon/src/client/pages/Home.tsx +187 -0
  291. package/carbon/src/client/pages/Legal.tsx +100 -0
  292. package/carbon/src/client/pages/Login.tsx +408 -0
  293. package/carbon/src/client/pages/MFAVerify.tsx +156 -0
  294. package/carbon/src/client/pages/NotFound.tsx +21 -0
  295. package/carbon/src/client/pages/Onboarding.tsx +246 -0
  296. package/carbon/src/client/pages/ResetPassword.tsx +200 -0
  297. package/carbon/src/client/pages/UIComponents.tsx +390 -0
  298. package/carbon/src/client/pages/admin/ContactSubmissions.tsx +220 -0
  299. package/carbon/src/client/pages/admin/Dashboard.tsx +24 -0
  300. package/carbon/src/client/pages/admin/Infrastructure.tsx +257 -0
  301. package/carbon/src/client/pages/admin/Jobs.tsx +225 -0
  302. package/carbon/src/client/pages/admin/Logs.tsx +18 -0
  303. package/carbon/src/client/pages/admin/Newsletter.tsx +300 -0
  304. package/carbon/src/client/pages/admin/Notifications.tsx +603 -0
  305. package/carbon/src/client/pages/admin/Organizations.tsx +306 -0
  306. package/carbon/src/client/pages/admin/Settings.tsx +314 -0
  307. package/carbon/src/client/pages/admin/Theme.tsx +465 -0
  308. package/carbon/src/client/pages/admin/Users.tsx +365 -0
  309. package/carbon/src/client/pages/api-docs.css +156 -0
  310. package/carbon/src/client/pages/organizations/Details.tsx +200 -0
  311. package/carbon/src/client/pages/organizations/Members.tsx +402 -0
  312. package/carbon/src/client/pages/settings/Billing.tsx +473 -0
  313. package/carbon/src/client/pages/settings/Profile.tsx +160 -0
  314. package/carbon/src/client/pages/settings/Security.tsx +341 -0
  315. package/carbon/src/client/public/favicon.svg +19 -0
  316. package/carbon/src/client/public/robots.txt +8 -0
  317. package/carbon/src/server/billing/index.ts +104 -0
  318. package/carbon/src/server/billing/provider.ts +81 -0
  319. package/carbon/src/server/billing/providers/paddle.ts +314 -0
  320. package/carbon/src/server/billing/providers/polar.ts +325 -0
  321. package/carbon/src/server/billing/providers/stripe.ts +233 -0
  322. package/carbon/src/server/emails/templates.ts +116 -0
  323. package/carbon/src/server/index.ts +554 -0
  324. package/carbon/src/server/lib/auth.ts +6 -0
  325. package/carbon/src/server/lib/email.ts +64 -0
  326. package/carbon/src/server/lib/env.ts +112 -0
  327. package/carbon/src/server/lib/errors.ts +21 -0
  328. package/carbon/src/server/lib/logger.ts +17 -0
  329. package/carbon/src/server/lib/rate-limiter.ts +288 -0
  330. package/carbon/src/server/lib/request.ts +34 -0
  331. package/carbon/src/server/lib/stripe.ts +42 -0
  332. package/carbon/src/server/lib/supabase.ts +65 -0
  333. package/carbon/src/server/middleware/requirePlan.ts +80 -0
  334. package/carbon/src/server/routes/_internal/services-status.ts +958 -0
  335. package/carbon/src/server/routes/_internal/verify-role.ts +185 -0
  336. package/carbon/src/server/routes/health.ts +48 -0
  337. package/carbon/src/server/routes/v1/admin/contact.ts +128 -0
  338. package/carbon/src/server/routes/v1/admin/jobs.ts +171 -0
  339. package/carbon/src/server/routes/v1/admin/newsletter.ts +237 -0
  340. package/carbon/src/server/routes/v1/auth.ts +390 -0
  341. package/carbon/src/server/routes/v1/billing.ts +718 -0
  342. package/carbon/src/server/routes/v1/contact.ts +93 -0
  343. package/carbon/src/server/routes/v1/index.ts +1333 -0
  344. package/carbon/src/server/routes/v1/newsletter.ts +181 -0
  345. package/carbon/src/server/routes/v1/performance.ts +157 -0
  346. package/carbon/src/server/routes/v1/stats.ts +170 -0
  347. package/carbon/src/server/routes/v1/theme.ts +106 -0
  348. package/carbon/src/server/routes/webhooks/billing.ts +376 -0
  349. package/carbon/src/server/routes/webhooks/stripe.ts +276 -0
  350. package/carbon/src/server/types.ts +11 -0
  351. package/carbon/src/shared/pricing.ts +155 -0
  352. package/carbon/src/shared/types.ts +338 -0
  353. package/carbon/supabase/migrations/00001_init.sql +717 -0
  354. package/carbon/supabase/migrations/00002_theme_settings.sql +13 -0
  355. package/carbon/supabase/migrations/00003_pg_cron.sql +121 -0
  356. package/carbon/supabase/migrations/00004_contact_newsletter.sql +81 -0
  357. package/carbon/supabase/migrations/00005_localization_languages.sql +22 -0
  358. package/carbon/supabase/seed.sql +16 -0
  359. package/carbon/tests/_helpers/app.ts +45 -0
  360. package/carbon/tests/_helpers/env.ts +37 -0
  361. package/carbon/tests/_helpers/factories.ts +69 -0
  362. package/carbon/tests/_helpers/jwt.ts +23 -0
  363. package/carbon/tests/_helpers/setup-integration.ts +20 -0
  364. package/carbon/tests/_helpers/setup-rtl.ts +12 -0
  365. package/carbon/tests/component/ErrorBoundary.test.tsx +53 -0
  366. package/carbon/tests/component/use-auth-settings.test.tsx +119 -0
  367. package/carbon/tests/integration/server/routes/contact.test.ts +162 -0
  368. package/carbon/tests/integration/server/routes/health.test.ts +61 -0
  369. package/carbon/tests/structural/i18n-parity.test.ts +42 -0
  370. package/carbon/tests/unit/client/utils.test.ts +49 -0
  371. package/carbon/tests/unit/shared/pricing.test.ts +93 -0
  372. package/carbon/tsconfig.json +27 -0
  373. package/carbon/tsconfig.server.json +27 -0
  374. package/carbon/tsconfig.test.json +9 -0
  375. package/carbon/vite.config.ts +110 -0
  376. package/carbon/vitest.config.ts +74 -0
  377. package/carbon/volumes/db/jwt.sql +57 -0
  378. package/carbon/volumes/db/metabase-init.sh +29 -0
  379. package/carbon/volumes/db/n8n-init.sh +25 -0
  380. package/carbon/volumes/db/realtime.sql +33 -0
  381. package/carbon/volumes/db/roles.sql +93 -0
  382. package/carbon/volumes/db/set-passwords.sh +12 -0
  383. package/carbon/volumes/db/super-admin.dev.sql +113 -0
  384. package/carbon/volumes/db/super-admin.generated.sql +113 -0
  385. package/carbon/volumes/db/super-admin.sql +114 -0
  386. package/carbon/volumes/grafana/dashboards/logs.json +179 -0
  387. package/carbon/volumes/grafana/dashboards/overview.json +523 -0
  388. package/carbon/volumes/grafana/dashboards/postgresql.json +337 -0
  389. package/carbon/volumes/grafana/dashboards.dev/logs.json +179 -0
  390. package/carbon/volumes/grafana/dashboards.dev/overview.json +156 -0
  391. package/carbon/volumes/grafana/dashboards.dev/postgresql.json +337 -0
  392. package/carbon/volumes/grafana/provisioning/dashboards/dashboards.dev.yml +16 -0
  393. package/carbon/volumes/grafana/provisioning/dashboards/dashboards.yml +16 -0
  394. package/carbon/volumes/grafana/provisioning/datasources/datasources.yml +43 -0
  395. package/carbon/volumes/kong/docker-entrypoint.sh +9 -0
  396. package/carbon/volumes/kong/kong.yml +208 -0
  397. package/carbon/volumes/loki/loki-config.yml +58 -0
  398. package/carbon/volumes/n8n/hooks.js +131 -0
  399. package/carbon/volumes/n8n/scripts/setup.sh +66 -0
  400. package/carbon/volumes/prometheus/prometheus.yml +43 -0
  401. package/carbon/volumes/promtail/promtail-config.yml +64 -0
  402. package/carbon/volumes/traefik/middlewares.dev.yml +83 -0
  403. package/carbon/volumes/traefik/middlewares.yml +95 -0
  404. package/carbon/volumes/traefik/vite-dev.yml +20 -0
  405. package/package.json +95 -0
  406. package/src/access.js +354 -0
  407. package/src/activate.js +187 -0
  408. package/src/add.js +718 -0
  409. package/src/backup.js +786 -0
  410. package/src/cli.js +350 -0
  411. package/src/configure.js +967 -0
  412. package/src/console.js +155 -0
  413. package/src/create.js +1499 -0
  414. package/src/deploy.js +311 -0
  415. package/src/destroy.js +2033 -0
  416. package/src/diagnose.js +735 -0
  417. package/src/down.js +80 -0
  418. package/src/failover.js +1032 -0
  419. package/src/lib/backup-s3.js +179 -0
  420. package/src/lib/build.js +33 -0
  421. package/src/lib/checksum.js +28 -0
  422. package/src/lib/ci-setup.js +666 -0
  423. package/src/lib/cli/help.js +129 -0
  424. package/src/lib/cli/parse-flags.js +160 -0
  425. package/src/lib/cli/select-action.js +65 -0
  426. package/src/lib/cli/select-environment.js +108 -0
  427. package/src/lib/cli/tty-guard.js +75 -0
  428. package/src/lib/cloudflare.js +447 -0
  429. package/src/lib/colors.js +52 -0
  430. package/src/lib/command.js +361 -0
  431. package/src/lib/config.js +359 -0
  432. package/src/lib/cost.js +103 -0
  433. package/src/lib/deploy/bundle.js +231 -0
  434. package/src/lib/deploy/compose/acme-verify.js +121 -0
  435. package/src/lib/deploy/compose/build-args.js +78 -0
  436. package/src/lib/deploy/compose/ha.js +1874 -0
  437. package/src/lib/deploy/compose/index.js +1294 -0
  438. package/src/lib/deploy/compose/reconcile.js +74 -0
  439. package/src/lib/deploy/github.js +382 -0
  440. package/src/lib/deploy/image.js +191 -0
  441. package/src/lib/deploy/index.js +119 -0
  442. package/src/lib/deploy/k8s/LICENSE +99 -0
  443. package/src/lib/deploy/k8s/gitops-deploy.js +298 -0
  444. package/src/lib/deploy/k8s/ha/index.js +1000 -0
  445. package/src/lib/deploy/k8s/index.js +62 -0
  446. package/src/lib/deploy/k8s/k3s.js +2515 -0
  447. package/src/lib/deploy/orchestrator.js +1401 -0
  448. package/src/lib/deploy/prompts.js +545 -0
  449. package/src/lib/deploy/remote-build.js +130 -0
  450. package/src/lib/deploy/state.js +120 -0
  451. package/src/lib/deploy/utils.js +328 -0
  452. package/src/lib/deploy-logger.js +93 -0
  453. package/src/lib/dns-propagation.js +48 -0
  454. package/src/lib/environment.js +58 -0
  455. package/src/lib/fetch-retry.js +103 -0
  456. package/src/lib/github-environments.js +335 -0
  457. package/src/lib/hetzner-dns.js +377 -0
  458. package/src/lib/hetzner-guided-setup.js +275 -0
  459. package/src/lib/host-keys.js +37 -0
  460. package/src/lib/iac/cloud-init.js +52 -0
  461. package/src/lib/iac/index.js +325 -0
  462. package/src/lib/iac/programs/hetzner-compose.js +130 -0
  463. package/src/lib/iac/programs/hetzner-k8s.js +320 -0
  464. package/src/lib/kubectl.js +81 -0
  465. package/src/lib/licensing/index.js +259 -0
  466. package/src/lib/licensing/tiers.js +181 -0
  467. package/src/lib/licensing/validator.js +171 -0
  468. package/src/lib/merge-package-json.js +90 -0
  469. package/src/lib/operator-ip.js +381 -0
  470. package/src/lib/package-manager.js +111 -0
  471. package/src/lib/perf.js +71 -0
  472. package/src/lib/project-guard.js +39 -0
  473. package/src/lib/project.js +334 -0
  474. package/src/lib/providers/base.js +276 -0
  475. package/src/lib/providers/hetzner-s3.js +656 -0
  476. package/src/lib/providers/hetzner.js +755 -0
  477. package/src/lib/providers/index.js +164 -0
  478. package/src/lib/s3.js +510 -0
  479. package/src/lib/secret-scan.js +583 -0
  480. package/src/lib/secrets.js +63 -0
  481. package/src/lib/server-types.js +195 -0
  482. package/src/lib/shell.js +91 -0
  483. package/src/lib/ssh.js +241 -0
  484. package/src/lib/tracker.js +242 -0
  485. package/src/lib/upgrade-policy.js +170 -0
  486. package/src/lib/validators.js +105 -0
  487. package/src/lib/version.js +5 -0
  488. package/src/remove.js +292 -0
  489. package/src/reset.js +97 -0
  490. package/src/restore.js +871 -0
  491. package/src/scale.js +1734 -0
  492. package/src/shell.js +222 -0
  493. package/src/status.js +981 -0
  494. package/src/up.js +264 -0
  495. package/src/upgrade.js +721 -0
@@ -0,0 +1,92 @@
1
+ apiVersion: networking.k8s.io/v1
2
+ kind: NetworkPolicy
3
+ metadata:
4
+ name: traefik-policy
5
+ namespace: vibecarbon
6
+ spec:
7
+ podSelector:
8
+ matchLabels:
9
+ app: vibecarbon-traefik
10
+ policyTypes:
11
+ - Ingress
12
+ - Egress
13
+ ingress:
14
+ # Allow external traffic on HTTP and HTTPS (from LB and direct)
15
+ - ports:
16
+ - protocol: TCP
17
+ port: 80
18
+ - protocol: TCP
19
+ port: 443
20
+ # Allow health check probes on traefik port
21
+ - ports:
22
+ - protocol: TCP
23
+ port: 8080
24
+ egress:
25
+ # Allow connection to all pods in namespace (Traefik routes to app, kong, studio)
26
+ - to:
27
+ - podSelector: {}
28
+ # Allow DNS resolution
29
+ - to:
30
+ - namespaceSelector: {}
31
+ podSelector:
32
+ matchLabels:
33
+ k8s-app: kube-dns
34
+ ports:
35
+ - protocol: UDP
36
+ port: 53
37
+ - protocol: TCP
38
+ port: 53
39
+ # Kubernetes API egress for traefik's CRD/Ingress informers.
40
+ # Without these rules kube-router rejects outbound traffic from
41
+ # traefik to the apiserver, traefik loops on `connect: connection
42
+ # refused`, never loads IngressRoutes, and serves its default 404
43
+ # on every request. Surfaced in k8s-ha 2026-04-28 deploy run
44
+ # (verify-1df-1dg log) when the public probe got 404 even though
45
+ # the app pods + Service endpoints were healthy.
46
+ #
47
+ # CIDR coupling: the two ranges below are k3s defaults
48
+ # (--service-cidr 10.43.0.0/16, --cluster-cidr 10.42.0.0/16) that
49
+ # carbon/cloud-init/k3s/master-init.sh does NOT override. If you
50
+ # ever pass --service-cidr or --cluster-cidr there, also update
51
+ # both this file AND carbon/k8s/base/app/network-policy.yaml.
52
+ # k8s NetworkPolicy has no Service-name selector, so we have to
53
+ # name the CIDRs explicitly.
54
+ #
55
+ # 10.43.0.1:443 = kubernetes.default Service ClusterIP via kube-proxy
56
+ # DNAT (works on worker nodes).
57
+ - to:
58
+ - ipBlock:
59
+ cidr: 10.43.0.1/32
60
+ ports:
61
+ - protocol: TCP
62
+ port: 443
63
+ # 0.0.0.0/0:6443 = the apiserver, dial-anywhere on apiserver-protocol
64
+ # port. Background: the kubernetes Service ClusterIP (10.43.0.1) DNATs
65
+ # at the OUTPUT chain BEFORE the CNI evaluates NetworkPolicy egress, so
66
+ # the policy sees the *post-NAT* destination — the master node IP from
67
+ # the EndpointSlice. With k3s installed via `--node-ip=<public>` and
68
+ # HCLOUD_NETWORK NOT set on the Hetzner CCM (the patch that would
69
+ # populate InternalIP=10.0.1.x was reverted in src/lib/deploy/k8s/k3s.js
70
+ # because it broke kubelet's TLS cert SAN — cert is generated for the
71
+ # public IP only, so kubectl logs/exec fail x509 verify when InternalIP
72
+ # changes post-startup), the master's reported IP is the public IP. So
73
+ # 10.0.0.0/8 doesn't match and 10.42.0.0/16 (pod CIDR) was never on the
74
+ # wire — both diagnostically wrong RCAs from earlier.
75
+ #
76
+ # The IP changes every deploy, so we can't list it. Allow any
77
+ # destination on 6443 — port 6443 is apiserver-protocol; the only
78
+ # listeners are k8s control planes. Deny-by-default is preserved on
79
+ # every other port.
80
+ #
81
+ # Repro chain:
82
+ # - k8s deploy fanout4 2026-04-30 e3: 10.42.0.0/16:6443 → connection refused
83
+ # - k8s-ha deploy fanout4b 2026-05-01: tightened to 10.0.0.0/8 + tried
84
+ # CCM HCLOUD_NETWORK; reverted CCM (cert SAN) — left 10.0.0.0/8
85
+ # - k8s-ha restore fanout5 2026-05-01: same connection-refused on
86
+ # redeploy because Endpoint resolved to public IP again. Final fix.
87
+ - to:
88
+ - ipBlock:
89
+ cidr: 0.0.0.0/0
90
+ ports:
91
+ - protocol: TCP
92
+ port: 6443
@@ -0,0 +1,38 @@
1
+ apiVersion: v1
2
+ kind: Service
3
+ metadata:
4
+ name: traefik
5
+ labels:
6
+ app: vibecarbon-traefik
7
+ component: ingress
8
+ spec:
9
+ type: ClusterIP
10
+ ports:
11
+ - port: 80
12
+ targetPort: web
13
+ protocol: TCP
14
+ name: web
15
+ - port: 443
16
+ targetPort: websecure
17
+ protocol: TCP
18
+ name: websecure
19
+ selector:
20
+ app: vibecarbon-traefik
21
+ ---
22
+ # Internal service for dashboard access
23
+ apiVersion: v1
24
+ kind: Service
25
+ metadata:
26
+ name: traefik-dashboard
27
+ labels:
28
+ app: vibecarbon-traefik
29
+ component: ingress
30
+ spec:
31
+ type: ClusterIP
32
+ ports:
33
+ - port: 8080
34
+ targetPort: traefik
35
+ protocol: TCP
36
+ name: traefik
37
+ selector:
38
+ app: vibecarbon-traefik
@@ -0,0 +1,49 @@
1
+ # Flux CD GitOps Configuration
2
+
3
+ This directory contains Flux CD cluster-level glue (the `clusters/` GitRepositories + Kustomizations that wire the app manifests). Chart-level resources (HelmRepositories + HelmReleases) moved to `carbon/k8s/gitops/<component>/` in Phases 2–3 of the GitOps refactor (see `plans/gitops-refactor-2026-04-20.md`).
4
+
5
+ You do **not** need the `flux` CLI locally — `deploy.js` bootstraps Flux via a single `kubectl apply -f <release url>`.
6
+
7
+ ## Directory layout
8
+
9
+ ```
10
+ carbon/k8s/
11
+ ├── flux/
12
+ │ ├── clusters/
13
+ │ │ ├── primary/vibecarbon.yaml # GitRepository + Kustomizations (app manifests)
14
+ │ │ └── standby/vibecarbon.yaml
15
+ │ └── README.md # you are here
16
+ └── gitops/
17
+ ├── supabase/
18
+ │ ├── kustomization.yaml # configMapGenerator + resources list
19
+ │ ├── helm-repository.yaml # supabase-community HelmRepository
20
+ │ └── helm-release.yaml # supabase HelmRelease (reads supabase-values ConfigMap)
21
+ └── cert-manager-webhook-hetzner/
22
+ ├── kustomization.yaml
23
+ ├── helm-repository.yaml # hetzner-cloud HelmRepository
24
+ └── helm-release.yaml
25
+ ```
26
+
27
+ ## How deploy wires Flux
28
+
29
+ 1. `ensureFluxRunning(env)` — applies `https://github.com/fluxcd/flux2/releases/download/v2.8.5/install.yaml`, then `kubectl rollout status` on the four flux-system controllers (`source`, `helm`, `kustomize`, `notification`).
30
+ 2. **Cert-manager webhook** (only when DNS provider = hetzner): `kubectl apply -k carbon/k8s/gitops/cert-manager-webhook-hetzner/` → `kubectl wait helmrelease/cert-manager-webhook-hetzner`.
31
+ 3. **Supabase**: deploy renders `supabase.values.yaml` (substituting `{{DOMAIN}}` / `{{PROJECT_NAME}}`) into a tempdir containing the bundle files, then `kubectl apply -k <tempdir>` (kustomize generates the `supabase-values` ConfigMap from the rendered file). Then `kubectl wait helmrelease/supabase` (25 min budget).
32
+
33
+ Flux's 5-minute HelmRepository interval means transient source-controller fetch failures self-heal inside the HelmRelease wait budget. There is no client-side reconcile poking.
34
+
35
+ ## Useful commands (post-deploy, for debugging)
36
+
37
+ ```bash
38
+ kubectl get helmrelease,kustomization,helmrepository -A
39
+ kubectl describe helmrelease supabase -n flux-system
40
+ kubectl annotate --overwrite helmrelease/supabase -n flux-system reconcile.fluxcd.io/requestedAt="$(date -u +%FT%TZ)"
41
+ kubectl logs -n flux-system deploy/helm-controller --tail=200
42
+ kubectl logs -n flux-system deploy/source-controller --tail=200
43
+ ```
44
+
45
+ ## Secrets
46
+
47
+ The Supabase HelmRelease reads secrets from the `vibecarbon-secrets` Secret in the `vibecarbon` namespace (created by deploy before the HelmRelease is applied). The cert-manager-webhook-hetzner HelmRelease reads `hetzner-api-token` in the `cert-manager` namespace.
48
+
49
+ If you need to ship additional secrets through Git (e.g. for other HelmReleases), use Sealed Secrets, SOPS, or External Secrets Operator. Phase 4 of the GitOps refactor (GitRepository-driven reconciliation, see plan doc) is when we introduce this.
@@ -0,0 +1,128 @@
1
+ ---
2
+ # Flux GitRepository + Kustomizations for the primary cluster.
3
+ #
4
+ # URL is templated at project-create time via substitution of
5
+ # {{GITHUB_OWNER}}/{{PROJECT_NAME}} (see src/create.js PLACEHOLDERS).
6
+ # Applied once by the GitHub Actions deploy workflow at
7
+ # .github/workflows/deploy.yml — after that, Flux reconciles the repo's
8
+ # k8s/ directory every minute (GitRepository interval) and the
9
+ # Kustomizations every 10 min.
10
+ #
11
+ # Layout in the customer's repo:
12
+ # k8s/base/ # app + traefik + backup + etc.
13
+ # k8s/gitops/supabase/ # HelmRepo + HelmRelease + values CM
14
+ # k8s/gitops/cert-manager-webhook-hetzner/ # HelmRepo + HelmRelease
15
+ # k8s/overlays/production-<region>/ # per-env overlay on top of base
16
+ apiVersion: source.toolkit.fluxcd.io/v1
17
+ kind: GitRepository
18
+ metadata:
19
+ name: vibecarbon
20
+ namespace: flux-system
21
+ spec:
22
+ # 1-min poll keeps the "git push → reconcile" feedback loop tight.
23
+ interval: 1m
24
+ url: https://github.com/{{GITHUB_OWNER}}/{{PROJECT_NAME}}
25
+ ref:
26
+ branch: main
27
+ # Secret populated by the deploy workflow at first run, containing a
28
+ # `username` + `password` (PAT or GitHub App token with repo:read).
29
+ secretRef:
30
+ name: flux-system
31
+ ---
32
+ # Base manifests (namespace, network policies, app, traefik, backup,
33
+ # hetzner-ccm/csi placeholder kustomizations).
34
+ apiVersion: kustomize.toolkit.fluxcd.io/v1
35
+ kind: Kustomization
36
+ metadata:
37
+ name: vibecarbon-base
38
+ namespace: flux-system
39
+ spec:
40
+ interval: 10m
41
+ targetNamespace: vibecarbon
42
+ sourceRef:
43
+ kind: GitRepository
44
+ name: vibecarbon
45
+ path: ./k8s/base
46
+ prune: true
47
+ wait: true
48
+ timeout: 10m
49
+ healthChecks:
50
+ - apiVersion: apps/v1
51
+ kind: Deployment
52
+ name: app
53
+ namespace: vibecarbon
54
+ ---
55
+ # Supabase chart install (Phase 2 overlay from 2026-04-20 refactor).
56
+ # The `supabase-values` ConfigMap content is generated by kustomize from
57
+ # values.yaml inside the overlay — Flux's kustomize-controller runs the
58
+ # same generation as `kubectl apply -k`.
59
+ apiVersion: kustomize.toolkit.fluxcd.io/v1
60
+ kind: Kustomization
61
+ metadata:
62
+ name: vibecarbon-supabase
63
+ namespace: flux-system
64
+ spec:
65
+ interval: 10m
66
+ targetNamespace: flux-system
67
+ sourceRef:
68
+ kind: GitRepository
69
+ name: vibecarbon
70
+ path: ./k8s/gitops/supabase
71
+ prune: true
72
+ wait: true
73
+ timeout: 30m
74
+ dependsOn:
75
+ - name: vibecarbon-base
76
+ healthChecks:
77
+ - apiVersion: helm.toolkit.fluxcd.io/v2
78
+ kind: HelmRelease
79
+ name: supabase
80
+ namespace: flux-system
81
+ ---
82
+ # cert-manager-webhook-hetzner chart install (Phase 3 overlay).
83
+ # Applied unconditionally; the ClusterIssuer DNS01 solver in
84
+ # ./k8s/base/cert-manager/ references the webhook at install time.
85
+ apiVersion: kustomize.toolkit.fluxcd.io/v1
86
+ kind: Kustomization
87
+ metadata:
88
+ name: vibecarbon-cert-manager-webhook-hetzner
89
+ namespace: flux-system
90
+ spec:
91
+ interval: 10m
92
+ targetNamespace: flux-system
93
+ sourceRef:
94
+ kind: GitRepository
95
+ name: vibecarbon
96
+ path: ./k8s/gitops/cert-manager-webhook-hetzner
97
+ prune: true
98
+ wait: true
99
+ timeout: 10m
100
+ dependsOn:
101
+ - name: vibecarbon-base
102
+ healthChecks:
103
+ - apiVersion: helm.toolkit.fluxcd.io/v2
104
+ kind: HelmRelease
105
+ name: cert-manager-webhook-hetzner
106
+ namespace: flux-system
107
+ ---
108
+ # Production overlay (region-specific patches on top of ./k8s/base).
109
+ # Applied only when the region matches; the deploy workflow renders the
110
+ # correct overlay name (production-nbg1, production-hel1, etc.) into a
111
+ # Kustomization name specific to the cluster at apply time.
112
+ apiVersion: kustomize.toolkit.fluxcd.io/v1
113
+ kind: Kustomization
114
+ metadata:
115
+ name: vibecarbon-production-nbg1
116
+ namespace: flux-system
117
+ spec:
118
+ interval: 10m
119
+ targetNamespace: vibecarbon
120
+ sourceRef:
121
+ kind: GitRepository
122
+ name: vibecarbon
123
+ path: ./k8s/overlays/production-nbg1
124
+ prune: true
125
+ wait: true
126
+ timeout: 10m
127
+ dependsOn:
128
+ - name: vibecarbon-base
@@ -0,0 +1,83 @@
1
+ ---
2
+ # Flux GitRepository + Kustomizations for the standby cluster (HA setup).
3
+ #
4
+ # Mirror of clusters/primary/vibecarbon.yaml, minus the supabase
5
+ # HelmRelease (the standby only runs replication-ready base resources;
6
+ # Supabase runs on primary and replicates its DB to the standby's
7
+ # postgres StatefulSet). The path layout + templating is identical.
8
+ #
9
+ # Applied once by the deploy workflow at first standby-cluster bootstrap.
10
+ apiVersion: source.toolkit.fluxcd.io/v1
11
+ kind: GitRepository
12
+ metadata:
13
+ name: vibecarbon
14
+ namespace: flux-system
15
+ spec:
16
+ interval: 1m
17
+ url: https://github.com/{{GITHUB_OWNER}}/{{PROJECT_NAME}}
18
+ ref:
19
+ branch: main
20
+ secretRef:
21
+ name: flux-system
22
+ ---
23
+ apiVersion: kustomize.toolkit.fluxcd.io/v1
24
+ kind: Kustomization
25
+ metadata:
26
+ name: vibecarbon-base
27
+ namespace: flux-system
28
+ spec:
29
+ interval: 10m
30
+ targetNamespace: vibecarbon
31
+ sourceRef:
32
+ kind: GitRepository
33
+ name: vibecarbon
34
+ path: ./k8s/base
35
+ prune: true
36
+ wait: true
37
+ timeout: 10m
38
+ healthChecks:
39
+ - apiVersion: apps/v1
40
+ kind: StatefulSet
41
+ name: postgres
42
+ namespace: vibecarbon
43
+ ---
44
+ apiVersion: kustomize.toolkit.fluxcd.io/v1
45
+ kind: Kustomization
46
+ metadata:
47
+ name: vibecarbon-cert-manager-webhook-hetzner
48
+ namespace: flux-system
49
+ spec:
50
+ interval: 10m
51
+ targetNamespace: flux-system
52
+ sourceRef:
53
+ kind: GitRepository
54
+ name: vibecarbon
55
+ path: ./k8s/gitops/cert-manager-webhook-hetzner
56
+ prune: true
57
+ wait: true
58
+ timeout: 10m
59
+ dependsOn:
60
+ - name: vibecarbon-base
61
+ healthChecks:
62
+ - apiVersion: helm.toolkit.fluxcd.io/v2
63
+ kind: HelmRelease
64
+ name: cert-manager-webhook-hetzner
65
+ namespace: flux-system
66
+ ---
67
+ apiVersion: kustomize.toolkit.fluxcd.io/v1
68
+ kind: Kustomization
69
+ metadata:
70
+ name: vibecarbon-production-hel1
71
+ namespace: flux-system
72
+ spec:
73
+ interval: 10m
74
+ targetNamespace: vibecarbon
75
+ sourceRef:
76
+ kind: GitRepository
77
+ name: vibecarbon
78
+ path: ./k8s/overlays/production-hel1
79
+ prune: true
80
+ wait: true
81
+ timeout: 10m
82
+ dependsOn:
83
+ - name: vibecarbon-base
@@ -0,0 +1,38 @@
1
+ ---
2
+ # Flux-managed replacement for the former imperative `helm install
3
+ # cert-manager-webhook-hetzner` in deploy.js. Installed only when the
4
+ # deployment uses Hetzner DNS (Cloudflare DNS01 has its own path).
5
+ #
6
+ # The webhook requires: cert-manager CRDs + controller Ready (installed
7
+ # imperatively earlier in deploy) and the `hetzner-api-token` Secret in
8
+ # the cert-manager namespace (created by deploy before this is applied).
9
+ apiVersion: helm.toolkit.fluxcd.io/v2
10
+ kind: HelmRelease
11
+ metadata:
12
+ name: cert-manager-webhook-hetzner
13
+ namespace: flux-system
14
+ spec:
15
+ interval: 10m
16
+ releaseName: cert-manager-webhook-hetzner
17
+ targetNamespace: cert-manager
18
+ chart:
19
+ spec:
20
+ chart: cert-manager-webhook-hetzner
21
+ sourceRef:
22
+ kind: HelmRepository
23
+ name: hetzner-cloud
24
+ namespace: flux-system
25
+ install:
26
+ timeout: 5m
27
+ remediation:
28
+ # First install failures are usually secret-missing or CRD-missing.
29
+ # Fail fast so the deploy surfaces the real issue.
30
+ retries: 0
31
+ upgrade:
32
+ timeout: 5m
33
+ remediation:
34
+ retries: 2
35
+ values:
36
+ secret:
37
+ name: hetzner-api-token
38
+ key: api-token
@@ -0,0 +1,16 @@
1
+ ---
2
+ # Hetzner Cloud Helm chart repository. Used by the
3
+ # cert-manager-webhook-hetzner HelmRelease in this same overlay.
4
+ # Migrated from carbon/k8s/flux/helm-repositories.yaml as part of
5
+ # Phase 3 of the GitOps refactor.
6
+ apiVersion: source.toolkit.fluxcd.io/v1
7
+ kind: HelmRepository
8
+ metadata:
9
+ name: hetzner-cloud
10
+ namespace: flux-system
11
+ spec:
12
+ # 5-minute interval matches Phase 1 convention. Short enough that
13
+ # initial source-controller fetch failures retry within the
14
+ # HelmRelease wait budget.
15
+ interval: 5m
16
+ url: https://charts.hetzner.cloud
@@ -0,0 +1,10 @@
1
+ # Phase 3 of the GitOps refactor: cert-manager-webhook-hetzner as a
2
+ # single kustomize bundle. Applied via `kubectl apply -k` directly from
3
+ # this directory (no values templating needed — the HelmRelease's
4
+ # values are static).
5
+ apiVersion: kustomize.config.k8s.io/v1beta1
6
+ kind: Kustomization
7
+ namespace: flux-system
8
+ resources:
9
+ - helm-repository.yaml
10
+ - helm-release.yaml
@@ -0,0 +1,66 @@
1
+ ---
2
+ # Flux-managed replacement for the former imperative `helm install supabase`
3
+ # in deploy.js. The values shape comes straight from supabase.values.yaml;
4
+ # {{DOMAIN}} and {{PROJECT_NAME}} are substituted at deploy time.
5
+ #
6
+ # The HelmRelease reads secrets from the pre-created vibecarbon-secrets
7
+ # Secret in the vibecarbon namespace (populated by our deploy flow before
8
+ # this resource is applied).
9
+ apiVersion: helm.toolkit.fluxcd.io/v2
10
+ kind: HelmRelease
11
+ metadata:
12
+ name: supabase
13
+ namespace: flux-system
14
+ spec:
15
+ interval: 10m
16
+ releaseName: supabase
17
+ targetNamespace: vibecarbon
18
+ chart:
19
+ spec:
20
+ chart: supabase
21
+ sourceRef:
22
+ kind: HelmRepository
23
+ name: supabase-community
24
+ namespace: flux-system
25
+ install:
26
+ # First-time chart install includes postgres-init + DB migrations + all
27
+ # subchart init containers (wait-for-db). Observed 20+ min on cold nodes
28
+ # where images pull from Docker Hub in parallel. Budget 25m to give it
29
+ # headroom without blowing up the overall deploy timeout.
30
+ timeout: 25m
31
+ remediation:
32
+ # First install failures are usually schema / values / image problems.
33
+ # Fail fast instead of burning another 25m on a doomed retry.
34
+ retries: 0
35
+ upgrade:
36
+ timeout: 15m
37
+ remediation:
38
+ retries: 1
39
+ valuesFrom:
40
+ - kind: ConfigMap
41
+ name: supabase-values
42
+ valuesKey: values.yaml
43
+ # Expose PostgreSQL port 5432 on the node's interface so cross-cluster
44
+ # replication works. The standby cluster's supabase node opens a TCP
45
+ # connection to the primary's public IP on 5432 during pg_basebackup and
46
+ # subsequent streaming. Without hostPort the service is only reachable
47
+ # via ClusterIP or NodePort; NodePort cross-cluster was historically
48
+ # blocked by Hetzner Cloud firewalls even with a rule in place (see
49
+ # memory project_replication_broken.md). hostPort binds the port on the
50
+ # node's host network namespace, so it's reachable at the public node IP
51
+ # — and the Hetzner firewall rule for 5432 that src/lib/deploy/k8s/ha/
52
+ # index.js:254-266 adds now has something to route traffic to.
53
+ postRenderers:
54
+ - kustomize:
55
+ patches:
56
+ - target:
57
+ kind: StatefulSet
58
+ name: supabase-supabase-db
59
+ patch: |
60
+ - op: add
61
+ path: /spec/template/spec/containers/0/ports/-
62
+ value:
63
+ containerPort: 5432
64
+ hostPort: 5432
65
+ protocol: TCP
66
+ name: postgres-host
@@ -0,0 +1,18 @@
1
+ ---
2
+ # Supabase community Helm chart repository.
3
+ # Extracted from carbon/k8s/flux/helm-repositories.yaml as part of the
4
+ # Phase 2 Supabase-kustomize bundle. The other HelmRepository
5
+ # (`hetzner-cloud`) stays in the old file until Phase 3 migrates
6
+ # cert-manager-webhook-hetzner.
7
+ apiVersion: source.toolkit.fluxcd.io/v1
8
+ kind: HelmRepository
9
+ metadata:
10
+ name: supabase-community
11
+ namespace: flux-system
12
+ spec:
13
+ # 5-minute interval matches the global convention set in
14
+ # carbon/k8s/flux/helm-repositories.yaml. Short enough that initial
15
+ # source-controller fetch failures retry within our HelmRelease wait
16
+ # budget.
17
+ interval: 5m
18
+ url: https://supabase-community.github.io/supabase-kubernetes
@@ -0,0 +1,33 @@
1
+ # Phase 2 of the GitOps refactor: Supabase HelmRepository + HelmRelease +
2
+ # values ConfigMap as a single kustomize bundle. See
3
+ # plans/gitops-refactor-2026-04-20.md.
4
+ #
5
+ # How the deploy code uses this:
6
+ # 1. Render carbon/k8s/values/supabase.values.yaml into a tempdir
7
+ # (substituting {{DOMAIN}} + {{PROJECT_NAME}}).
8
+ # 2. Copy this kustomization + helm-repository.yaml + helm-release.yaml
9
+ # into the same tempdir.
10
+ # 3. Run `kubectl apply -k <tempdir>`. Kustomize generates the values
11
+ # ConfigMap from the rendered values.yaml; Flux reconciles
12
+ # HelmRepository → HelmChart → HelmRelease in dependency order.
13
+ # 4. Wait for `helmrelease/supabase` Ready condition.
14
+ #
15
+ # Replaces the imperative apply/poke/wait flow in
16
+ # src/lib/deploy/k8s/index.js (~40 LOC eliminated).
17
+ apiVersion: kustomize.config.k8s.io/v1beta1
18
+ kind: Kustomization
19
+ namespace: flux-system
20
+ resources:
21
+ - helm-repository.yaml
22
+ - helm-release.yaml
23
+ configMapGenerator:
24
+ - name: supabase-values
25
+ files:
26
+ - values.yaml
27
+ generatorOptions:
28
+ # Kustomize defaults to hashed ConfigMap names (supabase-values-abc123)
29
+ # so rolling updates trigger. Our HelmRelease references the name
30
+ # directly via `valuesFrom.name: supabase-values`, so we disable the
31
+ # hash suffix. Flux will notice ConfigMap changes via generation bumps
32
+ # and re-reconcile.
33
+ disableNameSuffixHash: true
@@ -0,0 +1,51 @@
1
+ # Let's Encrypt ClusterIssuers for the `cloudflare` DNS provider strategy.
2
+ #
3
+ # Uses cert-manager's native Cloudflare DNS-01 solver: the controller
4
+ # writes a TXT record under `_acme-challenge.<domain>` via the
5
+ # Cloudflare API, Let's Encrypt resolves it to validate, no port-80
6
+ # round trip and no interaction with Cloudflare's edge proxy. Required
7
+ # when the domain is orange-clouded (HTTPS upgrade at the edge breaks
8
+ # HTTP-01) and is the right default for any user already running
9
+ # Cloudflare DNS.
10
+ #
11
+ # Requires Secret `cloudflare-api-token` with key `api-token` in the
12
+ # cert-manager namespace, scoped at minimum to:
13
+ # - Zone:DNS:Edit on the target zone
14
+ # - Zone:Zone:Read on all zones (cert-manager reads zone metadata)
15
+ # `applyK3sManifests` creates this Secret from `cloudflareApiToken`
16
+ # before applying these issuers; without it cert-manager Orders pin
17
+ # Pending forever.
18
+ apiVersion: cert-manager.io/v1
19
+ kind: ClusterIssuer
20
+ metadata:
21
+ name: letsencrypt-prod-cloudflare
22
+ spec:
23
+ acme:
24
+ server: https://acme-v02.api.letsencrypt.org/directory
25
+ email: "{{ADMIN_EMAIL}}"
26
+ privateKeySecretRef:
27
+ name: letsencrypt-prod-cloudflare-account-key
28
+ solvers:
29
+ - dns01:
30
+ cloudflare:
31
+ apiTokenSecretRef:
32
+ name: cloudflare-api-token
33
+ key: api-token
34
+ ---
35
+ apiVersion: cert-manager.io/v1
36
+ kind: ClusterIssuer
37
+ metadata:
38
+ name: letsencrypt-staging-cloudflare
39
+ spec:
40
+ acme:
41
+ # Staging has higher rate limits but issues untrusted certs.
42
+ server: https://acme-staging-v02.api.letsencrypt.org/directory
43
+ email: "{{ADMIN_EMAIL}}"
44
+ privateKeySecretRef:
45
+ name: letsencrypt-staging-cloudflare-account-key
46
+ solvers:
47
+ - dns01:
48
+ cloudflare:
49
+ apiTokenSecretRef:
50
+ name: cloudflare-api-token
51
+ key: api-token