teqo-backup/docs/plans/c165-importar-eventos-google.md
Francisco Solla 45617356ee
Some checks are pending
Deploy / preflight (push) Waiting to run
Deploy / verify (push) Blocked by required conditions
Deploy / deploy staging (teqo-staging) (push) Blocked by required conditions
Deploy / requeue when main advanced (push) Blocked by required conditions
Deploy / deploy production (teqo-1313) (push) Blocked by required conditions
docs(plan): C164 + C165 — canal de push do Google Calendar e importação automática de eventos (Related #1009, #1010)
2026-09-14 15:17:07 -03:00

10 KiB
Raw Permalink Blame History

Agenda: importar automaticamente eventos do Google como atividades (sem município, a partir de 16/08/2026)

Status: rascunho Atualizado em: 2026-09-14 Issue: #1010 Priority: P2 Model: cursor-grok-4.5-high Depends: C164 Impeccable: B — encaixe na lista de atividades, no overlay existente e na agenda Rascunho UI: docs/plans/c165-importar-eventos-google-ui-draft.html Appetite: ~3–4 dias eng; um outcome verificável — evento criado no Google após o início da campanha vira atividade no Teqo sozinho, e a coordenação atribui o município quando quiser Responsável: —

Intenção

A agenda da imprensa vive no Google Calendar, mas o Teqo só enxerga dela o que já nasceu no Teqo: o espelho (C114/C115) empurra atividades para o Google e aceita edições de eventos que o próprio Teqo criou — eventos estrangeiros são ignorados de propósito hoje. Daí o pedido do dono: "o que crio no Google não está aparecendo no Teqo". Este item reabre o corte do C115 (criação pelo Google fora de v1; "sem município não entra") para os eventos da conta conectada com início a partir do começo legal da campanha: eles entram como atividade sozinhos, nascem sem município — coisa que o precedente supporter já provou ser possível — e a coordenação tria quando quiser.

Persona e fluxo

  • Persona / contexto: assessoria de imprensa criando compromissos no Google Calendar, muitas vezes pelo celular; coordenação/candidato na mesa fazendo a triagem do que chegou.
  • Job principal: "o que eu crio no Google aparece no Teqo sozinho; eu só atribuo o município depois".
  • Fluxo desejado: a assessoria cria o evento no calendário da imprensa → em minutos ele aparece em /campanha/atividades como atividade confirmada, com badge "Do Google" e "Sem município" → a coordenação abre o overlay e escolhe o município (opcional, pode ficar sem) → a partir daí a atividade segue as regras normais (advisor da carteira vê) → editar/remarcar/cancelar no Google reflete; excluir no Google cancela a atividade.
  • Anti-goals de produto: não virar sincronizador universal (convidados, descrição, RSVP, Meet); não criar segundo cadastro nem segunda fila de triagem; não abrir acesso novo à liderança; não apagar/alterar evento estrangeiro; não virar um painel de administração do sync.

Esboço de fluxo (B)

[assessoria cria no Google Calendar] — início ≥ 16/08/2026
→ motor Google (C164) detecta e importa → atividade `confirmado`, sem município
→ lista/agenda mostram o card com "Do Google" + "Sem município"
→ coordenação triagem: overlay → escolhe o município quando quiser
→ advisor da carteira passa a ver; edições/cancelamento no Google seguem refletindo

Rascunho UI (B)

  • Rascunho UI (gate): docs/plans/c165-importar-eventos-google-ui-draft.html

Objetivo e aceite

  • Evento criado no Google (conta da imprensa já conectada) com início a partir de 16/08/2026 vira atividade no Teqo sozinho, com a imediatez Google→Teqo do C164 — sem ninguém copiar dado.
  • O overlay passa a permitir criar/editar atividade sem município; sem município só coordenação/candidato veem; ao atribuir, a atividade entra nas regras normais (advisor por carteira/responsável).
  • Vínculo estável e idempotente: re-sync não duplica; editar no Teqo atualiza o MESMO evento do Google — nunca nasce um segundo evento teqo….
  • Editar/cancelar no Google reflete na atividade (mesma regra de relógio do C115); excluir no Google cancela a atividade.
  • Nada anterior a 16/08/2026 entra (sem backfill); evento estrangeiro nunca é apagado/alterado pelo Teqo; leader lockdown intocado; sem Consent novo; o Teqo segue inteiro se o Google cair.

Dados (intenção)

  • Vou apresentar dados? Não — superfície operacional (lista, agenda, overlay); sem leitura agregada nova.
  • Decisões desbloqueadas: coordenação decide o município de um compromisso importado (triagem), o que muda quem o vê; nenhuma métrica.
  • Forma: adiada ao plano de implementação.

Dados da decisão (literais)

  • Corte: início do evento (instante na América/Bahia) ≥ 2026-08-16; reusar CALENDAR_PHASE_ANCHORS.consolidationStart (src/lib/visitPlannerAnchors.ts:22-29) — não duplicar o literal nem criar outro corte. Anterior fica fora para sempre.
  • Horizonte de varredura: a mesma janela que o espelho já usa (90 dias para trás / 365 para a frente), com o piso do corte; evento fora da janela não é importado nem espelhado na v1.
  • Importado nasce status: confirmado, título original do Google sem o prefixo [Município] (com espaço final; o prefixo é só de evento teqo… espelhado).
  • Atividade sem município é permitida; visível/editável só por coordinator/candidate (precedente supporter); com município, regras normais.
  • Vínculo atividade↔evento Google é system-write (invisível aos user paths): garante idempotência e que editar no Teqo atualiza O MESMO evento.
  • Google edita/cancela → atividade (relógio do C115); Google exclui → atividade cancelada.
  • location do evento → locality; descrição ignorada na v1 (texto vive no Google).
  • Recorrência: singleEvents=true expande; cada ocorrência vira atividade própria.
  • Sem Consent novo (dado interno de staff); leader lockdown intocado; Teqo fonte da verdade; evento estrangeiro nunca apagado/alterado pelo Teqo.

Direção no codebase (hipótese)

  • Áreas prováveis: src/collections/Activity.ts + src/lib/schemas/activity.ts (município opcional), src/utilities/activityFormData.ts, src/utilities/access/activities.ts, motor src/utilities/googleCalendarSync.ts (+ googleCalendarEventMapping.ts/googleCalendarReverseEdit.ts), src/components/campaign/activity/ActivityOverlay.tsx, ação em src/app/(campaign)/campanha/actions/activity.ts, omnibox src/utilities/activityOmnibox.ts + ActivityFilters.tsx.
  • Precedente a olhar: supporter com município opcional (src/utilities/access/supporters.ts:18-41,43-66; mensagem própria em src/lib/schemas/supporter.ts:18-19) e o C115 (relógio/conflito).
  • Risco de acoplamento: o vínculo com evento estrangeiro precisa nascer (hoje só o id teqo… codifica vínculo; não há googleEventId em Activity) — schema/migration é decisão do plano de implementação. Pontos que hoje assumem município: ação de rascunhos de demanda (actions/activity.ts:293-294 dereferencia .municipality.id), CampaignDemand.ts:242-279 ("Município da demanda inválido"), activityRelationOptions.ts:21-28; overlay exige município em ActivityOverlay.tsx:195-205,375-389,459. Dossiê/filtros por município não mostrarem sem-município é aceitável (a triagem é na lista).
  • Testes que pinam município obrigatório (mudam com o item): tests/int/campaignActivity.int.spec.ts:48-55,99-106, tests/unit/activityOverlay.unit.spec.tsx:245-258, tests/e2e/campaignActivity.e2e.spec.ts:88.

Dependências

  • Dura: C164 — mesmo motor Google e a imediatez Google→Teqo; sem ela o "sozinho" fica capenga.
  • Suaves: C114 (espelho), C115 (bidirecional/relógio; este item reabre o corte de criação), C149/C150 (conta e calendário principal conectados).

Fora de escopo

  • Eventos anteriores a 16/08/2026: sem backfill retroativo.
  • Descrição, convidados/RSVP, lembretes, Meet e demais metadados do Google não viram campo do Teqo na v1.
  • Tela dedicada de triagem/fila de aprovação: a triagem é inline (lista + overlay).
  • Importar de calendários secundários/inscritos além do principal conectado.
  • Qualquer mudança no leader lockdown ou no feed iCal público.

Rabbit holes de produto

  • Bidirecional total ("já que está lá, sincroniza convidados/descrição/cor"). Se alguém "só completar": a agenda vira espelho integral da API do Google. Corte: só vínculo + título/horário/local/cancelamento (relógio C115); descrição fica no Google.
  • Backfill do calendário histórico. Se alguém "só completar": anos de eventos pessoais/institucionais viram atividade. Corte: só início ≥ 16/08/2026, daqui pra frente.
  • Fila de aprovação com tela nova. Se alguém "só completar": segundo fluxo de triagem, notificações e estados. Corte: lista + filtro "Sem município" + overlay existente.
  • Apagar/alterar o evento estrangeiro para "limpar" o Teqo. Se alguém "só completar": Teqo escrevendo em evento que não criou. Corte: exclusão/edição no Teqo nunca toca evento estrangeiro — no máximo cancela a atividade.

Questões em aberto (produto)

  • Quem vê e edita atividade sem município? Opções: A) só coordenação/candidato (precedente supporter) | B) + assessores (sem carteira para casar; precisaria de claim) | C) todo staff lê, só coordenação edita. Recomendação: A. (assumido — validar)
  • Descrição do evento: importar ou ignorar na v1? Opções: A) ignorar (texto vive no Google) | B) guardar em campo livre/atualização | C) concatenar no locality. Recomendação: A. (assumido — validar)
  • Cancelar no Teqo remove o evento no Google? Opções: A) sim, cancela o MESMO evento (consistente com "Teqo fonte da verdade") | B) só marca a atividade cancelada e deixa o evento | C) perguntar a cada cancelamento. Recomendação: A.
  • Eventos pessoais futuros do calendário da imprensa (aniversário, médico) viram atividade? Opções: A) aceitar e triar (cancelar/descartar na lista) | B) exigir calendário dedicado da campanha | C) allowlist por palavra-chave. Recomendação: A — o corte de 16/08 limita o volume e um importado a mais custa pouco; B depende de mudança de hábito externa.
  • Evento importado que ganha município passa a levar [Município] no título do Google? Opções: A) não — mantém o título original (o vínculo system-write basta) | B) sim, vira o padrão dos teqo… (confunde quem criou no Google). Recomendação: A.

Referências

  • GitHub Issue #1010
  • Rascunho UI (gate): docs/plans/c165-importar-eventos-google-ui-draft.html
  • docs/plans/c115-google-calendar-edicao-bidirecional.md:21,65 (corte reaberto), C114, C149, C150
  • src/lib/visitPlannerAnchors.ts:22-29 (corte canônico), src/utilities/googleCalendarSync.ts, src/utilities/access/supporters.ts, AGENTS-campaign.md ("Campaign activities", "Campaign supporters", "Campaign Municípios model")