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
| Arquivo | Responsabilidade |
|---|---|
features/store/store-profile.controller.ts | handleSelectOrganization, ponto de entrada da troca manual |
features/store/components/organization-switch-bottom-sheet/organization-switch-bottom-sheet.tsx | Lista as organizações disponíveis para escolha |
services/order-header/order-header.service.ts | syncDrafts, 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.