Skip to content

eops-368-fix(commands): drop nine commands with no v2 route - #19

Closed
mykhaylob-de wants to merge 1 commit into
mainfrom
eops-368-fix-stale-commands
Closed

eops-368-fix(commands): drop nine commands with no v2 route#19
mykhaylob-de wants to merge 1 commit into
mainfrom
eops-368-fix-stale-commands

Conversation

@mykhaylob-de

@mykhaylob-de mykhaylob-de commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

make_resource_app() registers create and update by default. Several resources are read-only in public API v2, so the factory produced nine commands that shipped in --help but could only ever return 404 or 405: companies create/update, budgets create/update, depreciation-books create/update, paper-checks create/update, and inbox get.

None of these ever worked — there is no bespoke handler for any of them at any point in the history. They existed only because the factory registers those verbs unless told otherwise.

Checked against the v2 OpenAPI schema: across the 35 factory-built resources, 175 command/route pairs are valid and exactly these nine are not.

Changes

  • Pass has_create=False, has_update=False for companies, budgets, depreciation-books and paper-checks, which v2 exposes as list and detail only.
  • Drop has_number from paper-checks. Its detail route is keyed by primary key, and PublicPaperCheckSchemaOut carries neither internal_id nor number, so get-id could never resolve and get-number only duplicated get.
  • Add a has_get flag so inbox can drop its detail command. v2 has no bare /inbox/{id}/, and the two candidate routes (/inbox/transactions/{id}/, /inbox/records/{id}/) each require a mandatory type discriminator that the generic get cannot supply, so the command is removed rather than repointed. Reinstating it needs the command-factory work in EOPS-372.
  • Add tests/test_stale_commands.py: the nine operations stay unregistered, the four read-only resources keep exactly list and get, and a writable resource still has create and update.
  • Ride-along follow-up from the Send an idempotency key on write requests #17 review: rename _MAX_RETRIES to _MAX_ATTEMPTS = len(_RETRY_DELAYS) + 1 (the old name said 3 while the client makes 4 requests), and merge the two overlapping retry test classes in tests/test_client.py into one — the duplicated 409-without-Retry-After scenarios become a single test and both unreadable-Retry-After parametrizations now share one value list.

Verification

Command surface, origin/main → this branch (20 commands become 9):

Resource Before After
companies list, get, create, update list, get
budgets list, get, create, update list, get
depreciation-books list, get, create, update list, get
paper-checks list, get, get-number, get-id, create, update list, get
inbox list, get list
  • uv sync --locked --dev + uv run pytest171 passed, 125 skipped (169 before the retry-test consolidation, which nets +2 from the shared parametrization). --locked succeeds, so no dependency or lockfile changes are needed.
  • uv run ruff check src/ tests/All checks passed!; ruff format --check → 22 files already formatted.
  • dualentry companies create --file company.json on the built entry point → usage error, exit 2, offering only list and get.
  • Reintroducing the bug (dropping the flags from the companies registration) makes the suite fail with 3 failures, e.g. 'dualentry companies create' has no v2 route and must not be registered. Reverted immediately; the branch carries no such change.

Not covered: the 125 skips are the X_API_KEY-gated live-API suite, which was not run — nothing here confirms behaviour against a running backend. The test asserts the command surface, so it catches these nine being re-added; it does not catch a newly added resource registering a verb v2 lacks. Generating the command tree from the schema is the durable fix for that, and would also subsume EOPS-372.

Test plan

  • Unit tests pass (uv run pytest) — 171 passed, 125 skipped
  • Linter passes (uv run ruff check .)
  • Manually tested with dualentry <command> — removed commands exit 2; --help for the five affected groups lists only the operations v2 exposes

@mykhaylob-de
mykhaylob-de force-pushed the eops-368-fix-stale-commands branch 2 times, most recently from 9613d96 to 4ba7293 Compare August 31, 2026 19:27
@mykhaylob-de
mykhaylob-de marked this pull request as ready for review August 31, 2026 19:49
make_resource_app() registers create and update by default. Several resources
are read-only in public API v2, so the factory produced nine commands that were
advertised in --help but could only ever return 404 or 405: companies,
budgets, depreciation-books and paper-checks create/update, plus inbox get.

None of them ever worked. There is no bespoke handler for any at any point in
the history; they existed only because the factory registers those verbs unless
told otherwise.

Pass has_create=False / has_update=False for the four resources v2 exposes as
list and detail only. Paper checks additionally drop has_number: the detail
route is keyed by primary key and the schema carries neither internal_id nor
number, so get-id could never resolve and get-number only duplicated get.

Add has_get so inbox can drop its detail command. v2 has no bare /inbox/{id}/,
and both candidate routes require a mandatory type discriminator the generic get
cannot supply, so the command is removed rather than repointed.

Cover it with a test asserting the resulting command surface: the nine stay
unregistered, read-only resources keep exactly list and get, and a writable
resource still has create and update.

Also rename the client's _MAX_RETRIES to _MAX_ATTEMPTS, which is what it counts,
and fold the near-identical retry-after cases into parametrized tests.
@mykhaylob-de
mykhaylob-de force-pushed the eops-368-fix-stale-commands branch from 54562a0 to 271ddcc Compare September 1, 2026 15:56
@mykhaylob-de
mykhaylob-de deleted the eops-368-fix-stale-commands branch September 1, 2026 19:24
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.

1 participant