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.
- package/LICENSE +663 -0
- package/README.md +188 -0
- package/carbon/.claude/hooks/task-completed-gate.sh +19 -0
- package/carbon/.claude/hooks/teammate-idle-gate.sh +29 -0
- package/carbon/.claude/settings.json +29 -0
- package/carbon/.cursor/rules/vibecarbon.mdc +6 -0
- package/carbon/.dockerignore +57 -0
- package/carbon/.env.example +219 -0
- package/carbon/.github/copilot-instructions.md +3 -0
- package/carbon/.github/workflows/deploy.yml +346 -0
- package/carbon/.github/workflows/vibecarbon-build.yml +81 -0
- package/carbon/.windsurfrules +74 -0
- package/carbon/AGENTS.md +422 -0
- package/carbon/CLAUDE.md +3 -0
- package/carbon/DEVELOPMENT.md +187 -0
- package/carbon/Dockerfile +98 -0
- package/carbon/LICENSE +21 -0
- package/carbon/PRODUCTION.md +364 -0
- package/carbon/README.md +193 -0
- package/carbon/TESTING.md +138 -0
- package/carbon/backup/Dockerfile +75 -0
- package/carbon/backup/backup.sh +95 -0
- package/carbon/backup/compose-backup.sh +140 -0
- package/carbon/biome.json +83 -0
- package/carbon/cloud-init/docker-ce-setup.yaml +55 -0
- package/carbon/cloud-init/k3s/master-init.sh +215 -0
- package/carbon/cloud-init/k3s/supabase-init.sh +167 -0
- package/carbon/cloud-init/k3s/worker-init.sh +147 -0
- package/carbon/components.json +24 -0
- package/carbon/content/blog/authentication-guide.mdx +34 -0
- package/carbon/content/blog/getting-started.mdx +41 -0
- package/carbon/content/changelog/v0-1-0.mdx +40 -0
- package/carbon/content/docs/analytics.mdx +90 -0
- package/carbon/content/docs/authentication.mdx +231 -0
- package/carbon/content/docs/background-jobs.mdx +116 -0
- package/carbon/content/docs/cli.mdx +630 -0
- package/carbon/content/docs/database.mdx +236 -0
- package/carbon/content/docs/deployment.mdx +227 -0
- package/carbon/content/docs/development.mdx +238 -0
- package/carbon/content/docs/environments.mdx +84 -0
- package/carbon/content/docs/getting-started.mdx +112 -0
- package/carbon/content/docs/legal/privacy-policy.mdx +89 -0
- package/carbon/content/docs/legal/terms-of-service.mdx +99 -0
- package/carbon/content/docs/optional-services.mdx +160 -0
- package/carbon/db/Dockerfile +23 -0
- package/carbon/docker-compose.dev-init.yml +5 -0
- package/carbon/docker-compose.metabase.override.yml +14 -0
- package/carbon/docker-compose.metabase.prod.yml +28 -0
- package/carbon/docker-compose.metabase.yml +84 -0
- package/carbon/docker-compose.n8n.override.yml +14 -0
- package/carbon/docker-compose.n8n.prod.yml +31 -0
- package/carbon/docker-compose.n8n.yml +97 -0
- package/carbon/docker-compose.observability.override.yml +18 -0
- package/carbon/docker-compose.observability.prod.yml +28 -0
- package/carbon/docker-compose.observability.yml +125 -0
- package/carbon/docker-compose.override.yml +28 -0
- package/carbon/docker-compose.prod.yml +294 -0
- package/carbon/docker-compose.yml +508 -0
- package/carbon/docker-entrypoint.sh +12 -0
- package/carbon/ha/activate-standby.sh +52 -0
- package/carbon/ha/primary-init.sql +36 -0
- package/carbon/ha/standby-init.sh +74 -0
- package/carbon/k8s/LICENSE +99 -0
- package/carbon/k8s/README.md +272 -0
- package/carbon/k8s/base/app/deployment.yaml +130 -0
- package/carbon/k8s/base/app/hpa.yaml +44 -0
- package/carbon/k8s/base/app/kustomization.yaml +10 -0
- package/carbon/k8s/base/app/network-policy.yaml +124 -0
- package/carbon/k8s/base/app/pdb.yaml +14 -0
- package/carbon/k8s/base/app/rbac.yaml +36 -0
- package/carbon/k8s/base/app/service.yaml +16 -0
- package/carbon/k8s/base/backup/cronjob.yaml +120 -0
- package/carbon/k8s/base/backup/kustomization.yaml +7 -0
- package/carbon/k8s/base/backup/network-policy.yaml +31 -0
- package/carbon/k8s/base/backup/rbac.yaml +7 -0
- package/carbon/k8s/base/cluster-autoscaler/deployment.yaml +103 -0
- package/carbon/k8s/base/cluster-autoscaler/kustomization.yaml +17 -0
- package/carbon/k8s/base/cluster-autoscaler/rbac.yaml +109 -0
- package/carbon/k8s/base/config/configmap.yaml +48 -0
- package/carbon/k8s/base/config/kustomization.yaml +8 -0
- package/carbon/k8s/base/hetzner-ccm/kustomization.yaml +9 -0
- package/carbon/k8s/base/hetzner-csi/kustomization.yaml +9 -0
- package/carbon/k8s/base/kustomization.yaml +43 -0
- package/carbon/k8s/base/namespace.yaml +7 -0
- package/carbon/k8s/base/network-policies.yaml +95 -0
- package/carbon/k8s/base/registry/kustomization.yaml +5 -0
- package/carbon/k8s/base/registry/local-registry.yaml +193 -0
- package/carbon/k8s/base/traefik/certificate.yaml +21 -0
- package/carbon/k8s/base/traefik/configmap.yaml +13 -0
- package/carbon/k8s/base/traefik/deployment.yaml +165 -0
- package/carbon/k8s/base/traefik/ingressroute.yaml +141 -0
- package/carbon/k8s/base/traefik/kustomization.yaml +11 -0
- package/carbon/k8s/base/traefik/middleware.yaml +109 -0
- package/carbon/k8s/base/traefik/network-policy.yaml +92 -0
- package/carbon/k8s/base/traefik/service.yaml +38 -0
- package/carbon/k8s/flux/README.md +49 -0
- package/carbon/k8s/flux/clusters/primary/vibecarbon.yaml +128 -0
- package/carbon/k8s/flux/clusters/standby/vibecarbon.yaml +83 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-release.yaml +38 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-repository.yaml +16 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/kustomization.yaml +10 -0
- package/carbon/k8s/gitops/supabase/helm-release.yaml +66 -0
- package/carbon/k8s/gitops/supabase/helm-repository.yaml +18 -0
- package/carbon/k8s/gitops/supabase/kustomization.yaml +33 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-cloudflare.yaml +51 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-hetzner.yaml +59 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-manual.yaml +43 -0
- package/carbon/k8s/infra/cert-manager-resources/kustomization.yaml +15 -0
- package/carbon/k8s/infra/kustomization.yaml +21 -0
- package/carbon/k8s/infra/traefik-crds/kustomization.yaml +10 -0
- package/carbon/k8s/overlays/local/configmap.yaml +23 -0
- package/carbon/k8s/overlays/local/ingressroute-studio.yaml +104 -0
- package/carbon/k8s/overlays/local/kustomization.yaml +215 -0
- package/carbon/k8s/overlays/local/namespace.yaml +8 -0
- package/carbon/k8s/overlays/local/secrets.yaml +32 -0
- package/carbon/k8s/overlays/production/kustomization.yaml +34 -0
- package/carbon/k8s/test-local.sh +318 -0
- package/carbon/k8s/values/supabase.values.yaml +133 -0
- package/carbon/package.json +154 -0
- package/carbon/runtime.Dockerfile +17 -0
- package/carbon/scripts/_dev-jwt.mjs +45 -0
- package/carbon/scripts/check-rls.ts +53 -0
- package/carbon/scripts/dev-init.js +191 -0
- package/carbon/scripts/dev.js +191 -0
- package/carbon/scripts/docker-down.js +63 -0
- package/carbon/scripts/docker-logs.js +59 -0
- package/carbon/scripts/docker-up.js +222 -0
- package/carbon/scripts/generate-dev-configs.sh +131 -0
- package/carbon/scripts/generate-rss.ts +116 -0
- package/carbon/scripts/generate-sitemap.ts +102 -0
- package/carbon/scripts/k8s-apply.js +71 -0
- package/carbon/scripts/k8s-delete.js +75 -0
- package/carbon/scripts/lib/manifest.js +176 -0
- package/carbon/scripts/secret-scan.mjs +278 -0
- package/carbon/scripts/validate-dev-configs.sh +101 -0
- package/carbon/src/client/App.tsx +202 -0
- package/carbon/src/client/assets/hyperformant-dark.svg +29 -0
- package/carbon/src/client/assets/hyperformant-light.svg +29 -0
- package/carbon/src/client/assets/logos/aider.svg +1 -0
- package/carbon/src/client/assets/logos/antigravity.svg +1 -0
- package/carbon/src/client/assets/logos/bolt.svg +1 -0
- package/carbon/src/client/assets/logos/claude-code.svg +1 -0
- package/carbon/src/client/assets/logos/copilot.svg +1 -0
- package/carbon/src/client/assets/logos/cursor.svg +1 -0
- package/carbon/src/client/assets/logos/gemini-cli.svg +1 -0
- package/carbon/src/client/assets/logos/lovable.svg +1 -0
- package/carbon/src/client/assets/logos/openai-codex.svg +1 -0
- package/carbon/src/client/assets/logos/v0.svg +1 -0
- package/carbon/src/client/assets/logos/windsurf.svg +1 -0
- package/carbon/src/client/assets/vibecarbon-icon.svg +19 -0
- package/carbon/src/client/assets/vibecarbon-logo-dark.svg +29 -0
- package/carbon/src/client/assets/vibecarbon-logo-light.svg +29 -0
- package/carbon/src/client/components/AIIntegrationSection.tsx +120 -0
- package/carbon/src/client/components/AppSidebar.tsx +760 -0
- package/carbon/src/client/components/ArchitectureSection.tsx +46 -0
- package/carbon/src/client/components/CTAFooter.tsx +59 -0
- package/carbon/src/client/components/ComparisonSection.tsx +132 -0
- package/carbon/src/client/components/ContentPanel.tsx +66 -0
- package/carbon/src/client/components/ContentSkeleton.tsx +21 -0
- package/carbon/src/client/components/ErrorBoundary.tsx +46 -0
- package/carbon/src/client/components/FAQSection.tsx +76 -0
- package/carbon/src/client/components/FileUpload.tsx +210 -0
- package/carbon/src/client/components/HeaderActions.tsx +17 -0
- package/carbon/src/client/components/Hero.tsx +608 -0
- package/carbon/src/client/components/ImpersonationBanner.tsx +31 -0
- package/carbon/src/client/components/LanguageSwitcher.tsx +67 -0
- package/carbon/src/client/components/Logo.tsx +87 -0
- package/carbon/src/client/components/LogoStrip.tsx +76 -0
- package/carbon/src/client/components/MetricsStrip.tsx +48 -0
- package/carbon/src/client/components/Nav.tsx +195 -0
- package/carbon/src/client/components/NewsletterSignup.tsx +147 -0
- package/carbon/src/client/components/NotificationDrawer.tsx +171 -0
- package/carbon/src/client/components/PageHeader.tsx +24 -0
- package/carbon/src/client/components/PlanGate.tsx +36 -0
- package/carbon/src/client/components/PricingSection.tsx +371 -0
- package/carbon/src/client/components/SEO.tsx +34 -0
- package/carbon/src/client/components/SmoothScroll.tsx +45 -0
- package/carbon/src/client/components/TechStackSection.tsx +165 -0
- package/carbon/src/client/components/WorkflowSection.tsx +604 -0
- package/carbon/src/client/components/admin/DockerLogs.tsx +276 -0
- package/carbon/src/client/components/admin/PerformanceMetrics.tsx +230 -0
- package/carbon/src/client/components/admin/ServiceCard.tsx +45 -0
- package/carbon/src/client/components/admin/ServicesStatus.tsx +296 -0
- package/carbon/src/client/components/architecture/ArchitectureDiagram.tsx +413 -0
- package/carbon/src/client/components/auth/AuthProvider.tsx +466 -0
- package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +35 -0
- package/carbon/src/client/components/effects/FresnelEdge.tsx +49 -0
- package/carbon/src/client/components/effects/GlowTracker.tsx +46 -0
- package/carbon/src/client/components/effects/SparkBurst.tsx +145 -0
- package/carbon/src/client/components/effects/VGlowEffect.tsx +83 -0
- package/carbon/src/client/components/effects/index.ts +2 -0
- package/carbon/src/client/components/layouts/SidebarLayout.tsx +20 -0
- package/carbon/src/client/components/scroll/ScrollSection.tsx +76 -0
- package/carbon/src/client/components/scroll/ScrollytellingProvider.tsx +81 -0
- package/carbon/src/client/components/scroll/index.ts +2 -0
- package/carbon/src/client/components/ui/accordion.tsx +71 -0
- package/carbon/src/client/components/ui/alert-dialog.tsx +162 -0
- package/carbon/src/client/components/ui/alert.tsx +73 -0
- package/carbon/src/client/components/ui/aspect-ratio.tsx +22 -0
- package/carbon/src/client/components/ui/avatar.tsx +91 -0
- package/carbon/src/client/components/ui/badge.tsx +50 -0
- package/carbon/src/client/components/ui/breadcrumb.tsx +100 -0
- package/carbon/src/client/components/ui/button-group.tsx +78 -0
- package/carbon/src/client/components/ui/button.tsx +120 -0
- package/carbon/src/client/components/ui/calendar.tsx +182 -0
- package/carbon/src/client/components/ui/card.tsx +85 -0
- package/carbon/src/client/components/ui/carousel.tsx +227 -0
- package/carbon/src/client/components/ui/chart.tsx +357 -0
- package/carbon/src/client/components/ui/checkbox.tsx +27 -0
- package/carbon/src/client/components/ui/collapsible.tsx +15 -0
- package/carbon/src/client/components/ui/command.tsx +178 -0
- package/carbon/src/client/components/ui/context-menu.tsx +233 -0
- package/carbon/src/client/components/ui/dialog.tsx +132 -0
- package/carbon/src/client/components/ui/drawer.tsx +118 -0
- package/carbon/src/client/components/ui/dropdown-menu.tsx +242 -0
- package/carbon/src/client/components/ui/empty.tsx +94 -0
- package/carbon/src/client/components/ui/field.tsx +226 -0
- package/carbon/src/client/components/ui/hover-card.tsx +44 -0
- package/carbon/src/client/components/ui/input-group.tsx +146 -0
- package/carbon/src/client/components/ui/input-otp.tsx +83 -0
- package/carbon/src/client/components/ui/input.tsx +20 -0
- package/carbon/src/client/components/ui/item.tsx +188 -0
- package/carbon/src/client/components/ui/kbd.tsx +26 -0
- package/carbon/src/client/components/ui/label.tsx +21 -0
- package/carbon/src/client/components/ui/menubar.tsx +250 -0
- package/carbon/src/client/components/ui/navigation-menu.tsx +155 -0
- package/carbon/src/client/components/ui/pagination.tsx +102 -0
- package/carbon/src/client/components/ui/popover.tsx +75 -0
- package/carbon/src/client/components/ui/progress.tsx +66 -0
- package/carbon/src/client/components/ui/radio-group.tsx +36 -0
- package/carbon/src/client/components/ui/resizable.tsx +46 -0
- package/carbon/src/client/components/ui/scroll-area.tsx +48 -0
- package/carbon/src/client/components/ui/select.tsx +186 -0
- package/carbon/src/client/components/ui/separator.tsx +21 -0
- package/carbon/src/client/components/ui/sheet.tsx +124 -0
- package/carbon/src/client/components/ui/sidebar.tsx +702 -0
- package/carbon/src/client/components/ui/skeleton.tsx +13 -0
- package/carbon/src/client/components/ui/slider.tsx +57 -0
- package/carbon/src/client/components/ui/sonner.tsx +45 -0
- package/carbon/src/client/components/ui/spinner.tsx +15 -0
- package/carbon/src/client/components/ui/switch.tsx +30 -0
- package/carbon/src/client/components/ui/table.tsx +89 -0
- package/carbon/src/client/components/ui/tabs.tsx +73 -0
- package/carbon/src/client/components/ui/textarea.tsx +18 -0
- package/carbon/src/client/components/ui/toggle-group.tsx +87 -0
- package/carbon/src/client/components/ui/toggle.tsx +44 -0
- package/carbon/src/client/components/ui/tooltip.tsx +56 -0
- package/carbon/src/client/hooks/api/index.ts +14 -0
- package/carbon/src/client/hooks/api/useAuthSettings.ts +80 -0
- package/carbon/src/client/hooks/api/useSubscription.ts +87 -0
- package/carbon/src/client/hooks/use-mobile.ts +21 -0
- package/carbon/src/client/hooks/useMousePosition.ts +91 -0
- package/carbon/src/client/hooks/useNotifications.tsx +124 -0
- package/carbon/src/client/hooks/useOrganizationMembers.ts +127 -0
- package/carbon/src/client/hooks/useOrganizations.tsx +230 -0
- package/carbon/src/client/hooks/usePackageManager.ts +69 -0
- package/carbon/src/client/hooks/useReducedMotion.ts +20 -0
- package/carbon/src/client/hooks/useRunningServices.ts +114 -0
- package/carbon/src/client/hooks/useScrollProgress.ts +56 -0
- package/carbon/src/client/index.css +467 -0
- package/carbon/src/client/index.html +56 -0
- package/carbon/src/client/lib/admin-services.ts +151 -0
- package/carbon/src/client/lib/api.ts +32 -0
- package/carbon/src/client/lib/blog.ts +35 -0
- package/carbon/src/client/lib/changelog.ts +33 -0
- package/carbon/src/client/lib/docs-search.ts +101 -0
- package/carbon/src/client/lib/docs.ts +37 -0
- package/carbon/src/client/lib/i18n.ts +32 -0
- package/carbon/src/client/lib/supabase.ts +72 -0
- package/carbon/src/client/lib/tailwind-colors.ts +357 -0
- package/carbon/src/client/lib/theme.ts +117 -0
- package/carbon/src/client/lib/utils.ts +22 -0
- package/carbon/src/client/locales/de.json +529 -0
- package/carbon/src/client/locales/en.json +461 -0
- package/carbon/src/client/locales/es.json +529 -0
- package/carbon/src/client/locales/fr.json +529 -0
- package/carbon/src/client/locales/pt.json +529 -0
- package/carbon/src/client/main.tsx +56 -0
- package/carbon/src/client/mdx.d.ts +13 -0
- package/carbon/src/client/pages/ApiDocs.tsx +76 -0
- package/carbon/src/client/pages/AuthCallback.tsx +34 -0
- package/carbon/src/client/pages/Blog.tsx +167 -0
- package/carbon/src/client/pages/Changelog.tsx +171 -0
- package/carbon/src/client/pages/Charts.tsx +388 -0
- package/carbon/src/client/pages/Checkout.tsx +227 -0
- package/carbon/src/client/pages/Contact.tsx +174 -0
- package/carbon/src/client/pages/Dashboard.tsx +368 -0
- package/carbon/src/client/pages/Docs.tsx +372 -0
- package/carbon/src/client/pages/ForgotPassword.tsx +111 -0
- package/carbon/src/client/pages/Home.tsx +187 -0
- package/carbon/src/client/pages/Legal.tsx +100 -0
- package/carbon/src/client/pages/Login.tsx +408 -0
- package/carbon/src/client/pages/MFAVerify.tsx +156 -0
- package/carbon/src/client/pages/NotFound.tsx +21 -0
- package/carbon/src/client/pages/Onboarding.tsx +246 -0
- package/carbon/src/client/pages/ResetPassword.tsx +200 -0
- package/carbon/src/client/pages/UIComponents.tsx +390 -0
- package/carbon/src/client/pages/admin/ContactSubmissions.tsx +220 -0
- package/carbon/src/client/pages/admin/Dashboard.tsx +24 -0
- package/carbon/src/client/pages/admin/Infrastructure.tsx +257 -0
- package/carbon/src/client/pages/admin/Jobs.tsx +225 -0
- package/carbon/src/client/pages/admin/Logs.tsx +18 -0
- package/carbon/src/client/pages/admin/Newsletter.tsx +300 -0
- package/carbon/src/client/pages/admin/Notifications.tsx +603 -0
- package/carbon/src/client/pages/admin/Organizations.tsx +306 -0
- package/carbon/src/client/pages/admin/Settings.tsx +314 -0
- package/carbon/src/client/pages/admin/Theme.tsx +465 -0
- package/carbon/src/client/pages/admin/Users.tsx +365 -0
- package/carbon/src/client/pages/api-docs.css +156 -0
- package/carbon/src/client/pages/organizations/Details.tsx +200 -0
- package/carbon/src/client/pages/organizations/Members.tsx +402 -0
- package/carbon/src/client/pages/settings/Billing.tsx +473 -0
- package/carbon/src/client/pages/settings/Profile.tsx +160 -0
- package/carbon/src/client/pages/settings/Security.tsx +341 -0
- package/carbon/src/client/public/favicon.svg +19 -0
- package/carbon/src/client/public/robots.txt +8 -0
- package/carbon/src/server/billing/index.ts +104 -0
- package/carbon/src/server/billing/provider.ts +81 -0
- package/carbon/src/server/billing/providers/paddle.ts +314 -0
- package/carbon/src/server/billing/providers/polar.ts +325 -0
- package/carbon/src/server/billing/providers/stripe.ts +233 -0
- package/carbon/src/server/emails/templates.ts +116 -0
- package/carbon/src/server/index.ts +554 -0
- package/carbon/src/server/lib/auth.ts +6 -0
- package/carbon/src/server/lib/email.ts +64 -0
- package/carbon/src/server/lib/env.ts +112 -0
- package/carbon/src/server/lib/errors.ts +21 -0
- package/carbon/src/server/lib/logger.ts +17 -0
- package/carbon/src/server/lib/rate-limiter.ts +288 -0
- package/carbon/src/server/lib/request.ts +34 -0
- package/carbon/src/server/lib/stripe.ts +42 -0
- package/carbon/src/server/lib/supabase.ts +65 -0
- package/carbon/src/server/middleware/requirePlan.ts +80 -0
- package/carbon/src/server/routes/_internal/services-status.ts +958 -0
- package/carbon/src/server/routes/_internal/verify-role.ts +185 -0
- package/carbon/src/server/routes/health.ts +48 -0
- package/carbon/src/server/routes/v1/admin/contact.ts +128 -0
- package/carbon/src/server/routes/v1/admin/jobs.ts +171 -0
- package/carbon/src/server/routes/v1/admin/newsletter.ts +237 -0
- package/carbon/src/server/routes/v1/auth.ts +390 -0
- package/carbon/src/server/routes/v1/billing.ts +718 -0
- package/carbon/src/server/routes/v1/contact.ts +93 -0
- package/carbon/src/server/routes/v1/index.ts +1333 -0
- package/carbon/src/server/routes/v1/newsletter.ts +181 -0
- package/carbon/src/server/routes/v1/performance.ts +157 -0
- package/carbon/src/server/routes/v1/stats.ts +170 -0
- package/carbon/src/server/routes/v1/theme.ts +106 -0
- package/carbon/src/server/routes/webhooks/billing.ts +376 -0
- package/carbon/src/server/routes/webhooks/stripe.ts +276 -0
- package/carbon/src/server/types.ts +11 -0
- package/carbon/src/shared/pricing.ts +155 -0
- package/carbon/src/shared/types.ts +338 -0
- package/carbon/supabase/migrations/00001_init.sql +717 -0
- package/carbon/supabase/migrations/00002_theme_settings.sql +13 -0
- package/carbon/supabase/migrations/00003_pg_cron.sql +121 -0
- package/carbon/supabase/migrations/00004_contact_newsletter.sql +81 -0
- package/carbon/supabase/migrations/00005_localization_languages.sql +22 -0
- package/carbon/supabase/seed.sql +16 -0
- package/carbon/tests/_helpers/app.ts +45 -0
- package/carbon/tests/_helpers/env.ts +37 -0
- package/carbon/tests/_helpers/factories.ts +69 -0
- package/carbon/tests/_helpers/jwt.ts +23 -0
- package/carbon/tests/_helpers/setup-integration.ts +20 -0
- package/carbon/tests/_helpers/setup-rtl.ts +12 -0
- package/carbon/tests/component/ErrorBoundary.test.tsx +53 -0
- package/carbon/tests/component/use-auth-settings.test.tsx +119 -0
- package/carbon/tests/integration/server/routes/contact.test.ts +162 -0
- package/carbon/tests/integration/server/routes/health.test.ts +61 -0
- package/carbon/tests/structural/i18n-parity.test.ts +42 -0
- package/carbon/tests/unit/client/utils.test.ts +49 -0
- package/carbon/tests/unit/shared/pricing.test.ts +93 -0
- package/carbon/tsconfig.json +27 -0
- package/carbon/tsconfig.server.json +27 -0
- package/carbon/tsconfig.test.json +9 -0
- package/carbon/vite.config.ts +110 -0
- package/carbon/vitest.config.ts +74 -0
- package/carbon/volumes/db/jwt.sql +57 -0
- package/carbon/volumes/db/metabase-init.sh +29 -0
- package/carbon/volumes/db/n8n-init.sh +25 -0
- package/carbon/volumes/db/realtime.sql +33 -0
- package/carbon/volumes/db/roles.sql +93 -0
- package/carbon/volumes/db/set-passwords.sh +12 -0
- package/carbon/volumes/db/super-admin.dev.sql +113 -0
- package/carbon/volumes/db/super-admin.generated.sql +113 -0
- package/carbon/volumes/db/super-admin.sql +114 -0
- package/carbon/volumes/grafana/dashboards/logs.json +179 -0
- package/carbon/volumes/grafana/dashboards/overview.json +523 -0
- package/carbon/volumes/grafana/dashboards/postgresql.json +337 -0
- package/carbon/volumes/grafana/dashboards.dev/logs.json +179 -0
- package/carbon/volumes/grafana/dashboards.dev/overview.json +156 -0
- package/carbon/volumes/grafana/dashboards.dev/postgresql.json +337 -0
- package/carbon/volumes/grafana/provisioning/dashboards/dashboards.dev.yml +16 -0
- package/carbon/volumes/grafana/provisioning/dashboards/dashboards.yml +16 -0
- package/carbon/volumes/grafana/provisioning/datasources/datasources.yml +43 -0
- package/carbon/volumes/kong/docker-entrypoint.sh +9 -0
- package/carbon/volumes/kong/kong.yml +208 -0
- package/carbon/volumes/loki/loki-config.yml +58 -0
- package/carbon/volumes/n8n/hooks.js +131 -0
- package/carbon/volumes/n8n/scripts/setup.sh +66 -0
- package/carbon/volumes/prometheus/prometheus.yml +43 -0
- package/carbon/volumes/promtail/promtail-config.yml +64 -0
- package/carbon/volumes/traefik/middlewares.dev.yml +83 -0
- package/carbon/volumes/traefik/middlewares.yml +95 -0
- package/carbon/volumes/traefik/vite-dev.yml +20 -0
- package/package.json +95 -0
- package/src/access.js +354 -0
- package/src/activate.js +187 -0
- package/src/add.js +718 -0
- package/src/backup.js +786 -0
- package/src/cli.js +350 -0
- package/src/configure.js +967 -0
- package/src/console.js +155 -0
- package/src/create.js +1499 -0
- package/src/deploy.js +311 -0
- package/src/destroy.js +2033 -0
- package/src/diagnose.js +735 -0
- package/src/down.js +80 -0
- package/src/failover.js +1032 -0
- package/src/lib/backup-s3.js +179 -0
- package/src/lib/build.js +33 -0
- package/src/lib/checksum.js +28 -0
- package/src/lib/ci-setup.js +666 -0
- package/src/lib/cli/help.js +129 -0
- package/src/lib/cli/parse-flags.js +160 -0
- package/src/lib/cli/select-action.js +65 -0
- package/src/lib/cli/select-environment.js +108 -0
- package/src/lib/cli/tty-guard.js +75 -0
- package/src/lib/cloudflare.js +447 -0
- package/src/lib/colors.js +52 -0
- package/src/lib/command.js +361 -0
- package/src/lib/config.js +359 -0
- package/src/lib/cost.js +103 -0
- package/src/lib/deploy/bundle.js +231 -0
- package/src/lib/deploy/compose/acme-verify.js +121 -0
- package/src/lib/deploy/compose/build-args.js +78 -0
- package/src/lib/deploy/compose/ha.js +1874 -0
- package/src/lib/deploy/compose/index.js +1294 -0
- package/src/lib/deploy/compose/reconcile.js +74 -0
- package/src/lib/deploy/github.js +382 -0
- package/src/lib/deploy/image.js +191 -0
- package/src/lib/deploy/index.js +119 -0
- package/src/lib/deploy/k8s/LICENSE +99 -0
- package/src/lib/deploy/k8s/gitops-deploy.js +298 -0
- package/src/lib/deploy/k8s/ha/index.js +1000 -0
- package/src/lib/deploy/k8s/index.js +62 -0
- package/src/lib/deploy/k8s/k3s.js +2515 -0
- package/src/lib/deploy/orchestrator.js +1401 -0
- package/src/lib/deploy/prompts.js +545 -0
- package/src/lib/deploy/remote-build.js +130 -0
- package/src/lib/deploy/state.js +120 -0
- package/src/lib/deploy/utils.js +328 -0
- package/src/lib/deploy-logger.js +93 -0
- package/src/lib/dns-propagation.js +48 -0
- package/src/lib/environment.js +58 -0
- package/src/lib/fetch-retry.js +103 -0
- package/src/lib/github-environments.js +335 -0
- package/src/lib/hetzner-dns.js +377 -0
- package/src/lib/hetzner-guided-setup.js +275 -0
- package/src/lib/host-keys.js +37 -0
- package/src/lib/iac/cloud-init.js +52 -0
- package/src/lib/iac/index.js +325 -0
- package/src/lib/iac/programs/hetzner-compose.js +130 -0
- package/src/lib/iac/programs/hetzner-k8s.js +320 -0
- package/src/lib/kubectl.js +81 -0
- package/src/lib/licensing/index.js +259 -0
- package/src/lib/licensing/tiers.js +181 -0
- package/src/lib/licensing/validator.js +171 -0
- package/src/lib/merge-package-json.js +90 -0
- package/src/lib/operator-ip.js +381 -0
- package/src/lib/package-manager.js +111 -0
- package/src/lib/perf.js +71 -0
- package/src/lib/project-guard.js +39 -0
- package/src/lib/project.js +334 -0
- package/src/lib/providers/base.js +276 -0
- package/src/lib/providers/hetzner-s3.js +656 -0
- package/src/lib/providers/hetzner.js +755 -0
- package/src/lib/providers/index.js +164 -0
- package/src/lib/s3.js +510 -0
- package/src/lib/secret-scan.js +583 -0
- package/src/lib/secrets.js +63 -0
- package/src/lib/server-types.js +195 -0
- package/src/lib/shell.js +91 -0
- package/src/lib/ssh.js +241 -0
- package/src/lib/tracker.js +242 -0
- package/src/lib/upgrade-policy.js +170 -0
- package/src/lib/validators.js +105 -0
- package/src/lib/version.js +5 -0
- package/src/remove.js +292 -0
- package/src/reset.js +97 -0
- package/src/restore.js +871 -0
- package/src/scale.js +1734 -0
- package/src/shell.js +222 -0
- package/src/status.js +981 -0
- package/src/up.js +264 -0
- package/src/upgrade.js +721 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
# check=skip=SecretsUsedInArgOrEnv
|
|
3
|
+
|
|
4
|
+
# Base image can be overridden for Turbo Layer Caching
|
|
5
|
+
# Default is the standard node image
|
|
6
|
+
ARG BASE_IMAGE=node:22-alpine3.23
|
|
7
|
+
FROM ${BASE_IMAGE} AS builder
|
|
8
|
+
|
|
9
|
+
# Build args for Vite (baked into client bundle at build time).
|
|
10
|
+
# The anon key is a public value — it ships in the JS bundle to every browser.
|
|
11
|
+
ARG VITE_PROJECT_NAME
|
|
12
|
+
ARG VITE_SUPABASE_URL
|
|
13
|
+
ARG VITE_SUPABASE_ANON_KEY
|
|
14
|
+
# Optional service feature flags (set to "true" when the service is enabled)
|
|
15
|
+
ARG VITE_N8N_ENABLED
|
|
16
|
+
ARG VITE_METABASE_ENABLED
|
|
17
|
+
ARG VITE_REDIS_ENABLED
|
|
18
|
+
ARG VITE_OBSERVABILITY_ENABLED
|
|
19
|
+
# Routing mode: 'subdomain' (compose) or 'path' (k8s)
|
|
20
|
+
ARG VITE_ROUTING_MODE
|
|
21
|
+
# Analytics (optional — empty by default, no tracking unless configured)
|
|
22
|
+
ARG VITE_PLAUSIBLE_DOMAIN
|
|
23
|
+
ARG VITE_PLAUSIBLE_SCRIPT_URL
|
|
24
|
+
|
|
25
|
+
# Ensure pnpm is available (runtime base image already has it, standard node image doesn't)
|
|
26
|
+
RUN command -v pnpm >/dev/null 2>&1 || npm install -g pnpm@9
|
|
27
|
+
|
|
28
|
+
WORKDIR /app
|
|
29
|
+
|
|
30
|
+
# Install dependencies first so the layer caches independently of source.
|
|
31
|
+
# .dockerignore excludes node_modules, so this always runs against a clean
|
|
32
|
+
# /app — no need for a defensive `if [ ! -d node_modules ]` check.
|
|
33
|
+
COPY package.json pnpm-lock.yaml ./
|
|
34
|
+
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
|
|
35
|
+
pnpm install --frozen-lockfile
|
|
36
|
+
|
|
37
|
+
# Copy application code
|
|
38
|
+
COPY tsconfig.json tsconfig.server.json biome.json vite.config.ts components.json ./
|
|
39
|
+
COPY content/ ./content/
|
|
40
|
+
COPY scripts/ ./scripts/
|
|
41
|
+
COPY src/ ./src/
|
|
42
|
+
|
|
43
|
+
# Build client (Vite) and server (TypeScript). Split into TWO RUNs so an
|
|
44
|
+
# edit that only touches src/server/ doesn't bust the Vite client cache
|
|
45
|
+
# (and vice versa). The COPY src/ above still cache-busts both on any
|
|
46
|
+
# src change, but with split RUNs the slower of the two (Vite) can land
|
|
47
|
+
# from cache when only the other side moved.
|
|
48
|
+
# VITE_ env vars are available from ARGs during build
|
|
49
|
+
ENV VITE_PROJECT_NAME=$VITE_PROJECT_NAME
|
|
50
|
+
ENV VITE_SUPABASE_URL=$VITE_SUPABASE_URL
|
|
51
|
+
ENV VITE_SUPABASE_ANON_KEY=$VITE_SUPABASE_ANON_KEY
|
|
52
|
+
ENV VITE_N8N_ENABLED=$VITE_N8N_ENABLED
|
|
53
|
+
ENV VITE_METABASE_ENABLED=$VITE_METABASE_ENABLED
|
|
54
|
+
ENV VITE_REDIS_ENABLED=$VITE_REDIS_ENABLED
|
|
55
|
+
ENV VITE_OBSERVABILITY_ENABLED=$VITE_OBSERVABILITY_ENABLED
|
|
56
|
+
ENV VITE_ROUTING_MODE=$VITE_ROUTING_MODE
|
|
57
|
+
ENV VITE_PLAUSIBLE_DOMAIN=$VITE_PLAUSIBLE_DOMAIN
|
|
58
|
+
ENV VITE_PLAUSIBLE_SCRIPT_URL=$VITE_PLAUSIBLE_SCRIPT_URL
|
|
59
|
+
RUN pnpm build:client
|
|
60
|
+
RUN pnpm build:server
|
|
61
|
+
|
|
62
|
+
# Dependency stage — install runtime deps in a throwaway container
|
|
63
|
+
FROM node:22-alpine3.23 AS deps
|
|
64
|
+
WORKDIR /deps
|
|
65
|
+
RUN npm init -y > /dev/null 2>&1 && \
|
|
66
|
+
npm install --no-package-lock pino@10
|
|
67
|
+
|
|
68
|
+
# Production stage — minimal Alpine with just the node binary
|
|
69
|
+
FROM alpine:3.23 AS runner
|
|
70
|
+
|
|
71
|
+
RUN apk add --no-cache libstdc++ && \
|
|
72
|
+
addgroup -g 1001 -S hono && \
|
|
73
|
+
adduser -S hono -u 1001 -G hono
|
|
74
|
+
|
|
75
|
+
COPY --from=node:22-alpine3.23 /usr/local/bin/node /usr/local/bin/node
|
|
76
|
+
|
|
77
|
+
WORKDIR /app
|
|
78
|
+
|
|
79
|
+
# Copy pre-installed runtime dependencies from deps stage
|
|
80
|
+
COPY --from=deps /deps/node_modules ./node_modules
|
|
81
|
+
|
|
82
|
+
# Copy built application
|
|
83
|
+
COPY --from=builder /app/dist ./dist
|
|
84
|
+
|
|
85
|
+
# Copy entrypoint
|
|
86
|
+
COPY docker-entrypoint.sh ./
|
|
87
|
+
RUN chmod +x docker-entrypoint.sh
|
|
88
|
+
|
|
89
|
+
# Security: switch to non-root user
|
|
90
|
+
USER hono
|
|
91
|
+
|
|
92
|
+
EXPOSE 3000
|
|
93
|
+
|
|
94
|
+
ENV NODE_ENV=production
|
|
95
|
+
ENV PORT=3000
|
|
96
|
+
|
|
97
|
+
ENTRYPOINT ["./docker-entrypoint.sh"]
|
|
98
|
+
CMD ["node", "dist/server/index.js"]
|
package/carbon/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vibecarbon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# Production Deployment Guide
|
|
2
|
+
|
|
3
|
+
This guide explains the differences between local development and production deployments.
|
|
4
|
+
|
|
5
|
+
## Architecture Differences
|
|
6
|
+
|
|
7
|
+
### Local Development
|
|
8
|
+
**Goal**: Fast startup, minimal resources, easy debugging
|
|
9
|
+
|
|
10
|
+
Services included:
|
|
11
|
+
- ✓ Core Supabase stack (Auth, Database, Storage, Realtime, REST API)
|
|
12
|
+
- ✓ Development tools (Studio, Meta)
|
|
13
|
+
- ✓ Basic networking
|
|
14
|
+
|
|
15
|
+
**Start command:**
|
|
16
|
+
```bash
|
|
17
|
+
pnpm docker:up
|
|
18
|
+
# or
|
|
19
|
+
docker compose up -d
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Production
|
|
23
|
+
**Goal**: Performance, reliability, scalability
|
|
24
|
+
|
|
25
|
+
Additional services:
|
|
26
|
+
- ✓ **Supavisor** - Connection pooling (handles 1000+ concurrent connections)
|
|
27
|
+
- ✓ **Edge Functions** - Serverless function runtime
|
|
28
|
+
- ✓ **Resource limits** - Prevents resource exhaustion
|
|
29
|
+
- ✓ **Optimized settings** - Production-tuned configurations
|
|
30
|
+
|
|
31
|
+
**Start command:**
|
|
32
|
+
```bash
|
|
33
|
+
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Key Differences
|
|
37
|
+
|
|
38
|
+
### 1. Connection Pooling (Supavisor)
|
|
39
|
+
|
|
40
|
+
**Local**: Direct database connections
|
|
41
|
+
- Simpler debugging
|
|
42
|
+
- Lower latency
|
|
43
|
+
- No connection limits needed
|
|
44
|
+
|
|
45
|
+
**Production**: Connections via Supavisor
|
|
46
|
+
- Handles 1000+ concurrent connections efficiently
|
|
47
|
+
- Connection pooling (default: 15 per pool)
|
|
48
|
+
- Session mode for complex queries
|
|
49
|
+
- Exposed on port 5432
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Local connection
|
|
53
|
+
DATABASE_URL=postgres://postgres:password@localhost:5432/postgres
|
|
54
|
+
|
|
55
|
+
# Production connection (via pooler)
|
|
56
|
+
DATABASE_URL=postgres://postgres:password@localhost:5432/postgres
|
|
57
|
+
# Same URL, but routed through Supavisor internally
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2. Edge Functions
|
|
61
|
+
|
|
62
|
+
**Local**: Not included (use your Hono API for custom logic)
|
|
63
|
+
- Faster startup
|
|
64
|
+
- Simpler stack
|
|
65
|
+
|
|
66
|
+
**Production**: Edge Functions runtime available
|
|
67
|
+
- Run Deno/TypeScript functions
|
|
68
|
+
- Webhook handlers
|
|
69
|
+
- Scheduled tasks
|
|
70
|
+
- Custom API endpoints
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// Example edge function: functions/hello-world/index.ts
|
|
74
|
+
Deno.serve((req) => {
|
|
75
|
+
return new Response(JSON.stringify({ message: "Hello World!" }), {
|
|
76
|
+
headers: { "Content-Type": "application/json" },
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. Resource Limits
|
|
82
|
+
|
|
83
|
+
**Local**: No limits
|
|
84
|
+
- Use whatever resources you have
|
|
85
|
+
- Services compete for resources
|
|
86
|
+
|
|
87
|
+
**Production**: Hard limits enforced
|
|
88
|
+
- Database: 4GB RAM, 2 CPUs
|
|
89
|
+
- API services: 512MB RAM, 1 CPU
|
|
90
|
+
- Prevents one service from consuming all resources
|
|
91
|
+
- Predictable performance
|
|
92
|
+
|
|
93
|
+
## Configuration Files
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
.
|
|
97
|
+
├── docker-compose.yml # Base (local + production)
|
|
98
|
+
├── docker-compose.prod.yml # Production enhancements
|
|
99
|
+
├── docker-compose.observability.yml # Optional: Grafana, Prometheus, Loki
|
|
100
|
+
├── docker-compose.n8n.yml # Optional: n8n workflow automation
|
|
101
|
+
├── docker-compose.metabase.yml # Optional: Metabase analytics
|
|
102
|
+
├── k8s/ # Kubernetes manifests with Kustomize overlays
|
|
103
|
+
└── k8s/overlays/ # Optional: HA multi-region overlays
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Composition Examples
|
|
107
|
+
|
|
108
|
+
**Local development:**
|
|
109
|
+
```bash
|
|
110
|
+
docker compose up -d
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Local with n8n:**
|
|
114
|
+
```bash
|
|
115
|
+
docker compose -f docker-compose.yml -f docker-compose.n8n.yml up -d
|
|
116
|
+
# Access: http://n8n.localhost (requires super_admin login)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Local with Metabase:**
|
|
120
|
+
```bash
|
|
121
|
+
docker compose -f docker-compose.yml -f docker-compose.metabase.yml up -d
|
|
122
|
+
# Access: http://metabase.localhost (requires super_admin login)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Local with all optional services:**
|
|
126
|
+
```bash
|
|
127
|
+
docker compose -f docker-compose.yml \
|
|
128
|
+
-f docker-compose.observability.yml \
|
|
129
|
+
-f docker-compose.n8n.yml \
|
|
130
|
+
-f docker-compose.metabase.yml up -d
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Production:**
|
|
134
|
+
```bash
|
|
135
|
+
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Production with n8n + Metabase:**
|
|
139
|
+
```bash
|
|
140
|
+
docker compose -f docker-compose.yml \
|
|
141
|
+
-f docker-compose.prod.yml \
|
|
142
|
+
-f docker-compose.n8n.yml \
|
|
143
|
+
-f docker-compose.metabase.yml up -d
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Environment Variables
|
|
147
|
+
|
|
148
|
+
Most environment variables are the same between local and production. Key differences:
|
|
149
|
+
|
|
150
|
+
### Local (.env.local)
|
|
151
|
+
```bash
|
|
152
|
+
# Development URLs
|
|
153
|
+
SITE_URL=http://localhost:5173
|
|
154
|
+
SUPABASE_URL=http://localhost:8000
|
|
155
|
+
|
|
156
|
+
# No SMTP (emails logged to console)
|
|
157
|
+
SMTP_HOST=
|
|
158
|
+
SMTP_PORT=
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Production (.env.production)
|
|
162
|
+
```bash
|
|
163
|
+
# Production URLs
|
|
164
|
+
SITE_URL=https://yourdomain.com
|
|
165
|
+
SUPABASE_URL=https://api.yourdomain.com
|
|
166
|
+
|
|
167
|
+
# Real SMTP
|
|
168
|
+
SMTP_HOST=smtp.sendgrid.net
|
|
169
|
+
SMTP_PORT=587
|
|
170
|
+
SMTP_USER=apikey
|
|
171
|
+
SMTP_PASS=your_api_key
|
|
172
|
+
|
|
173
|
+
# S3 storage (required for production)
|
|
174
|
+
STORAGE_BACKEND=s3
|
|
175
|
+
S3_BUCKET=your-bucket
|
|
176
|
+
S3_REGION=us-east-1
|
|
177
|
+
AWS_ACCESS_KEY_ID=your_key
|
|
178
|
+
AWS_SECRET_ACCESS_KEY=your_secret
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Package.json Scripts
|
|
182
|
+
|
|
183
|
+
Add these scripts to your `package.json`:
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"scripts": {
|
|
188
|
+
"docker:up": "docker compose up -d",
|
|
189
|
+
"docker:prod:up": "docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d",
|
|
190
|
+
"docker:down": "docker compose down",
|
|
191
|
+
"docker:logs": "docker compose logs -f",
|
|
192
|
+
"docker:ps": "docker compose ps"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Migration Strategy
|
|
198
|
+
|
|
199
|
+
### 1. Test Locally First
|
|
200
|
+
```bash
|
|
201
|
+
# Start local stack
|
|
202
|
+
pnpm docker:up
|
|
203
|
+
|
|
204
|
+
# Run your application
|
|
205
|
+
pnpm dev
|
|
206
|
+
|
|
207
|
+
# Test everything works
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### 2. Test Production Stack Locally
|
|
211
|
+
```bash
|
|
212
|
+
# Stop local stack
|
|
213
|
+
docker compose down
|
|
214
|
+
|
|
215
|
+
# Start with production config
|
|
216
|
+
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
|
217
|
+
|
|
218
|
+
# Verify services start correctly
|
|
219
|
+
docker compose ps
|
|
220
|
+
|
|
221
|
+
# Test connection pooling
|
|
222
|
+
psql postgres://postgres:password@localhost:5432/postgres
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### 3. Deploy to Production Server
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
# SSH to your production server
|
|
229
|
+
ssh user@your-server
|
|
230
|
+
|
|
231
|
+
# Clone your repo
|
|
232
|
+
git clone your-repo
|
|
233
|
+
|
|
234
|
+
# Copy production environment variables
|
|
235
|
+
cp .env.example .env.production
|
|
236
|
+
# Edit .env.production with production values
|
|
237
|
+
|
|
238
|
+
# Start production stack
|
|
239
|
+
docker compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.production up -d
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Monitoring Production
|
|
243
|
+
|
|
244
|
+
### Check Service Health
|
|
245
|
+
```bash
|
|
246
|
+
docker compose ps
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
All services should show "healthy" or "Up".
|
|
250
|
+
|
|
251
|
+
### Check Resource Usage
|
|
252
|
+
```bash
|
|
253
|
+
docker stats
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Monitor CPU, memory, and network usage.
|
|
257
|
+
|
|
258
|
+
### Connection Pooler Stats
|
|
259
|
+
```bash
|
|
260
|
+
# Supavisor metrics
|
|
261
|
+
curl http://localhost:9999/metrics
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### View Logs
|
|
265
|
+
```bash
|
|
266
|
+
# All services
|
|
267
|
+
docker compose logs -f
|
|
268
|
+
|
|
269
|
+
# Specific service
|
|
270
|
+
docker compose logs -f supavisor
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Troubleshooting
|
|
274
|
+
|
|
275
|
+
### Too Many Database Connections
|
|
276
|
+
|
|
277
|
+
**Problem**: "remaining connection slots are reserved"
|
|
278
|
+
|
|
279
|
+
**Solution**: Use Supavisor in production
|
|
280
|
+
```bash
|
|
281
|
+
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Out of Memory
|
|
285
|
+
|
|
286
|
+
**Problem**: Services crash with OOM errors
|
|
287
|
+
|
|
288
|
+
**Solution**: Resource limits in `docker-compose.prod.yml` prevent this
|
|
289
|
+
- Database limited to 4GB
|
|
290
|
+
- Services limited to 512MB each
|
|
291
|
+
|
|
292
|
+
### Slow Performance
|
|
293
|
+
|
|
294
|
+
**Problem**: Queries are slow under load
|
|
295
|
+
|
|
296
|
+
**Solution**: Connection pooling + resource limits
|
|
297
|
+
- Supavisor handles connection overhead
|
|
298
|
+
- Resource limits prevent resource starvation
|
|
299
|
+
|
|
300
|
+
## Rate Limiting Considerations
|
|
301
|
+
|
|
302
|
+
The API server includes built-in rate limiting (100 requests/minute per IP). This uses an in-memory store which works well for:
|
|
303
|
+
- Single-server deployments
|
|
304
|
+
- Development and testing
|
|
305
|
+
|
|
306
|
+
### Horizontal Scaling Limitation
|
|
307
|
+
|
|
308
|
+
When running multiple API instances (Kubernetes deployments), the in-memory rate limiter does not share state across pods. This means:
|
|
309
|
+
- Each pod tracks its own request counts
|
|
310
|
+
- Users could potentially make 100 * N requests/minute (where N = number of pods)
|
|
311
|
+
|
|
312
|
+
### Solutions for Multi-Instance Deployments
|
|
313
|
+
|
|
314
|
+
**Option 1: Use Traefik Rate Limiting (Recommended)**
|
|
315
|
+
Configure rate limiting at the ingress level in `volumes/traefik/middlewares.yml`:
|
|
316
|
+
```yaml
|
|
317
|
+
http:
|
|
318
|
+
middlewares:
|
|
319
|
+
rate-limit:
|
|
320
|
+
rateLimit:
|
|
321
|
+
average: 100
|
|
322
|
+
burst: 200
|
|
323
|
+
period: 1m
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**Option 2: Add Redis for Shared State**
|
|
327
|
+
Add the Redis service and configure the rate limiter to use it:
|
|
328
|
+
```bash
|
|
329
|
+
npx vibecarbon add redis
|
|
330
|
+
```
|
|
331
|
+
Then update the rate limiter configuration to use Redis as the backing store.
|
|
332
|
+
|
|
333
|
+
**Option 3: External Rate Limiting**
|
|
334
|
+
Use Cloudflare Rate Limiting rules if using Cloudflare for DNS/CDN.
|
|
335
|
+
|
|
336
|
+
## Best Practices
|
|
337
|
+
|
|
338
|
+
### 1. Always Use Production Config in Production
|
|
339
|
+
Never run production with just `docker-compose.yml`.
|
|
340
|
+
|
|
341
|
+
### 2. Test Production Config Locally
|
|
342
|
+
Before deploying, test the full production stack locally.
|
|
343
|
+
|
|
344
|
+
### 3. Monitor Resource Usage
|
|
345
|
+
Use `docker stats` to ensure limits are appropriate.
|
|
346
|
+
|
|
347
|
+
### 4. Scale Horizontally
|
|
348
|
+
For even more performance, run multiple instances behind a load balancer:
|
|
349
|
+
```bash
|
|
350
|
+
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --scale rest=3
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### 5. Use External Database for Large Deployments
|
|
354
|
+
For very large deployments, consider external managed PostgreSQL:
|
|
355
|
+
- Better backups
|
|
356
|
+
- Automated failover
|
|
357
|
+
- Dedicated resources
|
|
358
|
+
|
|
359
|
+
## Learn More
|
|
360
|
+
|
|
361
|
+
- [Supavisor Documentation](https://github.com/supabase/supavisor)
|
|
362
|
+
- [Edge Functions Guide](https://supabase.com/docs/guides/functions)
|
|
363
|
+
- [Docker Compose Production Guide](https://docs.docker.com/compose/production/)
|
|
364
|
+
- [Self-Hosting Supabase](https://supabase.com/docs/guides/self-hosting)
|
package/carbon/README.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
A production-ready full-stack application built with React 19, Hono, and self-hosted Supabase.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Start development environment
|
|
9
|
+
npx vibecarbon up
|
|
10
|
+
|
|
11
|
+
# This runs: Docker services + database migrations + dev servers
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Access Points:**
|
|
15
|
+
- App: http://app.localhost (or http://localhost:5173)
|
|
16
|
+
- API: http://localhost:3000
|
|
17
|
+
- API Docs: http://localhost:3000/api/docs
|
|
18
|
+
- Supabase Studio: http://studio.localhost (or http://localhost:8000)
|
|
19
|
+
|
|
20
|
+
## Tech Stack
|
|
21
|
+
|
|
22
|
+
| Layer | Technology | Purpose |
|
|
23
|
+
|-------|------------|---------|
|
|
24
|
+
| Frontend | React 19, Vite, React Router, TanStack Query, Shadcn UI, Tailwind CSS v4, i18next | SPA with client-side routing, UI components, and i18n |
|
|
25
|
+
| Backend | Hono, Pino logger, Zod validation | Lightweight API server |
|
|
26
|
+
| Database | PostgreSQL | Self-hosted Supabase + RLS |
|
|
27
|
+
| Auth | Supabase Auth | Email, OAuth, magic links, MFA, & SSO |
|
|
28
|
+
| Security | Traefik, Cloudflare (optional) | |
|
|
29
|
+
| Automation | Node, Docker, K8s, Pulumi | Auto scaling, Backups, Failover, High Availability |
|
|
30
|
+
| Tooling | Biome (lint/format), TypeScript, Vitest | |
|
|
31
|
+
|
|
32
|
+
## Architecture
|
|
33
|
+
|
|
34
|
+
Architecture Diagram
|
|
35
|
+
|
|
36
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
37
|
+
│ CLOUDFLARE │
|
|
38
|
+
│ (TLS termination, WAF) │
|
|
39
|
+
└──────────────────────────┬──────────────────────────────────────┘
|
|
40
|
+
│
|
|
41
|
+
┌──────────────────────────▼──────────────────────────────────────┐
|
|
42
|
+
│ TRAEFIK INGRESS │
|
|
43
|
+
│ (Rate limiting, ForwardAuth) │
|
|
44
|
+
└──────────────────────────┬──────────────────────────────────────┘
|
|
45
|
+
│
|
|
46
|
+
┌──────────────────┼──────────────────┐
|
|
47
|
+
│ │ │
|
|
48
|
+
▼ ▼ ▼
|
|
49
|
+
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
|
|
50
|
+
│ HONO API │ │ KONG (API │ │ SUPABASE │
|
|
51
|
+
│ (Port 3000) │ │ Gateway) │ │ STUDIO │
|
|
52
|
+
│ │ │ (Port 8000) │ │ (Port 3000) │
|
|
53
|
+
│ • Auth checks │ │ │ │ │
|
|
54
|
+
│ • Rate limit │ │ Routes to: │ │ │
|
|
55
|
+
│ • Validation │ │ • Auth │ │ │
|
|
56
|
+
└───────┬───────┘ │ • REST API │ └───────────────┘
|
|
57
|
+
│ │ • Realtime │
|
|
58
|
+
│ │ • Storage │
|
|
59
|
+
│ └───────┬───────┘
|
|
60
|
+
│ │
|
|
61
|
+
└────────┬─────────┘
|
|
62
|
+
│
|
|
63
|
+
▼
|
|
64
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
65
|
+
│ POSTGRESQL │
|
|
66
|
+
│ │
|
|
67
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
|
|
68
|
+
│ │ RLS │ │ Helper │ │ Brute Force │ │
|
|
69
|
+
│ │ Policies │ │ Functions │ │ Protection │ │
|
|
70
|
+
│ │ │ │ │ │ │ │
|
|
71
|
+
│ │ • Per-table │ │ • auth.uid │ │ • failed_login_attempts │ │
|
|
72
|
+
│ │ • Per-role │ │ • org_ids │ │ • account lockout │ │
|
|
73
|
+
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
|
|
74
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
75
|
+
|
|
76
|
+
## Commands
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Development
|
|
80
|
+
pnpm dev:start # Full cold start (Docker + migrations + dev)
|
|
81
|
+
pnpm dev # Start dev servers only
|
|
82
|
+
pnpm dev:reset # Remove containers, volumes, and built images
|
|
83
|
+
|
|
84
|
+
# Build & Test
|
|
85
|
+
pnpm build # Build for production
|
|
86
|
+
pnpm lint # Run Biome linter
|
|
87
|
+
pnpm typecheck # TypeScript type checking
|
|
88
|
+
pnpm test # Run tests
|
|
89
|
+
|
|
90
|
+
# Docker
|
|
91
|
+
pnpm docker:up # Start Supabase services
|
|
92
|
+
pnpm docker:down # Stop services
|
|
93
|
+
pnpm db:migrate # Run SQL migrations
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Features
|
|
97
|
+
|
|
98
|
+
- **Auth**: Email/password, OAuth (Google, Microsoft, GitHub, Apple, Discord), magic links, MFA
|
|
99
|
+
- **Billing**: Multi-provider (Stripe, Paddle, Polar) subscriptions, checkout, portal, plan gating, webhooks
|
|
100
|
+
- **Teams**: Multi-tenant organizations with RBAC (Owner, Admin, Member)
|
|
101
|
+
- **Onboarding**: Guided wizard (profile, organization, plan, invite)
|
|
102
|
+
- **Contact Form**: Public form with honeypot spam protection, admin panel for submissions
|
|
103
|
+
- **Newsletter**: Double opt-in subscription, admin compose/send, CSV export
|
|
104
|
+
- **File Uploads**: Drag-and-drop uploads via S3-backed storage (Hetzner Object Storage) with avatar support
|
|
105
|
+
- **Email**: Transactional email via SMTP — welcome, invite, billing, contact notifications
|
|
106
|
+
- **Blog**: MDX-powered blog with frontmatter, auto-generated sitemap and RSS
|
|
107
|
+
- **Changelog**: MDX-powered changelog with version tags
|
|
108
|
+
- **Documentation**: MDX-powered docs with sidebar navigation, full-text search (Cmd+K), and prev/next links
|
|
109
|
+
- **Legal Pages**: Privacy policy and terms of service with placeholder support
|
|
110
|
+
- **i18n**: Internationalization with admin-toggled language switcher
|
|
111
|
+
- **Background Jobs**: Scheduled tasks via pg_cron (zero extra infrastructure)
|
|
112
|
+
- **Analytics**: Privacy-friendly product analytics via Plausible (cookie-free, GDPR-compliant)
|
|
113
|
+
- **Admin Panel**: User management, org management, notifications, jobs, contact, newsletter, impersonation, infrastructure dashboard
|
|
114
|
+
- **SEO**: Meta tags, Open Graph, sitemap.xml, robots.txt, RSS feed
|
|
115
|
+
- **AI-Ready**: Pre-configured rules for Claude Code, Cursor, Windsurf, and GitHub Copilot
|
|
116
|
+
|
|
117
|
+
## Project Structure
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
src/
|
|
121
|
+
├── client/ # React SPA
|
|
122
|
+
│ ├── components/ # UI components (50+ Shadcn components)
|
|
123
|
+
│ │ ├── ui/ # Shadcn UI primitives
|
|
124
|
+
│ │ ├── auth/ # AuthProvider, ProtectedRoute
|
|
125
|
+
│ │ ├── FileUpload.tsx # Drag-and-drop file upload
|
|
126
|
+
│ │ └── ImpersonationBanner.tsx
|
|
127
|
+
│ ├── pages/ # Route pages
|
|
128
|
+
│ │ ├── Blog.tsx # MDX blog (index + posts)
|
|
129
|
+
│ │ ├── Changelog.tsx # MDX changelog
|
|
130
|
+
│ │ ├── Docs.tsx # MDX docs with sidebar nav
|
|
131
|
+
│ │ ├── Onboarding.tsx # Multi-step onboarding wizard
|
|
132
|
+
│ │ ├── admin/ # Super admin pages
|
|
133
|
+
│ │ ├── settings/ # User settings (profile, billing, security)
|
|
134
|
+
│ │ └── organizations/ # Org details, members
|
|
135
|
+
│ ├── hooks/ # Custom React hooks
|
|
136
|
+
│ ├── lib/ # Supabase client, i18n, blog/docs loaders
|
|
137
|
+
│ └── locales/ # Translation files (en.json)
|
|
138
|
+
│
|
|
139
|
+
├── server/ # Hono API
|
|
140
|
+
│ ├── routes/ # API endpoints
|
|
141
|
+
│ │ ├── v1/ # Versioned API (users, orgs, billing, admin)
|
|
142
|
+
│ │ └── webhooks/ # Billing webhooks (Stripe, Paddle, Polar)
|
|
143
|
+
│ ├── emails/ # React Email templates
|
|
144
|
+
│ └── lib/ # Server utilities (env, logger, stripe, email)
|
|
145
|
+
│
|
|
146
|
+
└── shared/ # Shared TypeScript types & pricing config
|
|
147
|
+
|
|
148
|
+
content/
|
|
149
|
+
├── blog/ # Blog posts (MDX with frontmatter)
|
|
150
|
+
├── changelog/ # Changelog entries (MDX with version tags)
|
|
151
|
+
└── docs/ # Documentation pages (MDX with ordering)
|
|
152
|
+
|
|
153
|
+
supabase/
|
|
154
|
+
└── migrations/ # SQL migration files
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Documentation
|
|
158
|
+
|
|
159
|
+
- [AGENTS.md](./AGENTS.md) - Development patterns, architecture, and mandatory security rules (also the source for CLAUDE.md / Copilot / Cursor instructions)
|
|
160
|
+
- [PRODUCTION.md](./PRODUCTION.md) - Production deployment guide
|
|
161
|
+
- [k8s/README.md](./k8s/README.md) - Kubernetes deployment
|
|
162
|
+
|
|
163
|
+
## Running Multiple Projects
|
|
164
|
+
|
|
165
|
+
To run multiple vibecarbon projects simultaneously on the same machine, configure port offsets in `.env.local`:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Shift all ports by 100 (Vite: 5273, API: 3100, Kong: 8100)
|
|
169
|
+
DEV_PORT_OFFSET=100
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Or override individual ports:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
DEV_VITE_PORT=5273
|
|
176
|
+
DEV_API_PORT=3100
|
|
177
|
+
DEV_KONG_PORT=8100
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
| Service | Default | With Offset 100 |
|
|
181
|
+
|---------|---------|-----------------|
|
|
182
|
+
| Vite | 5173 | 5273 |
|
|
183
|
+
| API | 3000 | 3100 |
|
|
184
|
+
| Kong | 8000 | 8100 |
|
|
185
|
+
| Traefik | 80 | 180 |
|
|
186
|
+
|
|
187
|
+
## Default Credentials
|
|
188
|
+
|
|
189
|
+
The admin account created during setup:
|
|
190
|
+
- **Email**: (provided during `npx vibecarbon create`)
|
|
191
|
+
- **Password**: (provided during `npx vibecarbon create`)
|
|
192
|
+
|
|
193
|
+
This account has `super_admin` role for accessing `/admin/*` routes.
|