# Correção de concorrência do mapeamento de produto de planos Launch

AUTH-03 da análise de autorização foi corrigido. Apenas o servidor Launch e testes de regressão correspondentes foram alterados; SDK não foi implantado ou publicado; os limites de decisão de autorização de Licentivo e SDK permanecem inalterados.

## Editar

- Ao salvar mapeamento, a transação bloqueia primeiro o registro comum do produto Launch, depois a versão do plano. Solicitações de diferentes planos ou processos seguem o mesmo bloqueio de produto; solicitações conflitantes retornam HTTP 409 `PRODUCT_MAPPING_CONFLICT`.
- `products.licentivo_product_id` armazena rota pública estável do produto. Após o primeiro salvamento bem-sucedido, outros planos do mesmo produto Launch só podem escolher esse produto Licentivo; diferentes políticas dele são permitidas. O campo não armazena direitos de recursos, cota de dispositivos ou estado de autorização de clientes.
- A identidade do cliente lê a rota estável e não escolhe produto pela versão máxima de todos os planos. Publicação de plano e geração de configuração de integração SDK também verificam a mesma vinculação.
- Bancos antigos recebem automaticamente um campo anulável. Dados sem campo estável consultam, em ordem, histórico de compras como pagamentos, histórico de publicações e demais mapeamentos; múltiplos produtos na mesma prioridade geram conflito explícito, sem adivinhação. Um único produto comprado tem prioridade sobre rascunho irrelevante; salvar mapeamento compatível pode então fixar a vinculação. Edição de conteúdo do produto preserva a vinculação.

Dados históricos incorretos já vendidos para vários produtos Licentivo ainda exigem análise manual; esta mudança não reescreve compras ou licenças remotas. Para mudar para outro produto Licentivo, crie novo produto Launch; um novo plano não pode reescrever a rota original.

Implementação em [salvamento de mapeamento](https://github.com/spf86/licentivo-launch/blob/main/internal/app/connections.go), [rota do produto](https://github.com/spf86/licentivo-launch/blob/main/internal/app/product_mapping.go), [emissão de identidade](https://github.com/spf86/licentivo-launch/blob/main/internal/app/identity.go), [validação de publicação](https://github.com/spf86/licentivo-launch/blob/main/internal/app/catalog.go), [verificação de integração](https://github.com/spf86/licentivo-launch/blob/main/internal/app/integration.go) e [modelo de dados](https://github.com/spf86/licentivo-launch/blob/main/internal/storage/models.go).

## Verificação local

| Verificar | Resultado |
| --- | --- |
| Comparação com a implementação anterior à correção | O mesmo teste de regressão captura consistentemente dois salvamentos conflitantes bem-sucedidos ao mesmo tempo e falha conforme esperado |
| Regressão específica de mapeamento após a correção | Uma solicitação conflitante passa e outra retorna 409; dois salvamentos compatíveis passam; identidade após sincronização de pagamento não é afetada por rascunho incorreto; camada de integração SDK aceita contexto correto do produto |
| Proteção de dados históricos | Rota comprada prioritária, erro em ambiguidade, publicação de rascunho incorreto proibida, publicação histórica incorreta não gera configuração SDK e edição de conteúdo preserva vinculação: tudo passou |
| Todos os pacotes de fonte Go e regressão MySQL | 192 registros de testes aprovados, incluindo subtestes; nenhuma falha. `TestProductUploadRoundTrip` ignorado e não contado como aprovado |
| Atualização estrutural do banco antigo | Estrutura sem coluna de rota recebe campo anulável na inicialização; inicialização repetida passa |
| Teste conjunto real de Launch, Licentivo e Go SDK | 13 etapas comerciais aprovadas, incluindo compra, execução de recurso assinado real, recuperação após fechamento comum, logout, desvinculação remota, geração antiga, reembolso de renovação, revogação de conta e recusa de execução após reembolso/chargeback |
| Teste adicional final | Regressão específica de mapeamento passou em novo banco vazio, incluindo verificação de configuração de integração para publicação histórica; `go vet` passou |

Após regressão completa e teste conjunto com serviços reais, foi adicionada uma verificação de consistência à integração SDK e a regressão específica que inclui esse cenário e `go vet` foram executados novamente separadamente. A falha esperada da implementação antiga prova que o teste detecta a condição de corrida original; não é falha de regressão não resolvida.

O teste conjunto usou MySQL 8.0.32 local isolado, serviço Licentivo atual e Go SDK real; canais de pagamento e DeepL usaram serviços simulados isolados, sem cobrança real ou tradução paga. Testes específicos de concorrência e mapeamentos históricos incorretos usam lógica Launch real, MySQL e simulador de protocolo; não se afirma teste conjunto com serviço real para os nove SDKs nesta rodada.

`192.168.2.177` não foi acessado nesta rodada. Processos temporários MySQL e Licentivo iniciados foram encerrados, serviços existentes preservados. Material original está no diretório ignorado `.local/mapping-fix-20261024/`; resumo compartilhável em [evidências de verificação](https://github.com/spf86/licentivo-launch/blob/main/docs/product-mapping-fix-evidence-2026-10-24.json).
