Update cosm adverse action schemas to match business requirements#1326
Update cosm adverse action schemas to match business requirements#1326landonshumway-ia wants to merge 20 commits intocsg-org:mainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughNarrowed encumbrance types to three values and standardized clinical privilege action categories to Changes
Sequence Diagram(s)(Skipped — changes are schema/validation, tests, smoke-test refactors, and a small handler validation addition; no new multi-component sequential flow diagram required.) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 4❌ Failed checks (2 warnings, 2 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py (1)
359-362: Remove enum constraint from response schema.Response schemas should remain unconstrained for flexibility. The enum validation belongs in the runtime layer (
ClinicalPrivilegeActionCategoryField), not in CDK schema definitions.Proposed change
'clinicalPrivilegeActionCategories': JsonSchema( type=JsonSchemaType.ARRAY, - items=JsonSchema( - type=JsonSchemaType.STRING, - enum=['Fraud', 'Consumer Harm', 'Other'], - ), + items=JsonSchema(type=JsonSchemaType.STRING), ),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py` around lines 359 - 362, The response schema currently constrains values by including an enum on the JsonSchema used for items (JsonSchema(type=JsonSchemaType.STRING, enum=[...])). Remove the enum parameter from that JsonSchema so the response schema only declares type=JsonSchemaType.STRING (or leaves items as an unconstrained JsonSchema) and let the runtime validator (ClinicalPrivilegeActionCategoryField) enforce the allowed values; update the JsonSchema instantiation that contains items=JsonSchema(...) accordingly.backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py (1)
643-643: Split request and response category schemas.
_clinical_privilege_action_categories_schemais reused by both_encumbrance_request_schemaand theadverseActionsresponse objects, so the new enum now constrains response models too. Keep the enum on the request side only, and leave response items as plain strings to avoid doc drift when response payloads evolve.♻️ Suggested split
- def _clinical_privilege_action_categories_schema(self) -> JsonSchema: + def _clinical_privilege_action_categories_response_schema(self) -> JsonSchema: return JsonSchema( type=JsonSchemaType.ARRAY, description='The categories of clinical privilege action', - items=JsonSchema( - type=JsonSchemaType.STRING, - enum=['Fraud', 'Consumer Harm', 'Other'], - ), + items=JsonSchema(type=JsonSchemaType.STRING), ) + + `@property` + def _clinical_privilege_action_categories_request_schema(self) -> JsonSchema: + return JsonSchema( + type=JsonSchemaType.ARRAY, + description='The categories of clinical privilege action', + items=JsonSchema(type=JsonSchemaType.STRING, enum=['Fraud', 'Consumer Harm', 'Other']), + )# request-only usage 'clinicalPrivilegeActionCategories': self._clinical_privilege_action_categories_request_schema # response-only usage 'clinicalPrivilegeActionCategories': self._clinical_privilege_action_categories_response_schemaBased on learnings: request schemas should include enum validation constraints while response schemas should remain unconstrained.
Also applies to: 771-771, 810-819, 828-836
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py` at line 643, The shared enum schema _clinical_privilege_action_categories_schema is being used for both request and response models; create two separate schemas—_clinical_privilege_action_categories_request_schema (with the enum/validation) and _clinical_privilege_action_categories_response_schema (plain string/no enum)—then update usages: replace references inside _encumbrance_request_schema (and any other request schemas) to use the request variant and replace response object fields such as adverseActions to use the response variant; ensure all occurrences (including the other spots referenced around the diff) are switched so request-side validation keeps enums while responses remain unconstrained.backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py (1)
45-51: Add one regression case for a retired category value.These helpers now only exercise the new happy-path payload. A single negative case with an old value like
Unsafe Practice or Substandard Carewould lock in the enum contraction introduced by this PR.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py` around lines 45 - 51, The current helper _generate_test_body only builds a happy-path payload using ClinicalPrivilegeActionCategory.FRAUD; add a regression test that submits a payload with the retired category string "Unsafe Practice or Substandard Care" to ensure the service rejects it (e.g., assert a validation error / 4xx response). Implement this by either extending _generate_test_body to accept a category override or creating a new test helper that copies TEST_ENCUMBRANCE_EFFECTIVE_DATE and replaces clinicalPrivilegeActionCategories with the literal "Unsafe Practice or Substandard Care", then call the existing handler/test harness and assert the expected failure behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json`:
- Around line 11-21: The snapshot schema for clinicalPrivilegeActionCategories
is missing the non-empty constraint; update the source schema in
backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
to add minItems: 1 for the clinicalPrivilegeActionCategories array (the same
field that currently uses Length(min=1) at runtime), then regenerate the JSON
snapshot so the snapshot includes "minItems": 1 and matches the runtime
validator.
In `@backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py`:
- Around line 384-399: The current match predicate only compares
clinicalPrivilegeActionCategories and can match older records; update the
matching logic in the loop that builds matching_actions to also compare the
adverse_action's encumbranceEffectiveDate.effectiveStartDate against the
request_payload's encumbranceEffectiveDate.effectiveStartDate (or equivalent
key), i.e. compute request_effective =
request_payload.get('encumbranceEffectiveDate', {}).get('effectiveStartDate')
and adverse_effective = adverse_action.get('encumbranceEffectiveDate',
{}).get('effectiveStartDate') and require action_categories ==
expected_categories AND adverse_effective == request_effective when appending to
matching_actions so the test only passes for the newly created adverse action.
---
Nitpick comments:
In
`@backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py`:
- Around line 45-51: The current helper _generate_test_body only builds a
happy-path payload using ClinicalPrivilegeActionCategory.FRAUD; add a regression
test that submits a payload with the retired category string "Unsafe Practice or
Substandard Care" to ensure the service rejects it (e.g., assert a validation
error / 4xx response). Implement this by either extending _generate_test_body to
accept a category override or creating a new test helper that copies
TEST_ENCUMBRANCE_EFFECTIVE_DATE and replaces clinicalPrivilegeActionCategories
with the literal "Unsafe Practice or Substandard Care", then call the existing
handler/test harness and assert the expected failure behavior.
In `@backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py`:
- Line 643: The shared enum schema _clinical_privilege_action_categories_schema
is being used for both request and response models; create two separate
schemas—_clinical_privilege_action_categories_request_schema (with the
enum/validation) and _clinical_privilege_action_categories_response_schema
(plain string/no enum)—then update usages: replace references inside
_encumbrance_request_schema (and any other request schemas) to use the request
variant and replace response object fields such as adverseActions to use the
response variant; ensure all occurrences (including the other spots referenced
around the diff) are switched so request-side validation keeps enums while
responses remain unconstrained.
In `@backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py`:
- Around line 359-362: The response schema currently constrains values by
including an enum on the JsonSchema used for items
(JsonSchema(type=JsonSchemaType.STRING, enum=[...])). Remove the enum parameter
from that JsonSchema so the response schema only declares
type=JsonSchemaType.STRING (or leaves items as an unconstrained JsonSchema) and
let the runtime validator (ClinicalPrivilegeActionCategoryField) enforce the
allowed values; update the JsonSchema instantiation that contains
items=JsonSchema(...) accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5c8627d0-b48c-4200-9755-6c1d1dc9f20e
📒 Files selected for processing (25)
backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/__init__.pybackend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.pybackend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/record.pybackend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/common.pybackend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/fields.pybackend/cosmetology-app/lambdas/python/common/common_test/test_constants.pybackend/cosmetology-app/lambdas/python/common/common_test/test_data_generator.pybackend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.jsonbackend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_adverse_action.pybackend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_investigation.pybackend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.pybackend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.pybackend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.pybackend/cosmetology-app/lambdas/python/search/handlers/manage_opensearch_indices.pybackend/cosmetology-app/lambdas/python/search/tests/function/test_manage_opensearch_indices.pybackend/cosmetology-app/stacks/api_stack/v1_api/api_model.pybackend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.pybackend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/PATCH_LICENSE_INVESTIGATION_REQUEST_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/PROVIDER_USER_RESPONSE_SCHEMA.jsonbackend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.pybackend/cosmetology-app/tests/smoke/investigation_smoke_tests.py
💤 Files with no reviewable changes (4)
- backend/cosmetology-app/lambdas/python/search/handlers/manage_opensearch_indices.py
- backend/cosmetology-app/lambdas/python/common/common_test/test_data_generator.py
- backend/cosmetology-app/lambdas/python/search/tests/function/test_manage_opensearch_indices.py
- backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/fields.py
backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json
Show resolved
Hide resolved
152119a to
e8b539a
Compare
e8b539a to
1240fbd
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py`:
- Around line 588-592: The test sets
privilege_encumbrance_body['encumbranceType'] to an invalid enum value
'reprimand'; update the test to use one of the allowed EncumbranceType values
(e.g., 'suspension', 'revocation', or 'surrender of license') so the payload
validates against the EncumbranceType enum in common.py; locate and edit the
privilege_encumbrance_body definition in the encumbrance_smoke_tests.py test and
replace 'reprimand' with a permitted value (choose the one that fits the test
scenario).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a50e6180-a5d1-40b1-8862-c523fa646bf6
📒 Files selected for processing (17)
backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/common.pybackend/cosmetology-app/lambdas/python/common/common_test/test_constants.pybackend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.jsonbackend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_adverse_action.pybackend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_investigation.pybackend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.pybackend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.pybackend/cosmetology-app/stacks/api_stack/v1_api/api_model.pybackend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.pybackend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/PATCH_LICENSE_INVESTIGATION_REQUEST_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.jsonbackend/cosmetology-app/tests/resources/snapshots/PROVIDER_USER_RESPONSE_SCHEMA.jsonbackend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.pybackend/cosmetology-app/tests/smoke/investigation_smoke_tests.py
✅ Files skipped from review due to trivial changes (3)
- backend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.json
- backend/cosmetology-app/tests/smoke/investigation_smoke_tests.py
- backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py
🚧 Files skipped from review as they are similar to previous changes (10)
- backend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_adverse_action.py
- backend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_investigation.py
- backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.py
- backend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.json
- backend/cosmetology-app/lambdas/python/common/common_test/test_constants.py
- backend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.json
- backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json
- backend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.json
- backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py
- backend/cosmetology-app/tests/resources/snapshots/PROVIDER_USER_RESPONSE_SCHEMA.json
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
backend/cosmetology-app/tests/smoke/smoke_common.py (1)
236-241: Consider simplifying the pk construction logic.The explicit
if compact is not None and provider_id is not Nonecheck is redundant since theelsebranch withoroperators handles all cases correctly—when both are provided, theorexpressions simply return the provided values.♻️ Simplified implementation
def get_all_provider_database_records(compact: str | None = None, provider_id: str | None = None): - if compact is not None and provider_id is not None: - pk = f'{compact}#PROVIDER#{provider_id}' - else: - resolved_compact = compact or 'cosm' - resolved_provider_id = provider_id or config.test_provider_id - pk = f'{resolved_compact}#PROVIDER#{resolved_provider_id}' + resolved_compact = compact or 'cosm' + resolved_provider_id = provider_id or config.test_provider_id + pk = f'{resolved_compact}#PROVIDER#{resolved_provider_id}'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/cosmetology-app/tests/smoke/smoke_common.py` around lines 236 - 241, The pk construction is over-complicated: remove the if/else and always compute resolved_compact = compact or 'cosm' and resolved_provider_id = provider_id or config.test_provider_id, then set pk = f'{resolved_compact}#PROVIDER#{resolved_provider_id}'; update the code that currently references the explicit if (using variables compact, provider_id, config.test_provider_id, and pk) to use this single simplified assignment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@backend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.py`:
- Around line 39-41: The membership check in _ensure_jurisdiction_live uses raw
compact and jurisdiction values and can fail for mixed/upper-case inputs;
normalize both inputs (compact and jurisdiction) to lowercase before calling
config.compact_configuration_client.is_jurisdiction_live_in_compact and then
raise CCInvalidRequestException('Jurisdiction is not live in this compact') only
if the normalized check returns False so casing differences won't erroneously
reject valid jurisdictions.
---
Nitpick comments:
In `@backend/cosmetology-app/tests/smoke/smoke_common.py`:
- Around line 236-241: The pk construction is over-complicated: remove the
if/else and always compute resolved_compact = compact or 'cosm' and
resolved_provider_id = provider_id or config.test_provider_id, then set pk =
f'{resolved_compact}#PROVIDER#{resolved_provider_id}'; update the code that
currently references the explicit if (using variables compact, provider_id,
config.test_provider_id, and pk) to use this single simplified assignment.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b2a83644-61f5-477b-b221-4c92e5d98837
📒 Files selected for processing (6)
backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.pybackend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.pybackend/cosmetology-app/tests/smoke/config.pybackend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.pybackend/cosmetology-app/tests/smoke/smoke_common.pybackend/cosmetology-app/tests/smoke/smoke_tests_env_example.json
✅ Files skipped from review due to trivial changes (1)
- backend/cosmetology-app/tests/smoke/smoke_tests_env_example.json
🚧 Files skipped from review as they are similar to previous changes (1)
- backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
backend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.py
Show resolved
Hide resolved
There was a problem hiding this comment.
🧹 Nitpick comments (2)
backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py (1)
69-71: Minor data inconsistency: City and state mismatch.
homeAddressCityis set to'Omaha'(a city in Nebraska) whilehomeAddressStateis now'AZ'(Arizona). This inconsistency may be harmless for smoke tests since these are likely not validated together, but it could cause confusion when debugging test failures.Consider updating the city to an Arizona city (e.g.,
'Phoenix'or'Tucson') for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py` around lines 69 - 71, Update the test data in rollback_license_upload_smoke_tests.py so the address fields are consistent: change the 'homeAddressCity' value to an Arizona city (e.g., 'Phoenix' or 'Tucson') to match 'homeAddressState': 'AZ'; locate the object containing 'homeAddressState' and 'homeAddressCity' and replace the city string accordingly.backend/cosmetology-app/tests/smoke/smoke_common.py (1)
235-250: Default argument evaluated at module load time.The default
provider_id: str = config.test_provider_idis evaluated when the module is imported. Ifconfig.test_provider_id(which readsCC_TEST_PROVIDER_IDfrom environment) isn't set at import time, this will raise aKeyError.Currently this works because
load_smoke_test_env()is called at module level inconfig.py(line 105), but it creates a subtle coupling. Consider usingNoneas the default and resolving inside the function:♻️ Safer default argument pattern
-def get_all_provider_database_records(compact: str = 'cosm', provider_id: str = config.test_provider_id): +def get_all_provider_database_records(compact: str = 'cosm', provider_id: str | None = None): + if provider_id is None: + provider_id = config.test_provider_id items: list = []🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/cosmetology-app/tests/smoke/smoke_common.py` around lines 235 - 250, The function get_all_provider_database_records uses a default argument provider_id: str = config.test_provider_id which is evaluated at import time; change the signature to accept provider_id: Optional[str] = None and inside the function resolve provider_id = provider_id or config.test_provider_id before using it (so the env lookup happens at call time), keeping the rest of the logic (pagination, Key('pk').eq(f'{compact}#PROVIDER#{provider_id}'), and config.provider_user_dynamodb_table.query) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py`:
- Around line 69-71: Update the test data in
rollback_license_upload_smoke_tests.py so the address fields are consistent:
change the 'homeAddressCity' value to an Arizona city (e.g., 'Phoenix' or
'Tucson') to match 'homeAddressState': 'AZ'; locate the object containing
'homeAddressState' and 'homeAddressCity' and replace the city string
accordingly.
In `@backend/cosmetology-app/tests/smoke/smoke_common.py`:
- Around line 235-250: The function get_all_provider_database_records uses a
default argument provider_id: str = config.test_provider_id which is evaluated
at import time; change the signature to accept provider_id: Optional[str] = None
and inside the function resolve provider_id = provider_id or
config.test_provider_id before using it (so the env lookup happens at call
time), keeping the rest of the logic (pagination,
Key('pk').eq(f'{compact}#PROVIDER#{provider_id}'), and
config.provider_user_dynamodb_table.query) unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 496ede09-9028-42c7-8857-26310b93a855
📒 Files selected for processing (13)
backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.pybackend/cosmetology-app/lambdas/python/common/cc_common/email_service_client.pybackend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.pybackend/cosmetology-app/stacks/api_lambda_stack/provider_management.pybackend/cosmetology-app/tests/smoke/compact_configuration_smoke_tests.pybackend/cosmetology-app/tests/smoke/config.pybackend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.pybackend/cosmetology-app/tests/smoke/investigation_smoke_tests.pybackend/cosmetology-app/tests/smoke/license_upload_smoke_tests.pybackend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.pybackend/cosmetology-app/tests/smoke/smoke_common.pybackend/cosmetology-app/tests/smoke/smoke_tests_env_example.jsonbackend/cosmetology-app/tests/smoke/ssn_read_throttling_smoke_tests.py
💤 Files with no reviewable changes (1)
- backend/cosmetology-app/lambdas/python/common/cc_common/email_service_client.py
✅ Files skipped from review due to trivial changes (3)
- backend/cosmetology-app/tests/smoke/ssn_read_throttling_smoke_tests.py
- backend/cosmetology-app/tests/smoke/smoke_tests_env_example.json
- backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
🚧 Files skipped from review as they are similar to previous changes (2)
- backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
- backend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.py
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py (1)
79-84: Scope the upload key to the run too.
familyNameonly isolates the later provider query. The uploaded fixture still reuses the same business identifiers every run, so any leaked rollback data in the shared sandbox can be picked up again on Step 1 and turn this from a create/delete rollback case into an update/revert case. Please verify which incoming field the license ingest dedupes on and make that field run-scoped alongsidefamilyName.Also applies to: 620-621
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py` around lines 79 - 84, The uploaded fixture is not fully run-scoped: in addition to familyName (family_name) you must identify which incoming field the license ingest uses for deduplication (e.g., SSN or business identifier) and append the per-run unique token to that field as well so each test run creates distinct upload keys; update the test data where the fixture dict is constructed (the keys familyName and the deduped field such as ssn) to include the run-scoped suffix (use the existing family_name/run id), and apply the same change to the other occurrence of the fixture construction referenced in the comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py`:
- Around line 746-749: The current call to verify_rollback_results(results,
expected_reverted, expected_skipped) is insufficient because
verify_rollback_results only logs a warning on mismatched reverted counts;
instead assert the reverted count directly so the test fails on mismatch:
compute the actual reverted count from the results object (e.g.,
results.get('num_reverted') or len(results.get('reverted_providers'))), and add
an explicit assertion like assert actual_reverted == expected_reverted (and keep
or assert skipped with expected_skipped) using the same symbols
NUM_LICENSES_TO_UPLOAD, expected_reverted, expected_skipped and results to
guarantee the test fails on partial rollback.
- Around line 646-651: The call to wait_for_all_providers_created(...) discards
the provider IDs it finds, so capture and store them immediately (e.g., assign
its return to the same variable used by the cleanup path such as
ALL_PROVIDER_IDS or a dedicated first_step_provider_ids) so the except cleanup
can delete Step 1 providers if later steps fail; update the call site where
wait_for_all_providers_created is invoked (with staff_headers,
len(uploaded_licenses), family_name=run_family_name) to assign its return value
and ensure the except block references that variable when performing cleanup.
---
Nitpick comments:
In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py`:
- Around line 79-84: The uploaded fixture is not fully run-scoped: in addition
to familyName (family_name) you must identify which incoming field the license
ingest uses for deduplication (e.g., SSN or business identifier) and append the
per-run unique token to that field as well so each test run creates distinct
upload keys; update the test data where the fixture dict is constructed (the
keys familyName and the deduped field such as ssn) to include the run-scoped
suffix (use the existing family_name/run id), and apply the same change to the
other occurrence of the fixture construction referenced in the comment.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ee634404-4668-4a65-81eb-4fb245377955
📒 Files selected for processing (17)
backend/cosmetology-app/lambdas/python/cognito-backup/requirements-dev.txtbackend/cosmetology-app/lambdas/python/cognito-backup/requirements.txtbackend/cosmetology-app/lambdas/python/common/requirements-dev.txtbackend/cosmetology-app/lambdas/python/common/requirements.txtbackend/cosmetology-app/lambdas/python/compact-configuration/requirements-dev.txtbackend/cosmetology-app/lambdas/python/custom-resources/requirements-dev.txtbackend/cosmetology-app/lambdas/python/data-events/requirements-dev.txtbackend/cosmetology-app/lambdas/python/disaster-recovery/requirements-dev.txtbackend/cosmetology-app/lambdas/python/provider-data-v1/requirements-dev.txtbackend/cosmetology-app/lambdas/python/search/requirements-dev.txtbackend/cosmetology-app/lambdas/python/search/requirements.txtbackend/cosmetology-app/lambdas/python/staff-user-pre-token/requirements-dev.txtbackend/cosmetology-app/lambdas/python/staff-users/requirements-dev.txtbackend/cosmetology-app/requirements-dev.txtbackend/cosmetology-app/requirements.txtbackend/cosmetology-app/tests/smoke/query_provider_smoke_tests.pybackend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
💤 Files with no reviewable changes (1)
- backend/cosmetology-app/tests/smoke/query_provider_smoke_tests.py
✅ Files skipped from review due to trivial changes (15)
- backend/cosmetology-app/lambdas/python/cognito-backup/requirements.txt
- backend/cosmetology-app/lambdas/python/search/requirements.txt
- backend/cosmetology-app/lambdas/python/common/requirements.txt
- backend/cosmetology-app/lambdas/python/provider-data-v1/requirements-dev.txt
- backend/cosmetology-app/lambdas/python/search/requirements-dev.txt
- backend/cosmetology-app/lambdas/python/custom-resources/requirements-dev.txt
- backend/cosmetology-app/lambdas/python/data-events/requirements-dev.txt
- backend/cosmetology-app/lambdas/python/disaster-recovery/requirements-dev.txt
- backend/cosmetology-app/lambdas/python/cognito-backup/requirements-dev.txt
- backend/cosmetology-app/lambdas/python/compact-configuration/requirements-dev.txt
- backend/cosmetology-app/requirements.txt
- backend/cosmetology-app/lambdas/python/staff-users/requirements-dev.txt
- backend/cosmetology-app/requirements-dev.txt
- backend/cosmetology-app/lambdas/python/common/requirements-dev.txt
- backend/cosmetology-app/lambdas/python/staff-user-pre-token/requirements-dev.txt
backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
Show resolved
Hide resolved
backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py`:
- Around line 206-218: The resource creation for the smoke test is happening
before the try block, so failures in create_test_staff_user or
create_test_app_client bypass the failure logging and finally cleanup; move
create_test_staff_user and create_test_app_client (and any dependent variables
like client_id/client_secret) inside the existing try that already contains
get_client_auth_headers and upload_licenses_record, or expand the try to start
above those calls so that exceptions from
create_test_staff_user/create_test_app_client are caught and the finally cleanup
runs; ensure references to create_test_staff_user, create_test_app_client,
get_client_auth_headers, and upload_licenses_record are updated accordingly.
- Around line 181-188: The cleanup query is too broad and can delete other
tests' events; narrow it to the current test run by adding a run-specific filter
(e.g., upload_id or test_run_id) when querying data_events_table in
license_ingest_record_response and the similar block at 195-201: include the run
identifier in the KeyConditionExpression or add a FilterExpression with
ExpressionAttributeValues like ':run_id' and match the run-specific field (e.g.,
run_id, upload_id, request_id) present on the license.ingest items, and only
delete rows when the run identifier matches to avoid removing unrelated events;
also ensure _cleanup_test_generated_records() uses the same run-scoped query
before deleting.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2b824c26-b71f-4060-90e2-aad48d572c0d
📒 Files selected for processing (4)
backend/cosmetology-app/tests/smoke/README.mdbackend/cosmetology-app/tests/smoke/config.pybackend/cosmetology-app/tests/smoke/license_upload_smoke_tests.pybackend/cosmetology-app/tests/smoke/query_provider_smoke_tests.py
💤 Files with no reviewable changes (1)
- backend/cosmetology-app/tests/smoke/query_provider_smoke_tests.py
✅ Files skipped from review due to trivial changes (1)
- backend/cosmetology-app/tests/smoke/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- backend/cosmetology-app/tests/smoke/config.py
backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py`:
- Around line 259-266: The code currently treats num_found > expected_count as a
warning and continues; instead fail fast when the run-scoped provider query
over-matches. Replace the logger.warning branch (the check using num_found and
expected_count) with an immediate test failure (e.g., raise a RuntimeError or
call pytest.fail) that includes the counts and context, so the function (around
the block that logs via logger.warning/logger.info and returns
list(all_provider_ids)) aborts rather than proceeding to poll/mutate providers
outside the run.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6b362eb4-6647-4cd1-a3bd-c70531e5d233
📒 Files selected for processing (2)
backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.pybackend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py`:
- Around line 223-224: The except block that catches SmokeTestFailureException
currently only logs the error via logger.error and then returns, so the process
exits zero; after logging the failure in the except SmokeTestFailureException as
e handler, re-raise the exception (add a bare "raise" immediately after the
logger.error call) so the script exits non-zero, or alternatively call
sys.exit(1) if you prefer an explicit exit; update the handler around
SmokeTestFailureException and ensure it still logs using logger.error(str(e))
before re-raising.
In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py`:
- Around line 259-263: The failure message raised by SmokeTestFailureException
uses string interpolation placeholders but is missing the leading f-string
marker; update the raise in the block that checks "if num_found >
expected_count" so the entire multi-line message is an f-string (preface the
first quote with f) and interpolate num_found, expected_count, family_name,
JURISDICTION and COMPACT into the message so the actual values appear in the
logged exception.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 35bb4065-b058-4b95-b1a6-63cf46a8c059
📒 Files selected for processing (2)
backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.pybackend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
| except SmokeTestFailureException as e: | ||
| logger.error(f'License record upload smoke test failed: {str(e)}') |
There was a problem hiding this comment.
Re-raise the smoke-test failure so this script exits non-zero.
This handler logs SmokeTestFailureException and then returns normally, so a failed smoke test can still report success to the caller/pipeline. Please re-raise after logging, or explicitly exit with a failure code.
💡 Proposed fix
except SmokeTestFailureException as e:
logger.error(f'License record upload smoke test failed: {str(e)}')
+ raise📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| except SmokeTestFailureException as e: | |
| logger.error(f'License record upload smoke test failed: {str(e)}') | |
| except SmokeTestFailureException as e: | |
| logger.error(f'License record upload smoke test failed: {str(e)}') | |
| raise |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py` around
lines 223 - 224, The except block that catches SmokeTestFailureException
currently only logs the error via logger.error and then returns, so the process
exits zero; after logging the failure in the except SmokeTestFailureException as
e handler, re-raise the exception (add a bare "raise" immediately after the
logger.error call) so the script exits non-zero, or alternatively call
sys.exit(1) if you prefer an explicit exit; update the handler around
SmokeTestFailureException and ensure it still logs using logger.error(str(e))
before re-raising.
| if num_found > expected_count: | ||
| raise SmokeTestFailureException( | ||
| f'More providers ({num_found}) than uploads ({expected_count}) matched the query; ' | ||
| '(family_name="{family_name}", jurisdiction="{JURISDICTION}", compact="{COMPACT}"). ' | ||
| ) |
There was a problem hiding this comment.
Interpolate the over-match context in this failure message.
Line 262 is missing an f, so the exception prints {family_name}, {JURISDICTION}, and {COMPACT} literally. That makes isolation failures much harder to debug.
💡 Proposed fix
if num_found > expected_count:
raise SmokeTestFailureException(
f'More providers ({num_found}) than uploads ({expected_count}) matched the query; '
- '(family_name="{family_name}", jurisdiction="{JURISDICTION}", compact="{COMPACT}"). '
+ f'(family_name="{family_name}", jurisdiction="{JURISDICTION}", compact="{COMPACT}").'
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if num_found > expected_count: | |
| raise SmokeTestFailureException( | |
| f'More providers ({num_found}) than uploads ({expected_count}) matched the query; ' | |
| '(family_name="{family_name}", jurisdiction="{JURISDICTION}", compact="{COMPACT}"). ' | |
| ) | |
| if num_found > expected_count: | |
| raise SmokeTestFailureException( | |
| f'More providers ({num_found}) than uploads ({expected_count}) matched the query; ' | |
| f'(family_name="{family_name}", jurisdiction="{JURISDICTION}", compact="{COMPACT}"). ' | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py`
around lines 259 - 263, The failure message raised by SmokeTestFailureException
uses string interpolation placeholders but is missing the leading f-string
marker; update the raise in the block that checks "if num_found >
expected_count" so the entire multi-line message is an f-string (preface the
first quote with f) and interpolate num_found, expected_count, family_name,
JURISDICTION and COMPACT into the message so the actual values appear in the
logged exception.
Cosmetology will be using slightly different values for the encumbrance types and categories for encumbrances uploaded into the system. This updates those values along with any tests and api schemas that were referencing them.
Closes #1316
Summary by CodeRabbit