Repository navigation
docs(v3): document *.field.list, and state the camelCase rule once - #473
Merged
Merged
Conversation
`*.field.list` / `*.field.get` appeared **nowhere** in `docs/`, `skills/` or `packages/`. The only place a reader could reach it was a comment on a playground command -- somebody needed the method, used it, and the answer landed in a demo. It is roughly a third of the v3 surface. What the docs pointed at instead was the OpenAPI document: the right answer to "which methods exist", a heavy one to "which fields does this entity have", and no answer at all to `filterable`, `editable` and `requiredGroups`, which the request schema does not carry. New page `8.discovering-entity-fields.md`, numbered next to 7 because they are two halves of one question. Page 7 gained a pointer back. Everything on it was measured against a live portal rather than restated, and three things the issue marked "not verified" now are: - `<entity>.field.get` answers with `result.item` -- singular, not the `result.items` of `.field.list`. Worth a line of its own; a reader who assumes symmetry gets `undefined`. - `select` narrows the *descriptor* keys: `select: ['name', 'sortable']` returns rows with those two. - `requiredGroups` on `tasks.task` reads `["add"]` on `title`, `creatorId` and `responsibleId` -- not the `["add","update"]` the audit's reference recorded from the schema. The page says what the wire says. And one fact the issue did not have: the same validation refusal guards **`filter`**, not only `order`. `tasks.task.list` filtered on `title` (`filterable: false`) answers HTTP 400 with `Filterable` named in `validation[].field`, exactly as ordering on a non-`Sortable` field does. That matters because `filterable` has no source but this family -- which is why the playground comment had to call it in the first place. The camelCase rule is now stated once, as a rule. It was present only as a per-method footnote -- "most notably `tasks.task.list` on v2" -- while the code has encoded it as a default all along (`?? 'id'` on v3, `?? 'ID'` on v2). A reader who is told the rule predicts the next occurrence; a reader given the footnote waits to be bitten by it. 108 descriptors across two entities, not one uppercase name. Three lines taught it backwards and are corrected. `99.examples/8.ai-assistant.md` derived "camelCase means v3" from a **v2** call -- an example that disproves it. The filtering and recipes skills called `crm.item.list` a "v3-style method" when what they meant was that it is camelCase; v3 publishes no `crm.item.*` at all. The two v3 `cursorIdKey` rows illustrated the parameter with a v2 shape on a v3 page, and now state the rule instead. The **v2** rows are correct and untouched. Drive-by from the same file: the filtering skill promised `DtoFieldRequiredAttributeException` for a non-`Sortable` field. The wire carries `BITRIX_REST_V3_EXCEPTION_VALIDATION_REQUESTVALIDATIONEXCEPTION` -- the specific class inherits it and gets no code of its own -- with the distinguishing detail in `validation[].field`. Matching on the message would fail anyway: portals answer in the portal's language. No SDK change, as the issue asked. No `fieldList` helper: it is an ordinary method `call.make` already reaches, and a wrapper would re-import the per-portal knowledge 2.0.0 deleted with the allowlist. Closes #466 Refs #113, #185 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F22e2ft66y7nuBJjzdThBr
…llow each other The webhook gained the scopes it was missing, so the one thing this page took on trust is now first-hand: `main.eventlog.field.list` answers 13 descriptors under `result.items`, named exactly as the audit recorded, none of the 108 across the two entities starting with an uppercase letter; and `main.eventlog.list` ordered by `description` answers HTTP 400 naming `EventLogDto` and `Sortable`. The "not verified" note comes off. Measuring it turned up the thing most worth saying on the page, which no single entity shows. On `main.eventlog`, `sortable` and `filterable` name the same five fields of thirteen -- a coincidence that reads exactly like a rule. On `tasks.task` they diverge: `title` is sortable and not filterable, and one field of ninety-five is filterable at all. So the flags are independent, and a reader who checks one and assumes the other is wrong on the second entity they try. Now a warning, with both measurements. Two smaller corrections from the same run. `requiredGroups` is `null` rather than an empty array when nothing requires the field -- iterate it and you throw. And a field being *returned* says nothing about whether it may be sorted or filtered on: `description` is one of the thirteen `main.eventlog.list` gives back. The counts are mine now instead of approximate: 91 of 245 methods on the measured cloud portal are `*.field.*`, 37%, with the per-module split; and seven entities publish a `.list` with no `.field.list` -- the four `crm.*.timeline.activity.email` families among them -- where the issue knew of two on-premise. Separately, and worth recording because it was a prediction rather than an observation: widening this webhook's scopes changed the OpenAPI document by **zero** methods, 245 before and after. The audit inferred "module-driven, not scope-driven" by comparing two webhooks; this is the same portal before and after, which is the stronger form of the same claim. The committed snapshot therefore does not need refreshing, and `scripts/data/` is untouched. Refs #466, #463 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F22e2ft66y7nuBJjzdThBr
Two additions, both from the maintainer's reading of the same measurement. The flag is the source of truth, and which fields carry it is decided by the Bitrix24 module that owns the entity -- so the set changes from one module version to the next. Code that reads the flag keeps working across a portal upgrade; code that hard-codes today's answer does not. Said on the page, next to the numbers it governs. And the contrast that makes the numbers legible rather than alarming: a rich `order` beside a bare `filter` is a normal state for a v3 entity. `tasks.task` marks nineteen fields sortable and one filterable; the same entity on `restApi:v2` filters on `RESPONSIBLE_ID`, `STATUS` and `GROUP_ID` without complaint. That is a difference between the two APIs, not a fault to work around. A correction I owe the record: an earlier draft of this reasoning held that the reference documentation promised filtering the module does not deliver. It does not. The MCP docs tool answered with a merged v2/v3 record pointing at `rest-v3/tasks/tasks-task-list.html`, which omits the restriction; the actual v3 page, `tasks/tasks-task-list-rest-v3.html`, states that `id` is the only supported filter. The documentation was right and my source was wrong, so the page now cites it rather than contradicting it. Refs #466 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F22e2ft66y7nuBJjzdThBr
IgorShevchik
added a commit
that referenced
this pull request
Sep 5, 2026
…t guide (#474) Follow-up to #473, which added the "Discovering entity fields" guide but wired it only into the b24jssdk-rest skill — so the two skills where the question actually comes up had no way to reach it. One pointer each: b24jssdk-filtering (why a `filterable: false` field is refused rather than ignored), b24jssdk-recipes (folded into the sentence that already states the camelCase rule), and b24jssdk-rest next to the existing "Discovering v3 methods" link. Documentation only; no runtime change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #466. Documentation only — no SDK change, as the issue asked.
The gap
*.field.list/*.field.getappeared nowhere indocs/,skills/orpackages/.The only place a reader could reach it was a comment on a playground command — somebody
needed the method, used it, and the answer landed in a demo. It is 91 of 245 methods
on the measured cloud portal: 37% of the v3 surface.
What the docs pointed at instead was the OpenAPI document: the right answer to which
methods exist, a heavy one to which fields does this entity have, and no answer at all
to
filterable,editableandrequiredGroups, which the request schema does not carry.What lands
New page
8.discovering-entity-fields.md, numbered next to 7 because they are two halvesof one question; page 7 gained a pointer back.
Everything on it is measured first-hand. Six facts the issue listed as unverified or did
not have:
sortableandfilterableare independent. This is the one worth the page. Onmain.eventlogthey name the same five fields of thirteen — a coincidence that readsexactly like a rule. On
tasks.taskthey diverge:titleissortable: true,filterable: false, and one field of ninety-five is filterable at all. A reader whochecks one flag and assumes the other is wrong on the second entity they try.
<entity>.field.getanswers withresult.item— singular, not theresult.itemsof.field.list. Assume symmetry and you getundefined.selectnarrows the descriptor keys:select: ['name', 'sortable']returns rowswith exactly those two.
requiredGroupsisnull, not[], when nothing requires the field — iterate it andyou throw. It reads
["add"]ontasks.task'stitle/creatorId/responsibleId,not the
["add","update"]the audit's reference recorded from the schema.filter, not onlyorder.tasks.task.listfiltered ontitleanswers HTTP 400 withFilterableinvalidation[].field, exactly as ordering ona non-
Sortablefield does. That matters becausefilterablehas no other source — whichis why the playground comment had to call this family in the first place.
descriptionis one of the thirteenmain.eventlog.listgives back, and both flags arefalse.
Seven entities publish a
.listwith no.field.list— the fourcrm.*.timeline.activity.emailfamilies,humanresources.access.permission,humanresources.node.communication,rest.scope— where the issue knew of two on-premise.The camelCase rule
Stated once, as a rule. It existed only as a per-method footnote — "most notably
tasks.task.liston v2" — while the code has encoded it as a default all along(
?? 'id'on v3,?? 'ID'on v2). A reader told the rule predicts the next occurrence; areader given the footnote waits to be bitten by it. 108 descriptors across two entities,
not one uppercase initial.
Three lines taught it backwards and are corrected:
99.examples/8.ai-assistant.md:47crm.item.getviaactions.v2.call.make— an example that disproves the claim it is used to teachskills/b24jssdk-filtering/SKILL.md:164crm.item.list)"crm.item.*at all;crm.item.*is camelCase for reasons of its ownskills/b24jssdk-recipes/SKILL.md:130The two v3
cursorIdKeyrows illustrated the parameter with a v2 shape on a v3 page,and now state the rule instead. The v2 rows already name
tasks.task.listcorrectly andare untouched.
Drive-by, from the same file
skills/b24jssdk-filtering/SKILL.md:141promisedDtoFieldRequiredAttributeExceptionfor anon-
Sortablefield. The wire carriesBITRIX_REST_V3_EXCEPTION_VALIDATION_REQUESTVALIDATIONEXCEPTION— the specific class inherits it and gets no registry code of its own — with the
distinguishing detail in
validation[].field. Matching on the message would fail anyway:portals answer in the portal's language.
A prediction that held, recorded here because it is reusable
Widening the measuring webhook's scopes changed the OpenAPI document by zero methods —
245 before and after. #463's audit inferred "module-driven, not scope-driven" by comparing
two different webhooks; this is the same portal before and after, which is the stronger form
of the same claim. The committed snapshot therefore needs no refresh, and
scripts/data/isuntouched by this PR.
What is deliberately not here
No
actions.v3.fieldListhelper and no typedFieldDescriptor: it is an ordinary methodcall.makealready reaches, and a wrapper would re-import the per-portal knowledge 2.0.0deleted with the allowlist. No field-name normaliser — the SDK must pass portal names
through unchanged or
selectechoes and filters break. The 91 method names are notenumerated: the count is portal-specific (147 / 220 / 245 methods in total).
Checks
docs-lint --strict— 0/0docs:lint-links— 0 broken (the new in-page links are site-absolute)docs:typecheck-blocks— 160 blocks,skills:typecheck-blocks— 83, both cleanlint:v3-refs— clean, and the new page's method names are held against the committedportal snapshot from feat(scripts): hold v3 method names against a portal's own OpenAPI document #471
lint:md— clean🤖 Generated with Claude Code
https://claude.ai/code/session_01F22e2ft66y7nuBJjzdThBr