@sinequa/atomic

Server configuration

What the administrator decided — facets, tabs, sorting, column aliases — and how your interface reads it instead of hardcoding it.

Almost nothing about a Sinequa interface is your decision. Which facets exist, which tabs, which sort options, which columns are searchable and what they are called — all of it is configured on the server, and GET api/v1/app hands you the whole tree.

An interface that hardcodes that list works until the administrator changes it. One that reads it adapts.

Concept — the CC prefix

Types starting with CC are configuration types: CCApp, CCQuery, CCColumn. They describe what the administrator set up, as your code reads it. You never construct one.

Reading it

Build the interface from the configuration
src/interface-shape.ts
import { createAtomicClient, sysLang } from "@sinequa/atomic";
import type { CCApp, CCQuery } from "@sinequa/atomic";

const client = createAtomicClient({
  app: "<your-app>",
  backendUrl: "https://<your-sinequa-server>",
});

await client.initializeConfig();
await client.auth.login();

const app: CCApp = await client.api.app.get();

// Which query web service to search through. Do not assume "<your-query>".
const queryName = app.defaultQueryName ?? Object.keys(app.queries)[0];
const query: CCQuery = app.queries[queryName];

describe(query);

function describe(query: CCQuery) {
  console.log("page size:", query.pageSize);

  // Facets to render, in the order the administrator put them.
  for (const aggregation of query.aggregations ?? []) {
    console.log(`facet ${aggregation.name} on column ${aggregation.column}`);
  }

  // Sort options: `sort` on a query takes one of these names, not an SQL clause.
  for (const choice of query.sortingChoices ?? []) {
    // Labels come in Sinequa's multilingual format; decode before displaying.
    console.log(`sort ${choice.name}: ${sysLang(choice.display ?? choice.name, "en-US")}`);
  }

  // Tabs, each of which the server counts separately.
  for (const tab of query.tabSearch?.tabs ?? []) {
    console.log(`tab ${tab.value}${tab.isDefault ? " (default)" : ""}`);
  }
}

What CCApp contains

Prop

Type

CCQuery is where a search's shape comes from: pageSize, aggregations, columnsInfo, sortingChoices, scopes, tabSearch, plus relevance settings (sCMode, questionPrecision, questionStrategy, isNeural) and which indexes it searches.

Columns and their aliases

An interface talks about recordType; the index stores sourcestr1. That mapping is configuration, and it exists at two levels — per query web service, and in the index schema.

resolveToColumnName walks both, in the right order:

resolving a display alias to a real column
import { resolveToColumnName } from "@sinequa/atomic";

const column = resolveToColumnName("recordType", app, "<your-query>");
// "sourcestr1" — the query web service's aliases win over the index schema

filters = filter.eq(column ?? "recordType", "email");

Passing the query name matters: an alias declared on the query web service takes precedence over the same alias in the index schema. Without it, only the schema is consulted.

The two `aliases` fields have different types

CCColumnInfo.aliases is a comma-separated string; CCColumn.aliases is a string[]. That is why resolution has two branches, and why reading one as the other silently finds nothing.

makeColumn(name, type, typeModifier?, aliases?) builds a CCColumn from the textual type the server reports, translating it into the engine's enums. extraColumns holds the fourteen system columns a record carries but the index schema does not declare — id, text, matchlocations, accesslists and the like.

Pitfalls

What's next

On this page