@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.
- package/README.md +2 -2
- package/bin/morph-spec.js +18 -0
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +1 -1
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +9 -4
- package/framework/MORPH.md +4 -4
- package/framework/agents.json +1 -1
- package/framework/commands/create-umbraco-lp.md +35 -0
- package/framework/commands/migrate-lp-to-umbraco.md +33 -0
- package/framework/commands/morph-archive.md +17 -27
- package/framework/commands/morph-preflight.md +10 -5
- package/framework/hooks/claude-code/core/enforce-phase-writes.js +115 -90
- package/framework/hooks/claude-code/core/protect-spec-files.js +32 -30
- package/framework/hooks/claude-code/core/state-sync.js +16 -48
- package/framework/hooks/shared/state-reader.js +74 -8
- package/framework/hooks/shared/state-writer.js +124 -0
- package/framework/rules/infrastructure-standards.md +4 -4
- package/framework/rules/morph-task-tracking.md +69 -49
- package/framework/rules/morph-workflow.md +192 -191
- package/framework/skills/core/create-umbraco-lp/SKILL.md +272 -0
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +531 -0
- package/framework/skills/core/morph-apply/SKILL.md +15 -15
- package/framework/skills/core/morph-brainstorming/SKILL.md +5 -5
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-implement/SKILL.md +5 -4
- package/framework/skills/core/morph-plan/SKILL.md +6 -6
- package/framework/skills/core/morph-proposal/SKILL.md +8 -7
- package/framework/skills/core/morph-review/SKILL.md +3 -3
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/standards/STANDARDS.json +80 -8
- package/framework/standards/ai-agents/durable-workflows-hitl.md +191 -0
- package/framework/standards/ai-agents/rag-custom-pgvector.md +246 -243
- package/framework/standards/ai-agents/setup.md +3 -0
- package/framework/standards/ai-agents/vector-data-extensions.md +170 -0
- package/framework/standards/ai-agents/workflows.md +190 -187
- package/framework/standards/infrastructure/docker/{easypanel-deploy.md → coolify-deploy.md} +49 -20
- package/framework/templates/README.md +7 -7
- package/framework/templates/REGISTRY.json +15 -17
- package/framework/templates/context/CONTEXT-FEATURE.md +10 -17
- package/framework/templates/context/CONTEXT.md +181 -180
- package/framework/templates/docs/onboarding.md +122 -118
- package/framework/templates/docs/proposal.md +12 -2
- package/framework/templates/docs/spec.md +228 -228
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +1 -1
- package/framework/templates/infrastructure/docker/coolify.template.json +49 -0
- package/framework/templates/infrastructure/github/README.md +6 -6
- package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +33 -0
- package/framework/templates/meta-prompts/parallel-workers/parallel-worker.md +80 -80
- package/framework/templates/meta-prompts/squad-leaders/backend-squad.md +90 -89
- package/framework/templates/meta-prompts/squad-leaders/frontend-squad.md +2 -1
- package/framework/templates/meta-prompts/squad-leaders/squad-leader.md +44 -43
- package/framework/templates/meta-prompts/validators/checkpoint-validator.md +107 -107
- package/package.json +1 -1
- package/src/commands/project/update.js +415 -368
- package/src/commands/project/worktree.js +212 -210
- package/src/commands/state/advance.js +82 -0
- package/src/commands/state/archive.js +111 -0
- package/src/commands/validation/validate-feature.js +229 -105
- package/src/core/state/state-manager.js +238 -66
- package/src/dashboard/scanner/state-scanner.js +35 -8
- package/src/lib/generators/context-generator.js +12 -8
- package/src/utils/file-copier.js +7 -0
- package/framework/templates/infrastructure/docker/easypanel.template.json +0 -46
- 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`).
|