@polymorphism-tech/morph-spec 7.4.0 → 7.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.
Files changed (66) hide show
  1. package/README.md +2 -2
  2. package/bin/morph-spec.js +18 -0
  3. package/claude-plugin.json +1 -1
  4. package/docs/CHEATSHEET.md +1 -1
  5. package/docs/QUICKSTART.md +1 -1
  6. package/framework/CLAUDE.md +9 -4
  7. package/framework/MORPH.md +4 -4
  8. package/framework/agents.json +1 -1
  9. package/framework/commands/create-umbraco-lp.md +35 -0
  10. package/framework/commands/migrate-lp-to-umbraco.md +33 -0
  11. package/framework/commands/morph-archive.md +17 -27
  12. package/framework/commands/morph-preflight.md +10 -5
  13. package/framework/hooks/claude-code/core/enforce-phase-writes.js +115 -90
  14. package/framework/hooks/claude-code/core/protect-spec-files.js +32 -30
  15. package/framework/hooks/claude-code/core/state-sync.js +16 -48
  16. package/framework/hooks/shared/state-reader.js +74 -8
  17. package/framework/hooks/shared/state-writer.js +124 -0
  18. package/framework/rules/infrastructure-standards.md +4 -4
  19. package/framework/rules/morph-task-tracking.md +69 -49
  20. package/framework/rules/morph-workflow.md +192 -191
  21. package/framework/skills/core/create-umbraco-lp/SKILL.md +272 -0
  22. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +531 -0
  23. package/framework/skills/core/morph-apply/SKILL.md +15 -15
  24. package/framework/skills/core/morph-brainstorming/SKILL.md +5 -5
  25. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  26. package/framework/skills/core/morph-implement/SKILL.md +5 -4
  27. package/framework/skills/core/morph-plan/SKILL.md +6 -6
  28. package/framework/skills/core/morph-proposal/SKILL.md +8 -7
  29. package/framework/skills/core/morph-review/SKILL.md +3 -3
  30. package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
  31. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  32. package/framework/standards/STANDARDS.json +80 -8
  33. package/framework/standards/ai-agents/durable-workflows-hitl.md +191 -0
  34. package/framework/standards/ai-agents/rag-custom-pgvector.md +246 -243
  35. package/framework/standards/ai-agents/setup.md +3 -0
  36. package/framework/standards/ai-agents/vector-data-extensions.md +170 -0
  37. package/framework/standards/ai-agents/workflows.md +190 -187
  38. package/framework/standards/infrastructure/docker/{easypanel-deploy.md → coolify-deploy.md} +49 -20
  39. package/framework/templates/README.md +7 -7
  40. package/framework/templates/REGISTRY.json +15 -17
  41. package/framework/templates/context/CONTEXT-FEATURE.md +10 -17
  42. package/framework/templates/context/CONTEXT.md +181 -180
  43. package/framework/templates/docs/onboarding.md +122 -118
  44. package/framework/templates/docs/proposal.md +12 -2
  45. package/framework/templates/docs/spec.md +228 -228
  46. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +1 -1
  47. package/framework/templates/infrastructure/docker/coolify.template.json +49 -0
  48. package/framework/templates/infrastructure/github/README.md +6 -6
  49. package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +33 -0
  50. package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +80 -80
  51. package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +90 -89
  52. package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +2 -1
  53. package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +44 -43
  54. package/framework/templates/meta-prompts/validators/checkpoint-validator.md +107 -107
  55. package/package.json +1 -1
  56. package/src/commands/project/update.js +415 -368
  57. package/src/commands/project/worktree.js +212 -210
  58. package/src/commands/state/advance.js +82 -0
  59. package/src/commands/state/archive.js +111 -0
  60. package/src/commands/validation/validate-feature.js +229 -105
  61. package/src/core/state/state-manager.js +238 -66
  62. package/src/dashboard/scanner/state-scanner.js +35 -8
  63. package/src/lib/generators/context-generator.js +12 -8
  64. package/src/utils/file-copier.js +7 -0
  65. package/framework/templates/infrastructure/docker/easypanel.template.json +0 -46
  66. package/framework/templates/infrastructure/github/workflows/deploy-easypanel.yml.hbs +0 -31
@@ -0,0 +1,272 @@
1
+ ---
2
+ name: create-umbraco-lp
3
+ description: Guia a criação de uma landing page nova ponta-a-ponta a partir do template MORPH_Umbraco_LP_Template (Umbraco 17 + Next.js): coleta decisões, scaffolda, sobe e valida, customiza branding e módulos, e entrega checklist final.
4
+ version: core
5
+ when-to-invoke: ao iniciar um novo projeto de LP com o template Umbraco genérico
6
+ user-invokable: true
7
+ cliVersion: "7.6.0"
8
+ ---
9
+
10
+ # create-umbraco-lp
11
+
12
+ ## Objetivo
13
+
14
+ Conduzir um agente (ou dev) na criação de uma nova landing page usando o template canônico `MORPH_Umbraco_LP_Template` (repo privado, branch `master`). Cobre do clone ao smoke-test, passando por branding, módulos de conteúdo e configuração de integração de lead.
15
+
16
+ ## Quando invocar
17
+
18
+ Ao iniciar um projeto de LP do zero — quando o usuário disser "criar uma LP", "novo projeto Umbraco", "bootstrapar LP", "nova landing page", ou mencionar `/create-umbraco-lp`. Não invocar se o projeto já existe (repositório com `.env` presente); nesse caso, ir direto ao passo de customização ou ao troubleshoot.
19
+
20
+ ## O que fazer
21
+
22
+ ### Passo 1 — Coletar decisões (uma pergunta por vez via AskUserQuestion)
23
+
24
+ Faça cada pergunta separadamente e aguarde a resposta antes de seguir. Não liste todas de uma vez.
25
+
26
+ **Pergunta 1:** Nome do projeto (ex.: "Reserva das Flores").
27
+
28
+ **Pergunta 2:** Integração de lead. Use `AskUserQuestion` com as opções:
29
+ - `none` — sem integração (form recebe lead mas não envia a lugar nenhum; útil para fase de dev).
30
+ - `ghl` — GoHighLevel (requer API token GHL; configurado depois no backoffice).
31
+ - `prospectpro` — ProspectPRO (requer URL de API + token; configurado depois no backoffice).
32
+ - `webhook` — Webhook genérico (requer URL do webhook; configurado depois no backoffice).
33
+
34
+ **Pergunta 3:** Origins permitidas pelo CORS do backend — o domínio real do frontend em produção, separado por vírgula. Em dev local, `http://localhost:3000` já é o padrão gravado pelo script; pergunte apenas se houver domínio de produção a configurar agora.
35
+
36
+ **Pergunta 4 (opcional):** Seed de demo? Se sim, o boot semeará um Hero e um módulo de Contato de exemplo, facilitando a visualização imediata. Recomendado para projetos novos. Use `AskUserQuestion` com opções Sim / Não.
37
+
38
+ Persista as respostas em variáveis para uso nos passos seguintes.
39
+
40
+ ---
41
+
42
+ ### Passo 2 — Scaffold: clonar template e rodar `new-lp`
43
+
44
+ **2.1 — Clonar o template para o diretório do novo projeto:**
45
+
46
+ O repo do template é **privado** — prefira `gh repo clone` (usa o token já autenticado). Comando idêntico em bash e PowerShell:
47
+
48
+ ```bash
49
+ # Clonar o template canônico (privado) para o diretório do novo projeto.
50
+ # Branch padrão master (já generalizado) — sem checkout de branch.
51
+ gh repo clone polymorphism-tech/MORPH_Umbraco_LP_Template <NomeDoProjeto>
52
+ cd <NomeDoProjeto>
53
+ # (opcional) desacoplar do histórico do template para o projeto ter o seu:
54
+ # rm -rf .git && git init (PowerShell: Remove-Item .git -Recurse -Force; git init)
55
+ ```
56
+
57
+ - **Fallback** se `gh` não estiver disponível: `git clone https://github.com/polymorphism-tech/MORPH_Umbraco_LP_Template.git <NomeDoProjeto>` (ou SSH `git@github.com:polymorphism-tech/MORPH_Umbraco_LP_Template.git`) — exige credencial HTTPS ou chave SSH com acesso à org.
58
+ - Se o clone for por cópia local (sibling repo), substitua por `cp -r` ou `xcopy` preservando o conteúdo de `backend/uSync/` e `scripts/`.
59
+
60
+ **2.2 — Executar o script de bootstrap:**
61
+
62
+ No Windows (PowerShell):
63
+ ```powershell
64
+ .\scripts\new-lp.ps1 -ProjectName "<NomeDoProjeto>" -LeadIntegration "<none|ghl|prospectpro|webhook>" -ResetDb -EnableDemoSeed
65
+ ```
66
+
67
+ `-ResetDb` deve ser passado sempre no primeiro boot de um projeto novo; `-EnableDemoSeed` apenas se demo seed foi escolhido no passo 1.
68
+
69
+ No Linux / macOS (bash):
70
+ ```bash
71
+ ./scripts/new-lp.sh "<NomeDoProjeto>" \
72
+ --lead-integration <none|ghl|prospectpro|webhook> \
73
+ --reset-db \
74
+ --demo-seed # se demo seed foi escolhido
75
+ ```
76
+
77
+ O script escreve `.env` na raiz do repo com os campos:
78
+ ```
79
+ PROJECT_NAME=<NomeDoProjeto>
80
+ UMBRACO_ADMIN_EMAIL=admin@<slug>.com
81
+ UMBRACO_ADMIN_PASSWORD=<gerada>
82
+ UMBRACO_GLOBAL_ID=<uuid-gerado>
83
+ ALLOWED_ORIGINS=http://localhost:3000
84
+ REVALIDATE_SECRET=<gerado>
85
+ FRONTEND_URL=http://localhost:3000
86
+ LEADS_INTEGRATION=<integração-escolhida>
87
+ ```
88
+
89
+ `FRONTEND_URL` (junto com `REVALIDATE_SECRET`) alimenta o `RevalidateOnPublishHandler` do
90
+ backend: a cada publish no Umbraco, ele chama `/api/revalidate` do frontend sozinho, em
91
+ código — não depende de configurar nada em Settings > Webhooks no backoffice. **Em
92
+ produção, atualize `FRONTEND_URL` para o domínio público real do frontend.**
93
+
94
+ E gera `backend/appsettings.Development.json` com o bloco Unattended install do Umbraco (usando o email/senha computados pelo script). Isso significa que um projeto recém-scaffoldado **auto-instala no `dotnet run`** — sem necessidade de rodar o instalador UI manualmente.
95
+
96
+ E escreve `frontend/.env.local` com:
97
+ ```
98
+ NEXT_PUBLIC_UMBRACO_URL=https://localhost:44324
99
+ NEXT_PUBLIC_SITE_URL=http://localhost:3000
100
+ REVALIDATE_SECRET=<mesmo-secret>
101
+ ```
102
+
103
+ `NEXT_PUBLIC_SITE_URL` é usada por `robots.ts`/`sitemap.ts`. **Em produção, precisa ser
104
+ setada como Build Variable no Coolify** — o `Dockerfile` do template
105
+ declara `ARG NEXT_PUBLIC_SITE_URL` (e `ARG NEXT_PUBLIC_UMBRACO_URL`) justamente para isso;
106
+ sem marcar como Build Variable, a env var não chega ao `next build` e o `robots.txt`/
107
+ `sitemap.xml` publicam o domínio placeholder do template (`minha-landing-page.com.br`) em
108
+ produção — já aconteceu num projeto real.
109
+
110
+ > **Nota de overwrite:** se `.env` já existe, `new-lp.ps1` prompta (Read-Host) para sobrescrever — portanto, uma execução não-interativa em um diretório que já tem `.env` vai bloquear na prompt. Execute em um scaffold fresco, ou responda à prompt interativamente.
111
+
112
+ > **Nota importante:** `ALLOWED_ORIGINS` é gravado com `http://localhost:3000` pelo script independentemente do que foi informado no passo 1. Se o usuário especificou um domínio de produção, a forma de aplicá-lo depende do modo de execução:
113
+ > - **Docker Compose:** edite `.env` na raiz: `ALLOWED_ORIGINS=https://meuprojeto.com,http://localhost:3000`. O `docker-compose.yml` injeta essa variável e ela é lida pelo `builder.Configuration` em `Program.cs`.
114
+ > - **`dotnet run` local:** o `.env` **não** é lido automaticamente pelo `dotnet run`. Edite `backend/appsettings.json`, campo `AllowedOrigins` (array de strings), ou exporte a variável no shell antes de rodar (`$env:AllowedOrigins="https://meuprojeto.com,http://localhost:3000"` no PowerShell). O `Program.cs` lê `builder.Configuration.GetSection("AllowedOrigins")`, que é populado via `appsettings.json` ou env var do processo.
115
+
116
+ > `LEADS_INTEGRATION` NÃO está no `.env.example` — é uma variável extra gravada pelo script na seção `LEADS_INTEGRATION=`. O seed a lê via `Environment.GetEnvironmentVariable("LEADS_INTEGRATION")` para criar o node `Configurações de Lead` com o valor correto.
117
+
118
+ Guarde as credenciais exibidas na saída do script (`Admin:`, `Senha:`, `GUID:`).
119
+
120
+ ---
121
+
122
+ ### Passo 3 — Boot + verificar
123
+
124
+ **3.1 — Subir o backend (Umbraco 17 / .NET 10):**
125
+
126
+ ```bash
127
+ cd backend
128
+ dotnet run
129
+ # ou, com IIS Express: perfil "Umbraco.Web.UI"
130
+ ```
131
+
132
+ Portas padrão (dev local):
133
+ - HTTP: `http://localhost:19223`
134
+ - HTTPS: `https://localhost:44324` (IIS Express)
135
+
136
+ O banco de dados é SQLite em `backend/umbraco/Data/Umbraco.sqlite.db`. O flag `-ResetDb` / `--reset-db` apaga `Umbraco.sqlite.db*` e `TEMP/ExamineIndexes` antes do boot — use sempre no primeiro boot de um projeto novo para garantir um estado limpo.
137
+
138
+ > **⚠️ Primeiro `dotnet run` leva vários minutos:** cold compile com NuGet restore + build. Não é um hang — seja paciente.
139
+
140
+ **3.2 — Aguardar o uSync e o seed (após compilar):**
141
+
142
+ Na primeira subida, o Umbraco executa a instalação unattended (via `backend/appsettings.Development.json` configurado pelo script), depois o uSync importa todos os Content Types de `backend/uSync/v17/` (`ImportAtStartup: "All"`), e então o `SeedContentHandler` cria:
143
+ - O node raiz `lpHome` (home da LP, com `PROJECT_NAME` como título).
144
+ - O node `Configurações de Lead` (`leadsConfig`, com `LEADS_INTEGRATION` semeado como `["<integração>"]`).
145
+
146
+ Aguarde as seguintes linhas de log (strings exatas do `SeedContentHandler.cs`) antes de prosseguir:
147
+ - Home: `SeedContent: node created and published successfully.`
148
+ - Leads: `SeedContent: leads config node created and published.`
149
+
150
+ (Se os nodes já existiam de um boot anterior: `SeedContent: home already exists (...), skipping.` e `SeedContent: leads config node already exists, skipping.` — também é OK.)
151
+
152
+ **3.3 — Verificar a Delivery API:**
153
+
154
+ ```bash
155
+ curl "http://localhost:19223/umbraco/delivery/api/v2/content?contentType=lpHome&take=1"
156
+ # Deve retornar { total: 1, items: [...] }
157
+ ```
158
+
159
+ **3.4 — Verificar o endpoint Ping de leads:**
160
+
161
+ ```bash
162
+ curl http://localhost:19223/api/leads
163
+ # Deve retornar { "ok": true, "service": "leads" } (prod)
164
+ # Em Development: inclui "integration", "configFound", "ready"
165
+ ```
166
+
167
+ Se `configFound: false`, o node `leadsConfig` não foi criado pelo seed — verifique os logs e o passo 2.2.
168
+
169
+ **3.5 — Subir o frontend (Next.js):**
170
+
171
+ ```bash
172
+ cd frontend
173
+ npm install
174
+ npm run dev # com TLS
175
+ # ou:
176
+ npm run dev:no-tls # sem TLS (mais simples em dev inicial)
177
+ ```
178
+
179
+ Acesse `http://localhost:3000`. A home deve renderizar com o conteúdo semeado.
180
+
181
+ ---
182
+
183
+ ### Passo 4 — Customizar
184
+
185
+ **4.1 — Branding e cores (frontend):**
186
+
187
+ Edite `frontend/src/app/globals.css`. As variáveis CSS de base do tema são definidas no bloco `:root` e expostas via `@theme inline` para o Tailwind v4:
188
+
189
+ ```css
190
+ /* frontend/src/app/globals.css */
191
+ :root {
192
+ --background: #ffffff; /* troque pela cor de fundo da LP */
193
+ --foreground: #171717; /* troque pela cor de texto principal */
194
+ /* adicione variáveis de cores de marca, tipografia, etc. */
195
+ }
196
+ ```
197
+
198
+ Para tipografias customizadas, importe via `next/font` em `frontend/src/app/layout.tsx` e exponha como variável CSS.
199
+
200
+ **4.2 — Módulos disponíveis (Content Types *Section):**
201
+
202
+ O template já inclui os seguintes módulos versionados em `backend/uSync/v17/ContentTypes/`:
203
+
204
+ | Alias (Content Type) | Propósito |
205
+ |---|---|
206
+ | `heroSection` | Hero principal com título, subtítulo, CTA e imagem |
207
+ | `contatoSection` | Formulário de contato / captação de lead |
208
+ | `diferencialSection` | Lista de diferenciais (cada item: `diferencialItem`) |
209
+ | `galeriaSection` | Galeria de imagens |
210
+ | `videoSection` | Embed de vídeo |
211
+ | `testimonialSection` | Seção de depoimentos (cada item: `testimonialItem`) |
212
+ | `equipeSection` | Seção de equipe (cada membro: `equipeMembro`) |
213
+ | `tipologiasSection` | Tipologias/plantas (cada tipo: `tipologiaTipo`) |
214
+ | `certificacoesSection` | Certificações (cada item: `certificacaoItem`) |
215
+ | `localizacaoSection` | Seção de localização |
216
+ | `customHtmlSection` | HTML livre (escape hatch) |
217
+
218
+ Para adicionar ou reordenar módulos: acesse o backoffice em `https://localhost:44324/umbraco`, faça login com as credenciais geradas, abra o node `lpHome` e adicione os módulos desejados.
219
+
220
+ **4.3 — Configurar integração de lead no backoffice:**
221
+
222
+ Acesse o backoffice → Content → `Configurações de Lead`. Preencha os campos conforme a integração escolhida:
223
+
224
+ - **GHL:** preencha obrigatoriamente `ghlApiToken` (Private Integration Token da sub-conta) **e** `ghlLocationId` (ID da sub-conta/location). Sem `ghlLocationId`, os leads são enviados ao GHL mas vão para a conta errada ou falham silenciosamente. Campos opcionais de mapeamento: `ghlFieldFonte`, `ghlFieldCanal`, `ghlFieldSegmento`, `ghlFieldConsent`, `ghlFieldObs`, `ghlTags`.
225
+ - **ProspectPRO:** `ppApiUrl` + `ppApiToken`.
226
+ - **Webhook genérico:** `whUrl` (URL do webhook; o payload é o lead completo em JSON).
227
+
228
+ > Esses tokens **nunca são semeados pelo script** (por design: "Template genérico — NÃO semear tokens/ids"). O node é criado com campos em branco para o editor preencher. Tokens não aparecem na Delivery API pública (`leadsConfig` está em `DisallowedContentTypeAliases`).
229
+
230
+ > **Dropdown Flexível — gotcha:** o campo `leadIntegration` é um `Umbraco.DropDown.Flexible`. Mesmo com `Multiple: false`, o valor é persistido internamente como JSON array (ex.: `["ghl"]`). O seed já escreve no formato correto via `JsonSerializer.Serialize(new[]{ value })`. Ao ler no controller, `node.Value<string>("leadIntegration")` desembrulha para a string simples.
231
+
232
+ ---
233
+
234
+ ### Passo 5 — Checklist de entrega
235
+
236
+ Antes de fazer deploy ou entregar o projeto ao cliente:
237
+
238
+ - [ ] `dotnet build` sem warnings no backend.
239
+ - [ ] `npm run lint` no frontend sem erros (ESLint via `eslint.config.mjs`).
240
+ - [ ] `npm run build` no frontend (requer backend acessível em `NEXT_PUBLIC_UMBRACO_URL` — ou `E2E_FAKE_DATA=true` para CI sem backend).
241
+ - [ ] `GET /api/leads` retorna `{ ok: true, service: "leads" }`.
242
+ - [ ] Formulário de lead submete e a resposta é `{ ok: true }` (ou `{ ok: true, skipped: true }` se tokens ainda não configurados — comportamento esperado em dev).
243
+ - [ ] Delivery API responde com o node `lpHome` populado: `/umbraco/delivery/api/v2/content?contentType=lpHome&take=1`.
244
+ - [ ] `.env` contém `ALLOWED_ORIGINS` com o domínio de produção correto (separado por vírgula se múltiplos).
245
+ - [ ] `UMBRACO_GLOBAL_ID` é único para este projeto (gerado pelo script — não reutilizar de outro projeto).
246
+ - [ ] SEO: preencher no backoffice, aba SEO do node `lpHome` — Page Title, Meta Title, Meta Description, **Social Image** (1200x630, sem ela não há `og:image` e o link não gera preview no WhatsApp/redes), Canonical Url (só a URL, sem tag HTML).
247
+ - [ ] Favicon: preencher o campo **Favicon** no backoffice (aba Configuration) — `app/icon.tsx`/`apple-icon.tsx` já leem esse campo dinamicamente; sem ele, cai no favicon estático genérico do template.
248
+ - [ ] `NEXT_PUBLIC_SITE_URL` **e** `NEXT_PUBLIC_UMBRACO_URL` setadas como **Build Variable** no provedor (não só runtime) — conferir `robots.txt`/`sitemap.xml` em produção com o domínio real após o primeiro deploy.
249
+ - [ ] `FRONTEND_URL` + `REVALIDATE_SECRET` setadas no backend em produção (revalidação automática pós-publish via `RevalidateOnPublishHandler`) — testar: publicar algo no backoffice e conferir no log do backend a linha `RevalidateOnPublish: cache do frontend invalidado após publish.`
250
+ - [ ] No Index: confirmar que está **desligado** no backoffice antes de ir pra produção (o campo é opt-in pra esconder do Google, não deveria vir ligado por padrão).
251
+ - [ ] Variáveis sensíveis (`UMBRACO_ADMIN_PASSWORD`, `REVALIDATE_SECRET`, tokens de integração) não estão commitadas no repositório (`.env` deve estar no `.gitignore`).
252
+ - [ ] Em produção com Docker Compose: `docker-compose up --build` e confirmar que backend e frontend sobem com as variáveis do `.env`.
253
+ - [ ] `browserslist` presente em `frontend/package.json` — já vem do template; só confirmar que não foi removido/sobrescrito durante a customização.
254
+ - [ ] Se o cliente vai subir fotos de câmera/celular pelo Media Picker (galeria, hero, etc.): confirmar que `ResizeLargeMediaUploadsHandler` está registrado em `backend/Program.cs` (já vem do template) — sem ele, upload cru de 10+ MB pode virar 500 intermitente sob concorrência no otimizador do Next. Setar `MEDIA_BACKFILL_SECRET` em produção se for preciso reprocessar mídia já publicada (ver seção "Mídia" do README do template).
255
+
256
+ > **Nota Docker — `LEADS_INTEGRATION` e `SEED_DEMO_CONTENT`:** o `docker-compose.yml` **não** injeta essas duas variáveis no container do backend. Mesmo que estejam no `.env`, o seed sempre inicializa `leadIntegration` como `"none"` no boot Docker. Isso é esperado: o editor deve configurar a integração manualmente no backoffice após o primeiro boot. Se precisar seeding automático da integração via Docker, adicione a variável na seção `environment` do serviço `backend` em `docker-compose.yml` manualmente.
257
+
258
+ ## Output esperado
259
+
260
+ - Repositório do projeto com `.env` e `frontend/.env.local` configurados.
261
+ - Backend Umbraco subindo com node `lpHome` e node `Configurações de Lead` semeados.
262
+ - Frontend Next.js renderizando a home com conteúdo da Delivery API.
263
+ - `GET /api/leads` respondendo `{ ok: true, service: "leads" }`.
264
+ - Backoffice acessível para o editor adicionar módulos e configurar tokens de integração.
265
+
266
+ ## Referências
267
+
268
+ - `polymorphism-tech/MORPH_Umbraco_LP_Template` (privado, branch `master`) — template canônico: `scripts/new-lp.ps1`, `scripts/new-lp.sh`, `backend/Infrastructure/SeedContentHandler.cs`, `backend/Controllers/LeadController.cs`, `backend/uSync/v17/`.
269
+ - `docs/umbraco-lp-patterns.md` (em `main` neste repo) — padrões e gotchas detalhados: controller público (seção 1), DI multi-sink (seção 2), leitura server-side de config oculta (seção 3), segurança Delivery API (seção 4), uSync config-as-code (seção 5), dropdown gotcha (seção 6), seed idempotente (seção 7), endpoint Ping (seção 10), skip silencioso em dev (seção 11), build Next.js exige backend (seção 12).
270
+ - `backend/appsettings.json` — `Umbraco:CMS:DeliveryApi:DisallowedContentTypeAliases` e `uSync:Settings:ImportAtStartup`.
271
+ - `backend/Properties/launchSettings.json` — portas de dev: HTTP `:19223`, HTTPS `:44324`.
272
+ - `docker-compose.yml` — orquestração de produção (backend porta `5001`, frontend `3000`).