@tmf/communication-front (10.22.0)
Installation
@tmf:registry=npm install @tmf/communication-front@10.22.0"@tmf/communication-front": "10.22.0"About this package
@tmf/communication-front
Front React replicável do módulo de Comunicação da TMF (campanhas de marketing, e-mail, SMS, WhatsApp, push, provedores, financeiro/wallets e o Gestor de Campanhas WhatsApp; a UI de bots saiu deste pacote — o motor de bots vive na lib service-desk).
Componentes desacoplados que consomem um contrato (@tmf/platform-core → AppContract)
- um
CommunicationApiClient. Adoção por configuração, não por código — o produto host (Hub/TMF Management, TMF9, DAIS, Priceshow, HelpCor) só instala, fornece o contrato e renderiza. A regra de negócio e os dados vivem no backend do módulo (tmf-communication-back), que o host monta em memória (include_router, modelo canônico — ver../back/INTEGRATION.md).
Nenhum componente sabe quem o hospeda: todos consomem useCommunicationContext().client
(o CommunicationApiClient) e o pacote não faz chamadas HTTP diretamente — usa
createDefaultCommunicationClient como default.
Versão atual: ver
package.json(a constantePACKAGE_VERSIONé gerada a partir dele noprebuild). Não replique o número aqui.
1. Pré-requisitos
Dependências reais, conferidas em package.json:
| Dependência | Versão | Tipo | Observação |
|---|---|---|---|
react / react-dom |
>=18.0.0 |
peer, obrigatória | singleton — o host fornece |
react-email-editor |
>=1.8.0 |
peer opcional | só para o EmailDesignEditor (Unlayer) |
@tanstack/react-query, lucide-react, recharts, sonner |
ver package.json |
dependencies |
o npm resolve; o host não declara |
@tmf/platform-core |
— | devDependency, inlined no bundle (tsup.config.ts: noExternal) |
o consumidor não instala |
O CommunicationProvider cria um QueryClient interno — o host não precisa de
QueryClientProvider (pode injetar o seu via prop queryClient).
2. Registry + instalação
O pacote é publicado no registry npm do Forgejo da TMF. No frontend do host, garanta o
.npmrc:
# frontend/.npmrc
@tmf:registry=https://git.trademarketingforce.com/api/packages/TMF/npm/
legacy-peer-deps=true
Auth para instalar (NUNCA commitar o token — use env/CI):
//git.trademarketingforce.com/api/packages/TMF/npm/:_authToken=${FORGEJO_NPM_TOKEN}
Instalar:
npm install @tmf/communication-front --legacy-peer-deps
3. Como o host alcança o backend
A lib não sabe onde o backend roda — o host injeta baseUrl/getToken via
CommunicationProvider (ou contract do AppContract). baseUrl = RAIZ do host (ADR-002,
Convenção A): o createDefaultCommunicationClient soletra o prefixo do serviço em cada request
(DEFAULT_SERVICE_PREFIX = '/api/service/communication', em src/client/default-client.ts;
sobreponível via prop servicePrefix do CommunicationProvider, que não é exposta no
<CommunicationApp>). Pôr o prefixo dentro do baseUrl duplica o path e dá 404.
Cada host decide como o backend fica acessível nesse caminho: montagem em memória
(include_router — modelo canônico, ver ../back/INTEGRATION.md §4/§5) ou proxy para outro
processo.
- A auth do request é a do host (JWT do usuário, ou token S2S
mst_…single-client); o front só envia o Bearer devolvido porgetToken. - O client resolve
clientCodeautomaticamente decontract.tenant.clientCodequandocontract.tenant.isMultiTenanté verdadeiro (multi-tenant). - O isolamento por cliente é garantido no backend do módulo (eixo
client_iddoScopeContext). Credenciais de provider nunca trafegam (ProvidersViewsó exibe nome/canal/status).
4. Acoplamento mínimo ("config, não código")
import { CommunicationApp } from '@tmf/communication-front'
export function CommunicationPage({ contract }: { contract: AppContract }) {
return (
<CommunicationApp
contract={contract}
tenantMode="multi" // "multi" no Hub; "single" em tenant isolado (TMF9)
getToken={() => getAccessToken() ?? ''}
// sem `client` → usa createDefaultCommunicationClient default,
// que chama contract.services['communication'].baseUrl + o prefixo do serviço
/>
)
}
No contrato servido ao host, inclua o endpoint de comunicação:
// AppContract.services[]
{ "key": "communication", "baseUrl": "" } // RAIZ do host ("" = same-origin) — nunca o prefixo do serviço (ADR-002)
Pré-requisitos no app:
- Nenhum
QueryClientProvideré necessário (o Provider do pacote cria o seu). - O host precisa emitir
contract.permissions.granted(lista plana de permissões): sem isso oCommunicationClientTabnão mostra nenhuma sub-aba (fail-closed — verINTEGRATION.md§10).
5. Adapter próprio (opcional)
Se o produto preferir mapear para sua própria camada de API (em vez do client default),
implemente a interface CommunicationApiClient e injete via prop client:
import type { CommunicationApiClient } from '@tmf/communication-front'
const myClient: CommunicationApiClient = {
listCampaigns: (p) => myApi.campaigns.list(p),
getCampaign: (id) => myApi.campaigns.get(id),
// … apenas os métodos que o produto usa (todos são opcionais)
}
<CommunicationApp contract={contract} client={myClient} />
Os métodos da interface são opcionais (a grande maioria; ver CommunicationApiClient em
src/types.ts) — um produto que só usa campanhas implementa só esses. Componentes cujo método correspondente não existir exibem placeholder
informativo em vez de quebrar.
6. Componentes exportados
- Top-level:
CommunicationApp,CommunicationProvider,useCommunicationContext - Composição:
CommunicationClientTab(sub-abas do cliente),CommunicationPainel(O Gestor) - Autorização por seção:
COMMUNICATION_SECTIONS,ALL_SECTION_PERMISSIONS,hostGrantState(verINTEGRATION.md§10) - Campanhas:
CampaignListView,CampaignCreateModal,CampaignWizard,CampaignDetailView,CampaignAnalyticsView,CampaignGroupsView,CampaignsDashboardView - Canais:
ChannelShell,ChannelTemplatesList,TemplatesSectionView,EmailOptOutsView,MessagingSuppressionsView,SmsManagerPanel,PushManagerPanel - Editor de e-mail:
EmailDesignEditor(Unlayer) — merge tagscontato/campanha/empresa/chamado(resposta de chamado do Service Desk), extensível pelo host via propextraMergeTagssem bump; starter prontoTICKET_REPLY_STARTERpara pré-carregar o template de resposta de ticket [TMFP-63545] - Financeiro / config:
OverviewDashboard,FinancialView,ReconciliationView,ProvidersView,SandboxView,EmergencyStopView,CommunicationSettingsPage - Gestor / WAManager:
CampaignManagerView,WaDashboardView,WaAnalyticsView,WaFunnelView,WaScoringView,WaBestTimeView,WaRoiView,WaTemplatePerfView,WaOptOutTrendsView,WaOptOutsView - Infra:
createDefaultCommunicationClient,commQueryKeys,PACKAGE_VERSION, tiposComm*(lista completa:src/index.ts) - Utils:
getErrorMessage,hasTranslatedError,ERROR_MESSAGES(tradução pt-BR de erros de disparo Meta/SES/Twilio — TH-57013)
Detalhe por área em
FUNCIONALIDADES.md.
7. Ports plugáveis (do @tmf/platform-core)
CommunicationProvider/CommunicationApp aceitam:
toast(ToastPort) — ex.: adapter sobresonner/react-hot-toast.i18n(I18nPort) — default:DictI18nPortembutido viacreateDictI18nPort(pt-BR/en/es, namespacecommunication.*).theme(ThemePort) — aplica CSS vars do contrato (design-tokens).getToken— função que devolve o Bearer atual.
8. Checklist de adoção
.npmrccom registry Forgejo +legacy-peer-deps=true.npm install @tmf/communication-front --legacy-peer-deps.- Garantir as peers obrigatórias (
react/react-dom);react-email-editorsó se usar oEmailDesignEditor. - Backend
tmf-communication-backmontado no host e acessível sob o prefixo do serviço (/api/service/communicationpor default; outro prefixo viaservicePrefixdo Provider). - Renderizar
<CommunicationApp baseUrl={raizDoHost} getToken tenantMode />(ou comcontract, emitindopermissions.granted). - Validar
tsc --noEmit+ smoke (listar/criar campanha, analytics) num ambiente de QA.
Dúvidas de contrato/escopo do backend:
../back/INTEGRATION.md.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @tanstack/react-query | ^5.0.0 |
| lucide-react | ^0.400.0 |
| recharts | ^2.0.0 |
| sonner | ^1.0.0 |
Development dependencies
| ID | Version |
|---|---|
| @testing-library/jest-dom | ^6.0.0 |
| @testing-library/react | ^16.0.0 |
| @tmf/platform-core | file:../../platform-core |
| @types/react | ^18.2.47 |
| @types/react-dom | ^18.2.18 |
| jsdom | ^25.0.0 |
| react-email-editor | ^1.8.0 |
| tsup | ^8.5.1 |
| typescript | ^5.3.3 |
| vitest | ^4.1.11 |
Peer dependencies
| ID | Version |
|---|---|
| @tmf/design-tokens | >=0.6.0 |
| react | >=18.0.0 |
| react-dom | >=18.0.0 |
| react-email-editor | >=1.8.0 |