O EmDash mantém a versão publicada de uma entrada separada das alterações não publicadas. O painel de administração, a API REST, a interface de linha de comando (CLI) e as ferramentas Model Context Protocol (MCP) usam as mesmas regras de ciclo de vida.
Uma entrada pode estar em draft, scheduled ou published. Uma entrada publicada também pode ter um rascunho e uma
agendamento futuro: os visitantes continuam a receber a revisão ao vivo até que o rascunho agendado seja
publicado. A lixeira é separada do status. Uma entrada na lixeira mantém seus metadados de ciclo de vida, mas é
excluída das leituras ordinárias de conteúdo.
Transições de estado
A tabela a seguir é o contrato canônico para estado do conteúdo, ponteiros de revisão e carimbos de data/hora de publicação. “Sem alteração” significa que a operação preserva o valor armazenado.
| Ação | Estado inicial | Resultado | Efeito na revisão | publishedAt | scheduledAt | Chamada repetida |
|---|---|---|---|---|---|---|
| Salvar alterações | Qualquer entrada ativa | O status não muda | Em uma collection com revisões, substitui a revisão de rascunho enquanto a revisão ao vivo permanece pública | Sem alteração | Sem alteração | Um _rev fornecido recusa um salvamento obsoleto; omiti-lo torna a escrita REST incondicional |
| Publicar | Rascunho, agendada ou publicada | Publicada | Promove a revisão de rascunho a ao vivo e limpa o ponteiro de rascunho | Definido na primeira publicação; preservado em publicações posteriores salvo se um chamador autorizado o sobrescrever | Limpo | Preserva o conteúdo ao vivo e a hora de publicação, mas retorna um novo _rev |
| Publicar quando devido | Agendada, ou publicada com um rascunho agendado | Publicada | Igual a publicar | Usa a hora agendada na primeira publicação; preserva o valor existente ao publicar um novo rascunho sobre o conteúdo ao vivo | Limpo | Uma passagem posterior do agendador ignora uma entrada cujo agendamento já foi limpo |
| Despublicar | Qualquer entrada ativa | Rascunho | Limpa o ponteiro ao vivo; preserva o rascunho existente ou cria um a partir da revisão ao vivo | Preservado | Limpo | Uma entrada que já é um rascunho simples não muda |
| Agendar | Rascunho, agendada ou publicada | Um rascunho torna-se agendado; uma entrada publicada permanece publicada | Sem alteração | Sem alteração | Definido para a hora futura solicitada | Substitui o agendamento existente e retorna um novo _rev |
| Desagendar | Agendada, ou publicada com um agendamento | Uma entrada agendada torna-se rascunho; uma entrada publicada permanece publicada | Sem alteração | Sem alteração | Limpo | Uma entrada sem agendamento não muda |
| Descartar rascunho | Qualquer entrada ativa | O status não muda | Limpa o ponteiro de rascunho; a revisão ao vivo permanece inalterada | Sem alteração | Sem alteração | Uma entrada sem rascunho não muda |
| Mover para a lixeira | Qualquer entrada ativa | Na lixeira e ausente das leituras ordinárias | Preservado | Preservado | Preservado | Uma solicitação de uma entrada já na lixeira retorna não encontrado |
| Restaurar da lixeira | Na lixeira | Rascunho | Limpa o ponteiro ao vivo; preserva qualquer ponteiro de rascunho | Preservado | Limpo | Exige uma entrada que ainda esteja na lixeira |
| Excluir permanentemente | Na lixeira | Removida | Remove a entrada e suas revisões | Removido | Removido | Não pode ser repetido nem desfeito |
| Restaurar uma revisão | Qualquer entrada ativa | O status não muda | Em uma collection com revisões, substitui o rascunho por uma cópia da revisão selecionada; a revisão ao vivo permanece inalterada | Sem alteração | Sem alteração | Cria uma nova revisão e retorna um novo _rev |
Em uma collection sem suporte a revisões, salvamentos e publicações usam a linha de conteúdo em vez de ponteiros ao vivo e de rascunho. Restaurar uma revisão escreve os valores de campo selecionados diretamente nessa linha.
Restaurar uma revisão em uma collection com revisões não a publica. Publique a entrada depois de revisar o rascunho restaurado.
Permissões e proteção de escrita
As permissões dependem da propriedade. Um Author pode agir em uma entrada que possui; um Editor pode realizar a mesma ação em qualquer entrada. A exclusão permanente exige um Admin.
Definir publishedAt durante a publicação exige content:publish_any, mesmo quando o chamador possui a
entrada.
A API REST aceita _rev como uma pré-condição opcional de concorrência otimista onde indicado. As ferramentas MCP
o exigem para as mesmas operações, de modo que um agente deve ler a entrada antes de alterá-la. Um token obsoleto
retorna CONFLICT. Escritas de admin e REST protegidas por um bloqueio de entrada retornam ENTRY_LOCKED salvo se uma
solicitação autorizada usar a substituição de bloqueio suportada. Escritas MCP não participam de bloqueios de entrada.
| Ação | Permissão | REST _rev | MCP _rev | Bloqueio de admin e REST | Hooks |
|---|---|---|---|---|---|
| Salvar alterações | content:edit_own ou content:edit_any | Opcional | Obrigatório | Aplicado | content:beforeSave, content:afterSave |
| Publicar | content:publish_own ou content:publish_any | Opcional | Obrigatório | Aplicado | content:beforePublish, content:afterPublish |
| Despublicar | content:publish_own ou content:publish_any | Opcional | Obrigatório | Aplicado | content:beforeUnpublish, content:afterUnpublish |
| Agendar | content:publish_own ou content:publish_any | Opcional | Obrigatório | Aplicado | content:beforeSchedule, content:afterSchedule |
| Desagendar | content:publish_own ou content:publish_any | Não aceito | Não aceito | Aplicado | content:afterUnschedule |
| Descartar rascunho | content:edit_own ou content:edit_any | Opcional | Obrigatório | Aplicado | Nenhum |
| Mover para a lixeira | content:delete_own ou content:delete_any | Não aceito | Não aceito | Aplicado | content:beforeDelete, content:afterDelete |
| Restaurar da lixeira | content:edit_own ou content:edit_any | Não aceito | Não aceito | Não aplicado | content:afterRestore |
| Excluir permanentemente | content:delete_permanent | Não aceito | Não aceito | Não aplicado | content:afterDelete |
| Restaurar uma revisão | content:edit_own ou content:edit_any | Não aceito | Não aceito | Não aplicado | Nenhum |
O evento content:afterDelete define permanent como false quando uma entrada vai para a lixeira e como true
após a exclusão permanente. After-hooks bem-sucedidos são executados após a mudança de estado e podem ser executados depois que a
resposta foi enviada. Um plugin pode rejeitar salvar, publicar, despublicar, agendar ou mover para a lixeira a partir do
before-hook correspondente.
Quando a publicação agendada chega ao vencimento, usa os hooks de publicação. Se um
hook content:beforePublish rejeitar essa tentativa agendada, o EmDash limpa o agendamento e executa
content:afterUnschedule.
Conflitos e novas tentativas
Use o _rev retornado por cada leitura ou escrita para a próxima operação protegida. O EmDash recusa um
token desatualizado em vez de substituir uma alteração concorrente. Leia a entrada de novo, revise o estado
mais recente e então decida se tenta novamente.
Uma resposta de erro nem sempre prova que nenhum estado mudou. Se uma conexão terminar antes de o cliente receber uma resposta, leia a entrada antes de tentar de novo uma operação de ciclo de vida. Isso também evita que uma nova tentativa substitua o trabalho concluído por outro editor.
A restauração de revisão confirma o conteúdo restaurado e sua revisão de auditoria juntos. Se qualquer uma das escritas falhar, o EmDash preserva o conteúdo e o histórico de revisões de antes da solicitação.
Veja a referência da API REST para os esquemas de solicitação e resposta HTTP, a referência do servidor MCP para as entradas das ferramentas e a referência de hooks para os payloads dos eventos.