@polymorphism-tech/morph-spec 3.2.0 → 4.2.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 (319) hide show
  1. package/CLAUDE.md +352 -7
  2. package/README.md +1 -14
  3. package/bin/detect-agents.js +1 -1
  4. package/bin/morph-spec.js +122 -34
  5. package/bin/validate.js +1 -1
  6. package/docs/getting-started.md +0 -5
  7. package/docs/v3.0/AGENTS.md +521 -0
  8. package/docs/v3.0/ANALYSIS.md +555 -0
  9. package/docs/v3.0/ARCHITECTURE.md +436 -0
  10. package/docs/v3.0/EXECUTION-FLOW.md +1304 -0
  11. package/docs/v3.0/FEATURES.md +688 -0
  12. package/docs/v3.0/README.md +231 -0
  13. package/docs/v3.0/ROADMAP.md +801 -0
  14. package/docs/validation-checklist.md +0 -1
  15. package/package.json +1 -1
  16. package/src/commands/agents/index.js +4 -0
  17. package/src/commands/{spawn-team.js → agents/spawn-team.js} +172 -172
  18. package/src/commands/{create-story.js → feature/create-story.js} +357 -354
  19. package/src/commands/feature/index.js +6 -0
  20. package/src/commands/{shard-spec.js → feature/shard-spec.js} +2 -2
  21. package/src/commands/{sprint-status.js → feature/sprint-status.js} +1 -1
  22. package/src/commands/{generate-context.js → generation/generate-context.js} +40 -40
  23. package/src/commands/{generate.js → generation/generate.js} +4 -4
  24. package/src/commands/generation/index.js +5 -0
  25. package/src/commands/index.js +16 -0
  26. package/src/commands/{capture-pattern.js → learning/capture-pattern.js} +121 -121
  27. package/src/commands/learning/index.js +5 -0
  28. package/src/commands/{detect-agents.js → project/detect-agents.js} +178 -178
  29. package/src/commands/project/detect-workflow.js +174 -0
  30. package/src/commands/{detect.js → project/detect.js} +104 -104
  31. package/src/commands/{doctor.js → project/doctor.js} +356 -356
  32. package/src/commands/project/index.js +10 -0
  33. package/src/commands/{init.js → project/init.js} +305 -295
  34. package/src/commands/{sync.js → project/sync.js} +167 -167
  35. package/src/commands/{update.js → project/update.js} +240 -240
  36. package/src/commands/{advance-phase.js → state/advance-phase.js} +416 -357
  37. package/src/commands/{approve.js → state/approve.js} +221 -221
  38. package/src/commands/state/index.js +8 -0
  39. package/src/commands/{rollback-phase.js → state/rollback-phase.js} +185 -185
  40. package/src/commands/{state.js → state/state.js} +334 -334
  41. package/src/commands/{validate-phase.js → state/validate-phase.js} +221 -221
  42. package/src/commands/tasks/index.js +4 -0
  43. package/src/commands/{task.js → tasks/task.js} +78 -78
  44. package/src/commands/templates/index.js +8 -0
  45. package/src/commands/templates/template-customize.js +101 -0
  46. package/src/commands/templates/template-list.js +128 -0
  47. package/src/commands/templates/template-render.js +95 -0
  48. package/src/commands/templates/template-show.js +131 -0
  49. package/src/commands/templates/template-validate.js +91 -0
  50. package/src/commands/utils/index.js +7 -0
  51. package/src/commands/{session-summary.js → utils/session-summary.js} +291 -291
  52. package/src/commands/{troubleshoot.js → utils/troubleshoot.js} +222 -222
  53. package/src/commands/{analyze-blazor-concurrency.js → validation/analyze-blazor-concurrency.js} +193 -193
  54. package/src/commands/validation/index.js +8 -0
  55. package/src/commands/{lint-fluent.js → validation/lint-fluent.js} +352 -352
  56. package/src/commands/{validate-blazor-state.js → validation/validate-blazor-state.js} +210 -210
  57. package/src/commands/{validate-blazor.js → validation/validate-blazor.js} +156 -156
  58. package/src/commands/{validate-css.js → validation/validate-css.js} +84 -84
  59. package/src/core/index.js +10 -0
  60. package/src/core/registry/command-registry.js +302 -0
  61. package/src/core/registry/index.js +8 -0
  62. package/src/core/registry/validator-registry.js +204 -0
  63. package/src/core/state/index.js +8 -0
  64. package/src/{lib → core/state}/phase-state-machine.js +214 -214
  65. package/src/{lib → core/state}/state-manager.js +572 -534
  66. package/src/core/templates/index.js +9 -0
  67. package/src/core/templates/template-registry.js +335 -0
  68. package/src/core/templates/template-renderer.js +477 -0
  69. package/src/core/templates/template-validator.js +296 -0
  70. package/src/core/workflows/index.js +7 -0
  71. package/src/core/workflows/workflow-detector.js +354 -0
  72. package/src/lib/{complexity-analyzer.js → analysis/complexity-analyzer.js} +441 -441
  73. package/src/lib/analysis/index.js +7 -0
  74. package/src/lib/{checkpoint-hooks.js → checkpoints/checkpoint-hooks.js} +258 -258
  75. package/src/lib/checkpoints/index.js +7 -0
  76. package/src/lib/detectors/config-detector.js +223 -223
  77. package/src/lib/detectors/conversation-analyzer.js +163 -163
  78. package/src/lib/{design-system-detector.js → detectors/design-system-detector.js} +187 -187
  79. package/src/lib/detectors/index.js +87 -84
  80. package/src/lib/detectors/standards-generator.js +275 -275
  81. package/src/lib/detectors/structure-detector.js +245 -245
  82. package/src/lib/{context-generator.js → generators/context-generator.js} +526 -516
  83. package/src/lib/generators/index.js +10 -0
  84. package/src/lib/{metadata-extractor.js → generators/metadata-extractor.js} +387 -380
  85. package/src/lib/{recap-generator.js → generators/recap-generator.js} +205 -205
  86. package/src/lib/learning/index.js +7 -0
  87. package/src/lib/orchestration/index.js +7 -0
  88. package/src/lib/{team-orchestrator.js → orchestration/team-orchestrator.js} +323 -323
  89. package/src/lib/stacks/index.js +7 -0
  90. package/src/lib/{stack-resolver.js → stacks/stack-resolver.js} +180 -148
  91. package/src/lib/standards/index.js +7 -0
  92. package/src/lib/{standards-context-injector.js → standards/standards-context-injector.js} +298 -288
  93. package/src/lib/troubleshooting/index.js +8 -0
  94. package/src/lib/{troubleshoot-grep.js → troubleshooting/troubleshoot-grep.js} +204 -204
  95. package/src/lib/{troubleshoot-index.js → troubleshooting/troubleshoot-index.js} +144 -144
  96. package/src/lib/validators/architecture/architecture-validator.js +387 -0
  97. package/src/lib/validators/architecture/index.js +7 -0
  98. package/src/lib/validators/architecture-validator.js +40 -367
  99. package/src/lib/{blazor-concurrency-analyzer.js → validators/blazor/blazor-concurrency-analyzer.js} +277 -288
  100. package/src/lib/{blazor-state-validator.js → validators/blazor/blazor-state-validator.js} +279 -291
  101. package/src/lib/{blazor-validator.js → validators/blazor/blazor-validator.js} +369 -374
  102. package/src/lib/validators/blazor/index.js +9 -0
  103. package/src/lib/validators/content/content-validator.js +351 -0
  104. package/src/lib/validators/content/index.js +7 -0
  105. package/src/lib/validators/content-validator.js +164 -351
  106. package/src/lib/validators/{contract-compliance-validator.js → contracts/contract-compliance-validator.js} +273 -273
  107. package/src/lib/validators/contracts/index.js +7 -0
  108. package/src/lib/{css-validator.js → validators/css/css-validator.js} +352 -352
  109. package/src/lib/validators/css/index.js +7 -0
  110. package/src/lib/validators/{design-system-validator.js → design-system/design-system-validator.js} +231 -231
  111. package/src/lib/validators/design-system/index.js +7 -0
  112. package/src/lib/validators/package-validator.js +41 -340
  113. package/src/lib/validators/packages/index.js +7 -0
  114. package/src/lib/validators/packages/package-validator.js +360 -0
  115. package/src/lib/validators/shared/index.js +12 -0
  116. package/src/lib/validators/shared/issue-counter.js +18 -0
  117. package/src/lib/validators/shared/result-formatter.js +124 -0
  118. package/src/lib/{spec-validator.js → validators/spec-validator.js} +258 -258
  119. package/src/lib/validators/ui/index.js +7 -0
  120. package/src/lib/validators/ui/ui-contrast-validator.js +422 -0
  121. package/src/lib/validators/ui-contrast-validator.js +31 -409
  122. package/src/lib/{validation-runner.js → validators/validation-runner.js} +286 -284
  123. package/src/ui/wizard-questions.js +0 -2
  124. package/src/utils/color-utils.js +70 -0
  125. package/src/utils/file-copier.js +188 -189
  126. package/src/utils/process-handler.js +97 -0
  127. package/stacks/blazor-azure/.claude/skills/level-2-domains/ai-agents/ai-system-architect.md +3 -3
  128. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/api-designer.md +59 -0
  129. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/dotnet-senior.md +45 -255
  130. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ef-modeler.md +33 -88
  131. package/stacks/blazor-azure/.claude/skills/level-2-domains/backend/ms-agent-expert.md +25 -89
  132. package/stacks/blazor-azure/.claude/skills/level-2-domains/integrations/hangfire-orchestrator.md +64 -0
  133. package/stacks/blazor-azure/.morph/config/agents.json +879 -764
  134. package/stacks/blazor-azure/.morph/hooks/{pre-commit-tests.sh → pre-commit/tests-csharp.sh} +3 -2
  135. package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/cd-prod.yml.hbs +41 -0
  136. package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/cd-staging.yml.hbs +24 -0
  137. package/stacks/blazor-azure/.morph/templates/infrastructure/github/workflows/ci-build.yml.hbs +23 -0
  138. package/stacks/nextjs-supabase/.claude/commands/morph-apply.md +221 -0
  139. package/stacks/nextjs-supabase/.claude/commands/morph-archive.md +79 -0
  140. package/stacks/nextjs-supabase/.claude/commands/morph-deploy.md +529 -0
  141. package/stacks/nextjs-supabase/.claude/commands/morph-infra.md +209 -0
  142. package/stacks/nextjs-supabase/.claude/commands/morph-preflight.md +227 -0
  143. package/stacks/nextjs-supabase/.claude/commands/morph-proposal.md +122 -0
  144. package/stacks/nextjs-supabase/.claude/commands/morph-status.md +86 -0
  145. package/stacks/nextjs-supabase/.claude/commands/morph-troubleshoot.md +122 -0
  146. package/stacks/nextjs-supabase/.claude/settings.local.json +6 -0
  147. package/stacks/nextjs-supabase/.claude/skills/level-2-domains/integrations/supabase-expert.md +30 -150
  148. package/stacks/nextjs-supabase/.morph/config/agents.json +345 -345
  149. package/stacks/nextjs-supabase/.morph/hooks/pre-commit/tests-typescript.sh +61 -0
  150. package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/cd-prod.yml.hbs +22 -0
  151. package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/cd-staging.yml.hbs +22 -0
  152. package/stacks/nextjs-supabase/.morph/templates/infrastructure/github/workflows/ci-build.yml.hbs +35 -0
  153. package/stacks/nextjs-supabase/README.md +6 -15
  154. package/bin/render-template.js +0 -349
  155. package/bin/semantic-detect-agents.js +0 -247
  156. package/bin/validate-agents-skills.js +0 -257
  157. package/bin/validate-agents.js +0 -70
  158. package/bin/validate-phase.js +0 -263
  159. package/docs/examples.md +0 -328
  160. package/scripts/reorganize-skills.cjs +0 -175
  161. package/scripts/validate-agents-structure.cjs +0 -52
  162. package/scripts/validate-skills.cjs +0 -180
  163. package/src/commands/deploy.js +0 -780
  164. package/src/lib/continuous-validator.js +0 -421
  165. package/src/lib/decision-constraint-loader.js +0 -109
  166. package/src/lib/design-system-scaffolder.js +0 -299
  167. package/src/lib/hook-executor.js +0 -257
  168. package/src/lib/mockup-generator.js +0 -366
  169. package/src/lib/ui-detector.js +0 -350
  170. package/src/llm/schema-validator.js +0 -121
  171. package/src/sanitizer/.gitkeep +0 -0
  172. package/src/scanner/.gitkeep +0 -0
  173. package/src/types/index.js +0 -477
  174. package/src/ui/.gitkeep +0 -0
  175. package/src/writer/.gitkeep +0 -0
  176. package/stacks/blazor-azure/.azure/README.md +0 -293
  177. package/stacks/blazor-azure/.azure/docs/azure-devops-setup.md +0 -454
  178. package/stacks/blazor-azure/.azure/docs/branch-strategy.md +0 -398
  179. package/stacks/blazor-azure/.azure/docs/local-development.md +0 -515
  180. package/stacks/blazor-azure/.azure/pipelines/pipeline-variables.yml +0 -34
  181. package/stacks/blazor-azure/.azure/pipelines/prod-pipeline.yml +0 -319
  182. package/stacks/blazor-azure/.azure/pipelines/staging-pipeline.yml +0 -234
  183. package/stacks/blazor-azure/.azure/pipelines/templates/build-dotnet.yml +0 -75
  184. package/stacks/blazor-azure/.azure/pipelines/templates/deploy-app-service.yml +0 -94
  185. package/stacks/blazor-azure/.azure/pipelines/templates/deploy-container-app.yml +0 -120
  186. package/stacks/blazor-azure/.azure/pipelines/templates/infra-deploy.yml +0 -90
  187. package/stacks/blazor-azure/.claude/settings.local.json +0 -15
  188. package/stacks/blazor-azure/.morph/docs/STORY-DRIVEN-DEVELOPMENT.md +0 -392
  189. package/stacks/blazor-azure/.morph/docs/workflows/design-impl.md +0 -37
  190. package/stacks/blazor-azure/.morph/docs/workflows/enforcement-pipeline.md +0 -668
  191. package/stacks/blazor-azure/.morph/docs/workflows/fast-track.md +0 -29
  192. package/stacks/blazor-azure/.morph/docs/workflows/full-morph.md +0 -76
  193. package/stacks/blazor-azure/.morph/docs/workflows/standard.md +0 -44
  194. package/stacks/blazor-azure/.morph/docs/workflows/ui-refresh.md +0 -39
  195. package/stacks/blazor-azure/.morph/examples/api-nextjs/README.md +0 -241
  196. package/stacks/blazor-azure/.morph/examples/api-nextjs/contracts.ts +0 -307
  197. package/stacks/blazor-azure/.morph/examples/api-nextjs/spec.md +0 -399
  198. package/stacks/blazor-azure/.morph/examples/api-nextjs/tasks.md +0 -168
  199. package/stacks/blazor-azure/.morph/examples/micro-saas/README.md +0 -125
  200. package/stacks/blazor-azure/.morph/examples/micro-saas/contracts.cs +0 -358
  201. package/stacks/blazor-azure/.morph/examples/micro-saas/decisions.md +0 -246
  202. package/stacks/blazor-azure/.morph/examples/micro-saas/spec.md +0 -236
  203. package/stacks/blazor-azure/.morph/examples/micro-saas/tasks.md +0 -150
  204. package/stacks/blazor-azure/.morph/examples/multi-agent/README.md +0 -309
  205. package/stacks/blazor-azure/.morph/examples/multi-agent/contracts.cs +0 -433
  206. package/stacks/blazor-azure/.morph/examples/multi-agent/spec.md +0 -479
  207. package/stacks/blazor-azure/.morph/examples/multi-agent/tasks.md +0 -185
  208. package/stacks/blazor-azure/.morph/examples/scheduled-reports/decisions.md +0 -158
  209. package/stacks/blazor-azure/.morph/examples/scheduled-reports/proposal.md +0 -95
  210. package/stacks/blazor-azure/.morph/examples/scheduled-reports/spec.md +0 -267
  211. package/stacks/blazor-azure/.morph/examples/state-v3.json +0 -188
  212. package/stacks/blazor-azure/.morph/hooks/README.md +0 -348
  213. package/stacks/blazor-azure/.morph/hooks/pre-commit-agents.sh +0 -24
  214. package/stacks/blazor-azure/.morph/hooks/pre-commit-all.sh +0 -48
  215. package/stacks/blazor-azure/.morph/hooks/pre-commit-specs.sh +0 -49
  216. package/stacks/blazor-azure/.morph/hooks/task-completed.js +0 -73
  217. package/stacks/blazor-azure/.morph/hooks/teammate-idle.js +0 -68
  218. package/stacks/blazor-azure/.morph/standards/agent-framework-blazor-ui.md +0 -359
  219. package/stacks/blazor-azure/.morph/standards/agent-framework-production.md +0 -410
  220. package/stacks/blazor-azure/.morph/standards/agent-framework-setup.md +0 -413
  221. package/stacks/blazor-azure/.morph/standards/agent-framework-workflows.md +0 -349
  222. package/stacks/blazor-azure/.morph/standards/agent-teams-workflow.md +0 -474
  223. package/stacks/blazor-azure/.morph/standards/architecture.md +0 -325
  224. package/stacks/blazor-azure/.morph/standards/azure.md +0 -605
  225. package/stacks/blazor-azure/.morph/standards/coding.md +0 -377
  226. package/stacks/blazor-azure/.morph/standards/dotnet10-migration.md +0 -520
  227. package/stacks/blazor-azure/.morph/standards/fluent-ui-setup.md +0 -590
  228. package/stacks/blazor-azure/.morph/standards/migration-guide.md +0 -514
  229. package/stacks/blazor-azure/.morph/standards/passkeys-auth.md +0 -423
  230. package/stacks/blazor-azure/.morph/standards/vector-search-rag.md +0 -536
  231. package/stacks/blazor-azure/.morph/templates/CONTEXT-FEATURE.md +0 -276
  232. package/stacks/blazor-azure/.morph/templates/CONTEXT.md +0 -170
  233. package/stacks/blazor-azure/.morph/templates/FluentDesignTheme.cs +0 -149
  234. package/stacks/blazor-azure/.morph/templates/MudTheme.cs +0 -281
  235. package/stacks/blazor-azure/.morph/templates/agent.cs +0 -163
  236. package/stacks/blazor-azure/.morph/templates/clarify-questions.md +0 -159
  237. package/stacks/blazor-azure/.morph/templates/component.razor +0 -239
  238. package/stacks/blazor-azure/.morph/templates/contracts/Commands.cs +0 -74
  239. package/stacks/blazor-azure/.morph/templates/contracts/Entities.cs +0 -25
  240. package/stacks/blazor-azure/.morph/templates/contracts/Queries.cs +0 -74
  241. package/stacks/blazor-azure/.morph/templates/contracts/README.md +0 -74
  242. package/stacks/blazor-azure/.morph/templates/contracts.cs +0 -217
  243. package/stacks/blazor-azure/.morph/templates/decisions.md +0 -123
  244. package/stacks/blazor-azure/.morph/templates/design-system.css +0 -226
  245. package/stacks/blazor-azure/.morph/templates/infra/.dockerignore.example +0 -89
  246. package/stacks/blazor-azure/.morph/templates/infra/Dockerfile.example +0 -82
  247. package/stacks/blazor-azure/.morph/templates/infra/README.md +0 -286
  248. package/stacks/blazor-azure/.morph/templates/infra/app-insights.bicep +0 -63
  249. package/stacks/blazor-azure/.morph/templates/infra/app-service.bicep +0 -164
  250. package/stacks/blazor-azure/.morph/templates/infra/azure-pipelines-deploy.yml +0 -480
  251. package/stacks/blazor-azure/.morph/templates/infra/container-app-env.bicep +0 -49
  252. package/stacks/blazor-azure/.morph/templates/infra/container-app.bicep +0 -156
  253. package/stacks/blazor-azure/.morph/templates/infra/deploy-checklist.md +0 -426
  254. package/stacks/blazor-azure/.morph/templates/infra/deploy.ps1 +0 -229
  255. package/stacks/blazor-azure/.morph/templates/infra/deploy.sh +0 -208
  256. package/stacks/blazor-azure/.morph/templates/infra/key-vault.bicep +0 -91
  257. package/stacks/blazor-azure/.morph/templates/infra/main.bicep +0 -189
  258. package/stacks/blazor-azure/.morph/templates/infra/parameters.dev.json +0 -29
  259. package/stacks/blazor-azure/.morph/templates/infra/parameters.prod.json +0 -29
  260. package/stacks/blazor-azure/.morph/templates/infra/parameters.staging.json +0 -29
  261. package/stacks/blazor-azure/.morph/templates/infra/sql-database.bicep +0 -103
  262. package/stacks/blazor-azure/.morph/templates/infra/storage.bicep +0 -106
  263. package/stacks/blazor-azure/.morph/templates/integrations/asaas-client.cs +0 -387
  264. package/stacks/blazor-azure/.morph/templates/integrations/asaas-webhook.cs +0 -351
  265. package/stacks/blazor-azure/.morph/templates/integrations/azure-identity-config.cs +0 -288
  266. package/stacks/blazor-azure/.morph/templates/integrations/clerk-config.cs +0 -258
  267. package/stacks/blazor-azure/.morph/templates/job.cs +0 -171
  268. package/stacks/blazor-azure/.morph/templates/migration.cs +0 -83
  269. package/stacks/blazor-azure/.morph/templates/proposal.md +0 -141
  270. package/stacks/blazor-azure/.morph/templates/recap.md +0 -94
  271. package/stacks/blazor-azure/.morph/templates/repository.cs +0 -141
  272. package/stacks/blazor-azure/.morph/templates/saas/subscription.cs +0 -347
  273. package/stacks/blazor-azure/.morph/templates/saas/tenant.cs +0 -338
  274. package/stacks/blazor-azure/.morph/templates/service.cs +0 -139
  275. package/stacks/blazor-azure/.morph/templates/simulation.md +0 -353
  276. package/stacks/blazor-azure/.morph/templates/spec.md +0 -149
  277. package/stacks/blazor-azure/.morph/templates/sprint-status.yaml +0 -68
  278. package/stacks/blazor-azure/.morph/templates/state.template.json +0 -222
  279. package/stacks/blazor-azure/.morph/templates/story.md +0 -143
  280. package/stacks/blazor-azure/.morph/templates/tasks.md +0 -257
  281. package/stacks/blazor-azure/.morph/templates/test.cs +0 -239
  282. package/stacks/blazor-azure/.morph/templates/ui-components.md +0 -362
  283. package/stacks/blazor-azure/.morph/templates/ui-design-system.md +0 -286
  284. package/stacks/blazor-azure/.morph/templates/ui-flows.md +0 -336
  285. package/stacks/blazor-azure/.morph/templates/ui-mockups.md +0 -133
  286. package/stacks/nextjs-supabase/.morph/docs/easypanel-setup.md +0 -169
  287. package/stacks/nextjs-supabase/.morph/docs/supabase-mcp-setup.md +0 -247
  288. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/README.md +0 -697
  289. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/spec.md +0 -85
  290. package/stacks/nextjs-supabase/.morph/examples/crud-nextjs-supabase/tasks.md +0 -86
  291. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/README.md +0 -498
  292. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/decisions.md +0 -121
  293. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/spec.md +0 -138
  294. package/stacks/nextjs-supabase/.morph/examples/saas-nextjs-supabase/tasks.md +0 -162
  295. package/stacks/nextjs-supabase/.morph/standards/easypanel-deploy.md +0 -191
  296. package/stacks/nextjs-supabase/.morph/standards/nextjs-patterns.md +0 -193
  297. package/stacks/nextjs-supabase/.morph/standards/supabase-auth.md +0 -171
  298. package/stacks/nextjs-supabase/.morph/standards/supabase-pgvector.md +0 -164
  299. package/stacks/nextjs-supabase/.morph/standards/supabase-rls.md +0 -179
  300. package/stacks/nextjs-supabase/.morph/standards/supabase-storage.md +0 -148
  301. package/stacks/nextjs-supabase/.morph/templates/contracts.cs +0 -173
  302. package/stacks/nextjs-supabase/.morph/templates/contracts.ts +0 -168
  303. package/stacks/nextjs-supabase/.morph/templates/decisions.md +0 -115
  304. package/stacks/nextjs-supabase/.morph/templates/dockerfile-api.dockerfile +0 -38
  305. package/stacks/nextjs-supabase/.morph/templates/dockerfile-web.dockerfile +0 -48
  306. package/stacks/nextjs-supabase/.morph/templates/proposal.md +0 -145
  307. package/stacks/nextjs-supabase/.morph/templates/recap.md +0 -134
  308. package/stacks/nextjs-supabase/.morph/templates/rls-policy.sql +0 -57
  309. package/stacks/nextjs-supabase/.morph/templates/spec.md +0 -231
  310. package/stacks/nextjs-supabase/.morph/templates/supabase-migration.sql +0 -100
  311. package/stacks/nextjs-supabase/.morph/templates/tasks.md +0 -257
  312. /package/src/commands/{search-patterns.js → learning/search-patterns.js} +0 -0
  313. /package/src/commands/{migrate-state.js → utils/migrate-state.js} +0 -0
  314. /package/src/commands/{upgrade.js → utils/upgrade.js} +0 -0
  315. /package/src/{lib → core/templates}/template-data-sources.js +0 -0
  316. /package/src/lib/{design-system-generator.js → generators/design-system-generator.js} +0 -0
  317. /package/src/lib/{learning-system.js → learning/learning-system.js} +0 -0
  318. /package/{src/generator → stacks/blazor-azure/.morph/templates}/.gitkeep +0 -0
  319. /package/{src/llm → stacks/nextjs-supabase/.morph/templates}/.gitkeep +0 -0
@@ -1,121 +0,0 @@
1
- # Multi-Tenant SaaS - Architectural Decision Records
2
-
3
- ## ADR-001: RLS-Based Tenant Isolation vs Schema-Per-Tenant
4
-
5
- **Status**: Accepted
6
-
7
- **Context**: Choose a multi-tenancy strategy for data isolation. The two main approaches are (a) shared database with Row Level Security filtering by tenant_id, and (b) separate PostgreSQL schema per tenant.
8
-
9
- **Decision**: RLS-based tenant isolation with a single shared schema.
10
-
11
- **Rationale**:
12
- - Supabase natively supports RLS with built-in functions like `auth.uid()` and custom JWT claims
13
- - Single schema simplifies migrations (one migration applies to all tenants)
14
- - More cost-effective: one Supabase project serves all tenants
15
- - Scales well to thousands of small-to-medium tenants
16
- - Custom JWT claim `app_metadata.tenant_id` provides tenant context automatically
17
-
18
- **Alternatives Considered**:
19
- - Schema-per-tenant: Better isolation but Supabase does not natively manage multiple schemas per project. Migration management becomes complex. Operational overhead grows linearly with tenant count.
20
- - Database-per-tenant: Maximum isolation but requires separate Supabase projects. Cost-prohibitive ($25/tenant/month on Pro).
21
-
22
- **Consequences**:
23
- - All queries must include tenant_id (enforced by RLS, not application code)
24
- - Careful attention needed for admin/service-role queries that bypass RLS
25
- - Bulk data export for a single tenant requires explicit filtering
26
- - Index strategy must account for tenant_id prefix on all key queries
27
-
28
- ---
29
-
30
- ## ADR-002: Stripe for Subscription Billing
31
-
32
- **Status**: Accepted
33
-
34
- **Context**: Choose a billing provider for SaaS subscription management.
35
-
36
- **Decision**: Stripe Billing with Checkout Sessions and Customer Portal.
37
-
38
- **Rationale**:
39
- - Industry standard for SaaS billing with mature subscription lifecycle management
40
- - Stripe Checkout handles PCI compliance (no card data on our servers)
41
- - Customer Portal lets users self-manage subscriptions, reducing support burden
42
- - Webhook-driven architecture integrates cleanly with our event-based approach
43
- - Extensive test mode for development without real charges
44
- - Global reach with support for 135+ currencies
45
-
46
- **Alternatives Considered**:
47
- - Paddle: Simpler tax handling (Merchant of Record) but less customization and higher fees
48
- - LemonSqueezy: Good for indie hackers but less mature API and limited webhook events
49
- - Custom implementation: Too complex for MVP, PCI compliance burden
50
-
51
- **Consequences**:
52
- - Stripe fees: 2.9% + $0.30 per transaction
53
- - Webhook handler must be idempotent (Stripe retries on failure)
54
- - Subscription state must be synced between Stripe and our database
55
- - Need to handle edge cases: failed payments, plan changes mid-cycle, proration
56
-
57
- ---
58
-
59
- ## ADR-003: pgvector for AI-Powered Search
60
-
61
- **Status**: Accepted
62
-
63
- **Context**: Choose a vector storage and similarity search solution for semantic document search.
64
-
65
- **Decision**: pgvector extension on Supabase PostgreSQL.
66
-
67
- **Rationale**:
68
- - Native PostgreSQL extension, no additional infrastructure needed
69
- - Supabase Pro includes pgvector out of the box
70
- - Keeps vectors co-located with tenant data (RLS applies to vector queries too)
71
- - IVFFlat index provides good performance up to ~1M vectors per tenant
72
- - Cosine similarity search with SQL-native syntax
73
- - No vendor lock-in to proprietary vector databases
74
-
75
- **Alternatives Considered**:
76
- - Pinecone: Better performance at scale but adds another service, separate billing, and no native tenant isolation (would need namespace-per-tenant)
77
- - Qdrant: Open source and performant but requires self-hosting another service
78
- - Supabase Edge Functions + Pinecone: Adds latency and complexity for the AI path
79
-
80
- **Consequences**:
81
- - Embedding dimension fixed at 1536 (text-embedding-3-small). Changing models requires re-embedding all documents
82
- - IVFFlat index requires periodic `REINDEX` as data grows significantly
83
- - For >1M documents per tenant, consider HNSW index (higher memory, faster queries)
84
- - OpenAI API call required for each search query (adds ~200ms latency)
85
-
86
- ---
87
-
88
- ## ADR-004: Custom JWT Claims for Tenant Context
89
-
90
- **Status**: Accepted
91
-
92
- **Context**: Determine how to pass tenant context through the authentication flow so that RLS policies and API endpoints can identify the current tenant.
93
-
94
- **Decision**: Store `tenant_id` in Supabase Auth `app_metadata`, which is included in the JWT automatically.
95
-
96
- **Rationale**:
97
- - Supabase Auth includes `app_metadata` in every JWT token by default
98
- - No additional API calls needed to resolve tenant context
99
- - RLS policies can read `request.jwt.claims -> 'app_metadata' -> 'tenant_id'`
100
- - .NET API can extract tenant_id from JWT claims without database lookup
101
- - Set via database trigger when user joins a tenant (no application code needed for claim updates)
102
-
103
- **Alternatives Considered**:
104
- - Header-based (`X-Tenant-ID`): Requires client to send header on every request, vulnerable to spoofing unless validated server-side
105
- - Subdomain-based: Good UX but requires wildcard DNS, SSL, and URL parsing on every request. Supabase Auth redirect URLs become complex.
106
- - Database lookup per request: Adds latency and database load to every authenticated request
107
-
108
- **Implementation**:
109
- - Trigger on `tenant_members` INSERT sets `raw_app_meta_data.tenant_id`
110
- - User must re-authenticate (or refresh token) after joining a tenant to get updated claims
111
- - Multi-tenant users: current implementation supports one active tenant per session. Switching tenants requires token refresh.
112
-
113
- **Consequences**:
114
- - Token refresh needed when user switches tenants
115
- - app_metadata is read-only from client side (only service_role can modify)
116
- - JWT size increases slightly (~50 bytes for tenant_id claim)
117
- - Users without a tenant_id claim are redirected to onboarding
118
-
119
- ---
120
-
121
- *MORPH-SPEC by Polymorphism Tech*
@@ -1,138 +0,0 @@
1
- # Multi-Tenant SaaS - Specification
2
-
3
- ## 1. Overview
4
-
5
- Multi-tenant SaaS platform with tenant isolation via PostgreSQL RLS, Stripe subscription billing, team management, and AI-powered semantic search using pgvector.
6
-
7
- ### 1.1 Objectives
8
-
9
- - Tenant isolation at the database level via RLS with custom JWT claims
10
- - Subscription billing with Stripe (free, starter, pro tiers)
11
- - Team management with invite flows and role-based access
12
- - AI-powered document search using OpenAI embeddings + pgvector
13
- - Dashboard with tenant-scoped metrics and usage tracking
14
-
15
- ### 1.2 Personas
16
-
17
- | Persona | Description |
18
- |---------|-------------|
19
- | **Tenant Owner** | Creates tenant, manages billing and team |
20
- | **Tenant Admin** | Manages team members and settings |
21
- | **Tenant Member** | Uses the platform (documents, search) |
22
- | **Platform Admin** | Super admin with cross-tenant visibility |
23
-
24
- ## 2. Functional Requirements
25
-
26
- ### 2.1 Tenant Management
27
-
28
- | ID | Requirement |
29
- |----|-------------|
30
- | TEN-001 | Create tenant during onboarding (name, slug) |
31
- | TEN-002 | Tenant slug used for identification (unique) |
32
- | TEN-003 | Tenant settings page (name, logo) |
33
- | TEN-004 | Tenant status lifecycle: active, past_due, suspended |
34
- | TEN-005 | tenant_id stored in Supabase Auth app_metadata for JWT claims |
35
-
36
- ### 2.2 Billing (Stripe)
37
-
38
- | ID | Requirement |
39
- |----|-------------|
40
- | BILL-001 | Plans: Free, Starter ($29/mo), Pro ($79/mo) |
41
- | BILL-002 | Stripe Checkout for subscription creation |
42
- | BILL-003 | Stripe Customer Portal for plan management |
43
- | BILL-004 | Webhook handling: subscription.created, updated, deleted |
44
- | BILL-005 | Webhook handling: invoice.payment_failed |
45
- | BILL-006 | Grace period of 7 days on payment failure before suspension |
46
-
47
- ### 2.3 Team Management
48
-
49
- | ID | Requirement |
50
- |----|-------------|
51
- | TEAM-001 | Invite members by email |
52
- | TEAM-002 | Roles: owner, admin, member |
53
- | TEAM-003 | Owner can promote/demote members |
54
- | TEAM-004 | Admin can invite and remove members |
55
- | TEAM-005 | Member limits per plan (Free: 2, Starter: 5, Pro: 25) |
56
-
57
- ### 2.4 AI Search (pgvector)
58
-
59
- | ID | Requirement |
60
- |----|-------------|
61
- | SEARCH-001 | Upload documents with automatic embedding generation |
62
- | SEARCH-002 | Semantic search across tenant documents |
63
- | SEARCH-003 | Configurable similarity threshold (default 0.7) |
64
- | SEARCH-004 | Search results ranked by cosine similarity |
65
- | SEARCH-005 | Search quota per plan (Free: 100/mo, Starter: 1K/mo, Pro: 10K/mo) |
66
-
67
- ### 2.5 Dashboard
68
-
69
- | ID | Requirement |
70
- |----|-------------|
71
- | DASH-001 | Overview: total documents, team size, storage used, plan |
72
- | DASH-002 | Search usage counter (monthly resets) |
73
- | DASH-003 | Quick actions: invite member, upload document, search |
74
- | DASH-004 | Billing status and upgrade prompt |
75
-
76
- ## 3. Non-Functional Requirements
77
-
78
- ### 3.1 Performance
79
-
80
- | ID | Requirement |
81
- |----|-------------|
82
- | PERF-001 | API response < 200ms (P95) for CRUD endpoints |
83
- | PERF-002 | Semantic search < 500ms (P95) for 100K documents |
84
- | PERF-003 | pgvector IVFFlat index for sub-linear search time |
85
-
86
- ### 3.2 Security
87
-
88
- | ID | Requirement |
89
- |----|-------------|
90
- | SEC-001 | RLS enforced on all tenant-scoped tables |
91
- | SEC-002 | Stripe webhook signature validation |
92
- | SEC-003 | Service role key never exposed to frontend |
93
- | SEC-004 | Rate limiting per tenant (not per user) |
94
- | SEC-005 | Audit log for team management actions |
95
-
96
- ### 3.3 Data Isolation
97
-
98
- | ID | Requirement |
99
- |----|-------------|
100
- | ISO-001 | Single database with tenant_id column on all data tables |
101
- | ISO-002 | RLS policies read tenant_id from JWT app_metadata |
102
- | ISO-003 | No cross-tenant data leakage (validated by tests) |
103
-
104
- ## 4. Plans and Limits
105
-
106
- | Feature | Free | Starter | Pro |
107
- |---------|------|---------|-----|
108
- | Team Members | 2 | 5 | 25 |
109
- | Documents | 100 | 1,000 | 10,000 |
110
- | Storage | 100MB | 1GB | 10GB |
111
- | Searches/month | 100 | 1,000 | 10,000 |
112
- | Support | Community | Email | Priority |
113
- | Price/month | $0 | $29 | $79 |
114
-
115
- ## 5. Integrations
116
-
117
- ### 5.1 Stripe
118
-
119
- - Customer management (one customer per tenant)
120
- - Subscription lifecycle
121
- - Checkout sessions and Customer Portal
122
- - Webhook handling for payment events
123
-
124
- ### 5.2 OpenAI
125
-
126
- - text-embedding-3-small for document embeddings (1536 dimensions)
127
- - Called server-side only (API key never on frontend)
128
-
129
- ### 5.3 Supabase
130
-
131
- - Auth with custom claims (tenant_id in app_metadata)
132
- - PostgreSQL with RLS for tenant isolation
133
- - pgvector extension for similarity search
134
- - Storage for document files (per-tenant buckets)
135
-
136
- ---
137
-
138
- *MORPH-SPEC by Polymorphism Tech*
@@ -1,162 +0,0 @@
1
- # Multi-Tenant SaaS - Tasks
2
-
3
- ## Phase 1: Supabase Setup
4
-
5
- | ID | Task | Dependencies | Estimate |
6
- |----|------|--------------|----------|
7
- | T001 | Create Supabase Pro project with pgvector extension enabled | - | S |
8
- | T002 | Create tenants table and tenant_members table with RLS policies | T001 | M |
9
- | T003 | Create auth.tenant_id() helper function for RLS | T001 | S |
10
- | T004 | Create trigger to set app_metadata.tenant_id on tenant_members INSERT | T002 | M |
11
-
12
- ## Phase 2: Tenant Data Model
13
-
14
- | ID | Task | Dependencies | Estimate |
15
- |----|------|--------------|----------|
16
- | T005 | Create documents table with tenant_id, embedding column (vector 1536), and RLS | T003 | M |
17
- | T006 | Create IVFFlat index on documents.embedding for cosine similarity search | T005 | S |
18
- | T007 | Create search_logs table for usage tracking (searches per month per tenant) | T003 | S |
19
- | T008 | Create Supabase Storage bucket with per-tenant folder policies | T001 | S |
20
-
21
- ## Phase 3: .NET API Core
22
-
23
- | ID | Task | Dependencies | Estimate |
24
- |----|------|--------------|----------|
25
- | T009 | Create .NET 10 Minimal API project with Dapper, Npgsql, Stripe.net | - | S |
26
- | T010 | Configure JWT authentication with Supabase JWT secret and tenant_id claim extraction | T001, T009 | M |
27
- | T011 | Create TenantMiddleware to extract and validate tenant_id from JWT claims | T010 | M |
28
- | T012 | Configure CORS and health check endpoints | T009 | S |
29
-
30
- ## Phase 4: Stripe Billing Integration
31
-
32
- | ID | Task | Dependencies | Estimate |
33
- |----|------|--------------|----------|
34
- | T013 | Create Stripe products and prices (Free, Starter $29, Pro $79) in Stripe Dashboard | - | S |
35
- | T014 | Implement CreateCheckoutSession endpoint (creates Stripe customer + checkout) | T009, T013 | M |
36
- | T015 | Implement Stripe Customer Portal endpoint for subscription management | T014 | S |
37
- | T016 | Implement Stripe webhook handler (subscription.created/updated/deleted, invoice.payment_failed) | T009, T013 | L |
38
- | T017 | Add plan enforcement middleware (check limits: members, documents, searches) | T016 | M |
39
-
40
- ## Phase 5: Team Management Endpoints
41
-
42
- | ID | Task | Dependencies | Estimate |
43
- |----|------|--------------|----------|
44
- | T018 | Implement invite member endpoint (create tenant_member, trigger claim update) | T011 | M |
45
- | T019 | Implement list members, update role, remove member endpoints | T011 | M |
46
- | T020 | Add member count validation against plan limits | T017 | S |
47
-
48
- ## Phase 6: AI Search Endpoints
49
-
50
- | ID | Task | Dependencies | Estimate |
51
- |----|------|--------------|----------|
52
- | T021 | Implement document upload endpoint with OpenAI embedding generation | T005, T011 | L |
53
- | T022 | Implement semantic search endpoint with pgvector cosine similarity | T006, T011 | M |
54
- | T023 | Implement search quota tracking and enforcement per plan | T007, T017 | M |
55
-
56
- ## Phase 7: Dashboard Endpoint
57
-
58
- | ID | Task | Dependencies | Estimate |
59
- |----|------|--------------|----------|
60
- | T024 | Implement dashboard metrics endpoint (documents, members, storage, plan, searches) | T011 | M |
61
-
62
- ## Phase 8: Next.js Frontend Core
63
-
64
- | ID | Task | Dependencies | Estimate |
65
- |----|------|--------------|----------|
66
- | T025 | Create Next.js 15 project with Tailwind CSS, @supabase/ssr | - | S |
67
- | T026 | Implement Supabase client (browser) and server client with cookie handling | T025, T001 | M |
68
- | T027 | Create login/signup pages with Supabase Auth | T026 | M |
69
- | T028 | Create auth callback route and Next.js middleware for protected routes | T026 | M |
70
- | T029 | Create onboarding page (create tenant for new users without tenant_id) | T026 | M |
71
-
72
- ## Phase 9: Next.js Dashboard Pages
73
-
74
- | ID | Task | Dependencies | Estimate |
75
- |----|------|--------------|----------|
76
- | T030 | Create TenantProvider context component (reads tenant from session) | T028 | M |
77
- | T031 | Create dashboard layout with sidebar navigation | T030 | M |
78
- | T032 | Create dashboard overview page with metric cards | T024, T031 | M |
79
- | T033 | Create documents page (list, upload, delete) | T021, T031 | M |
80
- | T034 | Create search page with query input and ranked results | T022, T031 | M |
81
-
82
- ## Phase 10: Team and Billing Pages
83
-
84
- | ID | Task | Dependencies | Estimate |
85
- |----|------|--------------|----------|
86
- | T035 | Create team management page (list members, invite, remove, change role) | T018, T031 | M |
87
- | T036 | Create billing page (current plan, upgrade button, Stripe Portal link) | T014, T031 | M |
88
- | T037 | Create settings page (tenant name, logo) | T031 | S |
89
-
90
- ## Phase 11: Docker and Deploy
91
-
92
- | ID | Task | Dependencies | Estimate |
93
- |----|------|--------------|----------|
94
- | T038 | Create Dockerfile.api (multi-stage .NET build) | T024 | S |
95
- | T039 | Create Dockerfile.web (Next.js standalone output) | T037 | S |
96
- | T040 | Create docker-compose.yml for local development | T038, T039 | S |
97
- | T041 | Configure EasyPanel services (API + Web) with env vars and health checks | T040 | M |
98
-
99
- ## Phase 12: Testing and Validation
100
-
101
- | ID | Task | Dependencies | Estimate |
102
- |----|------|--------------|----------|
103
- | T042 | Write RLS isolation tests (verify no cross-tenant data leakage) | T005 | M |
104
- | T043 | Write Stripe webhook handler tests (idempotency, signature validation) | T016 | M |
105
- | T044 | Write search endpoint tests (embedding, similarity threshold, quota) | T022 | M |
106
-
107
- ## Checkpoints
108
-
109
- | Checkpoint | After Tasks | Validation |
110
- |------------|-------------|------------|
111
- | CP1 | T004 | Supabase tenant setup complete, auth claims working |
112
- | CP2 | T008 | Full data model with RLS, pgvector, and storage |
113
- | CP3 | T012 | API skeleton with JWT auth and tenant middleware |
114
- | CP4 | T017 | Stripe billing fully integrated with webhooks |
115
- | CP5 | T020 | Team management working with plan limits |
116
- | CP6 | T024 | All API endpoints complete (search, dashboard, team, billing) |
117
- | CP7 | T029 | Auth flow complete (login, signup, onboarding, protected routes) |
118
- | CP8 | T037 | All frontend pages complete |
119
- | CP9 | T041 | Docker setup and EasyPanel deployment ready |
120
- | CP10 | T044 | All tests passing, no cross-tenant leakage |
121
-
122
- ## Legend
123
-
124
- - **S** = Small (< 1h)
125
- - **M** = Medium (1-3h)
126
- - **L** = Large (3-8h)
127
-
128
- ## Execution Order
129
-
130
- ```
131
- Supabase Setup (independent):
132
- T001 -> T002 -> T003 -> T004 (CP1)
133
- T005 -> T006 -> T007 -> T008 (CP2)
134
-
135
- API Core (after T001):
136
- T009 -> T010 -> T011 -> T012 (CP3)
137
-
138
- Billing (after API core):
139
- T013 -> T014 -> T015 -> T016 -> T017 (CP4)
140
-
141
- Team + Search + Dashboard (after billing):
142
- T018 -> T019 -> T020 (CP5)
143
- T021 -> T022 -> T023
144
- T024 (CP6)
145
-
146
- Frontend (after T001):
147
- T025 -> T026 -> T027 -> T028 -> T029 (CP7)
148
-
149
- Frontend Pages (after API + auth):
150
- T030 -> T031 -> T032 -> T033 -> T034
151
- T035 -> T036 -> T037 (CP8)
152
-
153
- Deploy:
154
- T038 -> T039 -> T040 -> T041 (CP9)
155
-
156
- Tests:
157
- T042 -> T043 -> T044 (CP10)
158
- ```
159
-
160
- ---
161
-
162
- *MORPH-SPEC by Polymorphism Tech*
@@ -1,191 +0,0 @@
1
- # EasyPanel Deployment Standard
2
-
3
- > Stack: Next.js 15 + Supabase + .NET Backend
4
-
5
- ## Core Rules
6
-
7
- - ALWAYS use multi-stage Docker builds for minimal image size
8
- - ALWAYS configure health checks for zero-downtime deploys
9
- - NEVER hardcode secrets in Dockerfiles -- use EasyPanel environment variables
10
- - ALWAYS use `.dockerignore` to exclude node_modules, .git, .env files
11
- - SSL is automatic via Let's Encrypt -- no manual certificate management
12
-
13
- ## .NET 10 Dockerfile
14
-
15
- ```dockerfile
16
- FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
17
- WORKDIR /src
18
- COPY *.csproj .
19
- RUN dotnet restore
20
- COPY . .
21
- RUN dotnet publish -c Release -o /app/publish --no-restore
22
-
23
- FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
24
- WORKDIR /app
25
- RUN adduser --disabled-password --gecos "" appuser
26
- USER appuser
27
- COPY --from=build /app/publish .
28
- ENV ASPNETCORE_URLS=http://+:8080
29
- EXPOSE 8080
30
- HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
31
- CMD curl -f http://localhost:8080/health || exit 1
32
- ENTRYPOINT ["dotnet", "MyApp.Api.dll"]
33
- ```
34
-
35
- ## Next.js Standalone Dockerfile
36
-
37
- ```dockerfile
38
- FROM node:22-alpine AS base
39
-
40
- FROM base AS builder
41
- WORKDIR /app
42
- COPY package.json package-lock.json ./
43
- RUN npm ci
44
- COPY . .
45
- ENV NEXT_TELEMETRY_DISABLED=1
46
- RUN npm run build
47
-
48
- FROM base AS runner
49
- WORKDIR /app
50
- ENV NODE_ENV=production NEXT_TELEMETRY_DISABLED=1
51
- RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs
52
- COPY --from=builder /app/public ./public
53
- COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
54
- COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
55
- USER nextjs
56
- EXPOSE 3000
57
- ENV PORT=3000 HOSTNAME="0.0.0.0"
58
- HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
59
- CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
60
- CMD ["node", "server.js"]
61
- ```
62
-
63
- Required: `output: "standalone"` in `next.config.ts`.
64
-
65
- ## .dockerignore
66
-
67
- ```
68
- node_modules
69
- .next
70
- .git
71
- .env*
72
- *.md
73
- .vscode
74
- coverage
75
- test
76
- __tests__
77
- ```
78
-
79
- ## EasyPanel Service Config
80
-
81
- | Setting | .NET Backend | Next.js Frontend |
82
- |---------|-------------|-----------------|
83
- | Source | GitHub | GitHub |
84
- | Build method | Dockerfile | Dockerfile |
85
- | Dockerfile path | `./backend/Dockerfile` | `./frontend/Dockerfile` |
86
- | Port | 8080 | 3000 |
87
- | Domain | api.example.com | app.example.com |
88
-
89
- ### GitHub Integration
90
-
91
- 1. Generate GitHub PAT with `repo` scope
92
- 2. EasyPanel: Settings > GitHub > Add token
93
- 3. Select repository and branch
94
- 4. Enable "Auto Deploy" for webhook-triggered deploys
95
-
96
- ### Domain and SSL
97
-
98
- DNS setup (CNAME to EasyPanel server):
99
- ```
100
- app.example.com CNAME your-server.easypanel.host
101
- api.example.com CNAME your-server.easypanel.host
102
- ```
103
-
104
- SSL via Let's Encrypt is automatic. Force HTTPS enabled by default.
105
-
106
- ## Environment Variables
107
-
108
- ### .NET Backend
109
-
110
- ```env
111
- ASPNETCORE_ENVIRONMENT=Production
112
- ASPNETCORE_URLS=http://+:8080
113
- ConnectionStrings__DefaultConnection=Host=...;Database=...;Username=...;Password=...
114
- Supabase__Url=https://xxx.supabase.co
115
- Supabase__ServiceRoleKey=eyJ...
116
- Supabase__JwtSecret=your-jwt-secret
117
- ```
118
-
119
- ### Next.js Frontend
120
-
121
- ```env
122
- NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
123
- NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
124
- NEXT_PUBLIC_API_URL=https://api.example.com
125
- ```
126
-
127
- ## Health Check Endpoints
128
-
129
- ```csharp
130
- // .NET: Program.cs
131
- builder.Services.AddHealthChecks()
132
- .AddNpgSql(connectionString, name: "database");
133
- app.MapHealthChecks("/health");
134
- ```
135
-
136
- ```ts
137
- // Next.js: app/api/health/route.ts
138
- export async function GET() {
139
- return Response.json({ status: "healthy", timestamp: new Date().toISOString() });
140
- }
141
- ```
142
-
143
- ## Zero-Downtime Deploys
144
-
145
- EasyPanel uses Docker HEALTHCHECK to determine container readiness:
146
-
147
- 1. New container starts alongside old container
148
- 2. Health check passes after start-period + retries
149
- 3. Traffic shifts to new container
150
- 4. Old container stopped
151
-
152
- | HEALTHCHECK Param | Value | Purpose |
153
- |-------------------|-------|---------|
154
- | `--interval` | 30s | Time between checks |
155
- | `--timeout` | 5s | Max response wait |
156
- | `--start-period` | 10s | Startup grace period |
157
- | `--retries` | 3 | Failures before unhealthy |
158
-
159
- ## Monitoring
160
-
161
- - **Logs**: Real-time in EasyPanel UI
162
- - **Metrics**: CPU, memory, network via dashboard
163
- - **Restart**: Auto-restart on crash (default)
164
-
165
- Structured logging:
166
-
167
- ```csharp
168
- // .NET: Serilog with JSON output
169
- builder.Host.UseSerilog((ctx, cfg) => cfg
170
- .ReadFrom.Configuration(ctx.Configuration)
171
- .WriteTo.Console(new JsonFormatter()));
172
- ```
173
-
174
- ```ts
175
- // Next.js: pino
176
- import pino from "pino";
177
- const logger = pino({ level: process.env.LOG_LEVEL ?? "info" });
178
- ```
179
-
180
- ## Deployment Checklist
181
-
182
- | Step | Action |
183
- |------|--------|
184
- | 1 | Verify `output: "standalone"` in next.config.ts |
185
- | 2 | Test Docker build locally |
186
- | 3 | Test health endpoint |
187
- | 4 | Configure env vars in EasyPanel |
188
- | 5 | Set up custom domain + DNS |
189
- | 6 | Verify SSL certificate |
190
- | 7 | Enable auto-deploy from GitHub |
191
- | 8 | Push to main, verify deployment |