feat(C119): status de apoio 'Lembrança' em lideranças — enum, badge e exclusão de pendências
This commit is contained in:
parent
9789bf36e6
commit
5fa4e22c9d
17 changed files with 140 additions and 26 deletions
89
docs/plans/lembranca-status-liderancas-impl.md
Normal file
89
docs/plans/lembranca-status-liderancas-impl.md
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# Impl: Status de apoio "Lembrança" em lideranças
|
||||
|
||||
Status: em execução
|
||||
Atualizado em: 2026-08-11
|
||||
Issue: #661
|
||||
Intenção: docs/plans/lembranca-status-liderancas.md
|
||||
Appetite restante: herdado (~1 dia eng) — item pequeno, cabe folgado
|
||||
|
||||
## Leitura da intenção
|
||||
|
||||
- **Outcome:** novo valor `lembranca` no enum `supportStatus` de `leadership` (entre `em_disputa` e `negativo` no seletor), visível e marcável em TODAS as superfícies onde os 4 status atuais aparecem (célula da lista com auto-save, ficha/wizard/admin, filtro das listas de lideranças e de pessoas, Sollinha); **nunca** entra no critério de pendência de abordagem (fail-closed na query, não só na UI); badge visualmente distinto; nenhuma leitura existente quebra.
|
||||
- **O que NÃO negociar:** liderança "Lembrança" é favorável e não é pendente — exclusão das pendências espelhando o "Negativo" (na query `getPendingLeaderships`, que já é fail-closed); sem segundo eixo de classificação; sem fluxo próprio de votos (usa o campo de votos declarados existente); leader lockdown intacto (status é staff-only).
|
||||
- **O que reavaliar:** a hipótese da intenção cobre as áreas certas, mas encontrei duas superfícies que ela não nomeou: (1) `peopleData.ts` `leadershipStatusesInOrder` — lista dura dos 4 valores que **silenciosamente omitiria** o novo status do facet da lista de pessoas; (2) `getLeaderships.ts` mantém uma tabela de rótulos duplicada (`SUPPORT_LABELS`) que também esqueceria o valor novo — candidata a DRY com `supportStatusLabels`.
|
||||
|
||||
## Abordagem recomendada
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[leadershipSupportStatuses\n+ 'lembranca'] --> B[collection options\n+ migration ALTER TYPE]
|
||||
A --> C[labels + badge variant\n+ tokens CSS]
|
||||
A --> D[listas/filtros/forms\nvia enum array]
|
||||
A --> E[getLeaderships usa\nsupportStatusLabels]
|
||||
F[getPendingLeaderships\nINTOCADO + teste pin] --> G[pendências excluem\nlembranca fail-closed]
|
||||
H[systemPrompt +1 linha\nreconhecimento] --> I[Sollinha responde\nsobre o status]
|
||||
```
|
||||
|
||||
**Opções consideradas:** A (valor novo no enum existente, fonte única) | B (segundo campo/eixo de classificação) | C (status composto em string)
|
||||
**Recomendação:** A — o produto decidiu no gate que é um valor a mais no enum; a engenharia tem um único source of truth (`leadershipSupportStatuses` + `supportStatusLabels`) e as superfícies que derivam dele (listas, forms, URLs, omnibox) ganham o valor automaticamente.
|
||||
**Rejeitadas:** B porque a intenção corta explicitamente o segundo eixo (matriz de combinações); C porque destrói filtro `in` no Postgres e indexação.
|
||||
|
||||
### Decisões de engenharia
|
||||
|
||||
- **D1 — Migration do enum.** `ALTER TYPE "public"."enum_leadership_support_status" ADD VALUE 'lembranca' BEFORE 'negativo'` — o `BEFORE` preserva a ordem do enum no Postgres igual à do seletor (decisão do gate: entre "Em disputa" e "Negativo"), então `sort: 'supportStatus'` na lista ordena igual ao seletor.
|
||||
- _Rejeitadas:_ `ADD VALUE` sem `BEFORE` (anexa no fim → ordenação por status divergiria do seletor); recriar o tipo inteiro (rename+create+cast, precedente C14) — destrutivo demais para um valor novo, risco desnecessário em prod.
|
||||
- Precedentes: `20260723_025513` (ADD VALUE … BEFORE), `20260728_041547` / `20260724_180000` (ADD VALUE). Se o `migrate:create` gerar `ADD VALUE` sem `BEFORE`, editar o `.ts` da migration nova (migration não shipada — editável; nunca editar as antigas).
|
||||
- **D2 — Badge distinto.** Novo variant `support-remembered` no `Badge` + tokens `--support-remembered`/`-foreground` (índigo suave: `#e0e7ff` / `#3730a3`) — distinto dos 4 atuais (verde/cinza/âmbar/vermelho) e semanticamente "resolvido e favorável".
|
||||
- _Rejeitadas:_ reusar `estimate-*` (âmbar colide com "Em disputa"); variant `default` (não distinto).
|
||||
- **D3 — `getLeaderships.ts`: matar a tabela duplicada.** Substituir `SUPPORT_LABELS` por `supportStatusLabels` de `leadershipLabels.ts` (tabela de strings pura, client-safe, importável do server). Um valor novo no enum seria propagado pela fonte única em vez de exigir lembrar da duplicata.
|
||||
- _Rejeitada:_ só adicionar `lembranca` na duplicata — deixa a segunda fonte de verdade viva para o próximo status.
|
||||
- **D4 — `peopleData.ts` `leadershipStatusesInOrder`:** trocar a lista dura `['engajado','a_abordar','em_disputa','negativo']` por `leadershipSupportStatuses.filter(s => statuses.has(s))`. Sem isso o status novo não apareceria no facet da lista de pessoas (miss silencioso, sem teste pegando).
|
||||
- **D5 — Pendência: não tocar.** `PENDING_SUPPORT_STATUSES = ['a_abordar','em_disputa','engajado']` e `PENDING_CRITERION` ficam como estão — "Lembrança" e "Negativo" já são excluídos pela ausência da lista (fail-closed na query) e o critério declarado continua sem o novo estado (aceite: "pendências declaram o critério sem o novo estado"). Adicionar teste que pin a exclusão.
|
||||
- **D6 — Sollinha reconhece o status:** +1 linha na seção "Lideranças pendentes de abordagem" do `systemPrompt.ts` (ex.: "Liderança com status 'Lembrança' é favorável sem compromisso — não conta como pendente de abordagem"). O rótulo na leitura vem de D3.
|
||||
- **Semânticas que excluem "Lembrança" intencionalmente (verificar com testes, não mudar):** convite de login exige `engajado` (`campaignInvite*`), acesso ao app exige `engajado` (`access/contacts.ts`, `access/municipalities.ts`), opção de "responsável" de atividade exige `engajado` (`activityLeadershipOptions.ts`) — uma "Lembrança" não é engajada, comportamento correto.
|
||||
|
||||
### Componentes / mudanças
|
||||
|
||||
- **`leadershipSupportStatuses`** (`src/lib/schemas/leadership.ts`): `['engajado', 'a_abordar', 'em_disputa', 'lembranca', 'negativo']` — tipo `SupportStatus` e `isSupportStatus` derivam sozinhos.
|
||||
- **`Leadership.ts`** (collection): opção `{ label: 'Lembrança', value: 'lembranca' }` na posição 4 (admin select + admin filter automáticos).
|
||||
- **Migration:** `add_lembranca_support_status` via `pnpm migrate:create`, SQL conforme D1.
|
||||
- **`payload-types.ts`:** regenerar via `pnpm generate:types`.
|
||||
- **`leadershipLabels.ts`:** `lembranca: 'Lembrança'`.
|
||||
- **`SupportStatusBadge.tsx`:** `lembranca: { variant: 'support-remembered' }`.
|
||||
- **`Badge.tsx`** + **`styles.css`:** variant e tokens (D2).
|
||||
- **`getLeaderships.ts`:** `SUPPORT_LABELS` → `supportStatusLabels` (D3).
|
||||
- **`systemPrompt.ts`:** linha de reconhecimento (D6).
|
||||
- **`peopleData.ts`:** `leadershipStatusesInOrder` via enum canônico (D4).
|
||||
- **Automático (sem edição):** `LeadershipListSupportStatusControl`, `LeadershipForm`/`LeadershipInternalForm`/`WizardLeadershipForm`, `leadershipListFilters`/`peopleListFilters`, `leadershipListUrl`/`peopleListUrl` (parse enum exaustivo), omniboxes, `leadershipData`, `wizardLeadershipContract`, `municipalityV2Network*`, actions/routes zod (`z.enum(leadershipSupportStatuses)`), `support-status/route.ts`.
|
||||
- **Access / Consent:** nenhum — status é staff-only (`canManageCampaignStaffField`), leader lockdown intocado.
|
||||
|
||||
### Dados → forma
|
||||
|
||||
Não se aplica (nenhuma superfície de dado nova; valor de enum flui por filtros/facets existentes — decisão de produto do gate).
|
||||
|
||||
## Fases verificáveis
|
||||
|
||||
1. **Schema+server** — enum array + collection options + migration + `generate:types`; verificação: `pnpm migrate:status` e `pnpm migrate` local.
|
||||
2. **UI** — labels + Badge + tokens + `SupportStatusBadge`; verificação: badge unit test (it.each) renderiza `Lembrança`.
|
||||
3. **IA + pessoas** — `getLeaderships` DRY, `systemPrompt`, `peopleData` ordem; verificação: testes de tool e listas.
|
||||
4. **Testes** — atualizar os que enumeram status (badge it.each, "every status member" do `leadershipListUrl`, fixture e2e, int spec com `lembranca` persistindo, pin de exclusão de pendência); NENHUM teste novo de feature em volume.
|
||||
5. **Gates** — `tsc --noEmit`, `pnpm lint`, `pnpm format:check`, `pnpm exec knip`, `pnpm check:cycles`, `pnpm test`, `pnpm build` local.
|
||||
|
||||
## Rabbit holes / Não escopo (engenharia)
|
||||
|
||||
- Migração destrutiva do enum (recreate) — desnecessária com `BEFORE`.
|
||||
- Reordenar `a_abordar` no seletor — produto não pediu.
|
||||
- Tratamento especial de votos para "Lembrança" — decidido no gate: campo de votos declarados já existente.
|
||||
- Qualquer mudança em convites/acesso-app/atividade (engajado-only é o comportamento correto).
|
||||
|
||||
## Riscos e mitigação
|
||||
|
||||
- **Migration `ADD VALUE` + transação Postgres:** permitido desde PG 12 dentro de transação (novo valor não usado na mesma transação); precedente shipado em prod (`20260723_025513`). Mitigação: verificar `pnpm migrate` local e `migrate:status` antes do push.
|
||||
- **Superfície enumerada esquecida:** mitigado por D3/D4 (fonte única) + teste de badge it.each + teste "every status member" da URL.
|
||||
- **Filtro `lembranca` vazando para pendências:** fail-closed já está na query; o teste unit do `getPendingLeaderships` passa a incluir `lembranca` na exclusão pinada.
|
||||
|
||||
## Aceite de engenharia
|
||||
|
||||
- [x] Aceite de produto da intenção ainda coberto (superfícies todas + pendências excluem + badge distinto + Sollinha reconhece)
|
||||
- [x] Invariantes AGENTS/engineering-standards (sem transações novas, sem access novo, nomes EN, rótulos pt-BR)
|
||||
- [x] Testes de domínio previstos (badge it.each, URL enum exaustivo, pin pendência, int persistence)
|
||||
|
|
@ -72,6 +72,8 @@ body,
|
|||
--color-support-to-approach: var(--support-to-approach);
|
||||
--color-support-disputed-foreground: var(--support-disputed-foreground);
|
||||
--color-support-disputed: var(--support-disputed);
|
||||
--color-support-remembered-foreground: var(--support-remembered-foreground);
|
||||
--color-support-remembered: var(--support-remembered);
|
||||
--color-support-negative-foreground: var(--support-negative-foreground);
|
||||
--color-support-negative: var(--support-negative);
|
||||
--color-estimate-confirmed-foreground: var(--estimate-confirmed-foreground);
|
||||
|
|
@ -249,6 +251,8 @@ body,
|
|||
--support-to-approach-foreground: #46505c;
|
||||
--support-disputed: #fef3c7;
|
||||
--support-disputed-foreground: #92400e;
|
||||
--support-remembered: #e0e7ff;
|
||||
--support-remembered-foreground: #3730a3;
|
||||
--support-negative: #fee2e2;
|
||||
--support-negative-foreground: #991b1b;
|
||||
--estimate-confirmed: #dcfce7;
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ export const Leadership: CollectionConfig = {
|
|||
{ label: 'Engajado', value: 'engajado' },
|
||||
{ label: 'A abordar', value: 'a_abordar' },
|
||||
{ label: 'Em disputa', value: 'em_disputa' },
|
||||
{ label: 'Lembrança', value: 'lembranca' },
|
||||
{ label: 'Negativo', value: 'negativo' },
|
||||
],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ const statusPresentation = {
|
|||
engajado: { variant: 'support-engaged' },
|
||||
a_abordar: { variant: 'support-to-approach' },
|
||||
em_disputa: { variant: 'support-disputed' },
|
||||
lembranca: { variant: 'support-remembered' },
|
||||
negativo: { variant: 'support-negative' },
|
||||
} as const
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ const badgeVariants = cva(
|
|||
'bg-support-to-approach text-support-to-approach-foreground [a]:hover:bg-support-to-approach/80',
|
||||
'support-disputed':
|
||||
'bg-support-disputed text-support-disputed-foreground [a]:hover:bg-support-disputed/80',
|
||||
'support-remembered':
|
||||
'bg-support-remembered text-support-remembered-foreground [a]:hover:bg-support-remembered/80',
|
||||
'support-negative':
|
||||
'bg-support-negative text-support-negative-foreground [a]:hover:bg-support-negative/80',
|
||||
'estimate-confirmed':
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ export const leadershipSupportStatuses = [
|
|||
'engajado',
|
||||
'a_abordar',
|
||||
'em_disputa',
|
||||
'lembranca',
|
||||
'negativo',
|
||||
] as const
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ import * as migration_20260808_134911_add_calendar_feed from './20260808_134911_
|
|||
import * as migration_20260808_184113_remodel_activity_responsible from './20260808_184113_remodel_activity_responsible';
|
||||
import * as migration_20260809_204728_add_campaign_user_contact_and_leadership_advisors from './20260809_204728_add_campaign_user_contact_and_leadership_advisors';
|
||||
import * as migration_20260810_010844_add_activity_all_day from './20260810_010844_add_activity_all_day';
|
||||
import * as migration_20260811_111828_add_contact_phones_array from './20260811_111828_add_contact_phones_array';
|
||||
import * as migration_20260811_133332_add_google_calendar_sync from './20260811_133332_add_google_calendar_sync';
|
||||
import * as migration_20260811_153004_add_lembranca_support_status from './20260811_153004_add_lembranca_support_status';
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
|
|
@ -297,13 +296,8 @@ export const migrations = [
|
|||
name: '20260810_010844_add_activity_all_day',
|
||||
},
|
||||
{
|
||||
up: migration_20260811_111828_add_contact_phones_array.up,
|
||||
down: migration_20260811_111828_add_contact_phones_array.down,
|
||||
name: '20260811_111828_add_contact_phones_array',
|
||||
},
|
||||
{
|
||||
up: migration_20260811_133332_add_google_calendar_sync.up,
|
||||
down: migration_20260811_133332_add_google_calendar_sync.down,
|
||||
name: '20260811_133332_add_google_calendar_sync',
|
||||
up: migration_20260811_153004_add_lembranca_support_status.up,
|
||||
down: migration_20260811_153004_add_lembranca_support_status.down,
|
||||
name: '20260811_153004_add_lembranca_support_status'
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -590,7 +590,7 @@ export interface Leadership {
|
|||
stateDeputies?: (number | StateDeputy)[] | null;
|
||||
advisors?: (number | CampaignUser)[] | null;
|
||||
exclusive?: boolean | null;
|
||||
supportStatus: 'engajado' | 'a_abordar' | 'em_disputa' | 'negativo';
|
||||
supportStatus: 'engajado' | 'a_abordar' | 'em_disputa' | 'lembranca' | 'negativo';
|
||||
user?: (number | null) | CampaignUser;
|
||||
consent?: (number | null) | Consent;
|
||||
consentContentHash?: string | null;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ export const AI_SYSTEM_PROMPT = `Você é o Sollinha, assistente virtual da camp
|
|||
## Lideranças pendentes de abordagem
|
||||
- Use a ferramenta "getPendingLeaderships" para "quais lideranças ainda precisam ser abordadas em X", "lideranças sem assessor responsável" ou "quais municípios não têm liderança cadastrada".
|
||||
- A resposta da ferramenta traz o critério de pendência — declare-o sempre na sua resposta (ex.: "critério: status 'A abordar' ou 'Em disputa'; ou 'Engajado' sem compromisso de votos no escopo consultado").
|
||||
- Liderança com status "Lembrança" é favorável sem compromisso — não conta como pendente de abordagem; se perguntarem, explique isso e, se houver, aponte essas lideranças pela leitura normal de lideranças.
|
||||
- Escopos: território de identidade (aceita grafia sem acento, ex.: "Vale do Jiquiriça"), cidade ("Salvador" = as 19 zonas eleitorais juntas) ou município. Sem escopo, vale o escopo de acesso do usuário.
|
||||
- Quando a resposta trouxer "escopoRestrito: true", deixe claro que os resultados estão limitados aos municípios do portfólio do usuário; quando trouxer "truncado: true", sugira estreitar o escopo para ver o restante.
|
||||
- Ofereça links de navegação (buildCampaignLinks) para as lideranças citadas (por id) e municípios (por slug); assessores (por id) quando o perfil permitir.
|
||||
|
|
|
|||
|
|
@ -3,13 +3,7 @@ import type { Where } from 'payload'
|
|||
import { z } from 'zod'
|
||||
|
||||
import type { AIToolContext } from '@/lib/ai/types'
|
||||
|
||||
const SUPPORT_LABELS: Record<string, string> = {
|
||||
engajado: 'Engajado',
|
||||
a_abordar: 'A abordar',
|
||||
em_disputa: 'Em disputa',
|
||||
negativo: 'Negativo',
|
||||
}
|
||||
import { supportStatusLabels } from '@/utilities/leadership/leadershipLabels'
|
||||
|
||||
export const getLeaderships = (ctx: AIToolContext) =>
|
||||
tool({
|
||||
|
|
@ -67,7 +61,8 @@ export const getLeaderships = (ctx: AIToolContext) =>
|
|||
organizacoes: organizations.map((o) => o.name),
|
||||
apoioExclusivo: doc.exclusive === true,
|
||||
status:
|
||||
SUPPORT_LABELS[(doc.supportStatus as string) ?? ''] ?? (doc.supportStatus as string),
|
||||
supportStatusLabels[doc.supportStatus as keyof typeof supportStatusLabels] ??
|
||||
(doc.supportStatus as string),
|
||||
observacoes: (doc.notes as string) ?? null,
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ export const supportStatusLabels: Record<SupportStatus, string> = {
|
|||
engajado: 'Engajado',
|
||||
a_abordar: 'A abordar',
|
||||
em_disputa: 'Em disputa',
|
||||
lembranca: 'Lembrança',
|
||||
negativo: 'Negativo',
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ import type { Payload } from 'payload'
|
|||
|
||||
import { primaryPhoneOf } from '@/lib/phone'
|
||||
import { relationshipId, uniqueRelationshipIds } from '@/lib/relationship'
|
||||
import { isSupportStatus, type SupportStatus } from '@/lib/schemas/leadership'
|
||||
import {
|
||||
isSupportStatus,
|
||||
leadershipSupportStatuses,
|
||||
type SupportStatus,
|
||||
} from '@/lib/schemas/leadership'
|
||||
import type { CampaignUser, Contact, Leadership, StateDeputy } from '@/payload-types'
|
||||
import { municipalityIdsByAdvisorIds } from '@/utilities/advisorData'
|
||||
import { getAdvisorMunicipalityIds, isCampaignStaff } from '@/utilities/campaignAccess'
|
||||
|
|
@ -275,9 +279,7 @@ export const peopleFilterFacetsFromRows = (
|
|||
}
|
||||
|
||||
const leadershipStatusesInOrder = (statuses: ReadonlySet<SupportStatus>): SupportStatus[] =>
|
||||
(['engajado', 'a_abordar', 'em_disputa', 'negativo'] as const).filter((status) =>
|
||||
statuses.has(status),
|
||||
)
|
||||
leadershipSupportStatuses.filter((status) => statuses.has(status))
|
||||
|
||||
const EMPTY_FACETS: PeopleListFilterFacets = { municipalityIDs: [], statuses: [] }
|
||||
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ export class CampaignE2EOwnership {
|
|||
}: {
|
||||
namePrefix: string
|
||||
municipalities: { id: number; name: string }[]
|
||||
supportStatus?: 'a_abordar' | 'em_disputa' | 'engajado' | 'negativo'
|
||||
supportStatus?: 'a_abordar' | 'em_disputa' | 'lembranca' | 'engajado' | 'negativo'
|
||||
user?: number
|
||||
}): Promise<{ contactName: string; contactId: number; leadershipId: number }> {
|
||||
const contactName = this.value(namePrefix)
|
||||
|
|
|
|||
|
|
@ -427,6 +427,27 @@ describe('campaign leadership domain', () => {
|
|||
).rejects.toThrow()
|
||||
})
|
||||
|
||||
it('persists the "lembranca" support status through create and internal update (C119)', async () => {
|
||||
const coordinator = await campaignFixtures().createCampaignUser('coordinator')
|
||||
const municipality = await campaignFixtures().getMunicipality()
|
||||
|
||||
const created = await createLeadershipRecord(payload, coordinator, {
|
||||
municipalities: [municipality.id],
|
||||
name: 'Liderança Lembrança',
|
||||
phone: campaignFixtures().phone(),
|
||||
supportStatus: 'lembranca',
|
||||
})
|
||||
|
||||
const doc = await payload.findByID({ collection: 'leadership', id: created.id, depth: 0 })
|
||||
expect(doc.supportStatus).toBe('lembranca')
|
||||
|
||||
const updated = await updateLeadershipInternalRecord(payload, coordinator, {
|
||||
id: created.id,
|
||||
supportStatus: 'lembranca',
|
||||
})
|
||||
expect(updated.supportStatus).toBe('lembranca')
|
||||
})
|
||||
|
||||
it('denies leadership creation to leader accounts', async () => {
|
||||
const leader = await campaignFixtures().createCampaignUser('leader')
|
||||
const municipality = await campaignFixtures().getMunicipality()
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ describe('campaign visual foundation', () => {
|
|||
['engajado', 'Engajado'],
|
||||
['a_abordar', 'A abordar'],
|
||||
['em_disputa', 'Em disputa'],
|
||||
['lembranca', 'Lembrança'],
|
||||
['negativo', 'Negativo'],
|
||||
] as const)('renders the %s support status with text and semantic state', (status, label) => {
|
||||
const html = renderToStaticMarkup(createElement(SupportStatusBadge, { status }))
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ describe('leadership list URL contract', () => {
|
|||
it('canonicalizes selecting every status member to the absent filter (B18)', () => {
|
||||
expect(
|
||||
parseLeadershipListParams({
|
||||
status: ['engajado', 'a_abordar', 'em_disputa', 'negativo'],
|
||||
status: ['engajado', 'a_abordar', 'em_disputa', 'lembranca', 'negativo'],
|
||||
}),
|
||||
).toEqual({ page: 1 })
|
||||
})
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ describe('getPendingLeaderships gate (B185)', () => {
|
|||
})
|
||||
|
||||
describe('getPendingLeaderships pending criterion (B185)', () => {
|
||||
it('lists a_abordar/em_disputa e engajado sem pledge; exclui engajado com pledge e qualquer negativo', async () => {
|
||||
it('lists a_abordar/em_disputa e engajado sem pledge; exclui engajado com pledge, qualquer negativo e qualquer lembranca (C119)', async () => {
|
||||
const find = vi.fn()
|
||||
find.mockResolvedValueOnce(
|
||||
findResult([
|
||||
|
|
@ -95,6 +95,7 @@ describe('getPendingLeaderships pending criterion (B185)', () => {
|
|||
leadershipDoc({ id: 3, supportStatus: 'em_disputa' }),
|
||||
leadershipDoc({ id: 4, supportStatus: 'engajado' }),
|
||||
leadershipDoc({ id: 5, supportStatus: 'negativo' }),
|
||||
leadershipDoc({ id: 6, supportStatus: 'lembranca' }),
|
||||
]),
|
||||
)
|
||||
find.mockResolvedValueOnce(findResult([{ leadership: 2 }]))
|
||||
|
|
|
|||
Loading…
Reference in a new issue