Skip to content

MPT-17888: add first-level field annotations to Parameter and ParameterGroup models#230

Merged
albertsola merged 1 commit intomainfrom
parameters-resource
Mar 13, 2026
Merged

MPT-17888: add first-level field annotations to Parameter and ParameterGroup models#230
albertsola merged 1 commit intomainfrom
parameters-resource

Conversation

@albertsola
Copy link
Contributor

@albertsola albertsola commented Mar 13, 2026

Summary

Add type-annotated fields to the Parameter and ParameterGroup model classes derived from the OpenAPI spec (ParameterDefinition and ParameterGroup schemas respectively).

Changes

Parameter model (products_parameters.py)

Fields from the ParameterDefinition schema:

  • Primitives: name, description, scope, phase, context, type, status, external_id, display_order
  • Nested objects: group, product, constraints, audit, options

ParameterGroup model (products_parameter_groups.py)

Fields from the ParameterGroup schema:

  • Primitives: name, label, description, display_order, default, parameter_count
  • Nested objects: product, audit

Notes

  • All fields are typed as T | None since RQL select can exclude any field from the API response
  • Nested objects are typed as BaseModel | None (no dedicated sub-model classes needed at this level)
  • Unit tests extended to cover field access, to_dict() round-trip, nested BaseModel typing, and optional field absence

Closes MPT-17888

  • Add first-level, type-annotated fields to Parameter model: name, description, scope, phase, context, type, status, external_id, display_order, group, product, constraints, audit, options (all typed as T | None; nested objects as BaseModel | None)
  • Add first-level, type-annotated fields to ParameterGroup model: name, label, description, display_order, default, parameter_count, product, audit (all typed as T | None; nested objects as BaseModel | None)
  • Import and use BaseModel for nested object typing
  • Ensure all fields are nullable to support RQL select omission of fields
  • Extend unit tests to verify field access, to_dict() round-trip, nested BaseModel typing and values, and correct behavior when optional fields are absent

@albertsola albertsola requested a review from a team as a code owner March 13, 2026 16:09
@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 681adc60-e466-46b7-ad78-1a6b4e218753

📥 Commits

Reviewing files that changed from the base of the PR and between 4ea7102 and 637ccb6.

⛔ Files ignored due to path filters (1)
  • .gitignore is excluded by !.gitignore
📒 Files selected for processing (4)
  • mpt_api_client/resources/catalog/products_parameter_groups.py
  • mpt_api_client/resources/catalog/products_parameters.py
  • tests/unit/resources/catalog/test_products_parameter_groups.py
  • tests/unit/resources/catalog/test_products_parameters.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • mpt_api_client/resources/catalog/products_parameter_groups.py
  • tests/unit/resources/catalog/test_products_parameter_groups.py

📝 Walkthrough

Walkthrough

Adds nullable, type-annotated fields and detailed docstrings to ParameterGroup and Parameter models, introduces BaseModel-typed nested fields, and adds unit tests verifying serialization, nested deserialization, value access, and optional-field absence.

Changes

Cohort / File(s) Summary
Model Definitions
mpt_api_client/resources/catalog/products_parameter_groups.py, mpt_api_client/resources/catalog/products_parameters.py
Expanded ParameterGroup and Parameter classes with multiple optional attributes (e.g., name, label, description, display_order, default, parameter_count, scope, phase, type, status, external_id, display_order, etc.). Added BaseModel imports and typed nested fields (product, audit, group, constraints, options). Docstrings updated to list new Attributes.
Unit Tests
tests/unit/resources/catalog/test_products_parameter_groups.py, tests/unit/resources/catalog/test_products_parameters.py
Added fixtures with nested structures and tests asserting to_dict() preservation, nested BaseModel deserialization and field access, presence/absence of optional fields, and endpoint/method presence checks for synchronous/asynchronous services.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Jira Issue Key In Title ✅ Passed The PR title contains exactly one Jira issue key (MPT-17888) in the correct MPT-XXXX format at the beginning.
Test Coverage Required ✅ Passed PR modifies code files and includes corresponding test file changes with new test cases for validation.
Single Commit Required ✅ Passed The PR contains exactly one commit (637ccb6) that consolidates all changes related to adding first-level field annotations to the Parameter and ParameterGroup models.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

…erGroup models

Add type-annotated fields to the Parameter and ParameterGroup model
classes derived from the OpenAPI spec (ParameterDefinition and
ParameterGroup schemas respectively).

All fields are typed as T | None since RQL select can exclude any
field from the API response. Nested objects (audit, group, product,
constraints, options) are typed as BaseModel | None as no dedicated
sub-model classes exist for them yet.

Parameter fields: name, description, scope, phase, context, type,
status, external_id, display_order, group, product, constraints,
audit, options.

ParameterGroup fields: name, label, description, display_order,
default, parameter_count, product, audit.

Also extends unit tests for both models to cover field access,
nested BaseModel typing, and optional field absence.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@albertsola albertsola force-pushed the parameters-resource branch from 4ea7102 to 637ccb6 Compare March 13, 2026 16:35
@sonarqubecloud
Copy link

@albertsola albertsola merged commit 3d8b03f into main Mar 13, 2026
4 checks passed
@albertsola albertsola deleted the parameters-resource branch March 13, 2026 16:53
d3rky added a commit that referenced this pull request Mar 13, 2026
#231)

## Summary

Add typed field annotations to all 15 remaining catalog service model
classes in `mpt_api_client/resources/catalog/`, following the same
pattern established for `Parameter` and `ParameterGroup` in #230.

All fields are typed as `T | None` since RQL `select` can exclude any
field from the API response.

## Models updated

- `Authorization` — 11 fields
- `Item` — 11 fields
- `Listing` — 10 fields
- `PriceList` — 10 fields
- `PriceListItem` — 20 fields (including price columns with non-standard
casing)
- `PricingPolicy` — 11 fields
- `PricingPolicyAttachment` — 8 fields
- `Term` — 6 fields
- `TermVariant` — 12 fields
- `Document` — 11 fields
- `ItemGroup` — 10 fields
- `Media` — 11 fields
- `Template` — 6 fields
- `Product` — 11 fields
- `UnitOfMeasure` — 4 fields

## Tests

Each model's test file was extended with:
- Fixture with representative API response data
- Round-trip test via `to_dict()`
- Nested fields returning `BaseModel` instances
- Absent fields verified with `not hasattr()` (model raises
`AttributeError` for absent fields)

## Notes

- `PriceListItem` price columns use non-standard casing (e.g. `PPx1` →
`p_px1`) due to how `to_snake_case` works — round-trip via `to_dict()`
is lossy for these fields, so only attribute-access tests are used for
the price column group
- `list[BaseModel] | None` used for array-of-object fields
(`Item.parameters`, `PricingPolicy.products`)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

Closes [MPT-17888](https://softwareone.atlassian.net/browse/MPT-17888)

- Added typed first-level field annotations (T | None) to 15 catalog
service model classes: Authorization, Item, Listing, PriceList,
PriceListItem, PricingPolicy, PricingPolicyAttachment, Term,
TermVariant, Document, ItemGroup, Media, Template, Product, and
UnitOfMeasure
- All fields marked as optional (| None) to reflect RQL select behavior
where fields can be excluded from API responses
- Implemented bidirectional field name mapping via _FIELD_NAME_MAPPINGS
to handle API fields with consecutive uppercase letters (e.g., PPx1 →
ppx1, unitLP → unit_lp), enabling lossless round-trip serialization
- Updated case conversion utilities (to_snake_case and to_camel_case) to
prioritize explicit field mappings over regex-based transformations
- Extended test suite with representative API fixtures for each model
and comprehensive test coverage including primitive field round-trips,
nested BaseModel instances, and absent field behavior
- Added documentation via expanded class docstrings and a new Copilot
instructions guide (.github/copilot-instructions.md)
- All array-of-object fields properly typed as list[BaseModel] | None
(e.g., Item.parameters, PricingPolicy.products)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

[MPT-17888]:
https://softwareone.atlassian.net/browse/MPT-17888?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
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.

2 participants