create-nextdevtpl 2.6.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/README.md +29 -0
- package/catalog.json +385 -0
- package/dist/catalog.d.ts +3 -0
- package/dist/catalog.js +112 -0
- package/dist/catalog.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +115 -0
- package/dist/cli.js.map +1 -0
- package/dist/filesystem.d.ts +10 -0
- package/dist/filesystem.js +86 -0
- package/dist/filesystem.js.map +1 -0
- package/dist/generate.d.ts +5 -0
- package/dist/generate.js +758 -0
- package/dist/generate.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/selection.d.ts +2 -0
- package/dist/selection.js +111 -0
- package/dist/selection.js.map +1 -0
- package/dist/service-templates.d.ts +4 -0
- package/dist/service-templates.js +180 -0
- package/dist/service-templates.js.map +1 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
- package/template/.dockerignore +14 -0
- package/template/.env.example +282 -0
- package/template/.gitattributes +17 -0
- package/template/.node-version +1 -0
- package/template/Dockerfile +45 -0
- package/template/LICENSE +21 -0
- package/template/README.md +267 -0
- package/template/biome.json +68 -0
- package/template/cloudflare/templates/logger.ts +162 -0
- package/template/cloudflare/templates/mail/server.ts +6 -0
- package/template/cloudflare/templates/mail/templates.ts +87 -0
- package/template/cloudflare/templates/mail/utils.ts +69 -0
- package/template/cloudflare/worker.mjs +25 -0
- package/template/components.json +22 -0
- package/template/compose.yaml +74 -0
- package/template/deploy/check-health.mjs +25 -0
- package/template/deploy/docker/README.md +14 -0
- package/template/deploy/server/README.md +24 -0
- package/template/deploy/server/build.sh +24 -0
- package/template/deploy/server/nextdevtpl.service +19 -0
- package/template/deploy/server/start.sh +19 -0
- package/template/deploy/vercel/README.md +16 -0
- package/template/deploy/verify-production-health.mjs +86 -0
- package/template/drizzle.config.ts +47 -0
- package/template/gitignore +62 -0
- package/template/manifest.json +35 -0
- package/template/messages/en.json +766 -0
- package/template/messages/zh.json +762 -0
- package/template/next.config.mjs +28 -0
- package/template/open-next.config.ts +3 -0
- package/template/package.json +125 -0
- package/template/pnpm-lock.yaml +15901 -0
- package/template/postcss.config.mjs +7 -0
- package/template/public/file.svg +1 -0
- package/template/public/globe.svg +1 -0
- package/template/public/logo.svg +6 -0
- package/template/public/next.svg +1 -0
- package/template/public/vercel.svg +1 -0
- package/template/public/window.svg +1 -0
- package/template/sentry.client.config.ts +10 -0
- package/template/sentry.edge.config.ts +10 -0
- package/template/sentry.server.config.ts +10 -0
- package/template/source.config.ts +59 -0
- package/template/src/adapters/ai/anthropic.ts +113 -0
- package/template/src/adapters/ai/index.ts +6 -0
- package/template/src/adapters/ai/openai-compatible.ts +88 -0
- package/template/src/adapters/ai/workers-ai.ts +63 -0
- package/template/src/adapters/index.ts +10 -0
- package/template/src/adapters/jobs/cloudflare-workflows.ts +46 -0
- package/template/src/adapters/jobs/index.ts +5 -0
- package/template/src/adapters/jobs/inngest/adapter.ts +29 -0
- package/template/src/adapters/jobs/inngest/client.ts +8 -0
- package/template/src/adapters/jobs/inngest/functions.ts +17 -0
- package/template/src/adapters/jobs/inngest/handler.ts +6 -0
- package/template/src/adapters/jobs/inngest/index.ts +4 -0
- package/template/src/adapters/mail/cloudflare-email.ts +50 -0
- package/template/src/adapters/mail/disabled.ts +17 -0
- package/template/src/adapters/mail/index.ts +7 -0
- package/template/src/adapters/mail/resend.ts +76 -0
- package/template/src/adapters/mail/smtp.ts +82 -0
- package/template/src/adapters/payment/creem.ts +269 -0
- package/template/src/adapters/payment/index.ts +2 -0
- package/template/src/adapters/payment/stripe.ts +302 -0
- package/template/src/adapters/rate-limit/cloudflare.ts +42 -0
- package/template/src/adapters/rate-limit/index.ts +6 -0
- package/template/src/adapters/rate-limit/noop.ts +27 -0
- package/template/src/adapters/rate-limit/upstash.ts +113 -0
- package/template/src/adapters/registry.ts +228 -0
- package/template/src/adapters/storage/index.ts +3 -0
- package/template/src/adapters/storage/r2-binding.ts +105 -0
- package/template/src/adapters/storage/s3-compatible.ts +149 -0
- package/template/src/app/[locale]/(admin)/admin/layout.tsx +36 -0
- package/template/src/app/[locale]/(admin)/admin/page.tsx +345 -0
- package/template/src/app/[locale]/(admin)/admin/tickets/[id]/page.tsx +261 -0
- package/template/src/app/[locale]/(admin)/admin/tickets/page.tsx +236 -0
- package/template/src/app/[locale]/(admin)/admin/users/page.tsx +557 -0
- package/template/src/app/[locale]/(auth)/forgot-password/page.tsx +9 -0
- package/template/src/app/[locale]/(auth)/layout.tsx +28 -0
- package/template/src/app/[locale]/(auth)/sign-in/page.tsx +9 -0
- package/template/src/app/[locale]/(auth)/sign-up/page.tsx +9 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/credits/buy/buy-credits-view.tsx +170 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/credits/buy/page.tsx +12 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/credits/page.tsx +5 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/loading.tsx +41 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/page.tsx +299 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/settings/page.tsx +38 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/support/[id]/page.tsx +220 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/support/new/page.tsx +183 -0
- package/template/src/app/[locale]/(dashboard)/dashboard/support/page.tsx +145 -0
- package/template/src/app/[locale]/(dashboard)/layout.tsx +35 -0
- package/template/src/app/[locale]/(marketing)/blog/[slug]/page.tsx +178 -0
- package/template/src/app/[locale]/(marketing)/blog/blog-post-card.tsx +95 -0
- package/template/src/app/[locale]/(marketing)/blog/page.tsx +127 -0
- package/template/src/app/[locale]/(marketing)/demo/plan-badges/page.tsx +36 -0
- package/template/src/app/[locale]/(marketing)/layout.tsx +15 -0
- package/template/src/app/[locale]/(marketing)/legal/[slug]/page.tsx +130 -0
- package/template/src/app/[locale]/(marketing)/page.tsx +94 -0
- package/template/src/app/[locale]/(marketing)/pseo/[slug]/page.tsx +68 -0
- package/template/src/app/[locale]/(marketing)/pseo/page.tsx +137 -0
- package/template/src/app/[locale]/docs/[[...slug]]/page.tsx +63 -0
- package/template/src/app/[locale]/docs/layout.tsx +39 -0
- package/template/src/app/[locale]/layout.tsx +80 -0
- package/template/src/app/[locale]/opengraph-image.tsx +20 -0
- package/template/src/app/[locale]/twitter-image.tsx +20 -0
- package/template/src/app/api/auth/[...all]/route.ts +20 -0
- package/template/src/app/api/health/route.ts +45 -0
- package/template/src/app/api/inngest/route.ts +12 -0
- package/template/src/app/api/jobs/credits/expire/route.ts +102 -0
- package/template/src/app/api/search/route.ts +17 -0
- package/template/src/app/api/upload/presigned/route.ts +98 -0
- package/template/src/app/api/webhooks/payment/route.ts +363 -0
- package/template/src/app/globals.css +406 -0
- package/template/src/app/icon.svg +6 -0
- package/template/src/app/image-proxy/[...path]/route.ts +137 -0
- package/template/src/app/layout.tsx +73 -0
- package/template/src/app/robots.ts +29 -0
- package/template/src/app/sitemap.ts +68 -0
- package/template/src/components/motion/reveal.tsx +49 -0
- package/template/src/components/seo/json-ld.tsx +87 -0
- package/template/src/components/seo/og-image-template.tsx +118 -0
- package/template/src/components/ui/accordion.tsx +66 -0
- package/template/src/components/ui/alert-dialog.tsx +195 -0
- package/template/src/components/ui/avatar.tsx +53 -0
- package/template/src/components/ui/badge.tsx +46 -0
- package/template/src/components/ui/button.tsx +65 -0
- package/template/src/components/ui/card.tsx +92 -0
- package/template/src/components/ui/checkbox.tsx +32 -0
- package/template/src/components/ui/collapsible.tsx +33 -0
- package/template/src/components/ui/dialog.tsx +124 -0
- package/template/src/components/ui/dropdown-menu.tsx +257 -0
- package/template/src/components/ui/form.tsx +233 -0
- package/template/src/components/ui/index.ts +2 -0
- package/template/src/components/ui/input.tsx +21 -0
- package/template/src/components/ui/label.tsx +24 -0
- package/template/src/components/ui/navigation-menu.tsx +167 -0
- package/template/src/components/ui/pagination.tsx +125 -0
- package/template/src/components/ui/popover.tsx +48 -0
- package/template/src/components/ui/progress.tsx +27 -0
- package/template/src/components/ui/radio-group.tsx +45 -0
- package/template/src/components/ui/select.tsx +190 -0
- package/template/src/components/ui/separator.tsx +28 -0
- package/template/src/components/ui/sheet.tsx +140 -0
- package/template/src/components/ui/switch.tsx +31 -0
- package/template/src/components/ui/tabs.tsx +75 -0
- package/template/src/components/ui/textarea.tsx +18 -0
- package/template/src/config/index.ts +31 -0
- package/template/src/config/nav.ts +238 -0
- package/template/src/config/payment.ts +282 -0
- package/template/src/config/site.ts +53 -0
- package/template/src/config/subscription-plan.ts +164 -0
- package/template/src/content/blog/en/hello-world.mdx +48 -0
- package/template/src/content/blog/zh/hello-world.mdx +48 -0
- package/template/src/content/blog/zh/nextdevtpl-linuxdo-intro.mdx +98 -0
- package/template/src/content/docs/en/admin-and-support.mdx +65 -0
- package/template/src/content/docs/en/authentication.mdx +71 -0
- package/template/src/content/docs/en/background-jobs.mdx +53 -0
- package/template/src/content/docs/en/configuration.mdx +71 -0
- package/template/src/content/docs/en/credits.mdx +69 -0
- package/template/src/content/docs/en/customization.mdx +95 -0
- package/template/src/content/docs/en/database.mdx +66 -0
- package/template/src/content/docs/en/deployment.mdx +62 -0
- package/template/src/content/docs/en/email.mdx +48 -0
- package/template/src/content/docs/en/index.mdx +48 -0
- package/template/src/content/docs/en/internationalization.mdx +78 -0
- package/template/src/content/docs/en/meta.json +22 -0
- package/template/src/content/docs/en/observability.mdx +69 -0
- package/template/src/content/docs/en/payments.mdx +64 -0
- package/template/src/content/docs/en/project-structure.mdx +82 -0
- package/template/src/content/docs/en/quick-start.mdx +113 -0
- package/template/src/content/docs/en/storage.mdx +51 -0
- package/template/src/content/docs/zh/admin-and-support.mdx +65 -0
- package/template/src/content/docs/zh/authentication.mdx +71 -0
- package/template/src/content/docs/zh/background-jobs.mdx +53 -0
- package/template/src/content/docs/zh/configuration.mdx +70 -0
- package/template/src/content/docs/zh/credits.mdx +69 -0
- package/template/src/content/docs/zh/customization.mdx +95 -0
- package/template/src/content/docs/zh/database.mdx +66 -0
- package/template/src/content/docs/zh/deployment.mdx +61 -0
- package/template/src/content/docs/zh/email.mdx +47 -0
- package/template/src/content/docs/zh/index.mdx +48 -0
- package/template/src/content/docs/zh/internationalization.mdx +78 -0
- package/template/src/content/docs/zh/meta.json +22 -0
- package/template/src/content/docs/zh/observability.mdx +68 -0
- package/template/src/content/docs/zh/payments.mdx +64 -0
- package/template/src/content/docs/zh/project-structure.mdx +82 -0
- package/template/src/content/docs/zh/quick-start.mdx +110 -0
- package/template/src/content/docs/zh/storage.mdx +51 -0
- package/template/src/content/legal/en/cookie-policy.mdx +78 -0
- package/template/src/content/legal/en/privacy.mdx +131 -0
- package/template/src/content/legal/en/terms.mdx +93 -0
- package/template/src/content/legal/zh/cookie-policy.mdx +78 -0
- package/template/src/content/legal/zh/privacy.mdx +131 -0
- package/template/src/content/legal/zh/terms.mdx +92 -0
- package/template/src/core/modules/contract.ts +225 -0
- package/template/src/core/modules/index.ts +1 -0
- package/template/src/core/services/ai.ts +31 -0
- package/template/src/core/services/common.ts +112 -0
- package/template/src/core/services/index.ts +8 -0
- package/template/src/core/services/jobs.ts +24 -0
- package/template/src/core/services/mail.ts +35 -0
- package/template/src/core/services/manifest.ts +51 -0
- package/template/src/core/services/payment.ts +92 -0
- package/template/src/core/services/rate-limit.ts +47 -0
- package/template/src/core/services/storage.ts +42 -0
- package/template/src/db/index.ts +71 -0
- package/template/src/db/schema/auth.ts +67 -0
- package/template/src/db/schema/credits.ts +94 -0
- package/template/src/db/schema/index.ts +5 -0
- package/template/src/db/schema/mail.ts +14 -0
- package/template/src/db/schema/subscription.ts +21 -0
- package/template/src/db/schema/support.ts +56 -0
- package/template/src/db/schema.ts +2 -0
- package/template/src/features/admin/components/admin-sidebar.tsx +213 -0
- package/template/src/features/admin/components/index.ts +2 -0
- package/template/src/features/admin/index.ts +3 -0
- package/template/src/features/admin/manifest.ts +41 -0
- package/template/src/features/analytics/components/analytics.tsx +62 -0
- package/template/src/features/analytics/components/index.ts +2 -0
- package/template/src/features/analytics/index.ts +3 -0
- package/template/src/features/analytics/manifest.ts +13 -0
- package/template/src/features/auth/components/auth-brand-panel.tsx +82 -0
- package/template/src/features/auth/components/auth-error-alert.tsx +28 -0
- package/template/src/features/auth/components/auth-footer.tsx +52 -0
- package/template/src/features/auth/components/auth-logo.tsx +30 -0
- package/template/src/features/auth/components/forgot-password-form.tsx +146 -0
- package/template/src/features/auth/components/index.ts +9 -0
- package/template/src/features/auth/components/sign-in-form.tsx +241 -0
- package/template/src/features/auth/components/sign-up-form.tsx +307 -0
- package/template/src/features/auth/index.ts +3 -0
- package/template/src/features/auth/manifest.ts +30 -0
- package/template/src/features/blog/components/blog-post-item.tsx +72 -0
- package/template/src/features/blog/components/index.ts +1 -0
- package/template/src/features/blog/data/mock-posts.ts +62 -0
- package/template/src/features/blog/index.ts +3 -0
- package/template/src/features/blog/manifest.ts +22 -0
- package/template/src/features/credits/account.ts +76 -0
- package/template/src/features/credits/actions.ts +427 -0
- package/template/src/features/credits/components/credit-balance-badge.tsx +54 -0
- package/template/src/features/credits/components/credit-usage-section.tsx +160 -0
- package/template/src/features/credits/components/index.ts +7 -0
- package/template/src/features/credits/components/transaction-history.tsx +346 -0
- package/template/src/features/credits/config.ts +70 -0
- package/template/src/features/credits/consume.ts +140 -0
- package/template/src/features/credits/core.ts +23 -0
- package/template/src/features/credits/errors.ts +26 -0
- package/template/src/features/credits/expire.ts +112 -0
- package/template/src/features/credits/grant.ts +168 -0
- package/template/src/features/credits/index.ts +6 -0
- package/template/src/features/credits/manifest.ts +36 -0
- package/template/src/features/credits/query.ts +65 -0
- package/template/src/features/credits/types.ts +48 -0
- package/template/src/features/dashboard/components/index.ts +3 -0
- package/template/src/features/dashboard/components/main-wrapper.tsx +100 -0
- package/template/src/features/dashboard/components/sidebar.tsx +341 -0
- package/template/src/features/dashboard/context/index.ts +2 -0
- package/template/src/features/dashboard/context/sidebar-context.tsx +72 -0
- package/template/src/features/dashboard/index.ts +4 -0
- package/template/src/features/dashboard/manifest.ts +28 -0
- package/template/src/features/mail/actions.ts +175 -0
- package/template/src/features/mail/index.ts +5 -0
- package/template/src/features/mail/manifest.ts +13 -0
- package/template/src/features/mail/server.ts +8 -0
- package/template/src/features/mail/templates/index.ts +11 -0
- package/template/src/features/mail/templates/primary-action-email.tsx +224 -0
- package/template/src/features/mail/templates/welcome-email.tsx +121 -0
- package/template/src/features/mail/utils.ts +190 -0
- package/template/src/features/marketing/components/animated-price.tsx +51 -0
- package/template/src/features/marketing/components/cookie-consent.tsx +255 -0
- package/template/src/features/marketing/components/cta-section.tsx +50 -0
- package/template/src/features/marketing/components/faq-section.tsx +59 -0
- package/template/src/features/marketing/components/feature-grid.tsx +80 -0
- package/template/src/features/marketing/components/footer.tsx +128 -0
- package/template/src/features/marketing/components/header.tsx +255 -0
- package/template/src/features/marketing/components/hero-section.tsx +323 -0
- package/template/src/features/marketing/components/how-it-works.tsx +115 -0
- package/template/src/features/marketing/components/index.ts +14 -0
- package/template/src/features/marketing/components/nav-menu.tsx +236 -0
- package/template/src/features/marketing/components/pricing-section.tsx +446 -0
- package/template/src/features/marketing/components/testimonials.tsx +59 -0
- package/template/src/features/marketing/components/use-cases-section.tsx +78 -0
- package/template/src/features/marketing/index.ts +3 -0
- package/template/src/features/marketing/manifest.ts +35 -0
- package/template/src/features/payment/actions.ts +182 -0
- package/template/src/features/payment/index.ts +4 -0
- package/template/src/features/payment/manifest.ts +18 -0
- package/template/src/features/payment/server.ts +7 -0
- package/template/src/features/payment/types.ts +202 -0
- package/template/src/features/pseo/components/index.ts +6 -0
- package/template/src/features/pseo/components/pseo-cta.tsx +51 -0
- package/template/src/features/pseo/components/pseo-faq.tsx +40 -0
- package/template/src/features/pseo/components/pseo-feature-grid.tsx +74 -0
- package/template/src/features/pseo/components/pseo-hero.tsx +106 -0
- package/template/src/features/pseo/components/pseo-related.tsx +62 -0
- package/template/src/features/pseo/components/pseo-use-cases.tsx +50 -0
- package/template/src/features/pseo/data/pseo-pages.json +534 -0
- package/template/src/features/pseo/index.ts +4 -0
- package/template/src/features/pseo/lib/pseo-data.ts +140 -0
- package/template/src/features/pseo/manifest.ts +22 -0
- package/template/src/features/settings/actions/delete-account.ts +50 -0
- package/template/src/features/settings/actions/index.ts +3 -0
- package/template/src/features/settings/actions/update-profile.ts +49 -0
- package/template/src/features/settings/components/billing-section.tsx +283 -0
- package/template/src/features/settings/components/index.ts +3 -0
- package/template/src/features/settings/components/profile-form.tsx +154 -0
- package/template/src/features/settings/components/security-section.tsx +158 -0
- package/template/src/features/settings/components/settings-profile-view.tsx +506 -0
- package/template/src/features/settings/index.ts +5 -0
- package/template/src/features/settings/manifest.ts +28 -0
- package/template/src/features/settings/schemas/index.ts +2 -0
- package/template/src/features/settings/schemas/update-profile.ts +21 -0
- package/template/src/features/shared/components/cookie-settings-dialog.tsx +282 -0
- package/template/src/features/shared/components/index.ts +5 -0
- package/template/src/features/shared/components/language-switcher.tsx +82 -0
- package/template/src/features/shared/components/max-width-wrapper.tsx +49 -0
- package/template/src/features/shared/components/mode-toggle.tsx +119 -0
- package/template/src/features/shared/icons/google-icon.tsx +39 -0
- package/template/src/features/shared/icons/index.ts +7 -0
- package/template/src/features/shared/index.ts +5 -0
- package/template/src/features/shared/manifest.ts +13 -0
- package/template/src/features/shared/providers.tsx +59 -0
- package/template/src/features/storage/actions.ts +107 -0
- package/template/src/features/storage/index.ts +6 -0
- package/template/src/features/storage/manifest.ts +22 -0
- package/template/src/features/storage/types.ts +143 -0
- package/template/src/features/storage/utils.ts +85 -0
- package/template/src/features/storage/validation.ts +151 -0
- package/template/src/features/subscription/actions/get-user-plan.ts +26 -0
- package/template/src/features/subscription/actions/index.ts +5 -0
- package/template/src/features/subscription/components/current-plan-badge.tsx +18 -0
- package/template/src/features/subscription/components/index.ts +6 -0
- package/template/src/features/subscription/components/plan-badge.tsx +98 -0
- package/template/src/features/subscription/index.ts +25 -0
- package/template/src/features/subscription/manifest.ts +13 -0
- package/template/src/features/subscription/services/user-plan.ts +181 -0
- package/template/src/features/support/actions/admin-ticket.ts +172 -0
- package/template/src/features/support/actions/admin-users.ts +295 -0
- package/template/src/features/support/actions/index.ts +22 -0
- package/template/src/features/support/actions/ticket.ts +12 -0
- package/template/src/features/support/actions/user-ticket.ts +153 -0
- package/template/src/features/support/components/admin-ticket-reply-form.tsx +109 -0
- package/template/src/features/support/components/admin-ticket-status-select.tsx +119 -0
- package/template/src/features/support/components/index.ts +6 -0
- package/template/src/features/support/components/ticket-message-form.tsx +99 -0
- package/template/src/features/support/components/user-role-select.tsx +107 -0
- package/template/src/features/support/index.ts +5 -0
- package/template/src/features/support/manifest.ts +53 -0
- package/template/src/features/support/schemas/index.ts +15 -0
- package/template/src/features/support/schemas/ticket.ts +81 -0
- package/template/src/hooks/index.ts +2 -0
- package/template/src/i18n/index.ts +12 -0
- package/template/src/i18n/request.ts +24 -0
- package/template/src/i18n/routing.ts +23 -0
- package/template/src/instrumentation.ts +19 -0
- package/template/src/lib/ai/index.ts +16 -0
- package/template/src/lib/api-logger.ts +24 -0
- package/template/src/lib/auth/admin.ts +54 -0
- package/template/src/lib/auth/api.ts +17 -0
- package/template/src/lib/auth/client.ts +227 -0
- package/template/src/lib/auth/edge.ts +84 -0
- package/template/src/lib/auth/errors.ts +99 -0
- package/template/src/lib/auth/index.ts +159 -0
- package/template/src/lib/auth/server.ts +46 -0
- package/template/src/lib/auth/session-context.tsx +96 -0
- package/template/src/lib/cloudflare/bindings.ts +31 -0
- package/template/src/lib/cookie-consent.ts +33 -0
- package/template/src/lib/file-utils.ts +45 -0
- package/template/src/lib/fingerprint/index.ts +73 -0
- package/template/src/lib/health/checks.ts +6 -0
- package/template/src/lib/health/core.ts +86 -0
- package/template/src/lib/health/index.ts +11 -0
- package/template/src/lib/health/types.ts +13 -0
- package/template/src/lib/index.ts +2 -0
- package/template/src/lib/logger/index.ts +258 -0
- package/template/src/lib/monitoring/index.ts +384 -0
- package/template/src/lib/rate-limit/anonymous.ts +85 -0
- package/template/src/lib/rate-limit/index.ts +111 -0
- package/template/src/lib/safe-action.ts +127 -0
- package/template/src/lib/seo/json-ld.ts +188 -0
- package/template/src/lib/source.ts +122 -0
- package/template/src/lib/utils.ts +6 -0
- package/template/src/middleware.ts +162 -0
- package/template/src/modules/index.ts +10 -0
- package/template/src/modules/presets.ts +8 -0
- package/template/src/modules/registry.ts +34 -0
- package/template/src/modules/selection.ts +45 -0
- package/template/src/services/ai.ts +49 -0
- package/template/src/services/index.ts +6 -0
- package/template/src/services/jobs.ts +3 -0
- package/template/src/services/mail.ts +7 -0
- package/template/src/services/payment.ts +3 -0
- package/template/src/services/rate-limit.ts +12 -0
- package/template/src/services/storage.ts +3 -0
- package/template/src/types/fumadocs-source.d.ts +14 -0
- package/template/src/types/index.ts +2 -0
- package/template/tsconfig.json +53 -0
- package/template/vercel.json +11 -0
- package/template/vitest.config.ts +51 -0
- package/template/wrangler.jsonc +30 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Customization
|
|
3
|
+
description: Common places to customize branding, navigation, pricing, pages, and modules.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Customization
|
|
7
|
+
|
|
8
|
+
This page lists the most common places to edit when turning NextDevTpl into your own SaaS.
|
|
9
|
+
|
|
10
|
+
## Branding
|
|
11
|
+
|
|
12
|
+
| Edit | Path |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| Site name, URL, metadata | `src/config/site.ts` |
|
|
15
|
+
| Logo | `public/logo.svg` and header components |
|
|
16
|
+
| Global styles | `src/app/globals.css` |
|
|
17
|
+
| Open Graph image template | `src/features/shared/components/og-image-template.tsx` |
|
|
18
|
+
|
|
19
|
+
## Navigation
|
|
20
|
+
|
|
21
|
+
| Area | Path |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| Header and footer | `src/config/nav.ts` |
|
|
24
|
+
| Dashboard sidebar | `src/config/nav.ts` and `src/features/dashboard/components/sidebar.tsx` |
|
|
25
|
+
| Admin sidebar | `src/config/nav.ts` and `src/features/admin/components/admin-sidebar.tsx` |
|
|
26
|
+
|
|
27
|
+
## Landing page
|
|
28
|
+
|
|
29
|
+
Marketing sections live in:
|
|
30
|
+
|
|
31
|
+
```txt
|
|
32
|
+
src/features/marketing/components
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The home route is:
|
|
36
|
+
|
|
37
|
+
```txt
|
|
38
|
+
src/app/[locale]/(marketing)/page.tsx
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Most copy comes from:
|
|
42
|
+
|
|
43
|
+
```txt
|
|
44
|
+
messages/en.json
|
|
45
|
+
messages/zh.json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Pricing and plans
|
|
49
|
+
|
|
50
|
+
| Edit | Path |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| Plan names and limits | `src/config/subscription-plan.ts` |
|
|
53
|
+
| Payment product mapping | `src/config/payment.ts` |
|
|
54
|
+
| Pricing section UI | `src/features/marketing/components/pricing-section.tsx` |
|
|
55
|
+
| Subscription UI | `src/features/subscription` |
|
|
56
|
+
|
|
57
|
+
## Product modules
|
|
58
|
+
|
|
59
|
+
Add new product code under:
|
|
60
|
+
|
|
61
|
+
```txt
|
|
62
|
+
src/features/<your-feature>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Recommended shape:
|
|
66
|
+
|
|
67
|
+
```txt
|
|
68
|
+
src/features/example/
|
|
69
|
+
├── actions.ts
|
|
70
|
+
├── components/
|
|
71
|
+
├── schemas/
|
|
72
|
+
├── types.ts
|
|
73
|
+
└── index.ts
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Keep route-specific composition in `src/app` and reusable business logic inside the feature module.
|
|
77
|
+
|
|
78
|
+
## Content
|
|
79
|
+
|
|
80
|
+
| Content | Path |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| Docs | `src/content/docs/<locale>` |
|
|
83
|
+
| Blog | `src/content/blog/<locale>` |
|
|
84
|
+
| Legal | `src/content/legal/<locale>` |
|
|
85
|
+
| PSEO data | `src/features/pseo/data/pseo-pages.json` |
|
|
86
|
+
|
|
87
|
+
## Before committing customizations
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pnpm typecheck
|
|
91
|
+
pnpm lint
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Run focused tests if you changed auth, credits, payments, storage, support, or jobs.
|
|
95
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Database
|
|
3
|
+
description: Work with PostgreSQL and Drizzle ORM in NextDevTpl.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Database
|
|
7
|
+
|
|
8
|
+
NextDevTpl uses PostgreSQL with Drizzle ORM. The schema is the source of truth for auth, credits, payments, support tickets, and user data.
|
|
9
|
+
|
|
10
|
+
## Main files
|
|
11
|
+
|
|
12
|
+
| Path | Purpose |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| `src/db/schema.ts` | Table definitions |
|
|
15
|
+
| `src/db/index.ts` | Database client |
|
|
16
|
+
| `drizzle.config.ts` | Drizzle config |
|
|
17
|
+
| `drizzle/` | Generated migration files and snapshots |
|
|
18
|
+
| `src/test/utils/db.ts` | Test database helpers |
|
|
19
|
+
|
|
20
|
+
## Development workflow
|
|
21
|
+
|
|
22
|
+
For a new local database:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm db:push
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
For a change that should be reviewed and deployed:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm db:generate
|
|
32
|
+
pnpm db:migrate
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Use Drizzle Studio to inspect local data:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm db:studio
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## When to use push vs migrations
|
|
42
|
+
|
|
43
|
+
| Command | Use it when |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `pnpm db:push` | You are bootstrapping or iterating on a local database |
|
|
46
|
+
| `pnpm db:generate` | You changed `src/db/schema.ts` and need a migration file |
|
|
47
|
+
| `pnpm db:migrate` | You want to apply committed migrations |
|
|
48
|
+
|
|
49
|
+
## Schema changes checklist
|
|
50
|
+
|
|
51
|
+
1. Update `src/db/schema.ts`.
|
|
52
|
+
2. Update any feature service/action that reads or writes the changed table.
|
|
53
|
+
3. Generate or push the schema depending on environment.
|
|
54
|
+
4. Add or update tests under `src/test`.
|
|
55
|
+
5. Run `pnpm typecheck` and targeted tests.
|
|
56
|
+
|
|
57
|
+
## Common table areas
|
|
58
|
+
|
|
59
|
+
| Area | Used by |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| Auth users and sessions | Better Auth |
|
|
62
|
+
| Credits and transactions | Credits ledger and purchases |
|
|
63
|
+
| Subscriptions | Payment and plan lookup |
|
|
64
|
+
| Support tickets | User support and admin ticket queue |
|
|
65
|
+
| Storage records | Upload and file security tests |
|
|
66
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Deployment
|
|
3
|
+
description: Deploy NextDevTpl with the existing scripts or a managed Next.js platform.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Deployment
|
|
7
|
+
|
|
8
|
+
The repository includes a self-hosted deployment flow and can also be deployed on managed Next.js platforms.
|
|
9
|
+
|
|
10
|
+
## Self-hosted flow
|
|
11
|
+
|
|
12
|
+
The existing script pair is:
|
|
13
|
+
|
|
14
|
+
| File | Runs on | Purpose |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| `deploy-build.bat` | Windows/local machine | Build, package, upload artifacts |
|
|
17
|
+
| `start-prod.sh` | Linux/server | Install production dependencies and start/restart app |
|
|
18
|
+
|
|
19
|
+
Typical flow:
|
|
20
|
+
|
|
21
|
+
1. Configure SSH host, deploy path, and key path in `deploy-build.bat`.
|
|
22
|
+
2. Confirm production `.env` exists on the server.
|
|
23
|
+
3. Run the script locally:
|
|
24
|
+
|
|
25
|
+
```bat
|
|
26
|
+
deploy-build.bat
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
4. The script builds locally, creates an archive, uploads it, then starts the app on the server.
|
|
30
|
+
|
|
31
|
+
## Production environment
|
|
32
|
+
|
|
33
|
+
At minimum, production needs:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
DATABASE_URL="postgresql://..."
|
|
37
|
+
BETTER_AUTH_SECRET="strong-production-secret"
|
|
38
|
+
BETTER_AUTH_URL="https://your-domain.com"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Add the optional services you actually use: Creem, Resend, storage, Redis, Sentry, Axiom, Inngest, and AI provider credentials.
|
|
42
|
+
|
|
43
|
+
## Vercel
|
|
44
|
+
|
|
45
|
+
For Vercel:
|
|
46
|
+
|
|
47
|
+
1. Import the GitHub repository.
|
|
48
|
+
2. Set all production environment variables.
|
|
49
|
+
3. Make sure the database is reachable from Vercel.
|
|
50
|
+
4. Configure webhook URLs with the Vercel production domain.
|
|
51
|
+
5. Run migrations before or during release.
|
|
52
|
+
|
|
53
|
+
## Release checklist
|
|
54
|
+
|
|
55
|
+
- `pnpm typecheck` passes.
|
|
56
|
+
- `pnpm build` passes.
|
|
57
|
+
- Database migrations are ready.
|
|
58
|
+
- `BETTER_AUTH_URL` uses the production domain.
|
|
59
|
+
- OAuth callback URLs use the production domain.
|
|
60
|
+
- Creem webhook URL points to `/api/webhooks/creem`.
|
|
61
|
+
- Sentry/Axiom do not receive raw secrets.
|
|
62
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Email
|
|
3
|
+
description: Send product emails with Resend and React Email templates.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Email
|
|
7
|
+
|
|
8
|
+
Email delivery uses Resend and React Email templates.
|
|
9
|
+
|
|
10
|
+
## Main files
|
|
11
|
+
|
|
12
|
+
| Path | Purpose |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| `src/features/mail/client.ts` | Resend client setup |
|
|
15
|
+
| `src/features/mail/actions.ts` | Email send actions |
|
|
16
|
+
| `src/features/mail/utils.ts` | Email helpers |
|
|
17
|
+
| `src/features/mail/templates` | React Email templates |
|
|
18
|
+
| `src/test/mail/newsletter.test.ts` | Email-related test coverage |
|
|
19
|
+
|
|
20
|
+
## Environment variables
|
|
21
|
+
|
|
22
|
+
| Variable | Purpose |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| `RESEND_API_KEY` | Authenticates with Resend |
|
|
25
|
+
| `EMAIL_FROM` | Sender address displayed to users |
|
|
26
|
+
|
|
27
|
+
Example:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
RESEND_API_KEY="re_xxxxxxxxx"
|
|
31
|
+
EMAIL_FROM="NextDevTpl <noreply@example.com>"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Templates
|
|
35
|
+
|
|
36
|
+
Templates are React components. Current examples include:
|
|
37
|
+
|
|
38
|
+
| Template | Purpose |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `welcome-email.tsx` | Welcome/onboarding email |
|
|
41
|
+
| `primary-action-email.tsx` | Generic action email with a button |
|
|
42
|
+
|
|
43
|
+
When editing templates, keep copy short and avoid relying on app-only CSS. Email clients have limited CSS support.
|
|
44
|
+
|
|
45
|
+
## Local behavior
|
|
46
|
+
|
|
47
|
+
If Resend is not configured, email-dependent features should be treated as unavailable. Use email/password flows that do not require delivery first, then enable Resend when testing verification and reset flows.
|
|
48
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Introduction
|
|
3
|
+
description: Learn what NextDevTpl includes and how to use the template as a production SaaS starting point.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# NextDevTpl Documentation
|
|
7
|
+
|
|
8
|
+
NextDevTpl is a production-oriented SaaS starter built on Next.js, React, TypeScript, PostgreSQL, Drizzle ORM, Better Auth, next-intl, Creem payments, credits, admin tools, support tickets, email, storage, observability, and background jobs.
|
|
9
|
+
|
|
10
|
+
The goal of the template is not only to show a landing page. It gives you a working product shell that can be customized into a real SaaS application.
|
|
11
|
+
|
|
12
|
+
## What is included
|
|
13
|
+
|
|
14
|
+
| Area | What you get |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| App shell | Localized marketing site, blog, docs, dashboard, admin area, and legal pages |
|
|
17
|
+
| Authentication | Better Auth with email/password, OAuth providers, session handling, and roles |
|
|
18
|
+
| Database | PostgreSQL schema with Drizzle ORM, migrations, and integration tests |
|
|
19
|
+
| Billing | Creem checkout, subscription flow, webhook handling, and one-time credit purchases |
|
|
20
|
+
| Credits | Ledger-style credit accounting, FIFO batch expiration, and balance reads |
|
|
21
|
+
| Operations | Admin users, support tickets, logging, monitoring, rate limiting, and jobs |
|
|
22
|
+
| Content | Fumadocs-powered docs, MDX blog, and next-intl translated UI |
|
|
23
|
+
|
|
24
|
+
## Recommended reading path
|
|
25
|
+
|
|
26
|
+
If you are evaluating the template, start with:
|
|
27
|
+
|
|
28
|
+
- [Quick Start](/en/docs/quick-start)
|
|
29
|
+
- [Project Structure](/en/docs/project-structure)
|
|
30
|
+
- [Configuration](/en/docs/configuration)
|
|
31
|
+
|
|
32
|
+
If you are integrating product features, read:
|
|
33
|
+
|
|
34
|
+
- [Authentication](/en/docs/authentication)
|
|
35
|
+
- [Payments](/en/docs/payments)
|
|
36
|
+
- [Credits](/en/docs/credits)
|
|
37
|
+
- [Internationalization](/en/docs/internationalization)
|
|
38
|
+
|
|
39
|
+
If you are preparing production, read:
|
|
40
|
+
|
|
41
|
+
- [Deployment](/en/docs/deployment)
|
|
42
|
+
- [Observability](/en/docs/observability)
|
|
43
|
+
- [Background Jobs](/en/docs/background-jobs)
|
|
44
|
+
|
|
45
|
+
## Core principle
|
|
46
|
+
|
|
47
|
+
Most external services are optional during local development. The app should boot with only database and auth basics, then enable OAuth, email, payments, storage, Redis, Sentry, Axiom, and Inngest as your product needs them.
|
|
48
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Internationalization
|
|
3
|
+
description: Work with next-intl routes, UI messages, and localized documentation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Internationalization
|
|
7
|
+
|
|
8
|
+
NextDevTpl uses `next-intl` for UI translations and locale-aware routing. Documentation content is localized through Fumadocs content folders.
|
|
9
|
+
|
|
10
|
+
## Current locales
|
|
11
|
+
|
|
12
|
+
Locales are configured in:
|
|
13
|
+
|
|
14
|
+
```txt
|
|
15
|
+
src/i18n/routing.ts
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Current values:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
locales: ["en", "zh"]
|
|
22
|
+
defaultLocale: "en"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## UI messages
|
|
26
|
+
|
|
27
|
+
| File | Purpose |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| `messages/en.json` | English UI copy |
|
|
30
|
+
| `messages/zh.json` | Chinese UI copy |
|
|
31
|
+
| `src/i18n/request.ts` | Loads locale messages |
|
|
32
|
+
| `src/features/shared/components/language-switcher.tsx` | Header language switcher |
|
|
33
|
+
|
|
34
|
+
Use `useTranslations()` in client components and server translation helpers in server components.
|
|
35
|
+
|
|
36
|
+
## Route structure
|
|
37
|
+
|
|
38
|
+
Most pages live under:
|
|
39
|
+
|
|
40
|
+
```txt
|
|
41
|
+
src/app/[locale]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
|
|
46
|
+
```txt
|
|
47
|
+
/en
|
|
48
|
+
/zh
|
|
49
|
+
/en/dashboard
|
|
50
|
+
/zh/dashboard
|
|
51
|
+
/en/docs
|
|
52
|
+
/zh/docs
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Documentation i18n
|
|
56
|
+
|
|
57
|
+
Docs are stored by language:
|
|
58
|
+
|
|
59
|
+
```txt
|
|
60
|
+
src/content/docs/en
|
|
61
|
+
src/content/docs/zh
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The loader in `src/lib/source.ts` uses Fumadocs i18n with the `dir` parser. The docs route reads pages by `params.locale`, so `/en/docs` and `/zh/docs` get separate page trees.
|
|
65
|
+
|
|
66
|
+
## Adding a locale
|
|
67
|
+
|
|
68
|
+
1. Add the locale to `src/i18n/routing.ts`.
|
|
69
|
+
2. Add `messages/<locale>.json`.
|
|
70
|
+
3. Add docs under `src/content/docs/<locale>`.
|
|
71
|
+
4. Add blog/legal content if those routes should support the locale.
|
|
72
|
+
5. Update sitemap metadata if needed.
|
|
73
|
+
6. Test navigation and language switching.
|
|
74
|
+
|
|
75
|
+
## Translation quality
|
|
76
|
+
|
|
77
|
+
Do not mechanically translate product terms that are better left in English. Keep framework and API names unchanged: Next.js, Drizzle, Better Auth, Creem, Inngest, Sentry, Axiom, Fumadocs, next-intl.
|
|
78
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "NextDevTpl",
|
|
3
|
+
"root": true,
|
|
4
|
+
"pages": [
|
|
5
|
+
"index",
|
|
6
|
+
"quick-start",
|
|
7
|
+
"project-structure",
|
|
8
|
+
"configuration",
|
|
9
|
+
"authentication",
|
|
10
|
+
"database",
|
|
11
|
+
"credits",
|
|
12
|
+
"payments",
|
|
13
|
+
"email",
|
|
14
|
+
"storage",
|
|
15
|
+
"internationalization",
|
|
16
|
+
"background-jobs",
|
|
17
|
+
"admin-and-support",
|
|
18
|
+
"observability",
|
|
19
|
+
"deployment",
|
|
20
|
+
"customization"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Observability
|
|
3
|
+
description: Configure logging, monitoring, rate limits, and request diagnostics.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Observability
|
|
7
|
+
|
|
8
|
+
NextDevTpl includes structured logging, optional cloud log shipping, Sentry monitoring, rate limiting, and API request logging utilities.
|
|
9
|
+
|
|
10
|
+
## Logging
|
|
11
|
+
|
|
12
|
+
| Path | Purpose |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| `src/lib/logger/index.ts` | Pino logger wrapper |
|
|
15
|
+
| `src/lib/api-logger.ts` | API logging helpers |
|
|
16
|
+
|
|
17
|
+
When Axiom is configured, logs can be shipped to Axiom. Without Axiom, logs should still be available locally.
|
|
18
|
+
|
|
19
|
+
Common variables:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
AXIOM_TOKEN="xaat-..."
|
|
23
|
+
AXIOM_DATASET="nextdevtpl"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Error monitoring
|
|
27
|
+
|
|
28
|
+
Sentry config files:
|
|
29
|
+
|
|
30
|
+
| Path | Purpose |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `sentry.client.config.ts` | Browser Sentry setup |
|
|
33
|
+
| `sentry.server.config.ts` | Server Sentry setup |
|
|
34
|
+
| `sentry.edge.config.ts` | Edge Sentry setup |
|
|
35
|
+
| `src/instrumentation.ts` | Next.js instrumentation hook |
|
|
36
|
+
| `src/lib/monitoring/index.ts` | Monitoring helpers |
|
|
37
|
+
|
|
38
|
+
Common variables:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
NEXT_PUBLIC_SENTRY_DSN="https://..."
|
|
42
|
+
SENTRY_AUTH_TOKEN="sntrys_..."
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Rate limiting
|
|
46
|
+
|
|
47
|
+
Rate limiting lives in:
|
|
48
|
+
|
|
49
|
+
```txt
|
|
50
|
+
src/lib/rate-limit
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Upstash variables:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
UPSTASH_REDIS_REST_URL="https://..."
|
|
57
|
+
UPSTASH_REDIS_REST_TOKEN="..."
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If Redis is missing, development should continue without a hard startup failure.
|
|
61
|
+
|
|
62
|
+
## Production checklist
|
|
63
|
+
|
|
64
|
+
- Enable Sentry for user-visible errors.
|
|
65
|
+
- Enable structured logs for webhook and payment debugging.
|
|
66
|
+
- Log external event IDs for payment and job retries.
|
|
67
|
+
- Avoid logging raw credentials, tokens, or authorization headers.
|
|
68
|
+
- Verify rate limits on public mutation endpoints.
|
|
69
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Payments
|
|
3
|
+
description: Configure Creem payments, subscriptions, one-time purchases, and webhooks.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Payments
|
|
7
|
+
|
|
8
|
+
Payments are implemented through Creem. The template includes subscription billing, one-time credit purchases, webhook handling, and plan lookup.
|
|
9
|
+
|
|
10
|
+
## Main files
|
|
11
|
+
|
|
12
|
+
| Path | Purpose |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| `src/features/payment/creem.ts` | Creem client and API integration |
|
|
15
|
+
| `src/features/payment/actions.ts` | Checkout and payment Server Actions |
|
|
16
|
+
| `src/features/payment/types.ts` | Payment-related types |
|
|
17
|
+
| `src/config/payment.ts` | Product/payment configuration |
|
|
18
|
+
| `src/config/subscription-plan.ts` | Plan definitions |
|
|
19
|
+
| `src/app/api/webhooks/creem/route.ts` | Creem webhook endpoint |
|
|
20
|
+
| `src/features/subscription` | User plan lookup and subscription UI |
|
|
21
|
+
| `src/test/payment` | Payment and subscription tests |
|
|
22
|
+
|
|
23
|
+
## Required environment variables
|
|
24
|
+
|
|
25
|
+
| Variable | Purpose |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| `CREEM_API_KEY` | Calls Creem APIs |
|
|
28
|
+
| `CREEM_WEBHOOK_SECRET` | Verifies webhook signatures |
|
|
29
|
+
|
|
30
|
+
Production callback and webhook URLs should use your deployed domain.
|
|
31
|
+
|
|
32
|
+
## Subscription flow
|
|
33
|
+
|
|
34
|
+
1. Plans are defined in `src/config/subscription-plan.ts`.
|
|
35
|
+
2. The pricing UI renders available plans.
|
|
36
|
+
3. A checkout action creates a Creem checkout session.
|
|
37
|
+
4. Creem sends webhook events.
|
|
38
|
+
5. The webhook updates subscription state.
|
|
39
|
+
6. The dashboard reads the current user plan.
|
|
40
|
+
|
|
41
|
+
## Credit purchase flow
|
|
42
|
+
|
|
43
|
+
One-time credit purchases share the payment layer but grant credit packages after successful payment. See [Credits](/en/docs/credits) for ledger behavior.
|
|
44
|
+
|
|
45
|
+
## Webhook checklist
|
|
46
|
+
|
|
47
|
+
Before going live:
|
|
48
|
+
|
|
49
|
+
1. Configure the Creem webhook URL:
|
|
50
|
+
|
|
51
|
+
```txt
|
|
52
|
+
https://your-domain.com/api/webhooks/creem
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
2. Set `CREEM_WEBHOOK_SECRET`.
|
|
56
|
+
3. Test a checkout in sandbox mode if available.
|
|
57
|
+
4. Confirm subscription state updates.
|
|
58
|
+
5. Confirm duplicate webhook events do not double-grant credits.
|
|
59
|
+
6. Run payment tests.
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pnpm test:run src/test/payment
|
|
63
|
+
```
|
|
64
|
+
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Project Structure
|
|
3
|
+
description: Understand how the application is organized and where to customize each feature.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Project Structure
|
|
7
|
+
|
|
8
|
+
NextDevTpl uses a feature-based structure. Routes live under `src/app`, reusable product modules live under `src/features`, and infrastructure helpers live under `src/lib`.
|
|
9
|
+
|
|
10
|
+
## Top-level files
|
|
11
|
+
|
|
12
|
+
| Path | Purpose |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| `package.json` | Scripts and dependency versions |
|
|
15
|
+
| `next.config.mjs` | Next.js, MDX, and build configuration |
|
|
16
|
+
| `source.config.ts` | Fumadocs content collections |
|
|
17
|
+
| `drizzle.config.ts` | Drizzle migration configuration |
|
|
18
|
+
| `.env.example` | Environment variable reference |
|
|
19
|
+
| `deploy-build.bat` | Windows-side production build and upload script |
|
|
20
|
+
| `start-prod.sh` | Linux production start script |
|
|
21
|
+
|
|
22
|
+
## Application routes
|
|
23
|
+
|
|
24
|
+
```txt
|
|
25
|
+
src/app/
|
|
26
|
+
├── [locale]/
|
|
27
|
+
│ ├── (marketing)/ # Home, blog, legal, PSEO, public pages
|
|
28
|
+
│ ├── (auth)/ # Sign in, sign up, password reset
|
|
29
|
+
│ ├── (dashboard)/ # Authenticated customer dashboard
|
|
30
|
+
│ ├── (admin)/ # Admin-only area
|
|
31
|
+
│ └── docs/ # Fumadocs documentation
|
|
32
|
+
└── api/ # Route handlers and webhooks
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The locale segment is handled by `next-intl`. Current locales are configured in `src/i18n/routing.ts`.
|
|
36
|
+
|
|
37
|
+
## Feature modules
|
|
38
|
+
|
|
39
|
+
| Module | Main purpose |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `src/features/auth` | Auth UI and client hooks |
|
|
42
|
+
| `src/features/credits` | Credit ledger, purchases, and balance utilities |
|
|
43
|
+
| `src/features/payment` | Creem checkout and payment actions |
|
|
44
|
+
| `src/features/subscription` | User plan lookup and subscription UI |
|
|
45
|
+
| `src/features/settings` | Profile, security, billing, and account settings |
|
|
46
|
+
| `src/features/support` | User tickets and admin replies |
|
|
47
|
+
| `src/features/admin` | Admin UI components |
|
|
48
|
+
| `src/features/marketing` | Header, footer, hero, pricing, FAQ, and landing sections |
|
|
49
|
+
| `src/features/storage` | S3/R2 upload and provider abstraction |
|
|
50
|
+
| `src/features/mail` | React Email templates and send actions |
|
|
51
|
+
| `src/features/shared` | Providers, theme toggle, language switcher, shared icons |
|
|
52
|
+
|
|
53
|
+
## Infrastructure modules
|
|
54
|
+
|
|
55
|
+
| Path | Responsibility |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `src/db/schema.ts` | Database tables and relations |
|
|
58
|
+
| `src/lib/auth` | Better Auth server, client, edge helpers, and admin helpers |
|
|
59
|
+
| `src/lib/rate-limit` | Upstash-backed rate limiting with safe fallback |
|
|
60
|
+
| `src/lib/logger` | Pino logger wrapper and Axiom integration |
|
|
61
|
+
| `src/lib/monitoring` | Sentry integration helpers |
|
|
62
|
+
| `src/lib/source.ts` | Fumadocs, blog, and legal content loaders |
|
|
63
|
+
| `src/lib/safe-action.ts` | Server Action client setup |
|
|
64
|
+
| `src/inngest` | Inngest client and background functions |
|
|
65
|
+
|
|
66
|
+
## Content
|
|
67
|
+
|
|
68
|
+
| Path | Content type |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| `src/content/docs/en` | English documentation |
|
|
71
|
+
| `src/content/docs/zh` | Chinese documentation |
|
|
72
|
+
| `src/content/blog/en` | English blog posts |
|
|
73
|
+
| `src/content/blog/zh` | Chinese blog posts |
|
|
74
|
+
| `src/content/legal/en` | English legal pages |
|
|
75
|
+
| `src/content/legal/zh` | Chinese legal pages |
|
|
76
|
+
| `messages/en.json` | English UI translations |
|
|
77
|
+
| `messages/zh.json` | Chinese UI translations |
|
|
78
|
+
|
|
79
|
+
## Testing
|
|
80
|
+
|
|
81
|
+
Integration tests live under `src/test`. They cover payment, credits, support tickets, storage security, settings, jobs, and email flows.
|
|
82
|
+
|