Feature/graphql sources 20260906 - #897
Conversation
* Update ConceptDocument to use `display_name` field instead of `name` for GraphQL projections * Ensure GraphQL resolvers and tests correctly utilize the `display_name` field in the Elasticsearch index * This change allows clients to retrieve the human-readable display name instead of the internal name when fetching concepts via GraphQL
|
Still draft, but updated, please consider check @snyaggarwal |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 091bfb0377
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| 'display': ('display_name',), | ||
| 'description': ('preferred_description',), |
There was a problem hiding this comment.
Reindex locale-derived fields after source locale changes
When a source's default_locale or supported_locales changes, these projections continue serving the previously indexed display_name and preferred_description, even though both values are derived from the parent source's locale configuration. Source persistence only reindexes concepts for release or match-algorithm changes, and the new signal propagation handles only activity and visibility, so a lean query requesting display or description remains stale indefinitely while the ORM path returns the new locale selection. Reindex the source's concepts when the relevant locale settings change, or avoid directly projecting these derived fields.
Useful? React with 👍 / 👎.
Solves: OpenConceptLab/ocl_issues#2757
Why? CIEL Lab needs improvements when loading worklists to load fast using ES-only retrieve for minimal payloads
Also: OpenConceptLab/ocl_issues#2577
GraphQL: permission-aware source and concept projections
Adds a GraphQL
sourcequery and extendsconceptssearch so that simple payloads(
name,description,canonicalUrl,urion sources;id,conceptId,externalId,display,description,conceptClass,datatype.nameon concepts) are served directlyfrom Elasticsearch instead of hydrating ORM objects, while still enforcing the existing
REST visibility rules. Selections that need relationships, mappings, extras, audit metadata,
or datatype details still hydrate from the database as before.
Existing Elasticsearch indexes must be repopulated before this version is put into service.
This is a data requirement, not a code migration — there are no new database migrations or
environment variables — but skipping it produces incorrect GraphQL results with no error.
ConceptDocumentgains four fields with no equivalent in the current index:is_active,is_head,preferred_description,parent_public_can_view.SourceDocumentgains three fields:description,uri,is_active.are unchanged), but documents indexed before this change do not have these fields
populated, and Elasticsearch cannot backfill them on its own — they require reading the
source data again and reindexing.
Concrete impact if you deploy without reindexing first:
conceptsquery: the new index projection filters onis_active(and, for global/HEADscope,
is_head). Old documents don't have these fields set, so the filter matches zerodocuments. This is not surfaced as an error — the query returns a normal, valid-looking
response:
{"totalCount": 0, "hasNextPage": false, "results": []}. This is indistinguishablefrom a legitimate "no matches" search result. There is no partial-result flag, warning, or
degraded-mode indicator in the response.
sourcequery: degrades gracefully. Ifis_activeis missing on the source document, theindex projection returns
Noneand the resolver automatically falls back to the existingORM path. Slower, but correct — no silent data loss here.
conceptssearches can silently go to zeroresults across the board until the reindex finishes, with no visible indication to API
consumers that anything is wrong.
Required rollout step — reindex both models before/immediately after deploy:
Use your deployment's own rebuild procedure if it recreates indexes from scratch instead
(e.g. blue/green index + alias swap). Either way, do not route GraphQL traffic to this
version against an index that hasn't been repopulated. REST search availability should be
accounted for during the reindex regardless of which procedure you use.
Recommendation: treat the reindex as a pre-deploy gate, not a post-deploy cleanup step,
given that failures are silent. Consider adding an operational check (e.g. a canary GraphQL
query with a known concept, or an index field-presence check) before flipping traffic, since
totalCount: 0alone cannot be trusted to mean "index not ready" versus "no matches."New GraphQL API surface
conceptIdsperforms exact, case-sensitive mnemonic matching, deduplicates input, preservesorder, and takes precedence over
query.organdsourcefor a global concept search.page/limitmust be supplied together; the supported result window is 10,000. Withoutpagination, index responses are capped at 10,000, but
totalCountstill reflects the truetotal match count.
versionresolves toHEAD, falling back to the latest released version only whenHEADitself is absent. An explicitly requested version that doesn't exist does not fall back.are rejected before resolvers run. Anonymous callers see public data only; authenticated
callers still require the existing
graphql_apigroup.Permission model
requests), scoped by both owner mnemonic and owner type.
parent_public_can_view.externalSourcesindependently checks target-repository visibilityand excludes the current source and any linked private targets the caller cannot view.
HEADscope uses the same versioned-object identity asSource.get_concepts_queryset()(
id == versioned_object_id); released versions use their version membership lists.Compatibility notes
extras, or datatype details) keeps its existing empty-index database fallback — only the
new lean index projection path lacks a fallback for the zero-hit case described above.
Testing
zero-SQL projections, owner isolation, HEAD/release selection, inactive/retired filtering,
private-parent visibility).
core.graphql(739/753), excluding test files.