Pular para o conteúdo principal

Troca de Organização

Última atualização: 15 de julho de 2026

Visão Geral

Diferente da resolução automática de contexto de organização que acontece depois do login, documentada em Contexto de Organização, este documento cobre a troca manual: o vendedor escolhendo, pela própria tela de perfil, uma organização diferente entre as que ele tem acesso. Essa troca é o gatilho mais comum para uma sincronização completa em modo full, já que muda a identidade da sessão descrita em Sincronização Completa vs Incremental.

Arquivos-chave

ArquivoResponsabilidade
features/store/store-profile.controller.tshandleSelectOrganization, ponto de entrada da troca manual
features/store/components/organization-switch-bottom-sheet/organization-switch-bottom-sheet.tsxLista as organizações disponíveis para escolha
services/order-header/order-header.service.tssyncDrafts, com limpeza de rascunhos restrita à organização

A troca só aparece com a flag ativa

cfg-ativartrocadeorganizacao controla se a opção de trocar de organização aparece na tela de perfil (dentro da área de "Loja"). As organizações disponíveis para escolha vêm do mesmo storage já usado na resolução automática pós-login:

// store-profile.controller.ts
const isOrganizationSwitchEnabled = settings.get("cfg-ativartrocadeorganizacao") === "S";
const organizationContexts = useOrganizationContextsStorage();
const selectedOrganizationStorage = useSelectedOrganizationStorage();

O que acontece ao escolher uma organização diferente

const handleSelectOrganization = useCallback(
async (organizationId: string) => {
if (organizationId === selectedOrganizationId) {
closeOrganizationSheet();
return;
}

const nextOrganization = organizationContexts.find(
(organization) => organization.organizationId === organizationId,
);

if (nextOrganization) {
setSelectedOrganizationStorage(nextOrganization);
}

closeOrganizationSheet();
await wait(180);
reset();
void startSyncAll(organizationId);
},
[closeOrganizationSheet, organizationContexts, reset, selectedOrganizationId, startSyncAll],
);

Escolher a mesma organização que já está selecionada não faz nada além de fechar o bottom sheet. Escolher uma diferente persiste a nova seleção, fecha o bottom sheet, espera um instante (o suficiente para a animação de fechamento terminar), zera o estado do provider de sincronização (reset), e dispara startSyncAll já com o organizationId novo.

Por que isso vira uma sincronização completa

startSyncAll(organizationId) passa esse id para svc.Organization(organizationId), que troca o token de contexto (documentado em Contexto de Organização). A identidade resultante tem o mesmo userId de antes, mas um organizationId diferente, e isso é exatamente o que isSameSessionIdentity detecta como identidade diferente, forçando prepareFullSyncMode a retornar "full". Trocar de organização, na prática, sempre limpa e busca de novo os dados compartilhados (clientes, produtos, preços, estoque e o restante da lista documentada em Sincronização Completa vs Incremental).

A única exceção: rascunhos de venda não são apagados de outras organizações

Enquanto a limpeza de clientes, produtos e das demais entidades compartilhadas apaga a tabela inteira no SQLite (sem filtro de organização), os rascunhos de venda são tratados de forma diferente. OrderHeaderService.syncDrafts recebe o organizationId atual e limpa só os rascunhos daquela organização:

// order-header.service.ts
async syncDrafts(pageSize = 500, onProgress, options) {
const organizationId = options?.organizationId ?? "";

if (options?.clearLocal ?? true) {
await this.draftRepo.clearAll(organizationId);
}
// ...
}

Isso significa que um vendedor que atende mais de uma organização pelo mesmo aparelho não perde rascunhos de venda em andamento de uma organização ao trocar para outra e depois voltar. As demais entidades compartilhadas, por outro lado, são sempre buscadas de novo para a organização atual, sem manter um "cache" separado por organização anterior.

Armadilhas conhecidas

Ao adicionar uma nova entidade sincronizável, decida deliberadamente se a limpeza dela em troca de organização deve ser total (como a maioria) ou restrita à organização atual (como os rascunhos de venda). Copiar o padrão de clearAll() sem escopo para uma entidade que deveria sobreviver entre organizações apagaria dados que o vendedor esperava encontrar ao voltar para a organização anterior.