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,5 @@
1
+ apiVersion: kustomize.config.k8s.io/v1beta1
2
+ kind: Kustomization
3
+
4
+ resources:
5
+ - local-registry.yaml
@@ -0,0 +1,193 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: local-registry
5
+ namespace: vibecarbon
6
+ labels:
7
+ app: local-registry
8
+ spec:
9
+ replicas: 1
10
+ # Recreate (not RollingUpdate) because hostPort: 5000 can only be held by one pod at a time.
11
+ # RollingUpdate would leave the new pod Pending until the old one releases the port.
12
+ strategy:
13
+ type: Recreate
14
+ selector:
15
+ matchLabels:
16
+ app: local-registry
17
+ template:
18
+ metadata:
19
+ labels:
20
+ app: local-registry
21
+ spec:
22
+ # Run only on master node — hostPort exposes 5000 on master's private IP for SSH tunnel access.
23
+ # S3 backend stores all image layers externally; this affinity is for stable hostPort placement.
24
+ nodeSelector:
25
+ node-role.kubernetes.io/control-plane: "true"
26
+ tolerations:
27
+ - key: node-role.kubernetes.io/control-plane
28
+ operator: Exists
29
+ effect: NoSchedule
30
+ containers:
31
+ - name: registry
32
+ image: registry:2
33
+ # Strip https:// prefix from S3_ENDPOINT — registry:2 needs a bare hostname.
34
+ # REGISTRY_STORAGE_S3_SECURE=true controls HTTPS separately.
35
+ command: ["/bin/sh", "-c"]
36
+ args:
37
+ - |
38
+ if [ -z "$REGISTRY_STORAGE_S3_REGION" ]; then
39
+ # S3 not configured — fall back to local filesystem storage.
40
+ # Unset all S3 env vars so registry:2 uses its default filesystem driver.
41
+ unset REGISTRY_STORAGE \
42
+ REGISTRY_STORAGE_S3_ACCESSKEY \
43
+ REGISTRY_STORAGE_S3_SECRETKEY \
44
+ REGISTRY_STORAGE_S3_REGION \
45
+ REGISTRY_STORAGE_S3_BUCKET \
46
+ REGISTRY_STORAGE_S3_REGIONENDPOINT \
47
+ REGISTRY_STORAGE_S3_ROOTDIRECTORY \
48
+ REGISTRY_STORAGE_S3_SECURE \
49
+ REGISTRY_STORAGE_S3_V4AUTH
50
+ else
51
+ # S3 configured — strip https:// prefix from endpoint (registry:2 needs bare hostname).
52
+ REGISTRY_STORAGE_S3_REGIONENDPOINT="${REGISTRY_STORAGE_S3_REGIONENDPOINT#https://}"
53
+ REGISTRY_STORAGE_S3_REGIONENDPOINT="${REGISTRY_STORAGE_S3_REGIONENDPOINT#http://}"
54
+ export REGISTRY_STORAGE_S3_REGIONENDPOINT
55
+ fi
56
+ exec /entrypoint.sh /etc/docker/registry/config.yml
57
+ securityContext:
58
+ runAsUser: 1000
59
+ runAsNonRoot: true
60
+ allowPrivilegeEscalation: false
61
+ env:
62
+ - name: REGISTRY_STORAGE
63
+ value: s3
64
+ - name: REGISTRY_STORAGE_S3_ACCESSKEY
65
+ valueFrom:
66
+ secretKeyRef: { name: vibecarbon-secrets, key: S3_ACCESS_KEY }
67
+ - name: REGISTRY_STORAGE_S3_SECRETKEY
68
+ valueFrom:
69
+ secretKeyRef: { name: vibecarbon-secrets, key: S3_SECRET_KEY }
70
+ - name: REGISTRY_STORAGE_S3_REGION
71
+ valueFrom:
72
+ secretKeyRef: { name: vibecarbon-secrets, key: S3_REGION }
73
+ - name: REGISTRY_STORAGE_S3_BUCKET
74
+ valueFrom:
75
+ secretKeyRef: { name: vibecarbon-secrets, key: S3_BUCKET }
76
+ - name: REGISTRY_STORAGE_S3_REGIONENDPOINT
77
+ valueFrom:
78
+ secretKeyRef: { name: vibecarbon-secrets, key: S3_ENDPOINT }
79
+ - name: REGISTRY_STORAGE_S3_ROOTDIRECTORY
80
+ value: registry/
81
+ - name: REGISTRY_STORAGE_S3_SECURE
82
+ value: "true"
83
+ - name: REGISTRY_STORAGE_S3_V4AUTH
84
+ value: "true"
85
+ - name: REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR
86
+ value: inmemory
87
+ - name: REGISTRY_STORAGE_DELETE_ENABLED
88
+ value: "true"
89
+ ports:
90
+ - containerPort: 5000
91
+ # hostPort exposes the registry on the master's private IP (10.0.1.1:5000).
92
+ # Worker and supabase kubelets use 10.0.1.1:5000 to pull images — kubelet uses
93
+ # node DNS (not cluster DNS) so it can't resolve the "local-registry" service name.
94
+ hostPort: 5000
95
+ protocol: TCP
96
+ volumeMounts:
97
+ - name: registry-tmp
98
+ mountPath: /var/lib/registry
99
+ resources:
100
+ requests:
101
+ cpu: 100m
102
+ memory: 128Mi
103
+ limits:
104
+ cpu: 500m
105
+ # 1Gi headroom: registry:2 with the S3 driver buffers
106
+ # multipart uploads in memory, and large image layers
107
+ # (the backup image is ~300MB) can spike past 512Mi.
108
+ memory: 1Gi
109
+ readinessProbe:
110
+ httpGet:
111
+ path: /v2/
112
+ port: 5000
113
+ initialDelaySeconds: 5
114
+ periodSeconds: 10
115
+ # Default timeoutSeconds=1 is hostile to a registry busy
116
+ # streaming a layer to S3 — give it 10s before we declare
117
+ # the probe failed and pull it from the Service.
118
+ timeoutSeconds: 10
119
+ failureThreshold: 5
120
+ livenessProbe:
121
+ httpGet:
122
+ path: /v2/
123
+ port: 5000
124
+ initialDelaySeconds: 10
125
+ periodSeconds: 30
126
+ # Same reasoning as readinessProbe — but with a larger
127
+ # failureThreshold because killing the pod mid-push aborts
128
+ # the upload with `manifest blob unknown`/`EOF` (exactly
129
+ # the failure mode that bit e2e on 2026-04-30).
130
+ timeoutSeconds: 10
131
+ failureThreshold: 6
132
+ volumes:
133
+ - name: registry-tmp
134
+ emptyDir: {} # temp only; all image layers stored in S3
135
+ ---
136
+ apiVersion: networking.k8s.io/v1
137
+ kind: NetworkPolicy
138
+ metadata:
139
+ name: registry-policy
140
+ namespace: vibecarbon
141
+ labels:
142
+ app.kubernetes.io/part-of: vibecarbon
143
+ spec:
144
+ podSelector:
145
+ matchLabels:
146
+ app: local-registry
147
+ policyTypes:
148
+ - Ingress
149
+ - Egress
150
+ ingress:
151
+ # Allow image pulls from any pod in the namespace via ClusterIP
152
+ - ports:
153
+ - port: 5000
154
+ protocol: TCP
155
+ egress:
156
+ # Allow DNS resolution (required to resolve S3 endpoint hostnames)
157
+ - ports:
158
+ - port: 53
159
+ protocol: UDP
160
+ - port: 53
161
+ protocol: TCP
162
+ # Allow S3 access (Hetzner Object Storage and compatible providers)
163
+ - ports:
164
+ - port: 443
165
+ protocol: TCP
166
+ to:
167
+ - ipBlock:
168
+ cidr: 0.0.0.0/0
169
+ except:
170
+ - 10.0.0.0/8
171
+ - 172.16.0.0/12
172
+ - 192.168.0.0/16
173
+ ---
174
+ # ClusterIP Service for in-cluster push paths (e.g., a CI pod inside the
175
+ # cluster running `docker push` to localhost:5000 via kube-proxy). Kubelet
176
+ # itself does NOT use this Service — it pulls via hostPort because it
177
+ # resolves names against node DNS, not cluster DNS. See registries.yaml
178
+ # in cloud-init for the kubelet-side mirror config.
179
+ apiVersion: v1
180
+ kind: Service
181
+ metadata:
182
+ name: local-registry
183
+ namespace: vibecarbon
184
+ labels:
185
+ app: local-registry
186
+ spec:
187
+ type: ClusterIP
188
+ ports:
189
+ - port: 5000
190
+ targetPort: 5000
191
+ protocol: TCP
192
+ selector:
193
+ app: local-registry
@@ -0,0 +1,21 @@
1
+ # TLS Certificate for Vibecarbon application
2
+ # Requires cert-manager to be installed (kubectl apply -k k8s/infra/)
3
+ #
4
+ # issuerRef.name is patched per-deployment by applyK3sManifests in
5
+ # src/lib/deploy/k8s/k3s.js — it picks letsencrypt-{prod,staging}-{
6
+ # cloudflare,hetzner,manual} based on dnsProvider + ACME_CA_SERVER.
7
+ # The placeholder below keeps this template valid for kustomize and
8
+ # is overwritten before cert-manager ever sees a Certificate request.
9
+ apiVersion: cert-manager.io/v1
10
+ kind: Certificate
11
+ metadata:
12
+ name: vibecarbon-tls
13
+ spec:
14
+ secretName: vibecarbon-tls
15
+ issuerRef:
16
+ name: letsencrypt-prod-manual
17
+ kind: ClusterIssuer
18
+ dnsNames:
19
+ - app.example.com # Patched with actual domain at deploy time
20
+ # Optional: Include additional subdomains
21
+ # - "*.app.example.com"
@@ -0,0 +1,13 @@
1
+ apiVersion: v1
2
+ kind: ConfigMap
3
+ metadata:
4
+ name: traefik-config
5
+ labels:
6
+ app: vibecarbon-traefik
7
+ component: ingress
8
+ data:
9
+ # Additional Traefik configuration can be added here
10
+ # This is used by the Traefik deployment via volume mount if needed
11
+ traefik.yml: |
12
+ # Static configuration (if needed beyond CLI args)
13
+ # Currently most config is passed via CLI args
@@ -0,0 +1,165 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: traefik
5
+ labels:
6
+ app: vibecarbon-traefik
7
+ component: ingress
8
+ spec:
9
+ replicas: 1
10
+ selector:
11
+ matchLabels:
12
+ app: vibecarbon-traefik
13
+ template:
14
+ metadata:
15
+ labels:
16
+ app: vibecarbon-traefik
17
+ component: ingress
18
+ spec:
19
+ serviceAccountName: traefik
20
+ nodeSelector:
21
+ node-role.kubernetes.io/control-plane: 'true'
22
+ tolerations:
23
+ - key: node-role.kubernetes.io/control-plane
24
+ operator: Exists
25
+ effect: NoSchedule
26
+ containers:
27
+ - name: traefik
28
+ image: traefik:v3.6.11
29
+ imagePullPolicy: IfNotPresent
30
+ args:
31
+ - --api.dashboard=true
32
+ - --api.insecure=false
33
+ - --providers.kubernetescrd
34
+ - --providers.kubernetesingress
35
+ - --entrypoints.web.address=:80
36
+ - --entrypoints.websecure.address=:443
37
+ - --entrypoints.traefik.address=:8080
38
+ - --ping=true
39
+ - --log.level=INFO
40
+ - --accesslog=true
41
+ ports:
42
+ - containerPort: 80
43
+ name: web
44
+ hostPort: 80
45
+ - containerPort: 443
46
+ name: websecure
47
+ hostPort: 443
48
+ - containerPort: 8080
49
+ name: traefik
50
+ resources:
51
+ requests:
52
+ cpu: 100m
53
+ memory: 128Mi
54
+ limits:
55
+ cpu: 500m
56
+ memory: 256Mi
57
+ livenessProbe:
58
+ httpGet:
59
+ path: /ping
60
+ port: traefik
61
+ initialDelaySeconds: 10
62
+ periodSeconds: 10
63
+ timeoutSeconds: 5
64
+ failureThreshold: 3
65
+ readinessProbe:
66
+ httpGet:
67
+ path: /ping
68
+ port: traefik
69
+ initialDelaySeconds: 5
70
+ periodSeconds: 5
71
+ timeoutSeconds: 3
72
+ failureThreshold: 3
73
+ securityContext:
74
+ allowPrivilegeEscalation: false
75
+ readOnlyRootFilesystem: true
76
+ volumeMounts:
77
+ - name: tmp-vol-0
78
+ mountPath: /tmp
79
+ securityContext:
80
+ seccompProfile:
81
+ type: RuntimeDefault
82
+ volumes:
83
+ - name: tmp-vol-0
84
+ emptyDir: {}
85
+ ---
86
+ apiVersion: v1
87
+ kind: ServiceAccount
88
+ metadata:
89
+ name: traefik
90
+ labels:
91
+ app: vibecarbon-traefik
92
+ ---
93
+ apiVersion: rbac.authorization.k8s.io/v1
94
+ kind: ClusterRole
95
+ metadata:
96
+ name: traefik
97
+ rules:
98
+ - apiGroups:
99
+ - ''
100
+ resources:
101
+ - services
102
+ - endpoints
103
+ - secrets
104
+ - configmaps
105
+ - pods
106
+ - nodes
107
+ verbs:
108
+ - get
109
+ - list
110
+ - watch
111
+ - apiGroups:
112
+ - discovery.k8s.io
113
+ resources:
114
+ - endpointslices
115
+ verbs:
116
+ - get
117
+ - list
118
+ - watch
119
+ - apiGroups:
120
+ - extensions
121
+ - networking.k8s.io
122
+ resources:
123
+ - ingresses
124
+ - ingressclasses
125
+ verbs:
126
+ - get
127
+ - list
128
+ - watch
129
+ - apiGroups:
130
+ - extensions
131
+ - networking.k8s.io
132
+ resources:
133
+ - ingresses/status
134
+ verbs:
135
+ - update
136
+ - apiGroups:
137
+ - traefik.io
138
+ resources:
139
+ - middlewares
140
+ - middlewaretcps
141
+ - ingressroutes
142
+ - traefikservices
143
+ - ingressroutetcps
144
+ - ingressrouteudps
145
+ - tlsoptions
146
+ - tlsstores
147
+ - serverstransports
148
+ - serverstransporttcps
149
+ verbs:
150
+ - get
151
+ - list
152
+ - watch
153
+ ---
154
+ apiVersion: rbac.authorization.k8s.io/v1
155
+ kind: ClusterRoleBinding
156
+ metadata:
157
+ name: traefik
158
+ roleRef:
159
+ apiGroup: rbac.authorization.k8s.io
160
+ kind: ClusterRole
161
+ name: traefik
162
+ subjects:
163
+ - kind: ServiceAccount
164
+ name: traefik
165
+ namespace: vibecarbon
@@ -0,0 +1,141 @@
1
+ # Traefik CRDs - IngressRoute for Vibecarbon
2
+ apiVersion: traefik.io/v1alpha1
3
+ kind: IngressRoute
4
+ metadata:
5
+ name: vibecarbon-app
6
+ labels:
7
+ app: vibecarbon
8
+ spec:
9
+ entryPoints:
10
+ - websecure
11
+ routes:
12
+ # Main application routes
13
+ - match: PathPrefix(`/`)
14
+ kind: Rule
15
+ priority: 1
16
+ services:
17
+ - name: app
18
+ port: 3000
19
+ middlewares:
20
+ - name: security-headers
21
+ # API routes go to Kong (Supabase gateway)
22
+ - match: PathPrefix(`/auth`) || PathPrefix(`/rest`) || PathPrefix(`/realtime`) || PathPrefix(`/storage`)
23
+ kind: Rule
24
+ priority: 10
25
+ services:
26
+ - name: supabase-supabase-kong
27
+ port: 8000
28
+ middlewares:
29
+ - name: security-headers
30
+ # Admin routes - protected by ForwardAuth (requires admin role)
31
+ # Studio dashboard
32
+ - match: PathPrefix(`/admin/studio`)
33
+ kind: Rule
34
+ priority: 20
35
+ services:
36
+ - name: supabase-supabase-studio
37
+ port: 3000
38
+ middlewares:
39
+ - name: admin-auth
40
+ - name: security-headers
41
+ - name: strip-admin-studio-prefix
42
+ # Next.js static assets for Studio (/_next/... paths are absolute in Next.js builds).
43
+ # The main app uses Vite, so /_next/ requests only ever originate from Studio's HTML.
44
+ # Priority 15: higher than the app catch-all (1), lower than explicit admin routes (20).
45
+ - match: PathPrefix(`/_next`)
46
+ kind: Rule
47
+ priority: 15
48
+ middlewares:
49
+ - name: admin-auth
50
+ services:
51
+ - name: supabase-supabase-studio
52
+ port: 3000
53
+ # Studio's internal Next.js routes. After strip-prefix serves the root HTML,
54
+ # Studio redirects the browser to /project/default (the default project dashboard).
55
+ # These routes are protected by admin-auth so only super admins can access them.
56
+ - match: PathPrefix(`/project`)
57
+ kind: Rule
58
+ priority: 15
59
+ services:
60
+ - name: supabase-supabase-studio
61
+ port: 3000
62
+ middlewares:
63
+ - name: admin-auth
64
+ - name: security-headers
65
+ tls:
66
+ secretName: vibecarbon-tls
67
+ ---
68
+ # HTTP fallback - redirects HTTP to HTTPS via redirect-https middleware.
69
+ # When a domain is configured, this ensures all HTTP traffic is upgraded to HTTPS.
70
+ # When no TLS cert exists yet, Traefik serves with its default self-signed cert
71
+ # on the websecure entrypoint while cert-manager provisions the real certificate.
72
+ apiVersion: traefik.io/v1alpha1
73
+ kind: IngressRoute
74
+ metadata:
75
+ name: vibecarbon-http-direct
76
+ labels:
77
+ app: vibecarbon
78
+ spec:
79
+ entryPoints:
80
+ - web
81
+ routes:
82
+ - match: PathPrefix(`/`)
83
+ kind: Rule
84
+ priority: 1
85
+ services:
86
+ - name: app
87
+ port: 3000
88
+ middlewares:
89
+ - name: redirect-https
90
+ - match: PathPrefix(`/auth`) || PathPrefix(`/rest`) || PathPrefix(`/realtime`) || PathPrefix(`/storage`)
91
+ kind: Rule
92
+ priority: 10
93
+ services:
94
+ - name: supabase-supabase-kong
95
+ port: 8000
96
+ middlewares:
97
+ - name: redirect-https
98
+ ---
99
+ # Traefik Dashboard - exposed on websecure entrypoint via /admin/traefik/dashboard/
100
+ # Protected by admin-auth (ForwardAuth requires super_admin).
101
+ #
102
+ # How it works:
103
+ # - Dashboard HTML loads at /admin/traefik/dashboard/ (strip-prefix → /dashboard/)
104
+ # - Assets use ./relative paths so they resolve to /admin/traefik/dashboard/assets/...
105
+ # which the strip-prefix route forwards correctly as /dashboard/assets/...
106
+ # - The dashboard JS hardcodes window.APIUrl = "/api/" so API calls go to /api/version,
107
+ # /api/overview, /api/http/... etc. — these don't overlap with the Hono API paths
108
+ # (/api/v1/, /api/health, /api/_internal/, /api/webhooks/, /api/docs).
109
+ apiVersion: traefik.io/v1alpha1
110
+ kind: IngressRoute
111
+ metadata:
112
+ name: traefik-dashboard
113
+ labels:
114
+ app: vibecarbon-traefik
115
+ spec:
116
+ entryPoints:
117
+ - websecure
118
+ routes:
119
+ # Dashboard UI — strip /admin/traefik so Traefik's api@internal receives /dashboard/
120
+ - match: PathPrefix(`/admin/traefik`)
121
+ kind: Rule
122
+ priority: 20
123
+ services:
124
+ - name: api@internal
125
+ kind: TraefikService
126
+ middlewares:
127
+ - name: admin-auth
128
+ - name: security-headers
129
+ - name: strip-admin-traefik-prefix
130
+ # Traefik REST API — dashboard JS calls /api/version, /api/overview, /api/http/, etc.
131
+ # These paths don't overlap with Hono API routes so we can route them here.
132
+ - match: PathPrefix(`/api/version`) || PathPrefix(`/api/overview`) || PathPrefix(`/api/http`) || PathPrefix(`/api/tcp`) || PathPrefix(`/api/udp`) || PathPrefix(`/api/entrypoints`) || PathPrefix(`/api/rawdata`)
133
+ kind: Rule
134
+ priority: 12
135
+ services:
136
+ - name: api@internal
137
+ kind: TraefikService
138
+ middlewares:
139
+ - name: admin-auth
140
+ tls:
141
+ secretName: vibecarbon-tls
@@ -0,0 +1,11 @@
1
+ apiVersion: kustomize.config.k8s.io/v1beta1
2
+ kind: Kustomization
3
+
4
+ resources:
5
+ - deployment.yaml
6
+ - service.yaml
7
+ - configmap.yaml
8
+ - ingressroute.yaml
9
+ - middleware.yaml
10
+ - certificate.yaml
11
+ - network-policy.yaml
@@ -0,0 +1,109 @@
1
+ # Traefik Middlewares
2
+ apiVersion: traefik.io/v1alpha1
3
+ kind: Middleware
4
+ metadata:
5
+ name: security-headers
6
+ labels:
7
+ app: vibecarbon
8
+ spec:
9
+ headers:
10
+ browserXssFilter: true
11
+ contentTypeNosniff: true
12
+ frameDeny: true
13
+ stsIncludeSubdomains: true
14
+ stsPreload: true
15
+ stsSeconds: 31536000
16
+ customFrameOptionsValue: "SAMEORIGIN"
17
+ customResponseHeaders:
18
+ X-Robots-Tag: "noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex"
19
+ ---
20
+ apiVersion: traefik.io/v1alpha1
21
+ kind: Middleware
22
+ metadata:
23
+ name: redirect-https
24
+ labels:
25
+ app: vibecarbon
26
+ spec:
27
+ redirectScheme:
28
+ scheme: https
29
+ permanent: true
30
+ ---
31
+ apiVersion: traefik.io/v1alpha1
32
+ kind: Middleware
33
+ metadata:
34
+ name: strip-admin-studio-prefix
35
+ labels:
36
+ app: vibecarbon
37
+ spec:
38
+ stripPrefix:
39
+ prefixes:
40
+ - /admin/studio
41
+ ---
42
+ apiVersion: traefik.io/v1alpha1
43
+ kind: Middleware
44
+ metadata:
45
+ name: strip-admin-n8n-prefix
46
+ labels:
47
+ app: vibecarbon
48
+ spec:
49
+ stripPrefix:
50
+ prefixes:
51
+ - /admin/n8n
52
+ ---
53
+ apiVersion: traefik.io/v1alpha1
54
+ kind: Middleware
55
+ metadata:
56
+ name: strip-admin-metabase-prefix
57
+ labels:
58
+ app: vibecarbon
59
+ spec:
60
+ stripPrefix:
61
+ prefixes:
62
+ - /admin/metabase
63
+ ---
64
+ apiVersion: traefik.io/v1alpha1
65
+ kind: Middleware
66
+ metadata:
67
+ name: strip-admin-traefik-prefix
68
+ labels:
69
+ app: vibecarbon
70
+ spec:
71
+ stripPrefix:
72
+ prefixes:
73
+ - /admin/traefik
74
+ ---
75
+ apiVersion: traefik.io/v1alpha1
76
+ kind: Middleware
77
+ metadata:
78
+ name: rate-limit
79
+ labels:
80
+ app: vibecarbon
81
+ spec:
82
+ rateLimit:
83
+ average: 100
84
+ burst: 200
85
+ ---
86
+ apiVersion: traefik.io/v1alpha1
87
+ kind: Middleware
88
+ metadata:
89
+ name: compress
90
+ labels:
91
+ app: vibecarbon
92
+ spec:
93
+ compress: {}
94
+ ---
95
+ # ForwardAuth middleware for admin routes
96
+ # Verifies user is authenticated and has admin role via app's verify-role endpoint
97
+ apiVersion: traefik.io/v1alpha1
98
+ kind: Middleware
99
+ metadata:
100
+ name: admin-auth
101
+ labels:
102
+ app: vibecarbon
103
+ spec:
104
+ forwardAuth:
105
+ address: http://app:3000/api/_internal/verify-role?role=super_admin
106
+ authResponseHeaders:
107
+ - X-User-Id
108
+ - X-User-Email
109
+ - X-User-Role