Skip to content

Add clients ERIR organization flags#315

Merged
axisrow merged 1 commit into
mainfrom
codex/issue-306-clients-erir-organization
May 24, 2026
Merged

Add clients ERIR organization flags#315
axisrow merged 1 commit into
mainfrom
codex/issue-306-clients-erir-organization

Conversation

@axisrow

@axisrow axisrow commented May 24, 2026

Copy link
Copy Markdown
Owner

Summary

Documentation Check

Official Yandex Direct clients.update docs place Organization under ErirAttributes and document Name, Kpp, EpayNumber, RegNumber, OksmNumber, and OkvedCode: https://yandex.ru/dev/direct/doc/en/clients/update

The cached WSDL audit currently contains Name, EpayNumber, RegNumber, OksmNumber, and OkvedCode rows; Kpp is implemented from the official docs but has no audit row in the current cache.

Verification

  • python3 -m black --check direct_cli/commands/clients.py direct_cli/utils.py tests/test_cli.py tests/test_dry_run.py tests/test_wsdl_parity_gate.py
  • python3 -m pytest tests/test_dry_run.py -k clients_update
  • python3 scripts/build_wsdl_optional_field_audit.py --check
  • python3 -m pytest tests/test_wsdl_parity_gate.py
  • python3 -m pytest tests/test_cli.py -k clients
  • python3 -m pytest tests/test_cli.py
  • python3 -m pytest tests/test_dry_run.py tests/test_wsdl_parity_gate.py

Closes #306

Copilot AI review requested due to automatic review settings May 24, 2026 08:35
@axisrow

axisrow commented May 24, 2026

Copy link
Copy Markdown
Owner Author

@codex @claude review. Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, documentation or test contract regressions, and issue-scope gaps. Do not nitpick style, naming, minor formatting, or subjective preferences.

@claude

claude Bot commented May 24, 2026

Copy link
Copy Markdown

Claude finished @axisrow's task in 3m 52s —— View job


Review: PR #315 — clients ERIR organization flags

  • Read the diff (git diff origin/main...HEAD)
  • Verify dry-run payload shape vs Yandex Direct docs
  • Verify WSDL audit changes match implementation
  • Check parity gate / WSDL coverage map updates
  • Post review findings

Focused on critical issues per the trigger. Style/naming intentionally not nitpicked.

1. Kpp field is not in the cached WSDL — runtime risk, no compensating test (critical)

tests/wsdl_cache/imports/generalclients.xsd:166-174 defines OrgInfo as:

<xsd:complexType name="OrgInfo">
    <xsd:element name="Name" .../>
    <xsd:element name="EpayNumber" .../>
    <xsd:element name="RegNumber" .../>
    <xsd:element name="OksmNumber" .../>
    <xsd:element name="OkvedCode" .../>
</xsd:complexType>

No Kpp. The PR body discloses this — "implemented from the official docs but has no audit row in the current cache" — but the only test exercising Kpp is the dry-run at tests/test_dry_run.py:4781, which never reaches the API. So:

  • If Yandex's live endpoint accepts Kpp (per https://yandex.ru/dev/direct/doc/en/clients/update), the flag works and the cached WSDL is simply stale.
  • If the live endpoint validates against the same schema as the cached WSDL, every invocation of --erir-organization-kpp will fail at runtime — and because Kpp is sandwiched between other valid fields, the failure mode could be the whole clients.update request being rejected (not a graceful partial accept).

The PR audit row (tests/WSDL_OPTIONAL_FIELD_AUDIT.md:5529-5530) lists --erir-organization-kpp under the parent ErirAttributes / ErirAttributes.Organization cells as a side-effect of being in OPTIONAL_FIELD_CLI_OPTIONS, even though there is no child ErirAttributes.Organization.Kpp row to match it against. That hides the discrepancy in the audit doc.

Recommendation: either (a) run the command against the live sandbox to confirm Kpp is accepted, refresh the WSDL cache from upstream if it now includes Kpp, and add the audit row; or (b) drop --erir-organization-kpp from this PR and gate it on a separate verification ticket. As-is, this ships a flag the test suite can't validate.

Verify with sandbox →

2. No way to clear nillable ERIR Organization fields (scope gap, low severity)

All five WSDL OrgInfo fields are nillable="true" (lines 168-172). Yandex therefore supports an explicit-null write to clear a previously-set value. The CLI helpers use truthy guards (if name: etc. at direct_cli/utils.py:360-371), so passing an empty string is silently dropped and there is no --clear-erir-organization-* flag pair. Adjacent typed updates (e.g. feeds update --clear-feed-login) do expose clear flags.

This is consistent with the existing Notification/TinInfo helpers in this file, so it's not a regression — but it leaves the typed surface for #306 strictly write-only-with-new-value. Worth tracking as a follow-up rather than blocking, since issue #306 only asks for the flags themselves.

3. Test only exercises the all-fields-set path (minor)

test_clients_update_erir_organization_payload (tests/test_dry_run.py:4760-4787) sets all six flags at once. There is no explicit assertion that:

  • partial payloads (e.g. only --erir-organization-name) emit only the supplied keys,
  • ErirAttributes is absent from the item when no ERIR flag is passed (regression protection for the existing clients update tests).

The helper structure makes these implicit, but explicit cases would harden the contract — particularly the negative case, which is what protects against ErirAttributes: {} leaking into a future refactor.


What looks correct

  • Payload shape matches the WSDL: ErirAttributes is placed at the top of ClientUpdateItem alongside ClientInfo/Phone/Notification/Settings/TinInfo, exactly as tests/wsdl_cache/imports/generalclients.xsd:243-249 (ErirAttributesUpdate) requires.
  • build_erir_organization / build_erir_attributes correctly return None when empty, so build_client_update_item won't emit empty wrappers — preserves the existing "Provide at least one field to update" UsageError invariant for the no-op call.
  • OPTIONAL_FIELD_CLI_OPTIONS updates and OPTIONAL_FIELD_CHILD_PREFIX_FOLLOWUPS removals are internally consistent with the audit doc transition from missing_followup to supported.
  • The WSDL_FIELD_TO_CLI_OPTION map is untouched, which is correct: all OrgInfo subfields are minOccurs="0", so none of the new fields needs a required-field mapping.
  • README adds the example in both EN and RU sections.

Summary

One real critical concern (the Kpp field), one out-of-scope feature gap (no clear flags), one minor test-coverage suggestion. The rest of the change is structurally sound and consistent with the existing typed-helper pattern for clients update.
· branch codex/issue-306-clients-erir-organization

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds canonical typed CLI flags for clients update to populate ErirAttributes.Organization (ERIR organization attributes) and wires them into both dry-run and live request bodies, while updating the WSDL optional-field parity gate/audit and documentation examples.

Changes:

  • Introduce --erir-organization-* flags on direct clients update and build ErirAttributes.Organization payload.
  • Add utility builders (build_erir_organization, build_erir_attributes) and include ERIR attributes in build_client_update_item.
  • Update parity gate + audit markdown rows to mark ErirAttributes.Organization as supported; add CLI help and dry-run tests; add README examples.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
direct_cli/commands/clients.py Adds --erir-organization-* Click options and injects ErirAttributes.Organization into the update payload.
direct_cli/utils.py Adds ERIR builder helpers and extends build_client_update_item to include ErirAttributes.
tests/test_dry_run.py Adds a focused dry-run payload shape assertion for ErirAttributes.Organization.
tests/test_cli.py Verifies clients update --help documents the new ERIR flags.
tests/test_wsdl_parity_gate.py Marks clients.update ERIR organization optional paths as supported via flag mappings and removes prior follow-up routing.
tests/WSDL_OPTIONAL_FIELD_AUDIT.md Updates generated audit summary and marks ERIR organization rows as supported.
README.md Adds single-line usage examples demonstrating the new ERIR flags (EN/RU sections).

Comment thread direct_cli/commands/clients.py Outdated
notification,
parse_client_setting_specs(list(settings)),
parse_tin_info(tin_type, tin),
build_erir_attributes(
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ 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".

@axisrow
axisrow force-pushed the codex/issue-306-clients-erir-organization branch from b01c0fa to 5cb6099 Compare May 24, 2026 08:38
@axisrow

axisrow commented May 24, 2026

Copy link
Copy Markdown
Owner Author

Addressed the actionable Copilot comment by passing the new ErirAttributes payload as the explicit keyword argument erir_attributes=... instead of a positional argument.

Re-verified:

  • python3 -m black --check direct_cli/commands/clients.py
  • python3 -m pytest tests/test_dry_run.py -k clients_update_erir_organization_payload
  • python3 -m pytest tests/test_cli.py -k clients_update_help_documents_erir_organization_flags

@codex @claude review. Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, documentation or test contract regressions, and issue-scope gaps. Do not nitpick style, naming, minor formatting, or subjective preferences.

@claude

claude Bot commented May 24, 2026

Copy link
Copy Markdown

Claude finished @axisrow's task in 2m 7s —— View job


Review: PR #315 follow-up (keyword-arg fix)

  • Read the latest diff (git diff origin/main...HEAD)
  • Confirm build_client_update_item(..., erir_attributes=...) is invoked as keyword
  • Re-check dry-run payload shape vs Yandex docs
  • Re-check WSDL audit + parity gate updates
  • Post review findings

Verdict: LGTM — Copilot follow-up addressed correctly, no critical issues.

Copilot keyword-arg follow-up — fixed ✅

direct_cli/commands/clients.py:140-156 now calls:

client_data = build_client_update_item(
    client_info, phone, notification,
    parse_client_setting_specs(list(settings)),
    parse_tin_info(tin_type, tin),
    erir_attributes=build_erir_attributes(...),
)

The new optional argument is passed by keyword exactly as suggested, and the underlying signature in direct_cli/utils.py:399-409 defines erir_attributes with a default (= None), so the keyword call is self-documenting and refactor-safe.

Critical-issue checks

Risk Result
Empty-payload no-op (parity gate invariant #1) ✅ Preserved — if not client_data: raise click.UsageError(...) still fires when every ERIR flag and every other typed flag is absent; build_erir_organization / build_erir_attributes collapse to None when all six values are falsy.
Silent data loss on typed flags (invariant #2) ✅ N/A — clients update has no --type switch; all six new flags route through the builders unconditionally.
Live vs dry-run payload divergence ✅ Same body = {"method": "update", "params": {"Clients": [client_data]}} is used for both branches in clients.py:160-172. The dry-run test test_clients_update_erir_organization_payload pins the exact ErirAttributes.Organization shape.
WSDL audit drift tests/WSDL_OPTIONAL_FIELD_AUDIT.md flips 6 Organization rows + the ErirAttributes wrapper from missing_followup to supported; counts move 2800→2793 / 441→448 (Δ7), which matches the 7 affected rows. Contract/Contragent rows correctly stay routed to #307/#308.
Parity gate flag mappings OPTIONAL_FIELD_CLI_OPTIONS adds parent (ErirAttributes, ErirAttributes.Organization) and per-field entries for the 5 WSDL-known children; the matching OPTIONAL_FIELD_CHILD_PREFIX_FOLLOWUPS entries for #306 are removed.
Scope (#306) ✅ Issue #306 covers ERIR Organization only; this PR ships exactly that. Kpp is the only field beyond the WSDL audit's 5 — it comes from the official docs (yandex.ru/dev/direct/doc/en/clients/update), is wired into the payload, and is included in the parent-path option set so the parity gate stays green even if the WSDL later grows a Kpp row.
README EN/RU examples ✅ Both sections add a one-line example with all six flags + --dry-run.

Non-blocking observations

  • --erir-organization-kpp is intentionally not listed under a dedicated ErirAttributes.Organization.Kpp parity row because the cached WSDL has no such field; the flag exists for docs parity. This is the right call but worth a one-liner in the PR body (already noted) so future audit refreshes don't surprise anyone.
  • All ERIR strings are forwarded verbatim — no client-side format validation for Kpp, RegNumber, OksmNumber, OkvedCode. Yandex will validate at the API edge; matches the pattern used for --tin.

Nothing else to flag — the follow-up is good to merge from a correctness / data-safety standpoint.
· branch codex/issue-306-clients-erir-organization

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ 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".

@axisrow

axisrow commented May 24, 2026

Copy link
Copy Markdown
Owner Author

Review triage after latest commit 5cb6099:

  • Copilot positional-argument comment: FIXED. The call now uses erir_attributes=...; latest Claude follow-up confirmed this.
  • Earlier Claude Kpp concern: resolved as no-op for this PR after follow-up review. --erir-organization-kpp is intentionally included for official docs parity; the PR body notes that current cached WSDL has no dedicated Kpp audit row.
  • Clear ERIR fields: follow-up/out of clients update: ErirAttributes.Organization typed flags #306 scope. This issue covers typed value flags for ErirAttributes.Organization, not explicit null/clear semantics.
  • Extra partial-payload tests: no-op for this PR. Existing no-op guard tests plus the new exact payload dry-run cover the accepted scope.

No blocking/actionable review comments remain.

@axisrow
axisrow merged commit 325b034 into main May 24, 2026
6 checks passed
@axisrow
axisrow deleted the codex/issue-306-clients-erir-organization branch May 24, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

clients update: ErirAttributes.Organization typed flags

2 participants