Multi-source context
A DATTA context can bring together a graph, search indices, analytical tables and event streams, and the whole platform then sees that set as a single domain. Real data rarely lives in a single source, but until now each context pointed to exactly one graph database — combining sources required manual workarounds. With the multi-source model, you declare in the context registration as many heterogeneous sources as you need (Neo4j + OpenSearch + Trino + Kafka), and search, chat, screening and dashboards start considering all of them.
Concept
Before the multi-source model, "context" was a synonym for "domain" and for a single graph database (a 1:1:1 relation). Now a context can reference several sources of different types. Examples:
| Context | Neo4j databases | Search indices | Trino schemas | Kafka topics |
|---|---|---|---|---|
| Processos | processos, cpc, cpp, cdc | dattaprocessos* | — | — |
| Assistencia Social | assistencia-social, datta-ontology | dattaassistencia* | — | datta.cdc.assistencia.* |
| CNPJ | cnpj | dattacnpj* | iceberg.public.cnpj_eventos | — |
Where to configure
In , when creating or editing a context, the form includes the "Fontes de dados deste contexto" block, with four collapsible sections:
- Neo4j databases — the graph databases discovered by the platform.
- OpenSearch indices — the available
datta_*indices (the system's internal indices are already filtered out). - Trino tables/schemas — shown at the
catalog.schemalevel. - Kafka topics — the non-internal topics.
Each section has a search box to filter and a checkbox per item. For OpenSearch there is also an extra field where you can enter a manual pattern (e.g. datta_meucontexto_*). The counter at the top summarizes the selection: "X fonte(s) selecionada(s) (Y Neo4j, Z OS, W Trino, V Kafka)".
The ingestion index follows the convention. The context's primary OpenSearch source defines where ingestion writes — and the platform refuses to save, with a message in Portuguese, if the value diverges from the
datta_{normalized name}convention. The reason: ingestion always writes to the convention index, so a custom pattern would make documents "disappear" from search. Leave the field blank (or select the convention index) when saving. Additional (non-primary) OpenSearch sources remain free for multi-source composition.
Worked example — adding an analytical source to a context
The "CNPJ" context already has the graph and search, and now the team wants to cross-reference the corporate-events table in Trino:
- In , select "CNPJ" and open it for editing.
- In the "Fontes de dados deste contexto" block, open the Tabelas/Schemas Trino section and search for "cnpj".
- Check
iceberg.public.cnpj_eventos— the counter now includes the new source. - Save. Within about 2 minutes the platform's queries start considering the context's new source.
Legacy contexts migrate on their own
Contexts created before the multi-source model have no source list in their registration. When they are loaded, the platform populates the list synthetically:
- one Neo4j entry from the graph database already configured (role "primary");
- one OpenSearch entry from the index pattern already configured (role "primary").
Important: that migration happens in memory only. The registration is only rewritten when an administrator saves any context (creating a new one or editing an existing one). This makes rollback trivial — just go back to the previous version of the platform and the original configuration is read intact.
Forcing the migration to persist
Edit any context through the interface and click Salvar. The registration is rewritten with the sources populated for all contexts loaded in memory.
How changes propagate
After editing a context's sources, the platform's modules refresh their view in short windows:
| Module | Window | Note |
|---|---|---|
| Chat / Copilot | up to ~60 s | lifetime of the context settings cache |
| Graph query routing | up to ~2 min | re-read interval, adjustable via DATTA_GRAPH_DOMAIN_REFRESH_MS |
Nothing needs restarting: wait for the window and repeat the query. To speed it up, the platform exposes a source-aggregator invalidation resource used by integrations — see the API reference.
If you need to confirm the behaviour, the platform's log records show: the migration of legacy contexts on load, the registration of the context → graph database mappings when routing starts up, and the source aggregator's cache hits.
Current version limitations
- No external Neo4j address. The multiple graph databases live in the platform's primary cluster; pointing to an external Neo4j by its own address is planned evolution.
- Trino at schema level. Selection is by
catalog.schema; tables are resolved dynamically by Trino when referenced in SIQL. - Kafka topics are listed and registered in the context configuration, but real-time consumption by the search screens is planned evolution.
- Re-read every ~2 min for graph routing. Edits are rare and do not justify a dedicated event channel; worst case, a new Neo4j source becomes visible to routing within 2 minutes.
Procedural code database
What it is
Besides the context's data sources (the case-records graph, search indices, etc.), a context can declare a separate graph database holding the procedural code — the law articles and the decisions related to each article. Typical examples: cpc (Code of Civil Procedure), cpp, cdc.
That database feeds the Appeal copilot: when drafting an appeal brief, it identifies the articles cited in the case text and enriches the instruction sent to the model with each article's caput and up to 4 recent rulings per article (court, rapporteur, date, headnote). The brief comes out with real legal grounding, instead of the model "remembering" the article's content.
The field is optional: it stays empty when the context has no associated procedural code (e.g. a social assistance or CNPJ context).
Where to edit
In , when creating or editing a context, fill in the text field "Base do código processual (opcional)":
- Examples (placeholder):
cpc, cpp, cdc. - Help text: "Base Neo4j de artigos + jurisprudência usada pelo copiloto de Recurso. Deixe em branco se não se aplica."
- Expected value: the name of the graph database containing the articles and the case law of the applicable code. It is a context database, not a system one — which is why it carries no
datta-prefix.
Write behaviour is as follows:
- On creation, the database is only set when the registration carries a non-empty value.
- On update, an empty value clears the field; the field's absence from the submitted registration preserves the context's current value.
- On read, the field appears only when filled in (it is omitted when empty).
The same registration is reachable by integrations — see the API reference.
What happens when the field is empty
The Appeal copilot resolves the database dynamically per context, reading the field from the context settings. If the context does not define the field (or the settings are momentarily unavailable, or the appeal arrives without a domain), the copilot falls back to a documented fallback and logs a warning:
Contexto '{dominio}' sem 'codigoProcessualDatabase' — usando fallback '{db}'The fallback is the cpc database, as it is the most general procedural code. It is a last resort: the normal path is always dynamic resolution, never a database name pinned in code. The appeal is still generated — what changes is where the articles and case law come from. The warning exists so the operator can fix the context registration.
Relation to "Regras Não Aplicáveis (Sem Contexto)"
When screening (and the copilot) cannot ground a rule for lack of the legal database, the rules come back as "without context" — displayed in the audit detail as "Regras Não Aplicáveis (Sem Contexto)" / "Itens sem contexto suficiente para análise", and the screening verdict may end up Inconclusivo.
A missing procedural code database, or one pointing to a database without articles and case law, is one of the causes of this symptom: without the database, the copilot falls back to cpc and, if the context is not civil-law, the grounding may not match the case.
When investigating many "rules without context" in a specific context, check:
- Is the "Base do código processual (opcional)" field filled in under ?
- Does the referenced database exist and contain articles and case law?
- Do the log records show the fallback warning above?
See also the case audit detail for the semantics of "without context" / "Inconclusivo" in the report.
Propagation
Like the other context settings, the procedural code database is read through a cache (the same up-to-~60 s window from the How changes propagate section above). After editing it, wait for the cache to expire — or force the invalidation — for the copilot to see the new value.
See also
- Case audit detail
- Roles and permissions
- API reference