# Migrações

URL: /administrar/migracoes

Traga projetos de outra instância do Mira ou envie os desta para outra, sem copiar o banco.

**Quem faz:** administrador, nas duas instâncias.

Uma migração copia projetos de uma instância do Mira, a origem, para outra, o destino. As duas instâncias conversam pela API, então a migração não depende de versão de banco nem de `pg_dump`. Os projetos mantêm os ids, as chaves de ingestão e os links internos, e as apps que já usam o DSN continuam enviando erros depois da troca.

## Quando usar [#quando-usar]

- Você troca o Mira de servidor ou de domínio e quer levar os projetos.
- Você junta duas instâncias, ou separa um projeto numa instância nova.
- Você quer uma cópia de um projeto para teste.

A migração não é um retrato do momento. A origem continua recebendo dados enquanto ela roda. Para trazer o que entrou depois, rode de novo com a regra **Manter o do destino**.

## Antes de começar [#antes-de-começar]

1. Seja **Administrador** nas duas instâncias.
2. Emita um token de migração na outra instância. Para trazer, o escopo é **Exportar**, emitido na origem. Para enviar, o escopo é **Importar**, emitido no destino. Veja [Tokens de migração](#tokens-de-migração).
3. Confirme o caminho de rede. Ao trazer, o servidor do destino precisa alcançar a origem. Ao enviar, o servidor da origem precisa alcançar o destino. Escolha o sentido em que a rede permite: uma origem em rede interna envia para um destino público.
4. Use uma URL `https://`. Só `http://localhost` é aceito, e fora de produção.

## Tokens de migração [#tokens-de-migração]

Abra **Administração do Mira → Migrações → Tokens de migração** e use **Novo token**.

| Campo | O que define |
| --- | --- |
| **Nome** | Identifica o token na lista. |
| **Escopo** | **Exportar** deixa outra instância trazer projetos desta. **Importar** deixa outra instância enviar projetos para esta. |
| **Validade** | De 1 a 7 dias. O padrão é 7. |

O token (`mira_mig_...`) aparece uma vez, em **Copie o token agora**. Cole na outra instância ao começar a migração. A lista mostra o escopo, a validade e o último uso. Para revogar, use o menu da linha: a outra instância perde o acesso na hora.

O token vale só nas rotas da migração e só enquanto quem o emitiu continuar sendo administrador ativo. Ele não abre nenhuma outra rota da API.

## Trazer de outra instância [#trazer-de-outra-instância]

Faça no **destino**.

<Steps>
<Step>

### Abrir o formulário [#abrir-o-formulário]

Em **Migrações**, clique em **Nova migração** e escolha **Trazer de outra instância**.

<Figure src="/images/admin-migrations.png" alt="Lista de Migrações vazia, com os botões Tokens de migração e Nova migração" caption="A lista de Migrações, com Nova migração em destaque." />

</Step>
<Step>

### Conectar à origem [#conectar-à-origem]

Informe a **URL da origem** e o **Token de migração da origem**, com escopo **Exportar**, e clique em **Conectar**. Se der certo, a tela mostra **Conectado a** e a versão do Mira da origem. Trocar a URL ou o token descarta a leitura.

<Figure src="/images/admin-migrations-pull.png" alt="Formulário Trazer de outra instância, com a URL e o token da origem e o botão Conectar" caption="O formulário de Trazer, antes de conectar." />

TODO print: a tela depois de conectar, com os projetos e as opções, precisa de uma segunda instância no pipeline de prints.

</Step>
<Step>

### Escolher projetos e opções [#escolher-projetos-e-opções]

Em **Projetos**, marque os projetos da origem. Cada linha mostra a contagem de reports, anexos, membros e erros. Em **Opções**, decida se entra o grupo **Incluir os Erros** e escolha a regra de conflito.

</Step>
<Step>

### Iniciar [#iniciar]

Clique em **Iniciar migração** e confirme. O Mira abre o detalhe da migração.

</Step>
</Steps>

## Enviar para outra instância [#enviar-para-outra-instância]

Faça na **origem**. O formulário é o mesmo, com duas diferenças: os campos são **URL do destino** e **Token de migração do destino**, com escopo **Importar**, e a tela confere as chaves de projeto no destino ao conectar.

Escolha **Enviar** quando a origem está numa rede interna e o destino é público, como na troca de um servidor interno para uma instância na internet.

## O que migra [#o-que-migra]

Por projeto marcado:

- O projeto e as configurações, os ambientes e as chaves de ingestão, os membros, as tags e os templates.
- Os reports, com tags, vínculo de duplicado e anexos.
- Os comentários, com anexos, e a atividade dos reports.
- Os vínculos com issues do Jira e do GitHub.
- Com **Incluir os Erros**: releases, Erros, contadores, Ocorrências, a atividade do projeto, os vínculos com reports e os source maps. A opção vem ligada.

As contas entram só quando algum dado migrado cita a pessoa, e são casadas pelo email. Uma conta que não existe no destino nasce como **Usuário**, sem senha, com o bloqueio que tinha na origem. A pessoa entra pelo Google ou por um link de redefinição de senha. O papel **Administrador** nunca vem da origem, e uma conta que já existe no destino não muda de papel, de senha nem de bloqueio.

A migração não dispara webhook, notificação, email nem envio ao Jira.

## O que não migra [#o-que-não-migra]

- **Segredos.** O token do Jira, a chave privada do GitHub e o segredo dos webhooks ficam na origem. Veja [Avisos](#avisos).
- Convites pendentes, sessões, tokens, serviços de API e vínculos com o Google.
- Notificações e entregas de email, resumos semanais e as execuções e sugestões do assistente.
- Eventos e entregas de webhook.
- O log de auditoria. O destino registra só o começo e o fim da migração.

## Conflitos [#conflitos]

Um registro já existe no destino quando tem o mesmo id ou a mesma chave natural: a chave do projeto, o email da conta, o nome da tag no projeto, a chave de ingestão ou o Debug ID do source map. Em **Quando o registro já existe no destino**, uma regra vale para a migração inteira.

| Regra | Efeito |
| --- | --- |
| **Manter o do destino** | O registro do destino fica como está, e as referências passam a apontar para ele. |
| **Sobrescrever com o da origem** | O registro do destino recebe os dados da origem. |

Uma conta nunca é sobrescrita, em nenhuma das regras.

### A chave do projeto [#a-chave-do-projeto]

Se a chave de um projeto já pertence a outro projeto do destino, a tela mostra que a chave é de outro projeto e pede uma decisão. Em **Chave no destino**, escolha outra chave, com 2 a 32 letras minúsculas, números ou hífens. Ou marque **Juntar ao projeto** para levar os dados ao projeto que já existe.

Um report cujo número já pertence a outro report do projeto ganha o próximo número livre. O detalhe da migração lista cada troca como aviso.

Duas migrações ativas não escrevem no mesmo projeto do destino. Se outra migração usa a chave, o Mira recusa o início com **Outra migração ativa já usa uma dessas chaves**. Espere ela terminar.

## Acompanhar [#acompanhar]

A lista de **Migrações** mostra a outra instância, a **Direção** (**Trazida**, **Enviada** ou **Recebida**), o **Estado** e quando foi criada. A **Recebida** é o registro que o destino guarda de um envio.

| Estado | Significa |
| --- | --- |
| **Na fila** | Aguarda o servidor pegar o trabalho. |
| **Rodando** | Está copiando. A tela atualiza sozinha a cada 3 segundos. |
| **Concluída** | Tudo foi copiado. |
| **Concluída com falhas** | Terminou, e alguns registros falharam. |
| **Interrompida** | Parou num erro, como queda de rede ou token recusado. |
| **Cancelada** | Um administrador cancelou. |

Abra uma migração para ver o detalhe: as **Etapas**, uma por recurso, com o progresso e as contagens de **Importados**, **Mantidos**, **Sobrescritos** e **Falhas**, e as listas de **Falhas** e **Avisos**. Use **Filtrar por recurso** para achar um tipo. Uma falha traz o **Id na origem**, o tipo (**Registro inválido**, **Referência ausente**, **Conflito**, **Arquivo ausente** ou **Falha ao gravar**) e o **Motivo**.

Erro de rede, timeout e erro 5xx da outra instância repetem sozinhos, com espera crescente, até 5 vezes. Token recusado e erro 4xx interrompem na hora, com a mensagem em **Último erro**.

## Retomar, tentar as falhas e cancelar [#retomar-tentar-as-falhas-e-cancelar]

As ações aparecem no detalhe, conforme o estado.

| Ação | Quando | O que faz |
| --- | --- | --- |
| **Retomar** | **Interrompida** | Continua do ponto onde parou, sem repetir o que já foi copiado. |
| **Tentar de novo as falhas** | **Concluída com falhas** | Refaz só os registros com falha. Os que dão certo saem da lista de falhas. |
| **Cancelar migração** | **Na fila**, **Rodando** ou **Interrompida** | Para depois da página em gravação. O que já foi importado fica no destino. |

**Retomar** e **Tentar de novo as falhas** chamam a outra instância de novo, então o token precisa continuar válido. Se ele expirou, emita outro e comece uma migração nova com a regra **Manter o do destino**: ela pula o que já chegou. Uma migração **Cancelada** não volta. Para continuar, comece outra.

No destino, uma migração **Recebida** que ficou em **Rodando** porque a origem caiu pode ser cancelada para liberar o projeto.

## Avisos [#avisos]

Os avisos listam o que a migração gravou e pede atenção. Há dois tipos.

- **Pede ação**: uma integração que não veio inteira e que você refaz no destino.
  - **Jira**: o destino do Jira vem sem credencial. Cadastre a conexão com o mesmo site em **Configurações do projeto**, e o destino volta a valer.
  - **GitHub**: a conexão não é criada. Conecte de novo.
  - **Webhook**: o destino entra desligado e com segredo novo. Revele o segredo, atualize o consumidor e só então ligue.
- **Report renumerado**: o report ganhou outro número porque o original já era de outro report do projeto.

## Pela CLI [#pela-cli]

Cada rota de administração da migração vira um comando da [CLI](/desenvolvedores/cli#migrações): `preview-migration`, `create-migration`, `list-migrations`, `get-migration`, `list-migration-failures`, `list-migration-notices`, `resume-migration`, `retry-migration-failures` e `cancel-migration`, além dos três comandos de [tokens de migração](/desenvolvedores/tokens#token-de-migração).
