Skip to content

Update cosm adverse action schemas to match business requirements#1326

Merged
isabeleliassen merged 22 commits intocsg-org:mainfrom
InspiringApps:feat/cosm-encumbrance
Apr 15, 2026
Merged

Update cosm adverse action schemas to match business requirements#1326
isabeleliassen merged 22 commits intocsg-org:mainfrom
InspiringApps:feat/cosm-encumbrance

Conversation

@landonshumway-ia
Copy link
Copy Markdown
Collaborator

@landonshumway-ia landonshumway-ia commented Mar 31, 2026

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

  • API Updates

    • Clinical privilege action categories simplified to: fraud, consumer harm, other (now enforced as a single-item list).
    • Encumbrance types restricted to: suspension, revocation, surrender of license.
    • Added jurisdiction live-checks for encumbrance operations.
  • Notification Changes

    • Removed provider-targeted email notifications for encumbrance creation and lifting.
  • Tests

    • Updated tests, fixtures, and smoke suites to align with new enums, payloads, and smoke-test config.
  • Documentation

    • Added smoke test README and environment guidance.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cd8906b8-37c3-4e4d-a191-3a42f055eb1c

📥 Commits

Reviewing files that changed from the base of the PR and between 3413bb5 and 6961587.

📒 Files selected for processing (1)
  • backend/cosmetology-app/tests/smoke/smoke_common.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/cosmetology-app/tests/smoke/smoke_common.py

📝 Walkthrough

Walkthrough

This PR narrows encumbrance and clinical-privilege enums and schema constraints, updates tests and snapshots accordingly, refactors smoke-test provider authentication to use provider-details, removes provider-targeted encumbrance email methods, and adds jurisdiction-liveness validation to encumbrance handlers.

Changes

Cohort / File(s) Summary
Enum & Schema Definitions
backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/common.py
Reduced EncumbranceType to SUSPENSION, REVOCATION, SURRENDER_OF_LICENSE; simplified ClinicalPrivilegeActionCategory to FRAUD, CONSUMER_HARM, OTHER.
API Schema (stack)
backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py, backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py
Constrained clinicalPrivilegeActionCategories items to enum ['fraud','consumer harm','other']; narrowed encumbranceType enum to ['suspension','revocation','surrender of license'].
Request Schema Validation
backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
AdverseActionPostRequestSchema.clinicalPrivilegeActionCategories validator changed from Length(min=1) to Length(equal=1) (single-category requirement).
Snapshots / Tests: schemas & fixtures
backend/cosmetology-app/tests/resources/snapshots/*, backend/cosmetology-app/tests/resources/api/adverse-action-post.json, backend/cosmetology-app/lambdas/python/common/common_test/test_constants.py, backend/cosmetology-app/tests/unit/**
Updated JSON schemas and test fixtures/snapshots to use new enum strings (fraud, consumer harm, other) and narrowed encumbranceType values; adjusted unit test expected values.
Handler & Tests (provider-data-v1)
backend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.py, .../tests/function/test_handlers/*
Added _ensure_jurisdiction_live() validation in encumbrance handlers; updated related functional tests to use new enum values and set live jurisdictions in setUp.
Email Service
backend/cosmetology-app/lambdas/python/common/cc_common/email_service_client.py
Removed four provider-targeted encumbrance notification methods (license/privilege encumbrance and lifting variants).
IAM Grant
backend/cosmetology-app/stacks/api_lambda_stack/provider_management.py
Granted ProviderEncumbranceHandler read access to compact_configuration_table.
Smoke Test infra
backend/cosmetology-app/tests/smoke/config.py, .../smoke_common.py, .../smoke_tests_env_example.json
Removed provider-user Cognito and Authorize.Net config; replaced /me auth flow with call_provider_details_endpoint; updated provider DB query to accept compact/provider_id and paginate.
Smoke Test updates & refactors
backend/cosmetology-app/tests/smoke/*.py
Refactored multiple smoke tests (encumbrance, investigation, uploads, rollback, throttling, compact config): updated jurisdiction defaults (ne→az/al), tightened rollback verification, added family_name where required, removed privilege encumberedStatus polling, and switched payloads to new enum values.
Utilities / Formatting
backend/cosmetology-app/lambdas/python/common/cc_common/data_model/provider_record_util.py
Reformatted privilege-generation skip-condition and logger call (no behavior change).
Documentation
backend/cosmetology-app/tests/smoke/README.md
Added smoke test README documenting setup, env vars, and execution.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • jlkravitz
  • isabeleliassen
  • jusdino

Poem

🐰 I nibbled enums down with care,
One category here, three truths to share.
Tests hopped along, snapshots set right,
Smoke paths cleared to a brighter light.
a happy rabbit approves the patch

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning PR includes substantial out-of-scope changes unrelated to encumbrance schema updates: smoke test refactoring, removal of provider notification emails, and config restructuring with new jurisdiction/provider handling. Separate schema/enum changes from smoke test infrastructure changes and email service refactoring into distinct PRs focused on their respective concerns.
Docstring Coverage ⚠️ Warning Docstring coverage is 69.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive Linked issue #1316 contains only placeholder tasks without specific implementation requirements, making it difficult to fully validate whether all objectives were met. Review the actual implementation against the business requirements for encumbrance types and categories mentioned in the description to ensure all changes are intentional and complete.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: updating cosmetology adverse action schemas to align with new business requirements for encumbrance types and categories.
Description check ✅ Passed The description clearly explains the purpose (updated encumbrance values for cosmetology), references the linked issue (#1316), and covers the scope (updates to values, tests, and API schemas).

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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_schema is reused by both _encumbrance_request_schema and the adverseActions response 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_schema

Based 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 Care would 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

📥 Commits

Reviewing files that changed from the base of the PR and between 674ca38 and 152119a.

📒 Files selected for processing (25)
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/__init__.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/record.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/common.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/fields.py
  • backend/cosmetology-app/lambdas/python/common/common_test/test_constants.py
  • backend/cosmetology-app/lambdas/python/common/common_test/test_data_generator.py
  • backend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.json
  • 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/handlers/encumbrance.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.py
  • backend/cosmetology-app/lambdas/python/search/handlers/manage_opensearch_indices.py
  • backend/cosmetology-app/lambdas/python/search/tests/function/test_manage_opensearch_indices.py
  • backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py
  • backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py
  • backend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_LICENSE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PROVIDER_USER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
  • backend/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

Comment thread backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
@landonshumway-ia landonshumway-ia force-pushed the feat/cosm-encumbrance branch 2 times, most recently from e8b539a to 1240fbd Compare April 3, 2026 02:12
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between e8b539a and 1240fbd.

📒 Files selected for processing (17)
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/common.py
  • backend/cosmetology-app/lambdas/python/common/common_test/test_constants.py
  • backend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.json
  • 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_encumbrance.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.py
  • backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py
  • backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py
  • backend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_LICENSE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PROVIDER_USER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
  • backend/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

Comment thread backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 None check is redundant since the else branch with or operators handles all cases correctly—when both are provided, the or expressions 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

📥 Commits

Reviewing files that changed from the base of the PR and between 6b2faa3 and 709879a.

📒 Files selected for processing (6)
  • 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
  • backend/cosmetology-app/tests/smoke/config.py
  • backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/smoke_common.py
  • backend/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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py (1)

69-71: Minor data inconsistency: City and state mismatch.

homeAddressCity is set to 'Omaha' (a city in Nebraska) while homeAddressState is 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_id is evaluated when the module is imported. If config.test_provider_id (which reads CC_TEST_PROVIDER_ID from environment) isn't set at import time, this will raise a KeyError.

Currently this works because load_smoke_test_env() is called at module level in config.py (line 105), but it creates a subtle coupling. Consider using None as 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

📥 Commits

Reviewing files that changed from the base of the PR and between 6b2faa3 and f12dafe.

📒 Files selected for processing (13)
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/email_service_client.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.py
  • backend/cosmetology-app/stacks/api_lambda_stack/provider_management.py
  • backend/cosmetology-app/tests/smoke/compact_configuration_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/config.py
  • backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/investigation_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/smoke_common.py
  • backend/cosmetology-app/tests/smoke/smoke_tests_env_example.json
  • backend/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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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.

familyName only 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 alongside familyName.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 996076f and 8a67b6e.

📒 Files selected for processing (17)
  • backend/cosmetology-app/lambdas/python/cognito-backup/requirements-dev.txt
  • backend/cosmetology-app/lambdas/python/cognito-backup/requirements.txt
  • backend/cosmetology-app/lambdas/python/common/requirements-dev.txt
  • backend/cosmetology-app/lambdas/python/common/requirements.txt
  • backend/cosmetology-app/lambdas/python/compact-configuration/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/provider-data-v1/requirements-dev.txt
  • backend/cosmetology-app/lambdas/python/search/requirements-dev.txt
  • backend/cosmetology-app/lambdas/python/search/requirements.txt
  • backend/cosmetology-app/lambdas/python/staff-user-pre-token/requirements-dev.txt
  • backend/cosmetology-app/lambdas/python/staff-users/requirements-dev.txt
  • backend/cosmetology-app/requirements-dev.txt
  • backend/cosmetology-app/requirements.txt
  • backend/cosmetology-app/tests/smoke/query_provider_smoke_tests.py
  • backend/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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8a67b6e and a5e2fa7.

📒 Files selected for processing (4)
  • backend/cosmetology-app/tests/smoke/README.md
  • backend/cosmetology-app/tests/smoke/config.py
  • backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
  • backend/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

Comment thread backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
Comment thread backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 828025d and 72effca.

📒 Files selected for processing (2)
  • backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py

Comment thread backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 72effca and d047cf6.

📒 Files selected for processing (2)
  • backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py

Comment thread backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
Comment thread backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py
Comment thread backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
Comment thread backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
Copy link
Copy Markdown
Collaborator

@ChiefStief ChiefStief left a comment

Choose a reason for hiding this comment

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

Ok looks good. I had some questions about some of the stuff deleted / altered that dont seem directly related to this feature but is likely just outstanding clean up

@landonshumway-ia
Copy link
Copy Markdown
Collaborator Author

@jlkravitz This is ready for your review. Thanks

Copy link
Copy Markdown
Collaborator

@jlkravitz jlkravitz left a comment

Choose a reason for hiding this comment

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

two small comments!

Comment thread backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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/stacks/api_stack/v1_api/api_model.py`:
- Around line 651-652: The response models are using the shared enum-constrained
schema (_clinical_privilege_action_categories_schema), which turns GET responses
into an allow-list; update response fields like
clinicalPrivilegeActionCategories (and other occurrences noted around the same
area) to use an unconstrained array-of-strings schema instead of the shared enum
schema — e.g. replace references to _clinical_privilege_action_categories_schema
in response shapes with a JsonSchema representing an array of strings
(JsonSchema type ARRAY with items type STRING) so request validation keeps enums
but responses remain array<string>.

In `@backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py`:
- Around line 610-613: The second call to
helper.verify_privilege_adverse_action_lifted is a duplicate of the first and
does not assert the provider state; replace that second call with a
provider-state assertion so the test verifies the provider flips back to
"unencumbered" after the privilege lift — e.g. call
helper.verify_provider_unencumbered(provider_id=provider_id) or, if your helper
uses a generic checker, helper.verify_provider_state(provider_id=provider_id,
expected_state='unencumbered') instead of the duplicate
helper.verify_privilege_adverse_action_lifted(privilege_adverse_action_id).

In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py`:
- Around line 79-85: The test currently scopes the lookup via family_name but
still generates ssn from i only, which allows stale rows from previous runs to
be updated; update the identity creation to thread the same run token (e.g.,
family_name or run_token) into the uploaded identity fields so they are unique
per run — specifically, change how 'ssn' is computed (replace the plain
f'555-50-{i:04d}' with a value that incorporates the run token) and likewise
inject the run token into any other uploaded identity fields used when creating
the provider (the same pattern must be applied to the other ssn generation site
referenced in the diff). Ensure you modify the function/section that builds the
identity payload (look for variables family_name, ssn, i, and the uploaded
identity construction) so both lookup keys and uploaded identities share the
run-scoped token.
🪄 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: 0cbbd7cb-93e6-467c-8bd5-213f742774d7

📥 Commits

Reviewing files that changed from the base of the PR and between 72effca and b2d5d31.

📒 Files selected for processing (30)
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/provider_record_util.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/common.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/email_service_client.py
  • backend/cosmetology-app/lambdas/python/common/common_test/test_constants.py
  • backend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.json
  • 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/handlers/encumbrance.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.py
  • backend/cosmetology-app/stacks/api_lambda_stack/provider_management.py
  • backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py
  • backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py
  • backend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_LICENSE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PROVIDER_USER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/smoke/README.md
  • backend/cosmetology-app/tests/smoke/compact_configuration_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/config.py
  • backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/investigation_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/smoke_common.py
  • backend/cosmetology-app/tests/smoke/smoke_tests_env_example.json
  • backend/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 (8)
  • backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py
  • backend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_adverse_action.py
  • backend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.json
  • backend/cosmetology-app/lambdas/python/common/common_test/test_constants.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.py
  • backend/cosmetology-app/tests/smoke/README.md
  • backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.json
🚧 Files skipped from review as they are similar to previous changes (11)
  • backend/cosmetology-app/stacks/api_lambda_stack/provider_management.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/provider_record_util.py
  • backend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
  • backend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_investigation.py
  • backend/cosmetology-app/tests/smoke/ssn_read_throttling_smoke_tests.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.py
  • backend/cosmetology-app/tests/smoke/compact_configuration_smoke_tests.py
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/smoke/smoke_common.py
  • backend/cosmetology-app/tests/smoke/investigation_smoke_tests.py

Comment thread backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py
Comment thread backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py (1)

59-73: ⚠️ Potential issue | 🟠 Major

Cleanup only partially resets the license record.

This helper removes adverse actions and flips encumberedStatus, but it leaves other persisted side effects behind. If a previous failed run already stored licenseStatus='inactive', the next run can still start from an ineligible/dirty baseline even though setup says the provider was cleaned. Please restore the other encumbrance-mutated fields here as well, or rebuild the test provider from a known-good fixture before rerunning.

Based on learnings: in the cosmetology backend, compactEligibility is computed from jurisdictionUploadedCompactEligibility, licenseStatus, and encumberedStatus, so clearing only encumberedStatus is not enough to restore the baseline record.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py` around lines
59 - 73, The cleanup helper _remove_encumbered_status_from_license_and_provider
only clears encumberedStatus; update it to also reset other encumbrance-mutated
fields (for records where type is 'license' or 'provider') by writing
licenseStatus back to a valid active value (e.g., 'active'), clearing
adverseActions (set to an empty list or remove the attribute), and restoring
jurisdictionUploadedCompactEligibility to the expected value used for
eligibility computation; locate the DB write in
get_provider_user_dynamodb_table().update_item and extend the
UpdateExpression/ExpressionAttributeValues to set encumberedStatus,
licenseStatus, jurisdictionUploadedCompactEligibility and remove or set
adverseActions accordingly so the record returns to a known-good baseline for
tests.
♻️ Duplicate comments (1)
backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py (1)

76-85: ⚠️ Potential issue | 🟠 Major

Run scoping still misses the uploaded identity fields.

The query is now run-scoped by familyName, but Line 76 and Line 84 still reuse stable licenseNumber and ssn values. A stale earlier run can still be updated instead of creating a fresh provider set, which makes the rollback counts nondeterministic. Thread the same run token into the uploaded identifiers, not just the lookup key.

🤖 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 76 - 85, The uploaded identity fields still use stable values so an
earlier run can be updated; update the test payload creation in
rollback_license_upload_smoke_tests.py to include the run-specific token (the
same token used to build family_name) in the uploaded identifiers (specifically
the 'licenseNumber' and 'ssn' string templates that currently use
f'ROLLBACK-TEST-{i:04d}' and f'555-50-{i:04d}'), so those values are unique per
run and tie to family_name; keep LICENSE_TYPE and other fields unchanged.
🧹 Nitpick comments (1)
backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py (1)

820-829: Keep these enum lists sourced from one shared definition.

These values now exist in runtime validation (backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/common.py) and are repeated again here and in backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py. The next business-rule update can easily desync one surface. Prefer reusing a shared constant/value list instead of hardcoding the three literals in each API model.

Based on learnings, validation constraints like enum values should be defined only in runtime code (Lambda) rather than duplicating them in CDK API schema definitions.

Also applies to: 852-861

🤖 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` around lines
820 - 829, Replace the hardcoded enum literals in the property
_clinical_privilege_action_categories_schema (and the similar schema at the
other noted location) with the shared constant list exported by the
runtime/common schema module (import the list from the Lambda common schema,
e.g. the CLINICAL_PRIVILEGE_ACTION_CATEGORIES constant in
cc_common.data_model.schema.common) and pass that list into the
JsonSchema(enum=...) instead of the three string literals; add the import and
remove the duplicated literals so both API model schemas reuse the single shared
definition.
🤖 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/smoke_common.py`:
- Around line 232-247: The function get_all_provider_database_records currently
binds config.test_provider_id at import time via the default parameter; change
the signature to default provider_id to None and inside
get_all_provider_database_records resolve provider_id = provider_id or
config.test_provider_id so the value is read at call time (preserve compact
default and existing logic using
Key('pk').eq(f'{compact}#PROVIDER#{provider_id}') and pagination handling).

---

Outside diff comments:
In `@backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py`:
- Around line 59-73: The cleanup helper
_remove_encumbered_status_from_license_and_provider only clears
encumberedStatus; update it to also reset other encumbrance-mutated fields (for
records where type is 'license' or 'provider') by writing licenseStatus back to
a valid active value (e.g., 'active'), clearing adverseActions (set to an empty
list or remove the attribute), and restoring
jurisdictionUploadedCompactEligibility to the expected value used for
eligibility computation; locate the DB write in
get_provider_user_dynamodb_table().update_item and extend the
UpdateExpression/ExpressionAttributeValues to set encumberedStatus,
licenseStatus, jurisdictionUploadedCompactEligibility and remove or set
adverseActions accordingly so the record returns to a known-good baseline for
tests.

---

Duplicate comments:
In `@backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py`:
- Around line 76-85: The uploaded identity fields still use stable values so an
earlier run can be updated; update the test payload creation in
rollback_license_upload_smoke_tests.py to include the run-specific token (the
same token used to build family_name) in the uploaded identifiers (specifically
the 'licenseNumber' and 'ssn' string templates that currently use
f'ROLLBACK-TEST-{i:04d}' and f'555-50-{i:04d}'), so those values are unique per
run and tie to family_name; keep LICENSE_TYPE and other fields unchanged.

---

Nitpick comments:
In `@backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py`:
- Around line 820-829: Replace the hardcoded enum literals in the property
_clinical_privilege_action_categories_schema (and the similar schema at the
other noted location) with the shared constant list exported by the
runtime/common schema module (import the list from the Lambda common schema,
e.g. the CLINICAL_PRIVILEGE_ACTION_CATEGORIES constant in
cc_common.data_model.schema.common) and pass that list into the
JsonSchema(enum=...) instead of the three string literals; add the import and
remove the duplicated literals so both API model schemas reuse the single shared
definition.
🪄 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: 863a9a23-736e-46fb-ba3c-9380f311bb8a

📥 Commits

Reviewing files that changed from the base of the PR and between 72effca and 3413bb5.

📒 Files selected for processing (30)
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/provider_record_util.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/common.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/email_service_client.py
  • backend/cosmetology-app/lambdas/python/common/common_test/test_constants.py
  • backend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.json
  • 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/handlers/encumbrance.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.py
  • backend/cosmetology-app/stacks/api_lambda_stack/provider_management.py
  • backend/cosmetology-app/stacks/api_stack/v1_api/api_model.py
  • backend/cosmetology-app/stacks/search_api_stack/v1_api/api_model.py
  • backend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_LICENSE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/PROVIDER_USER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/smoke/README.md
  • backend/cosmetology-app/tests/smoke/compact_configuration_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/config.py
  • backend/cosmetology-app/tests/smoke/encumbrance_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/investigation_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/rollback_license_upload_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/smoke_common.py
  • backend/cosmetology-app/tests/smoke/smoke_tests_env_example.json
  • backend/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 (8)
  • backend/cosmetology-app/lambdas/python/common/tests/resources/api/adverse-action-post.json
  • backend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_adverse_action.py
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_investigation.py
  • backend/cosmetology-app/lambdas/python/common/tests/unit/test_data_model/test_schema/test_investigation.py
  • backend/cosmetology-app/lambdas/python/common/common_test/test_constants.py
  • backend/cosmetology-app/tests/resources/snapshots/PRIVILEGE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/smoke/README.md
  • backend/cosmetology-app/tests/smoke/license_upload_smoke_tests.py
🚧 Files skipped from review as they are similar to previous changes (14)
  • backend/cosmetology-app/tests/smoke/ssn_read_throttling_smoke_tests.py
  • backend/cosmetology-app/stacks/api_lambda_stack/provider_management.py
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/provider_record_util.py
  • backend/cosmetology-app/tests/resources/snapshots/PROVIDER_USER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/lambdas/python/provider-data-v1/handlers/encumbrance.py
  • backend/cosmetology-app/tests/smoke/compact_configuration_smoke_tests.py
  • backend/cosmetology-app/tests/smoke/smoke_tests_env_example.json
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_PRIVILEGE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/lambdas/python/common/cc_common/data_model/schema/adverse_action/api.py
  • backend/cosmetology-app/tests/resources/snapshots/GET_PROVIDER_RESPONSE_SCHEMA.json
  • backend/cosmetology-app/tests/resources/snapshots/LICENSE_ENCUMBRANCE_REQUEST_SCHEMA.json
  • backend/cosmetology-app/lambdas/python/provider-data-v1/tests/function/test_handlers/test_encumbrance.py
  • backend/cosmetology-app/tests/resources/snapshots/PATCH_LICENSE_INVESTIGATION_REQUEST_SCHEMA.json
  • backend/cosmetology-app/tests/smoke/config.py

Comment thread backend/cosmetology-app/tests/smoke/smoke_common.py Outdated
Copy link
Copy Markdown
Collaborator

@jlkravitz jlkravitz left a comment

Choose a reason for hiding this comment

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

@isabeleliassen This is good to merge.

@isabeleliassen isabeleliassen merged commit 88f8c53 into csg-org:main Apr 15, 2026
4 of 5 checks passed
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.

add encumbrance BE

4 participants