fix(number-pool): ignore the number_pool_id a schema load submits [IFC-3381]

Merged
AJ
2d ago
+93-35

Why

A team that loads a schema containing the number_pool_id of a NumberPool attribute gets one of two failures. This happens with a schema exported from another instance, or with an attribute copied from an existing one (IFC-3381):

  • The attribute has no pool yet (a new kind or a new attribute): the load stores the submitted id. The schema synchronizer then skips the attribute because it already has an id, so no pool is created and every create of that kind fails.
  • The attribute already has a pool: the load is refused with not_supported, because the submitted id differs from the stored one.

Only the schema synchronizer should assign this id. With this PR, a schema load ignores the submitted value, as it already does for the other read-only fields of a schema.

Closes IFC-3381. Depends on opsmill/infrahub-sdk-python#1466.

What changed

  • A schema load (POST /api/schema/load, and so also infrahubctl schema load and Git repository imports) drops number_pool_id from NumberPool attribute parameters. It returns the warning 'parameters.number_pool_id' is a read-only field, the submitted value is ignored.
  • An attribute that has no pool gets one from the synchronizer. An attribute that already has a pool keeps its stored id, and a load that submits a different id is accepted.
  • GET /api/schema still returns number_pool_id.

Implementation: tasks/backend.py declares number_pool_id with read visibility in the SDK generator. The write model NumberPoolParametersWrite therefore no longer has the field, and the generated READ_ONLY_FIELDS lists it. The load endpoint already drops a read-only field and warns about it, as it does for parameters.id.

What stayed the same: no database migration and no GraphQL schema change. The synchronizer, branch merges and migrations still write the id through the internal models.

How to review

  • tasks/backend.py is the only hand-written source change.
  • The following are generated:
  • test_schema_validator_stored_data.py: the _with_pool_id helper copied the stored pool id into each loaded schema, so that the load would not be refused. A load now ignores the id, so the helper is removed.

How to test

uv run pytest backend/tests/functional/pools/test_numberpool_lifecycle.py
uv run pytest backend/tests/integration/schema_lifecycle/test_schema_validator_stored_data.py

The two new tests in test_numberpool_lifecycle.py fail when the previous SDK write contract is restored:

  • test_schema_load_ignores_number_pool_id_of_new_attribute: the load returns no warning.
  • test_schema_load_keeps_pool_of_existing_attribute: the load is refused with 'not_supported': TestImportedTicket number None.

Also run locally and passing:

  • backend/tests/functional/api/test_load_schema.py
  • backend/tests/integration/schema_lifecycle/test_migration_hierarchy_change.py and test_number_pool_branch_merge.py
  • backend/tests/component/pools, backend/tests/component/graphql/resource_manager/number_pools
  • backend/tests/unit/core/schema, backend/tests/unit/pools, backend/tests/unit/core/validators

Impact & rollout

  • Backward compatibility: the REST contract of POST /api/schema/load changes. number_pool_id moves from a writable field to a read-only field that is ignored with a warning. A load that sent the stored id keeps working and now also returns the warning.
  • Deployment notes: merge opsmill/infrahub-sdk-python#1466 first, then move the python_sdk pointer to the merged commit before this PR merges.

Checklist

  • Tests added/updated
  • Changelog entry added (changelog/+ifc-3381-ignore-number-pool-id.fixed.md)
  • External docs updated (if user-facing or ops-facing change)
  • Internal .md docs updated (internal knowledge and AI code tools knowledge)

šŸ¤– Generated with Claude Code