Pular para conteúdo

Relacionamentos e referências

MongoDB não impõe foreign keys entre estas collections. A cardinalidade aqui descreve a intenção dos modelos e as consultas, não uma restrição física universal. Integridade depende dos serviços, índices declarados e limites de transação.

Modelos visuais

Catálogo global e modelo do autor

Recorte: templateRevision é número de versão, não ID de revisão.

Catálogo global e modelo do autor; visão simplificada. Detalhes no visualizador abaixo. Catálogo global e modelo do autor; visão simplificada em tema escuro.

Explorar diagramas detalhados com zoom

Legenda e convenções dos modelos. Os dicionários e evidências desta página permanecem a referência dos campos.

Tipos de relação

Tipo Exemplo Significado
Referência por identificador route_revisions.routeId → routes._id Documento separado, resolvido pelo repository/serviço
Documento embutido route_revisions.client.authentication Parte da mesma gravação do documento de revisão
Snapshot publishedRouteRevisions[] Cópia histórica embutida; não deve acompanhar alterações posteriores na origem
Referência de versão gatewayRevisionId / templateRevisionId Aponta a uma revisão específica, distinta do ID lógico
Relacionamento lógico catalog.ownerTenantId Identifica contexto proprietário; não cria FK nem autoriza acesso
Dependência por serviço Rate Limit → Scheduler HTTP coordena dados em owners distintos; não é join Mongo

Dentro dos domínios

Origem / campo Destino Cardinalidade lógica / observação
gateway_revisions.gatewayId gateways._id Muitas revisões para uma identidade; um DRAFT é imposto pelo índice parcial
routes.gatewayId, categories.gatewayId gateways._id Muitas raízes por gateway
routes.categoryId categories._id Categoria opcional conforme autoria; não existe FK
route_revisions.routeId routes._id Histórico da identidade estável da rota
route_revisions.gatewayRevisionId gateway_revisions._id Configuração da rota vinculada ao histórico do gateway
gateway_wizard.gatewayRevisionId gateway_revisions._id Serviço trata wizard por revisão; não há índice unique secundário declarado
gateway_template_revisions.gatewayTemplateId gateway_templates._id Histórico do modelo; índice parcial limita revisão de trabalho
route_templates.gatewayTemplateId, route_template_categories.gatewayTemplateId gateway_templates._id Autoria por modelo raiz
route_templates.categoryId route_template_categories._id Agrupamento de rotas modelo
route_template_revisions.routeTemplateId route_templates._id Versões da identidade lógica
route_template_revisions.gatewayTemplateRevisionId gateway_template_revisions._id Associação de versões; snapshots publicados preservam a configuração
gateway_import_status.gatewayImportId gateway_import._id Um resultado por recurso na lógica de upsert; índice unique não declarado

Fontes e dicionários: Core, Templates, Importer.

Entre owners e databases

%%{init: {"theme":"base","themeVariables":{"fontFamily":"Arial, sans-serif","fontSize":"16px","lineColor":"#64748b","primaryTextColor":"#172b4d"},"flowchart":{"htmlLabels":true,"useMaxWidth":true,"nodeSpacing":28,"rankSpacing":38,"padding":14,"curve":"linear","subGraphTitleMargin":{"top":12,"bottom":16}},"sequence":{"useMaxWidth":true,"actorMargin":28,"width":145,"height":45,"diagramMarginX":32,"diagramMarginY":12,"messageMargin":24,"wrap":true,"mirrorActors":false},"themeCSS":".edgeLabel, .edgeLabel p {background-color:var(--diagram-surface)!important;color:var(--diagram-text)!important}\n.cluster rect {fill:var(--diagram-group)!important;stroke:var(--diagram-line)!important}\n.cluster-label span, .cluster-label text {color:var(--diagram-text)!important;fill:var(--diagram-text)!important}\n.flowchart-link, .actor-line {stroke:var(--diagram-line)!important}\nmarker path {fill:var(--diagram-line)!important;stroke:var(--diagram-line)!important}\n.actor {fill:var(--diagram-domain)!important;stroke:var(--diagram-domain-border)!important}\ntext.actor, .messageText, .loopText, .labelText {fill:var(--diagram-text)!important}\n.messageLine0, .messageLine1, .loopLine {stroke:var(--diagram-line)!important}\n.labelBox {fill:var(--diagram-surface)!important;stroke:var(--diagram-line)!important}\n.note {fill:var(--diagram-async)!important;stroke:var(--diagram-async-border)!important}\n.noteText {fill:var(--diagram-text)!important}\n.nodeLabel, .nodeLabel p, .nodeLabel span {color:var(--diagram-text)!important}\n.node .nodeLabel, .node .nodeLabel p {font-size:17px;font-weight:600;line-height:1.4;text-align:center}\n.nodeLabel small {display:inline-block;margin-top:4px;font-size:15px;font-weight:400;line-height:1.4;color:var(--diagram-description)!important}\ntext.actor, text.actor tspan {font-size:17px;font-weight:600}\n.node.entry rect, .node.entry polygon, .node.entry path, .node.entry circle {fill:var(--diagram-entry)!important;stroke:var(--diagram-entry-border)!important}\n.node.domain rect, .node.domain polygon, .node.domain path, .node.domain circle {fill:var(--diagram-domain)!important;stroke:var(--diagram-domain-border)!important}\n.node.security rect, .node.security polygon, .node.security path, .node.security circle {fill:var(--diagram-security)!important;stroke:var(--diagram-security-border)!important}\n.node.store rect, .node.store polygon, .node.store path, .node.store circle {fill:var(--diagram-store)!important;stroke:var(--diagram-store-border)!important}\n.node.async rect, .node.async polygon, .node.async path, .node.async circle {fill:var(--diagram-async)!important;stroke:var(--diagram-async-border)!important}\n.node.external rect, .node.external polygon, .node.external path, .node.external circle {fill:var(--diagram-external)!important;stroke:var(--diagram-external-border)!important}\n text.actor tspan, .loopText tspan, .labelText tspan, .messageText tspan, .noteText tspan {fill:var(--diagram-text)!important}\n\n"}}%%
flowchart TB
    catalog["catalog · global<br/><small>Owner, modelo e versão</small>"]:::store
    template["gateway_template_revisions<br/><small>Database do autor</small>"]:::store
    instance["gateway_revisions<br/><small>Database do consumidor</small>"]:::store
    catalog -->|ownerTenantId / templateId / templateRevision| template
    instance -->|sourceCatalogGatewayId| catalog
    instance -->|templateState: origem exata| template
    classDef store stroke-width:1.5px;

catalog.templateRevision é número de versão em string; não é _id de revisão. templateState.templateRevisionId identifica a revisão exata. A consulta da origem combina owner com identidade e versão.

Origem Referência / destino Resolução e consistência
Core / políticas locais authenticationId, ipPolicyIds[], rateLimitId IDs de Security/IP Policy/Rate Limit no contexto aplicável
Core / políticas herdadas de modelo sourceTenantId + sourceAuthenticationId ou sourceIpPolicyIds[] Consulta no owner da política, não automaticamente no tenant consumidor
Core / proveniência templateState.routes/categories Mapas ID lógico do template → ID da instância; não comparar nome/path/posição
Core / upgrade templateUpgrade.baselineRevisionId e operationId Relação com a revisão original e Operation no consumidor; baselineState é snapshot embutido
Templates / Operation template.{templateId,version,ownerTenantId} Fonte no autor; gateway.gatewayId, wizard.wizardId, gatewayRevisionId apontam ao Core
Templates / recursos clonados rateLimits[], categories[], routes[] IDs de origem/destino e checkpoints; não são os documentos completos de destino
Catálogo / favorito catalog_item_state.catalogItemId Referência string ao item global. Aquisição é projetada de revisões Core
Importer / Core gateway_import.gatewayId, status routeId/categoryId IDs gerados remotamente; escrita Mongo e chamada HTTP não são atômicas
Object Storage público global_file_registry.fileId/ownerTenantId Localiza object_storage._id no banco do dono, depois lê blob
Template / ícone gateway_templates.icon e catalog.icon Identidade de arquivo; String no modelo Template e UUID no catálogo
OpenAPI Doc gateway_openapi.gatewayId ID de gateway ou template na mesma propriedade; documento é projeção derivada
Outbox / Inbox eventId Identidade lógica de mensagem; tipos produtor/consumidor e deduplicação estão em eventos

Fontes: leitura de owner, projeção de políticas, registro de arquivos, catálogo, upgrade Core.

Exclusão, duplicação e referências históricas

Core implementa cascatas e exclusão lógica; Mongo não executa cascata por referência. Templates guardam cópias de metadados/revisões em publicações e Core guarda proveniência da instância. Essa duplicação é intencional para histórico. Projeções de catálogo, documentos, aliases e caches têm sincronização própria; não compartilham uma transação distribuída.

Não foi feita varredura de banco para contar referências órfãs. Os mecanismos presentes e os pontos em que não há garantia física são registrados em Análises de dados, separados do modelo implementado.