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.
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.