From fcefcac4e6873db771b2bf88ac6babef863e6259 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Mon, 24 Aug 2026 18:39:00 -0300 Subject: [PATCH] style: prettier format dos docs da entrega C120 --- docs/changelog/2026-08-24-c120.md | 2 +- docs/plans/c121-unificar-chave-invite-redemption-ficha.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/changelog/2026-08-24-c120.md b/docs/changelog/2026-08-24-c120.md index 1deea0f2..f019b4bc 100644 --- a/docs/changelog/2026-08-24-c120.md +++ b/docs/changelog/2026-08-24-c120.md @@ -1 +1 @@ -**C120 — race de append de telefone em `findOrCreateContactByPhone` serializada por lock de ficha (2026-08-24):** lock de ficha `contact-ficha:` AO REDOR do read-modify-write de reuso, com **re-leitura da ficha dentro do lock** (sem ela o lock seria inócuo: o array do find pré-lock fica stale). Débito colhido no /simplify do C112: os locks eram só por telefone — disjuntos entre fluxos que resolvem a MESMA ficha por primários DIFERENTES —, cada fluxo lia o array antes do outro commitar e o last-writer-wins sumia com um número digitado. **`src/utilities/contactPhoneLocks.ts`** ganhou `contactFichaLockKey`/`acquireContactFichaLock` + doc da ordem (telefones em batch primeiro, ficha por último e sozinha — sem ciclo); **`src/utilities/contactIdentity.ts`** adquire a ficha-lock e re-lê (`findByID`, `select: {phones}`) antes de montar o append no reuso; **`src/collections/CampaignUser.ts`** aplica o mesmo lock no sync conta→ficha (2 linhas; collections ⇒ CI int full + e2e curated + build). Sem migration (schema intocado). **Spec int `tests/int/contactPhoneAppendRace.int.spec.ts`**: ficha `{P1,P2}`, fluxos disjuntos [P1,P3]/[P2,P4] com gate determinístico no find — rodado contra o código antigo prova a perda (3 phones), com a fix prova a sobrevivência {P1,P2,P3,P4} (fase TDD vermelho→verde). Pin do key em `postgresTransactionLocks.int.spec.ts`. /simplify (2 revisores): sem achados alta/média bloqueantes; fixes pontuais aplicados (comentário de bypass no re-read, nota READ COMMITTED no header, gate do spec casado por `equals` em vez de substring do where, fixture via `createContact`). Débitos: **C121 (#885) registrado** — unificar a chave da redenção de convite (`invite-redemption-contact:`, `campaignInviteRepository.ts:127-132`/`campaignInviteRedemption.ts:66-145`) com `contact-ficha:` + revalidar spec literal (~1 dia); full-replace/reorder editors e tombstones **Explicitamente fora** (semântica de editor; documentado); extração do helper RMW deferida com gatilho 3º call site; rename `contactPhoneLocks.ts`→`contactLocks.ts` descartado. Verificação: `pnpm gate:fast` verde (lint/typecheck/2458 unit), int full verde (94 arquivos/831 testes), build verde, e2e `campaignContacts` verde (6/6); impl plan `docs/plans/c120-race-append-telefone-ficha-impl.md` + `docs/plans/c121-unificar-chave-invite-redemption-ficha.md`. \ No newline at end of file +**C120 — race de append de telefone em `findOrCreateContactByPhone` serializada por lock de ficha (2026-08-24):** lock de ficha `contact-ficha:` AO REDOR do read-modify-write de reuso, com **re-leitura da ficha dentro do lock** (sem ela o lock seria inócuo: o array do find pré-lock fica stale). Débito colhido no /simplify do C112: os locks eram só por telefone — disjuntos entre fluxos que resolvem a MESMA ficha por primários DIFERENTES —, cada fluxo lia o array antes do outro commitar e o last-writer-wins sumia com um número digitado. **`src/utilities/contactPhoneLocks.ts`** ganhou `contactFichaLockKey`/`acquireContactFichaLock` + doc da ordem (telefones em batch primeiro, ficha por último e sozinha — sem ciclo); **`src/utilities/contactIdentity.ts`** adquire a ficha-lock e re-lê (`findByID`, `select: {phones}`) antes de montar o append no reuso; **`src/collections/CampaignUser.ts`** aplica o mesmo lock no sync conta→ficha (2 linhas; collections ⇒ CI int full + e2e curated + build). Sem migration (schema intocado). **Spec int `tests/int/contactPhoneAppendRace.int.spec.ts`**: ficha `{P1,P2}`, fluxos disjuntos [P1,P3]/[P2,P4] com gate determinístico no find — rodado contra o código antigo prova a perda (3 phones), com a fix prova a sobrevivência {P1,P2,P3,P4} (fase TDD vermelho→verde). Pin do key em `postgresTransactionLocks.int.spec.ts`. /simplify (2 revisores): sem achados alta/média bloqueantes; fixes pontuais aplicados (comentário de bypass no re-read, nota READ COMMITTED no header, gate do spec casado por `equals` em vez de substring do where, fixture via `createContact`). Débitos: **C121 (#885) registrado** — unificar a chave da redenção de convite (`invite-redemption-contact:`, `campaignInviteRepository.ts:127-132`/`campaignInviteRedemption.ts:66-145`) com `contact-ficha:` + revalidar spec literal (~1 dia); full-replace/reorder editors e tombstones **Explicitamente fora** (semântica de editor; documentado); extração do helper RMW deferida com gatilho 3º call site; rename `contactPhoneLocks.ts`→`contactLocks.ts` descartado. Verificação: `pnpm gate:fast` verde (lint/typecheck/2458 unit), int full verde (94 arquivos/831 testes), build verde, e2e `campaignContacts` verde (6/6); impl plan `docs/plans/c120-race-append-telefone-ficha-impl.md` + `docs/plans/c121-unificar-chave-invite-redemption-ficha.md`. diff --git a/docs/plans/c121-unificar-chave-invite-redemption-ficha.md b/docs/plans/c121-unificar-chave-invite-redemption-ficha.md index 1a27534a..768a805f 100644 --- a/docs/plans/c121-unificar-chave-invite-redemption-ficha.md +++ b/docs/plans/c121-unificar-chave-invite-redemption-ficha.md @@ -28,6 +28,7 @@ o C120; aqui é só o call-site novo + revalidar as asserções **literais** do spec `tests/int/campaignInvite.int.spec.ts:799-898` (que ancora a chave antiga). **Opções consideradas:** + - **A — reusar `acquireContactFichaLock` trocando a chave (recomendada):** 1 call-site + revalidação do spec; alinha com o C120. - **B — manter chaves separadas e documentar (rejeitada):** é exatamente o gap @@ -82,4 +83,4 @@ spec `tests/int/campaignInvite.int.spec.ts:799-898` (que ancora a chave antiga). - [ ] Redenção e create-flow serializam a ficha com a MESMA chave - [ ] Spec `campaignInvite.int.spec.ts` revalidado com a chave nova - [ ] Sem migration/schema; Access/Consent intocados -- [ ] CI verde antes do merge (spec + gates) \ No newline at end of file +- [ ] CI verde antes do merge (spec + gates)