create-nexst-monorepo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. package/dist/index.js +1727 -0
  2. package/package.json +37 -0
  3. package/template/.agents/plugins/marketplace.json +21 -0
  4. package/template/.claude/settings.json +6 -0
  5. package/template/.claude/skills/frontend-design/LICENSE.txt +177 -0
  6. package/template/.claude/skills/frontend-design/SKILL.md +154 -0
  7. package/template/.claude/skills/theme-factory/SKILL.md +95 -0
  8. package/template/.claude/skills/theme-factory/references/schema.md +104 -0
  9. package/template/.claude/skills/theme-factory/scripts/theme.mjs +261 -0
  10. package/template/.dockerignore +43 -0
  11. package/template/.editorconfig +10 -0
  12. package/template/.github/workflows/ci.yaml +289 -0
  13. package/template/.github/workflows/publish-app.yaml +66 -0
  14. package/template/.github/workflows/publish.yaml +148 -0
  15. package/template/.github/workflows/snyk.yaml +34 -0
  16. package/template/.vscode/settings.json +8 -0
  17. package/template/AGENTS.md +42 -0
  18. package/template/Dockerfile.base +9 -0
  19. package/template/README.md +54 -0
  20. package/template/_gitignore +10 -0
  21. package/template/apps/api/.env.example +32 -0
  22. package/template/apps/api/AGENTS.md +44 -0
  23. package/template/apps/api/Dockerfile +69 -0
  24. package/template/apps/api/_gitignore +8 -0
  25. package/template/apps/api/knip.config.ts +22 -0
  26. package/template/apps/api/kustomize/base/application.properties +16 -0
  27. package/template/apps/api/kustomize/base/deployment.yaml +94 -0
  28. package/template/apps/api/kustomize/base/kustomization.yaml +17 -0
  29. package/template/apps/api/kustomize/base/service.yaml +10 -0
  30. package/template/apps/api/kustomize/overlays/prod/kustomization.yaml +17 -0
  31. package/template/apps/api/kustomize/overlays/staging/application.properties +1 -0
  32. package/template/apps/api/kustomize/overlays/staging/kustomization.yaml +21 -0
  33. package/template/apps/api/kustomize/secret.keys +14 -0
  34. package/template/apps/api/oxfmt.config.ts +8 -0
  35. package/template/apps/api/oxlint.config.ts +107 -0
  36. package/template/apps/api/package.json +79 -0
  37. package/template/apps/api/prisma/migrations/20260927000000_init/migration.sql +113 -0
  38. package/template/apps/api/prisma/migrations/migration_lock.toml +3 -0
  39. package/template/apps/api/prisma/schema.prisma +113 -0
  40. package/template/apps/api/prisma.config.ts +7 -0
  41. package/template/apps/api/scripts/auth.cli.ts +19 -0
  42. package/template/apps/api/scripts/seal-secret.sh +171 -0
  43. package/template/apps/api/sonar-project.properties +9 -0
  44. package/template/apps/api/src/app-info/app-info.dto.ts +10 -0
  45. package/template/apps/api/src/app-info/app-info.module.ts +7 -0
  46. package/template/apps/api/src/app-info/app-info.resolver.spec.ts +14 -0
  47. package/template/apps/api/src/app-info/app-info.resolver.ts +21 -0
  48. package/template/apps/api/src/app.module.spec.ts +93 -0
  49. package/template/apps/api/src/app.module.ts +77 -0
  50. package/template/apps/api/src/auth/auth.guard.spec.ts +90 -0
  51. package/template/apps/api/src/auth/auth.guard.ts +97 -0
  52. package/template/apps/api/src/auth/auth.ts +129 -0
  53. package/template/apps/api/src/auth/decorator/allow-anonymous.decorator.ts +17 -0
  54. package/template/apps/api/src/auth/decorator/is-email-verified.decorator.spec.ts +41 -0
  55. package/template/apps/api/src/auth/decorator/is-email-verified.decorator.ts +20 -0
  56. package/template/apps/api/src/auth/decorator/roles.decorator.ts +27 -0
  57. package/template/apps/api/src/auth/testing/make-session.ts +31 -0
  58. package/template/apps/api/src/auth/types/auth.types.ts +27 -0
  59. package/template/apps/api/src/bootstrap/register-graphql-enums.ts +12 -0
  60. package/template/apps/api/src/bootstrap/security.ts +24 -0
  61. package/template/apps/api/src/bootstrap/swagger.ts +28 -0
  62. package/template/apps/api/src/config/app.config.spec.ts +22 -0
  63. package/template/apps/api/src/config/app.config.ts +122 -0
  64. package/template/apps/api/src/config/graphql-depth-limit.ts +103 -0
  65. package/template/apps/api/src/config/graphql.config.ts +77 -0
  66. package/template/apps/api/src/config/resources/app.yaml +29 -0
  67. package/template/apps/api/src/errors/app-parse-uuid.pipe.ts +27 -0
  68. package/template/apps/api/src/errors/app.exception.ts +47 -0
  69. package/template/apps/api/src/errors/error-code.enum.ts +54 -0
  70. package/template/apps/api/src/errors/http-status-fallback-code.util.ts +27 -0
  71. package/template/apps/api/src/errors/validation-exception.factory.ts +43 -0
  72. package/template/apps/api/src/health/health.controller.spec.ts +82 -0
  73. package/template/apps/api/src/health/health.controller.ts +57 -0
  74. package/template/apps/api/src/health/health.module.ts +12 -0
  75. package/template/apps/api/src/logging/context-logger.ts +18 -0
  76. package/template/apps/api/src/logging/logger.config.ts +23 -0
  77. package/template/apps/api/src/logging/logging.module.ts +22 -0
  78. package/template/apps/api/src/mail/mail.module.ts +12 -0
  79. package/template/apps/api/src/mail/mail.service.spec.ts +47 -0
  80. package/template/apps/api/src/mail/mail.service.ts +123 -0
  81. package/template/apps/api/src/main.ts +41 -0
  82. package/template/apps/api/src/prisma/prisma.module.ts +12 -0
  83. package/template/apps/api/src/prisma/prisma.service.spec.ts +136 -0
  84. package/template/apps/api/src/prisma/prisma.service.ts +138 -0
  85. package/template/apps/api/src/queue/dto/enqueue-example.input.ts +11 -0
  86. package/template/apps/api/src/queue/example-queue.resolver.ts +14 -0
  87. package/template/apps/api/src/queue/example-queue.service.spec.ts +21 -0
  88. package/template/apps/api/src/queue/example-queue.service.ts +32 -0
  89. package/template/apps/api/src/queue/queue.module.ts +27 -0
  90. package/template/apps/api/src/r2/r2.module.ts +12 -0
  91. package/template/apps/api/src/r2/r2.service.spec.ts +117 -0
  92. package/template/apps/api/src/r2/r2.service.ts +131 -0
  93. package/template/apps/api/src/user/dto/user.dto.ts +26 -0
  94. package/template/apps/api/src/user/user.module.ts +10 -0
  95. package/template/apps/api/src/user/user.resolver.spec.ts +18 -0
  96. package/template/apps/api/src/user/user.resolver.ts +24 -0
  97. package/template/apps/api/src/utils/catch-everything-exception.filter.spec.ts +292 -0
  98. package/template/apps/api/src/utils/catch-everything-exception.filter.ts +70 -0
  99. package/template/apps/api/src/utils/error-handler.util.spec.ts +20 -0
  100. package/template/apps/api/src/utils/error-handler.util.ts +12 -0
  101. package/template/apps/api/src/utils/escape-like-pattern.util.spec.ts +29 -0
  102. package/template/apps/api/src/utils/escape-like-pattern.util.ts +11 -0
  103. package/template/apps/api/src/utils/pagination.input.ts +20 -0
  104. package/template/apps/api/src/utils/prisma-exception.filter.spec.ts +186 -0
  105. package/template/apps/api/src/utils/prisma-exception.filter.ts +45 -0
  106. package/template/apps/api/src/utils/prisma-graphql-exception.filter.spec.ts +216 -0
  107. package/template/apps/api/src/utils/prisma-graphql-exception.filter.ts +43 -0
  108. package/template/apps/api/tests/app.e2e-spec.ts +35 -0
  109. package/template/apps/api/tests/auth.e2e-spec.ts +38 -0
  110. package/template/apps/api/tests/helpers/api.ts +27 -0
  111. package/template/apps/api/tsconfig.json +11 -0
  112. package/template/apps/api/vitest.config.e2e.ts +16 -0
  113. package/template/apps/api/vitest.config.ts +40 -0
  114. package/template/apps/web/.env.example +7 -0
  115. package/template/apps/web/.storybook/decorators.tsx +38 -0
  116. package/template/apps/web/.storybook/main.ts +17 -0
  117. package/template/apps/web/.storybook/preview.ts +38 -0
  118. package/template/apps/web/.storybook/vitest.setup.ts +5 -0
  119. package/template/apps/web/AGENTS.md +29 -0
  120. package/template/apps/web/Dockerfile +49 -0
  121. package/template/apps/web/_gitignore +16 -0
  122. package/template/apps/web/knip.config.ts +15 -0
  123. package/template/apps/web/kustomize/base/application.properties +5 -0
  124. package/template/apps/web/kustomize/base/deployment.yaml +60 -0
  125. package/template/apps/web/kustomize/base/kustomization.yaml +17 -0
  126. package/template/apps/web/kustomize/base/service.yaml +10 -0
  127. package/template/apps/web/kustomize/overlays/prod/kustomization.yaml +12 -0
  128. package/template/apps/web/kustomize/overlays/staging/application.properties +2 -0
  129. package/template/apps/web/kustomize/overlays/staging/kustomization.yaml +18 -0
  130. package/template/apps/web/messages/de.json +124 -0
  131. package/template/apps/web/messages/en.json +124 -0
  132. package/template/apps/web/next-env.d.ts +7 -0
  133. package/template/apps/web/next.config.ts +39 -0
  134. package/template/apps/web/oxfmt.config.ts +9 -0
  135. package/template/apps/web/oxlint.config.ts +36 -0
  136. package/template/apps/web/package.json +80 -0
  137. package/template/apps/web/playwright.config.ts +34 -0
  138. package/template/apps/web/postcss.config.mjs +7 -0
  139. package/template/apps/web/sonar-project.properties +9 -0
  140. package/template/apps/web/src/app/[locale]/(auth)/recovery/page.tsx +22 -0
  141. package/template/apps/web/src/app/[locale]/(auth)/reset-password/page.tsx +29 -0
  142. package/template/apps/web/src/app/[locale]/(auth)/sign-in/page.tsx +24 -0
  143. package/template/apps/web/src/app/[locale]/(auth)/sign-up/page.tsx +24 -0
  144. package/template/apps/web/src/app/[locale]/(auth)/verify/page.tsx +24 -0
  145. package/template/apps/web/src/app/[locale]/dashboard/page.tsx +34 -0
  146. package/template/apps/web/src/app/[locale]/layout.tsx +60 -0
  147. package/template/apps/web/src/app/[locale]/page.tsx +23 -0
  148. package/template/apps/web/src/app/api/health/route.ts +3 -0
  149. package/template/apps/web/src/app/global-error.tsx +19 -0
  150. package/template/apps/web/src/app/globals.css +98 -0
  151. package/template/apps/web/src/app/icon.svg +1 -0
  152. package/template/apps/web/src/app/robots.ts +15 -0
  153. package/template/apps/web/src/app/sitemap.ts +24 -0
  154. package/template/apps/web/src/components/alert/alert.stories.tsx +25 -0
  155. package/template/apps/web/src/components/alert/alert.tsx +50 -0
  156. package/template/apps/web/src/components/avatar/avatar.stories.tsx +116 -0
  157. package/template/apps/web/src/components/avatar/avatar.tsx +88 -0
  158. package/template/apps/web/src/components/button/button-variants.ts +28 -0
  159. package/template/apps/web/src/components/button/button.stories.tsx +33 -0
  160. package/template/apps/web/src/components/button/button.tsx +32 -0
  161. package/template/apps/web/src/components/checkbox/checkbox.stories.tsx +312 -0
  162. package/template/apps/web/src/components/checkbox/checkbox.tsx +38 -0
  163. package/template/apps/web/src/components/dialog/danger-panel.stories.tsx +41 -0
  164. package/template/apps/web/src/components/dialog/danger-panel.tsx +32 -0
  165. package/template/apps/web/src/components/dialog/dialog.stories.tsx +239 -0
  166. package/template/apps/web/src/components/dialog/dialog.tsx +136 -0
  167. package/template/apps/web/src/components/dialog-buttons.stories.tsx +55 -0
  168. package/template/apps/web/src/components/dialog-buttons.tsx +48 -0
  169. package/template/apps/web/src/components/drawer/drawer.stories.tsx +251 -0
  170. package/template/apps/web/src/components/drawer/drawer.tsx +120 -0
  171. package/template/apps/web/src/components/dropdown-menu/dropdown-menu.stories.tsx +329 -0
  172. package/template/apps/web/src/components/dropdown-menu/dropdown-menu.tsx +263 -0
  173. package/template/apps/web/src/components/empty-state.stories.tsx +49 -0
  174. package/template/apps/web/src/components/empty-state.tsx +33 -0
  175. package/template/apps/web/src/components/field-group.stories.tsx +47 -0
  176. package/template/apps/web/src/components/field-group.tsx +20 -0
  177. package/template/apps/web/src/components/field-label.stories.tsx +34 -0
  178. package/template/apps/web/src/components/field-label.tsx +28 -0
  179. package/template/apps/web/src/components/icons.tsx +25 -0
  180. package/template/apps/web/src/components/input/input-otp.stories.tsx +86 -0
  181. package/template/apps/web/src/components/input/input-otp.tsx +184 -0
  182. package/template/apps/web/src/components/input/input.stories.tsx +35 -0
  183. package/template/apps/web/src/components/input/input.tsx +180 -0
  184. package/template/apps/web/src/components/popover/popover.stories.tsx +479 -0
  185. package/template/apps/web/src/components/popover/popover.tsx +45 -0
  186. package/template/apps/web/src/components/responsive-dialog/responsive-dialog.stories.tsx +307 -0
  187. package/template/apps/web/src/components/responsive-dialog/responsive-dialog.tsx +96 -0
  188. package/template/apps/web/src/components/searchbar/searchbar.stories.tsx +59 -0
  189. package/template/apps/web/src/components/searchbar/searchbar.tsx +64 -0
  190. package/template/apps/web/src/components/select/select.stories.tsx +293 -0
  191. package/template/apps/web/src/components/select/select.tsx +445 -0
  192. package/template/apps/web/src/components/skeleton/skeleton.stories.tsx +76 -0
  193. package/template/apps/web/src/components/skeleton/skeleton.tsx +13 -0
  194. package/template/apps/web/src/components/spinner/spinner.tsx +18 -0
  195. package/template/apps/web/src/components/switch/switch.stories.tsx +71 -0
  196. package/template/apps/web/src/components/switch/switch.tsx +35 -0
  197. package/template/apps/web/src/components/tabs/tabs.stories.tsx +209 -0
  198. package/template/apps/web/src/components/tabs/tabs.tsx +69 -0
  199. package/template/apps/web/src/components/tabs/url-tabs.stories.tsx +68 -0
  200. package/template/apps/web/src/components/tabs/url-tabs.tsx +42 -0
  201. package/template/apps/web/src/components/textarea/textarea.stories.tsx +144 -0
  202. package/template/apps/web/src/components/textarea/textarea.tsx +115 -0
  203. package/template/apps/web/src/components/toast/toaster.tsx +38 -0
  204. package/template/apps/web/src/components/tooltip/tooltip.stories.tsx +237 -0
  205. package/template/apps/web/src/components/tooltip/tooltip.tsx +49 -0
  206. package/template/apps/web/src/config/csp.ts +59 -0
  207. package/template/apps/web/src/config/routes.ts +14 -0
  208. package/template/apps/web/src/config/site.ts +5 -0
  209. package/template/apps/web/src/env.ts +15 -0
  210. package/template/apps/web/src/features/auth/auth-card.tsx +20 -0
  211. package/template/apps/web/src/features/auth/auth-divider.tsx +14 -0
  212. package/template/apps/web/src/features/auth/google-auth-button.tsx +49 -0
  213. package/template/apps/web/src/features/auth/google-one-tap.tsx +23 -0
  214. package/template/apps/web/src/features/auth/lib/auth-error.test.ts +22 -0
  215. package/template/apps/web/src/features/auth/lib/auth-error.ts +16 -0
  216. package/template/apps/web/src/features/auth/lib/return-to.test.ts +41 -0
  217. package/template/apps/web/src/features/auth/lib/return-to.ts +19 -0
  218. package/template/apps/web/src/features/auth/lib/validator.test.ts +45 -0
  219. package/template/apps/web/src/features/auth/lib/validator.ts +49 -0
  220. package/template/apps/web/src/features/auth/passkey-settings.tsx +106 -0
  221. package/template/apps/web/src/features/auth/recovery-form.tsx +61 -0
  222. package/template/apps/web/src/features/auth/resend-verification-button.tsx +36 -0
  223. package/template/apps/web/src/features/auth/reset-password-form.tsx +62 -0
  224. package/template/apps/web/src/features/auth/sign-in-form.stories.tsx +22 -0
  225. package/template/apps/web/src/features/auth/sign-in-form.tsx +116 -0
  226. package/template/apps/web/src/features/auth/sign-out-button.tsx +26 -0
  227. package/template/apps/web/src/features/auth/sign-up-form.tsx +107 -0
  228. package/template/apps/web/src/features/shared/provider.tsx +16 -0
  229. package/template/apps/web/src/features/shared/site-header.tsx +48 -0
  230. package/template/apps/web/src/features/shared/theme-toggle.tsx +24 -0
  231. package/template/apps/web/src/i18n/navigation.ts +5 -0
  232. package/template/apps/web/src/i18n/request.ts +21 -0
  233. package/template/apps/web/src/i18n/routing.ts +6 -0
  234. package/template/apps/web/src/lib/auth-client.ts +19 -0
  235. package/template/apps/web/src/lib/auth-server.ts +46 -0
  236. package/template/apps/web/src/lib/auth.ts +8 -0
  237. package/template/apps/web/src/lib/codegen.ts +30 -0
  238. package/template/apps/web/src/lib/graphql-client.ts +29 -0
  239. package/template/apps/web/src/lib/graphql-server.ts +28 -0
  240. package/template/apps/web/src/lib/graphql-utils.test.ts +32 -0
  241. package/template/apps/web/src/lib/graphql-utils.ts +76 -0
  242. package/template/apps/web/src/lib/hooks/use-media-query.ts +21 -0
  243. package/template/apps/web/src/lib/metadata.ts +17 -0
  244. package/template/apps/web/src/lib/network-error.test.ts +30 -0
  245. package/template/apps/web/src/lib/network-error.ts +17 -0
  246. package/template/apps/web/src/lib/proxy-utils.ts +42 -0
  247. package/template/apps/web/src/lib/query-client.ts +29 -0
  248. package/template/apps/web/src/lib/utils.ts +5 -0
  249. package/template/apps/web/src/proxy.ts +57 -0
  250. package/template/apps/web/test-results/.last-run.json +4 -0
  251. package/template/apps/web/tests/auth.spec.ts +17 -0
  252. package/template/apps/web/tests/csp-theme-script.spec.ts +37 -0
  253. package/template/apps/web/tests/home.spec.ts +25 -0
  254. package/template/apps/web/tsconfig.build.json +4 -0
  255. package/template/apps/web/tsconfig.json +28 -0
  256. package/template/apps/web/vitest.config.ts +40 -0
  257. package/template/apps/web/vitest.shims.d.ts +1 -0
  258. package/template/apps/worker/.env.example +4 -0
  259. package/template/apps/worker/AGENTS.md +11 -0
  260. package/template/apps/worker/Dockerfile +35 -0
  261. package/template/apps/worker/knip.config.ts +3 -0
  262. package/template/apps/worker/kustomize/base/application.properties +4 -0
  263. package/template/apps/worker/kustomize/base/deployment.yaml +62 -0
  264. package/template/apps/worker/kustomize/base/kustomization.yaml +16 -0
  265. package/template/apps/worker/kustomize/overlays/prod/kustomization.yaml +12 -0
  266. package/template/apps/worker/kustomize/overlays/staging/application.properties +1 -0
  267. package/template/apps/worker/kustomize/overlays/staging/kustomization.yaml +18 -0
  268. package/template/apps/worker/oxfmt.config.ts +8 -0
  269. package/template/apps/worker/oxlint.config.ts +15 -0
  270. package/template/apps/worker/package.json +33 -0
  271. package/template/apps/worker/sonar-project.properties +8 -0
  272. package/template/apps/worker/src/env.ts +13 -0
  273. package/template/apps/worker/src/lib/graceful-shutdown.ts +27 -0
  274. package/template/apps/worker/src/lib/logger.ts +20 -0
  275. package/template/apps/worker/src/main.ts +17 -0
  276. package/template/apps/worker/src/processors/example-processor.ts +15 -0
  277. package/template/apps/worker/src/worker/redis.ts +19 -0
  278. package/template/apps/worker/src/worker/worker.ts +37 -0
  279. package/template/apps/worker/tests/example-processor.test.ts +13 -0
  280. package/template/apps/worker/tests/graceful-shutdown.test.ts +34 -0
  281. package/template/apps/worker/tsconfig.json +4 -0
  282. package/template/apps/worker/vitest.config.ts +13 -0
  283. package/template/bun.lock +3053 -0
  284. package/template/bunfig.toml +2 -0
  285. package/template/compose.yaml +53 -0
  286. package/template/docker-bake.hcl +86 -0
  287. package/template/package.json +47 -0
  288. package/template/packages/lint/knip.ts +40 -0
  289. package/template/packages/lint/oxfmt.ts +8 -0
  290. package/template/packages/lint/oxlint.ts +136 -0
  291. package/template/packages/lint/package.json +13 -0
  292. package/template/packages/queues/oxfmt.config.ts +8 -0
  293. package/template/packages/queues/oxlint.config.ts +7 -0
  294. package/template/packages/queues/package.json +15 -0
  295. package/template/packages/queues/src/example-job.ts +11 -0
  296. package/template/packages/queues/src/index.ts +3 -0
  297. package/template/packages/queues/src/queue-names.ts +2 -0
  298. package/template/packages/queues/src/redis-connection.ts +27 -0
  299. package/template/packages/queues/tsconfig.json +4 -0
  300. package/template/packages/tsconfig/base.json +23 -0
  301. package/template/packages/tsconfig/node.json +11 -0
  302. package/template/packages/tsconfig/package.json +4 -0
  303. package/template/turbo.json +50 -0
@@ -0,0 +1,148 @@
1
+ name: Publish Images
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ concurrency:
8
+ group: publish-images-${{ github.ref }}
9
+ cancel-in-progress: false
10
+
11
+ permissions:
12
+ contents: read
13
+ packages: write
14
+
15
+ jobs:
16
+ changes:
17
+ runs-on: ubuntu-latest
18
+ outputs:
19
+ web: ${{ steps.filter.outputs.web }}
20
+ api: ${{ steps.filter.outputs.api }}
21
+ # @if worker
22
+ worker: ${{ steps.filter.outputs.worker }}
23
+ # @endif
24
+ steps:
25
+ - uses: actions/checkout@v6
26
+ - uses: dorny/paths-filter@v3
27
+ id: filter
28
+ with:
29
+ filters: |
30
+ shared: &shared
31
+ - 'package.json'
32
+ - 'bun.lock'
33
+ - 'bunfig.toml'
34
+ - 'turbo.json'
35
+ - '.dockerignore'
36
+ - 'Dockerfile.base'
37
+ - 'docker-bake.hcl'
38
+ - 'packages/**'
39
+ web:
40
+ - *shared
41
+ - 'apps/web/**'
42
+ - '!apps/web/kustomize/**'
43
+ api:
44
+ - *shared
45
+ - 'apps/api/**'
46
+ - '!apps/api/kustomize/**'
47
+ # @if worker
48
+ worker:
49
+ - *shared
50
+ - 'apps/worker/**'
51
+ - '!apps/worker/kustomize/**'
52
+ # @endif
53
+
54
+ web:
55
+ needs: changes
56
+ if: needs.changes.outputs.web == 'true'
57
+ uses: ./.github/workflows/publish-app.yaml
58
+ with:
59
+ app: web
60
+ secrets: inherit
61
+
62
+ api:
63
+ needs: changes
64
+ if: needs.changes.outputs.api == 'true'
65
+ uses: ./.github/workflows/publish-app.yaml
66
+ with:
67
+ app: api
68
+ secrets: inherit
69
+
70
+ api-migrate:
71
+ needs: changes
72
+ if: needs.changes.outputs.api == 'true'
73
+ uses: ./.github/workflows/publish-app.yaml
74
+ with:
75
+ app: api-migrate
76
+ secrets: inherit
77
+ # @if worker
78
+
79
+ worker:
80
+ needs: changes
81
+ if: needs.changes.outputs.worker == 'true'
82
+ uses: ./.github/workflows/publish-app.yaml
83
+ with:
84
+ app: worker
85
+ secrets: inherit
86
+ # @endif
87
+
88
+ # Pins the freshly pushed sha-* tags in the prod overlays so GitOps (Flux/Argo)
89
+ # rolls them out.
90
+ rewind:
91
+ if: >-
92
+ always() &&
93
+ needs.changes.result == 'success' &&
94
+ !contains(needs.*.result, 'failure') &&
95
+ !contains(needs.*.result, 'cancelled') &&
96
+ contains(needs.*.result, 'success')
97
+ # @if worker
98
+ needs: [changes, web, api, api-migrate, worker]
99
+ # @endif
100
+ # @if !worker
101
+ # needs: [changes, web, api, api-migrate]
102
+ # @endif
103
+ runs-on: ubuntu-latest
104
+ permissions:
105
+ contents: write
106
+ steps:
107
+ - uses: actions/checkout@v6
108
+ with:
109
+ fetch-depth: 0
110
+ ref: main
111
+
112
+ - name: Set up Kustomize
113
+ working-directory: ${{ runner.temp }}
114
+ run: |
115
+ curl -sSfL https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash
116
+ sudo mv kustomize /usr/local/bin/
117
+
118
+ - name: Update image tags in prod overlays
119
+ env:
120
+ API_CHANGED: ${{ needs.changes.outputs.api }}
121
+ WEB_CHANGED: ${{ needs.changes.outputs.web }}
122
+ WORKER_CHANGED: ${{ needs.changes.outputs.worker }} # @if worker
123
+ run: |
124
+ TAG="sha-${GITHUB_SHA::7}"
125
+ REGISTRY="ghcr.io/${GITHUB_REPOSITORY_OWNER,,}"
126
+
127
+ pin() { # <app dir> <image>
128
+ (cd "apps/$1/kustomize/overlays/prod" && kustomize edit set image "$2=$REGISTRY/$2:$TAG")
129
+ }
130
+
131
+ if [ "$WEB_CHANGED" = "true" ]; then pin web nexst-web; fi
132
+ if [ "$API_CHANGED" = "true" ]; then
133
+ pin api nexst-api
134
+ pin api nexst-api-migrate
135
+ fi
136
+ if [ "$WORKER_CHANGED" = "true" ]; then pin worker nexst-worker; fi # @if worker
137
+
138
+ - name: Commit and push
139
+ run: |
140
+ git config user.name "github-actions[bot]"
141
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
142
+ git add apps/*/kustomize/overlays/prod/kustomization.yaml
143
+ if git diff --cached --quiet; then
144
+ echo "No image tag changes to commit."
145
+ exit 0
146
+ fi
147
+ git commit -m "chore: rewind images to sha-${GITHUB_SHA::7} [skip ci]"
148
+ git push origin HEAD:main
@@ -0,0 +1,34 @@
1
+ name: Snyk Scan
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: '0 0 * * *'
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ security:
16
+ permissions:
17
+ contents: read
18
+ security-events: write
19
+
20
+ runs-on: ubuntu-latest
21
+ env:
22
+ SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
23
+
24
+ steps:
25
+ - uses: actions/checkout@v6
26
+ - uses: snyk/actions/setup@master
27
+
28
+ - name: Snyk Code test
29
+ run: snyk code test --sarif-file-output=snyk.sarif || true
30
+
31
+ - name: Upload result to GitHub Code Scanning
32
+ uses: github/codeql-action/upload-sarif@v3
33
+ with:
34
+ sarif_file: snyk.sarif
@@ -0,0 +1,8 @@
1
+ {
2
+ "css.lint.unknownAtRules": "ignore",
3
+ "editor.defaultFormatter": "oxc.oxc-vscode",
4
+ "editor.formatOnSave": true,
5
+ "editor.codeActionsOnSave": {
6
+ "source.fixAll.oxc": "explicit"
7
+ }
8
+ }
@@ -0,0 +1,42 @@
1
+ # Nexst
2
+
3
+ Bun workspace: one `package.json`, one lockfile (`bun.lock`), one CI (root
4
+ `.github/workflows/`). `apps/*/AGENTS.md` add app-specific rules.
5
+
6
+ - **web** — Next.js 16, next-intl (en, de), Tailwind 4, React Query.
7
+ - **api** — NestJS 12 on Fastify (REST + GraphQL), Prisma 7 on Postgres.
8
+ <!-- @if worker -->
9
+ - **worker** — BullMQ worker for background jobs the API enqueues; shared queue
10
+ contracts in `packages/queues`.
11
+ <!-- @endif -->
12
+ - **packages/lint**, **packages/tsconfig** — shared oxlint/oxfmt/knip and TS configs.
13
+
14
+ ## Local dev
15
+
16
+ `bun dev` starts the infra from `compose.yaml` and runs all apps in watch mode.
17
+ The backend apps have no build step; bun runs `src/*.ts` directly, also in production.
18
+ Secrets live in each app's `.env`/`.env.development` (see `.env.example`); bun loads
19
+ them itself. Run TypeScript with bun (`bun <file>`, `bunx --bun prisma`), not node.
20
+
21
+ ## Docker
22
+
23
+ `docker buildx bake <api|api-migrate|web> --load` (arm64, needs `docker login dhi.io`).
24
+ Images are DHI bun Alpine and must stay small: pruned lockfile +
25
+ `--production --omit=peer`, prisma only in the `prisma` stage, system packages via
26
+ `apk add --root`. Kustomize manifests per app in `apps/*/kustomize`; the publish
27
+ workflow pins new `sha-*` tags into the prod overlays.
28
+
29
+ ## Rules
30
+
31
+ - Check the installed version (`package.json`, `bun.lock`) and use the docs for exactly
32
+ that version, not training knowledge.
33
+ - Superpowers skills (`.agents/plugins/marketplace.json`): `brainstorming` before
34
+ behavior-changing features, then `writing-plans`; `systematic-debugging` before bug
35
+ fixes; `test-driven-development` for app code; `requesting-code-review` for larger
36
+ changes; `verification-before-completion` before claiming done.
37
+ - After every TS/JS change, in the affected app: `bun run lint` (Oxlint, no ESLint),
38
+ `bun run lint:ts`, and the smallest relevant Vitest run (`bun run vitest run <path>`).
39
+ Visible web UI changes also need Playwright (`bun run test`) and browser verification;
40
+ api changes to external interfaces, DB or auth need the affected E2E tests.
41
+ - Touch `bun.lock` only with an intentional dependency change. Fix root causes; new
42
+ lint-disable comments need a narrow, documented reason.
@@ -0,0 +1,9 @@
1
+ ARG BUN_VERSION
2
+
3
+ FROM dhi.io/bun:${BUN_VERSION}-alpine-dev
4
+ ENV PATH="/root/.bun/bin:${PATH}"
5
+ WORKDIR /app
6
+ COPY package.json ./
7
+ RUN --mount=type=cache,id=bun-turbo-install,sharing=locked,target=/root/.bun/install/cache \
8
+ bun add -g turbo@$(bun -p 'require("./package.json").devDependencies.turbo')
9
+ COPY . .
@@ -0,0 +1,54 @@
1
+ # Nexst
2
+
3
+ Monorepo generated with `create-nexst-monorepo`:
4
+
5
+ - `apps/web` — Next.js frontend
6
+ - `apps/api` — NestJS backend (REST + GraphQL, Prisma)
7
+ - `apps/worker` — BullMQ worker <!-- @if worker -->
8
+
9
+ ## Getting started
10
+
11
+ ```bash
12
+ cp apps/api/.env.example apps/api/.env.development # fill in secrets
13
+ cp apps/web/.env.example apps/web/.env
14
+ <!-- @if worker -->
15
+ cp apps/worker/.env.example apps/worker/.env
16
+ <!-- @endif -->
17
+ bun install
18
+ (cd apps/api && bun run db:generate && bunx --bun prisma migrate deploy)
19
+ bun dev
20
+ ```
21
+
22
+ - Web: http://localhost:3000
23
+ - API: http://localhost:3001 (GraphiQL `/graphql`, Swagger `/api`, health `/health`)
24
+ <!-- @if auth -->
25
+ - Mail (MailHog): http://localhost:8025
26
+
27
+ Google sign-in (button + One Tap) stays hidden until it is configured: create an OAuth
28
+ client (type "Web application") in the Google Cloud console with the redirect URI
29
+ `http://localhost:3001/api/auth/callback/google` and the JavaScript origin
30
+ `http://localhost:3000`, then set `GOOGLE_CLIENT_ID`/`GOOGLE_CLIENT_SECRET` in
31
+ `apps/api/.env.development` and `NEXT_PUBLIC_GOOGLE_CLIENT_ID` in `apps/web/.env`.
32
+ <!-- @endif -->
33
+
34
+ ## Scripts (root, via turbo)
35
+
36
+ | Script | What it does |
37
+ | --- | --- |
38
+ | `bun dev` | Infra via docker compose + all apps in watch mode |
39
+ | `bun run lint` / `lint:fix` | Oxlint (type-aware) |
40
+ | `bun run fmt` / `fmt:check` | Oxfmt |
41
+ | `bun run lint:ts` | TypeScript (tsgo) |
42
+ | `bun run test:unit` | Vitest in every app |
43
+ | `bun run unused` | knip |
44
+
45
+ ## Deployment
46
+
47
+ - Images: `docker buildx bake` (targets in `docker-bake.hcl`), pushed to ghcr.io by
48
+ `.github/workflows/publish.yaml`, which also pins the new tags in
49
+ `apps/*/kustomize/overlays/prod`.
50
+ - Secrets: `apps/api/scripts/seal-secret.sh` seals the keys listed in
51
+ `apps/api/kustomize/secret.keys` into a SealedSecret.
52
+ - CI secrets: `DHI_REGISTRY_USERNAME`/`DHI_REGISTRY_PASSWORD` (image builds),
53
+ optional `SONAR_TOKEN`/`SONAR_HOST_URL`, `SNYK_TOKEN`. Repository variables
54
+ `NEXT_PUBLIC_API_URL`/`NEXT_PUBLIC_HOST_URL` are baked into the web image.
@@ -0,0 +1,10 @@
1
+ node_modules/
2
+ .DS_Store
3
+ .turbo/
4
+ *.tsbuildinfo
5
+ coverage/
6
+ dist/
7
+
8
+ # env
9
+ .env
10
+ .env.development
@@ -0,0 +1,32 @@
1
+ # Copy to .env.development (bun loads it automatically in dev) and fill in.
2
+ NODE_ENV=development
3
+ LOG_LEVEL=debug
4
+ PORT=3001
5
+
6
+ DATABASE_URL=postgresql://nexst_user:test-pw@localhost:5432/nexst_db?schema=nexst_user
7
+ # @if auth
8
+
9
+ # openssl rand -base64 32
10
+ BETTER_AUTH_SECRET=change-me-change-me-change-me-change-me
11
+ BETTER_AUTH_URL=http://localhost:3001
12
+ # Mail goes to MailHog (http://localhost:8025) outside production.
13
+ MAIL_SMTP_HOST=localhost
14
+ # RESEND_API_KEY=
15
+ # Google sign-in: OAuth client (Web application) from https://console.cloud.google.com/apis/credentials
16
+ # with redirect URI http://localhost:3001/api/auth/callback/google. Disabled while unset.
17
+ # GOOGLE_CLIENT_ID=
18
+ # GOOGLE_CLIENT_SECRET=
19
+ # @endif
20
+ # @if r2
21
+
22
+ R2_ACCESS_KEY_ID=
23
+ R2_SECRET_ACCESS_KEY=
24
+ R2_BUCKET=nexst
25
+ R2_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
26
+ # R2_PUBLIC_URL=https://cdn.example.com
27
+ # @endif
28
+ # @if worker
29
+
30
+ REDIS_HOST=localhost
31
+ REDIS_PORT=6379
32
+ # @endif
@@ -0,0 +1,44 @@
1
+ # api (NestJS)
2
+
3
+ This project uses NestJS 12 with ESM (`"type": "module"` in `package.json`,
4
+ `module`/`moduleResolution: nodenext` in `tsconfig.json`) — not the CommonJS setup most
5
+ NestJS tutorials, examples, and training data assume. Import paths, dynamic `import()`
6
+ usage, decorator/metadata behavior, and module interop can differ under ESM. When in
7
+ doubt, read the official NestJS documentation for the installed version
8
+ (`@nestjs/core` in `package.json`) rather than relying on memory.
9
+
10
+ ## Conventions
11
+
12
+ - Imports use the `#src/*` / `#tests/*` subpath aliases with a `.js` suffix.
13
+ - Prisma client always from `#src/generated/prisma/client.js` (`bun run db:generate`
14
+ after schema changes), never `@prisma/client`.
15
+ - Codes-only errors: throw `new AppException(ErrorCode.X, HttpStatus.Y, params?)`
16
+ (`src/errors/`), never a free-text `HttpException`. `bun run lint:error-codes` and
17
+ oxlint's `no-restricted-imports` enforce it; add new codes to `error-code.enum.ts`.
18
+ - Loggers: inject `ContextLogger`, not `nestjs-pino` directly.
19
+ - Config: static defaults in `src/config/resources/app.yaml`, secrets/env in
20
+ `src/config/app.config.ts` (zod-validated at startup).
21
+ - The global `ValidationPipe` runs with `whitelist: true`: every input field needs a
22
+ class-validator decorator (`@IsOptional()`/`@Allow()` for JSON fields) or it is
23
+ silently stripped.
24
+ - Auth (if present): every route needs a session unless marked `@AllowAnonymous()`;
25
+ `@IsEmailVerified()` and `@Roles(...)` are enforced by `src/auth/auth.guard.ts`.
26
+
27
+ ## Local dev
28
+
29
+ - Schema changes: `bun run db:migrate` (creates a migration) or `bun run db:push`
30
+ against the local dev Postgres (`DATABASE_URL` from `.env.development`).
31
+ - Swagger UI at `/api`, GraphiQL at `/graphql` when `NODE_ENV=development`.
32
+
33
+ ## Tests
34
+
35
+ - Unit: `bun run test:unit` (co-located `*.spec.ts`, no services needed).
36
+ - E2E: `bun run test:e2e` against a running API (`API_URL`, default
37
+ `http://localhost:3001`); start it with `NODE_ENV=test` so sign-up skips mail.
38
+
39
+ ## Docker image testing
40
+
41
+ Separate path, not the regular dev loop. Build with `docker buildx bake api --load`
42
+ (`api-migrate` for the migrator), then run it against the local infra from `bun dev`
43
+ (env from `.env`, `DATABASE_URL` pointing at `host.docker.internal`) and check
44
+ `/health` plus the container logs.
@@ -0,0 +1,69 @@
1
+ ARG BUN_VERSION
2
+
3
+ # ---------------------------------------------------
4
+ # Stage 1: Pruner
5
+ # ---------------------------------------------------
6
+ FROM toolchain AS pruner
7
+ RUN turbo prune @nexst/api --docker
8
+
9
+ # ---------------------------------------------------
10
+ # Stage 2: Deps
11
+ # ---------------------------------------------------
12
+ FROM dhi.io/bun:${BUN_VERSION}-alpine-dev AS deps
13
+ WORKDIR /app
14
+ COPY --from=pruner /app/out/json/ .
15
+ RUN --mount=type=cache,id=bun-install,sharing=locked,target=/root/.bun/install/cache \
16
+ bun install --frozen-lockfile --production --omit=peer
17
+
18
+ # ---------------------------------------------------
19
+ # Stage 3: Prisma
20
+ # ---------------------------------------------------
21
+ FROM dhi.io/bun:${BUN_VERSION}-alpine-dev AS prisma
22
+ WORKDIR /app/apps/api
23
+ RUN --mount=type=bind,from=pruner,source=/app/out/json/bun.lock,target=/tmp/bun.lock \
24
+ --mount=type=cache,id=bun-install,sharing=locked,target=/root/.bun/install/cache \
25
+ bun add --omit=peer $(bun -p 'require("/tmp/bun.lock").packages.prisma[0]') && \
26
+ find node_modules -path '*@prisma/engines/schema-engine-*' -type f | grep -q .
27
+ COPY --from=pruner /app/out/full/apps/api/prisma ./prisma
28
+ COPY --from=pruner /app/out/full/apps/api/prisma.config.ts ./
29
+
30
+ # ---------------------------------------------------
31
+ # Stage 4: Builder
32
+ # ---------------------------------------------------
33
+ FROM prisma AS builder
34
+ RUN --mount=type=bind,from=pruner,source=/app/out/json/bun.lock,target=/tmp/bun.lock \
35
+ --mount=type=cache,id=bun-install,sharing=locked,target=/root/.bun/install/cache \
36
+ bun add --omit=peer $(bun -p 'require("/tmp/bun.lock").packages["@prisma/client"][0]') && \
37
+ bunx --bun prisma generate
38
+
39
+ # ---------------------------------------------------
40
+ # Stage 5: Migrator
41
+ # ---------------------------------------------------
42
+ FROM prisma AS migrator
43
+ ENV NODE_ENV=production
44
+ USER nonroot
45
+ CMD ["bunx", "--bun", "prisma", "migrate", "deploy"]
46
+
47
+ # ---------------------------------------------------
48
+ # Stage 6: Runtime
49
+ # ---------------------------------------------------
50
+ FROM dhi.io/bun:${BUN_VERSION}-alpine AS runtime
51
+ WORKDIR /app
52
+ ENV NODE_ENV=production \
53
+ PRISMA_AUTO_MIGRATE=false
54
+
55
+ COPY --from=deps --chown=nonroot:nonroot /app/node_modules ./node_modules
56
+ COPY --from=deps --chown=nonroot:nonroot /app/apps/api/node_modules ./apps/api/node_modules
57
+ # @if worker
58
+ COPY --from=pruner --chown=nonroot:nonroot /app/out/full/packages/queues ./packages/queues
59
+ # @endif
60
+ COPY --from=pruner --chown=nonroot:nonroot /app/out/full/apps/api ./apps/api
61
+ COPY --from=builder --chown=nonroot:nonroot /app/apps/api/src/generated ./apps/api/src/generated
62
+
63
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=15s --retries=3 \
64
+ CMD ["bun", "-e", "require('http').get('http://localhost:3001/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) }).on('error', () => process.exit(1))"]
65
+
66
+ EXPOSE 3001
67
+ STOPSIGNAL SIGTERM
68
+ WORKDIR /app/apps/api
69
+ CMD ["bun", "src/main.ts"]
@@ -0,0 +1,8 @@
1
+ # tests
2
+ report.html
3
+
4
+ # prisma
5
+ src/generated
6
+
7
+ # sealed secrets
8
+ kustomize/sealedsecrets.pem
@@ -0,0 +1,22 @@
1
+ import { createKnipConfig } from "@nexst/lint/knip";
2
+ import type { KnipConfig } from "knip";
3
+
4
+ const config: KnipConfig = createKnipConfig({
5
+ entry: [
6
+ "prisma/schema.prisma",
7
+ "src/main.ts",
8
+ "scripts/auth.cli.ts", // @if auth
9
+ // Template building blocks, kept until the first feature uses them.
10
+ "src/auth/decorator/roles.decorator.ts", // @if auth
11
+ "src/errors/app-parse-uuid.pipe.ts",
12
+ "src/utils/pagination.input.ts",
13
+ ],
14
+ ignoreBinaries: [
15
+ "better-auth", // @if auth
16
+ ],
17
+ ignoreDependencies: ["@prisma/client-runtime-utils", "@types/js-yaml"],
18
+ project: ["prisma/**/*.prisma"],
19
+ vitest: { config: ["vitest.config.ts", "vitest.config.e2e.ts"] },
20
+ });
21
+
22
+ export default config;
@@ -0,0 +1,16 @@
1
+ NODE_ENV=production
2
+ LOG_LEVEL=info
3
+ PRISMA_AUTO_MIGRATE=false
4
+ # @if auth
5
+ BETTER_AUTH_URL=https://api.example.com
6
+ COOKIE_DOMAIN=.example.com
7
+ # GOOGLE_CLIENT_ID=<id>.apps.googleusercontent.com
8
+ # @endif
9
+ # @if worker
10
+ REDIS_HOST=redis-master
11
+ REDIS_PORT=6379
12
+ # @endif
13
+ # @if r2
14
+ R2_BUCKET=nexst
15
+ R2_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
16
+ # @endif
@@ -0,0 +1,94 @@
1
+ apiVersion: apps/v1
2
+ kind: Deployment
3
+ metadata:
4
+ name: nexst-api
5
+ spec:
6
+ replicas: 1
7
+ selector:
8
+ matchLabels:
9
+ app: nexst-api
10
+ template:
11
+ metadata:
12
+ labels:
13
+ app: nexst-api
14
+ spec:
15
+ securityContext:
16
+ runAsNonRoot: true
17
+ runAsUser: 10001
18
+ runAsGroup: 10001
19
+ fsGroup: 10001
20
+ seccompProfile:
21
+ type: RuntimeDefault
22
+ serviceAccountName: ghcr-puller
23
+ initContainers:
24
+ - name: db-migrate
25
+ image: nexst-api-migrate
26
+ imagePullPolicy: IfNotPresent
27
+ envFrom:
28
+ - configMapRef:
29
+ name: nexst-api-config
30
+ - secretRef:
31
+ name: nexst-api-secret
32
+ resources:
33
+ requests:
34
+ memory: 128Mi
35
+ cpu: 50m
36
+ limits:
37
+ memory: 256Mi
38
+ cpu: 200m
39
+ securityContext:
40
+ allowPrivilegeEscalation: false
41
+ runAsNonRoot: false
42
+ readOnlyRootFilesystem: false
43
+ capabilities:
44
+ drop: [ALL]
45
+ seccompProfile:
46
+ type: RuntimeDefault
47
+ containers:
48
+ - name: nexst-api
49
+ image: nexst-api
50
+ imagePullPolicy: IfNotPresent
51
+ ports:
52
+ - name: http
53
+ containerPort: 3001
54
+ protocol: TCP
55
+ securityContext:
56
+ allowPrivilegeEscalation: false
57
+ runAsNonRoot: true
58
+ runAsUser: 10001
59
+ runAsGroup: 10001
60
+ readOnlyRootFilesystem: true
61
+ capabilities:
62
+ drop: [ALL]
63
+ seccompProfile:
64
+ type: RuntimeDefault
65
+ envFrom:
66
+ - configMapRef:
67
+ name: nexst-api-config
68
+ - secretRef:
69
+ name: nexst-api-secret
70
+ volumeMounts:
71
+ - name: tmp
72
+ mountPath: /tmp
73
+ resources:
74
+ requests:
75
+ memory: 256Mi
76
+ cpu: 100m
77
+ limits:
78
+ memory: 512Mi
79
+ cpu: 500m
80
+ livenessProbe:
81
+ httpGet:
82
+ path: /health/live
83
+ port: http
84
+ initialDelaySeconds: 5
85
+ periodSeconds: 10
86
+ readinessProbe:
87
+ httpGet:
88
+ path: /health
89
+ port: http
90
+ initialDelaySeconds: 5
91
+ periodSeconds: 5
92
+ volumes:
93
+ - name: tmp
94
+ emptyDir: {}
@@ -0,0 +1,17 @@
1
+ labels:
2
+ - pairs:
3
+ app.kubernetes.io/name: nexst-api
4
+ app.kubernetes.io/part-of: nexst
5
+ app.kubernetes.io/managed-by: kustomize
6
+ app.kubernetes.io/created-by: your-org
7
+ app.kubernetes.io/component: api
8
+ includeSelectors: true
9
+
10
+ resources:
11
+ - deployment.yaml
12
+ - service.yaml
13
+
14
+ configMapGenerator:
15
+ - name: nexst-api-config
16
+ envs:
17
+ - application.properties
@@ -0,0 +1,10 @@
1
+ apiVersion: v1
2
+ kind: Service
3
+ metadata:
4
+ name: nexst-api
5
+ spec:
6
+ ports:
7
+ - name: http
8
+ port: 80
9
+ targetPort: 3001
10
+ protocol: TCP
@@ -0,0 +1,17 @@
1
+ apiVersion: kustomize.config.k8s.io/v1beta1
2
+ kind: Kustomization
3
+
4
+ resources:
5
+ - ../../base
6
+ # Generate with scripts/seal-secret.sh, then uncomment.
7
+ # - sealedsecret.yaml
8
+
9
+ namespace: nexst
10
+
11
+ images:
12
+ - name: nexst-api
13
+ newName: ghcr.io/your-org/nexst-api
14
+ newTag: latest
15
+ - name: nexst-api-migrate
16
+ newName: ghcr.io/your-org/nexst-api-migrate
17
+ newTag: latest
@@ -0,0 +1 @@
1
+ # Staging overrides for base/application.properties.
@@ -0,0 +1,21 @@
1
+ apiVersion: kustomize.config.k8s.io/v1beta1
2
+ kind: Kustomization
3
+
4
+ resources:
5
+ - ../../base
6
+
7
+ namespace: nexst-staging
8
+
9
+ images:
10
+ - name: nexst-api
11
+ newName: ghcr.io/your-org/nexst-api
12
+ newTag: test
13
+ - name: nexst-api-migrate
14
+ newName: ghcr.io/your-org/nexst-api-migrate
15
+ newTag: test
16
+
17
+ configMapGenerator:
18
+ - name: nexst-api-config
19
+ behavior: merge
20
+ envs:
21
+ - application.properties