Skip to content

Feat/Setting Privilege Fee Per License Type #749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

landonshumway-ia
Copy link
Collaborator

@landonshumway-ia landonshumway-ia commented Apr 18, 2025

several jurisdictions have reported that they set different
privilege fees based on the type of license for which the
privilege record is being purchased. This deprecates the old
jurisdictionFee field in place of a 'privilegeFees' field, which
is a list of objects defining the amount for every license type
supported by the compact.

Testing List

  • tests/test data updated to reference new schema

Closes #635

Summary by CodeRabbit

  • New Features

    • Introduced support for jurisdiction-specific privilege fees, allowing multiple license types with distinct fee amounts per jurisdiction.
    • Added new configuration fields for privilege fees across various jurisdictions and compacts.
    • Updated API responses and schemas to include detailed privilege fee information for each license type.
  • Bug Fixes

    • Improved validation to ensure all required license types have corresponding privilege fees and to detect duplicates or unknown license types.
  • Refactor

    • Deprecated the single jurisdiction fee field in favor of the new privilege fees structure.
    • Enhanced fee calculation logic to apply discounts and determine fees by license type.
    • Renamed license type properties for clarity and improved configuration validation.
  • Tests

    • Updated test data and assertions to validate the new privilege fees structure and deprecation of the old fee field.
    • Improved test coverage for multiple license types and privilege fee scenarios.
  • Chores

    • Added new environment variable to smoke test configuration.

Copy link
Contributor

coderabbitai bot commented Apr 18, 2025

## Walkthrough

This change introduces support for jurisdiction-specific privilege fees per license type throughout the backend. Configuration files for multiple jurisdictions are updated to include a new `privilegeFees` field, specifying fees for each license type. The backend data models, schemas, and validation logic are updated to handle and require `privilegeFees` instead of a single `jurisdictionFee`. Fee calculation logic in the purchase client is refactored to use the per-license-type fees, and related test data and assertions are updated accordingly. API models and schemas are also adjusted to reflect the new structure, deprecating the old `jurisdictionFee` property.

## Changes

| Files/Paths                                                                                      | Change Summary                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
|--------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `backend/compact-connect/common_constructs/stack.py`                                             | Renamed property `license_types` to `license_type_names` and added a new property `license_types` returning the original dictionary; updated docstrings.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `backend/compact-connect/compact-config/.../*.yml`                                               | Added new `privilegeFees` sections to jurisdiction configuration files for various states and compacts, specifying per-license-type fees.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `backend/compact-connect/lambdas/nodejs/tests/lib/jurisdiction-client.test.ts`,<br>`backend/compact-connect/lambdas/nodejs/tests/sample-records.ts` | Updated test data to include `privilegeFees` for jurisdictions; marked `jurisdictionFee` as deprecated.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/__init__.py` | Added `JurisdictionPrivilegeFee` class and `privilege_fees` property to `Jurisdiction`; deprecated `jurisdiction_fee`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/api.py`   | Added `JurisdictionPrivilegeFeeResponseSchema`; updated `JurisdictionOptionsResponseSchema` to use `privilegeFees` list and deprecated `jurisdictionFee`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/record.py` | Added `JurisdictionPrivilegeFeeRecordSchema`; updated `JurisdictionRecordSchema` to require `privilegeFees` and deprecate `jurisdictionFee`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `backend/compact-connect/lambdas/python/common/tests/resources/dynamo/jurisdiction.json`          | Added `privilegeFees` array to jurisdiction test JSON.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `backend/compact-connect/lambdas/python/custom-resources/tests/function/test_handlers/test_compact_configuration_uploader.py` | Updated test data generation and assertions to use `privilegeFees` per compact; deprecated `jurisdictionFee`; standardized decimal formatting.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `backend/compact-connect/lambdas/python/purchases/purchase_client.py`                            | Refactored fee calculation to use `privilegeFees` per license type; updated function signatures and error handling; military discount logic now applies to per-license fee.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `backend/compact-connect/lambdas/python/purchases/tests/unit/test_purchase_client.py`             | Updated tests to use `licenseFee` and set amounts in `privilegeFees` array; removed reliance on single `jurisdictionFee`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `backend/compact-connect/stacks/api_stack/v1_api/api_model.py`                                   | Updated schemas and models to use `license_type_names` for enums; added `privilegeFees` property and deprecated `jurisdictionFee` in purchase privilege options schema.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `backend/compact-connect/stacks/persistent_stack/compact_configuration_upload.py`                | Enhanced jurisdiction config validation to require and check `privilegeFees` for all license types, detect duplicates and unknowns, and improved error messages.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `backend/compact-connect/tests/resources/snapshots/COMPACT_CONFIGURATION_UPLOADER_BETA_ENV_INPUT.json`,<br>`backend/compact-connect/tests/resources/snapshots/PURCHASE_PRIVILEGE_OPTIONS_RESPONSE_SCHEMA.json` | Updated test snapshots to include `privilegeFees` in jurisdiction objects and schemas.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `backend/compact-connect/tests/smoke/purchasing_privileges_smoke_tests.py`                       | Updated expected data to include `privilegeFees`; marked `jurisdictionFee` as deprecated.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `backend/compact-connect/tests/smoke/smoke_tests_env_example.json`                               | Added `ENVIRONMENT_NAME` key to smoke test environment config.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Client
    participant API
    participant PurchaseClient
    participant Jurisdiction

    Client->>API: Request privilege purchase (licenseTypeAbbreviation)
    API->>PurchaseClient: process_charge_on_credit_card_for_privilege_purchase(...)
    PurchaseClient->>Jurisdiction: Get privilege_fees
    PurchaseClient->>PurchaseClient: _calculate_jurisdiction_fee(jurisdiction, licenseTypeAbbreviation, ...)
    alt privilege fee found
        PurchaseClient->>PurchaseClient: Apply military discount if applicable
        PurchaseClient-->>API: Return calculated fee
    else privilege fee not found
        PurchaseClient-->>API: Raise error
    end
    API-->>Client: Respond with result or error

Assessment against linked issues

Objective Addressed Explanation
Ability to charge a different fee for each license type (e.g., OT vs OTA); state can designate charge based on license type (#635)

Suggested reviewers

  • jlkravitz
  • jusdino
  • isabeleliassen

Poem

In the warren of code, a new fee takes its place,
Each license type now runs its own race.
No more one-size-fits-all, the states decide,
OT or OTA, their costs now reside.
With schemas aligned and tests all anew,
This rabbit’s quite proud of what the team can do!
🐇💸


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=csg-org/CompactConnect&utm_content=749):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@landonshumway-ia landonshumway-ia force-pushed the feat/fee-per-license-type branch from bf9ed1d to 59f3dc3 Compare April 21, 2025 17:30
several jurisdictions have reported that they set different
privilege fees based on the type of license for which the
privilege record is being purchased. This deprecates the old
jurisdictionFee field in place of a 'privilegeFees' field, which
is a list of objects defining the amount for every license type
supported by the compact.
@landonshumway-ia landonshumway-ia force-pushed the feat/fee-per-license-type branch from 59f3dc3 to 032f9a7 Compare April 21, 2025 18:23
@landonshumway-ia landonshumway-ia changed the title WIP - setting license fee per license type Setting license fee per license type Apr 21, 2025
@landonshumway-ia landonshumway-ia marked this pull request as ready for review April 21, 2025 19:30
Copy link
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 (10)
backend/compact-connect/compact-config/octp/kentucky.yml (1)

4-9: Consider adding a deprecation comment for jurisdictionFee.

Both the old jurisdictionFee and new privilegeFees are present, which could cause confusion about which takes precedence. Consider adding a comment indicating that jurisdictionFee is deprecated and will be removed in a future update.

backend/compact-connect/compact-config/octp/mississippi.yml (1)

4-9: Consider adding a deprecation comment for jurisdictionFee.

As with the Kentucky configuration, both the old jurisdictionFee and new privilegeFees fields are present. Consider adding a comment indicating that jurisdictionFee is deprecated to clarify the transition to the new fee structure.

backend/compact-connect/compact-config/octp/alabama.yml (1)

4-4: Deprecate jurisdictionFee with a comment
Since jurisdictionFee is now superseded by privilegeFees, annotate it with a YAML comment referencing issue #635 to signal its removal in a future release.

backend/compact-connect/compact-config/coun/florida.yml (1)

4-4: Annotate deprecation of jurisdictionFee
Add a YAML comment to jurisdictionFee: 15 indicating deprecation (issue #635) for consistency across all jurisdiction configs.

backend/compact-connect/compact-config/coun/kentucky.yml (1)

4-4: Annotate jurisdictionFee deprecation
Include a comment on jurisdictionFee: 100 marking it as deprecated (issue #635) to clearly communicate its upcoming removal.

backend/compact-connect/tests/resources/snapshots/PURCHASE_PRIVILEGE_OPTIONS_RESPONSE_SCHEMA.json (1)

99-102: Add deprecation notice to jurisdictionFee description.

Since jurisdictionFee is being deprecated in favor of the new privilegeFees field, it would be helpful to include a deprecation notice in its description to guide API consumers.

"jurisdictionFee": {
-  "description": "The fee for the jurisdiction",
+  "description": "The fee for the jurisdiction (DEPRECATED: Use privilegeFees instead)",
  "type": "number"
},
backend/compact-connect/tests/resources/snapshots/COMPACT_CONFIGURATION_UPLOADER_BETA_ENV_INPUT.json (1)

373-373: Consider adding comments about jurisdictionFee deprecation.

To maintain consistency with the sample-records.ts file, consider adding deprecation comments for the jurisdictionFee property in these configurations as well.

Add a comment similar to this before each jurisdictionFee entry:

// deprecated - to be removed

Also applies to: 253-253, 283-283, 313-313, 343-343

backend/compact-connect/lambdas/python/purchases/tests/unit/test_purchase_client.py (1)

111-111: Ensure licenseFee naming is consistent with the rest of the codebase.

The parameter name licenseFee is used in the test data, while the actual field in the model is called privilegeFees. Consider using more consistent naming to avoid confusion, especially since this is test data that might be referenced by other developers.

-            {'postalCode': 'oh', 'jurisdictionName': 'ohio', 'licenseFee': 100.00},
+            {'postalCode': 'oh', 'jurisdictionName': 'ohio', 'privilegeFee': 100.00},

Then update the iteration code accordingly:

 for licensee_fee in jurisdiction['privilegeFees']:
     # DynamoDB loads this as a decimal
-    licensee_fee['amount'] = Decimal(jurisdiction_test_item['licenseFee'])
+    licensee_fee['amount'] = Decimal(jurisdiction_test_item['privilegeFee'])

Also applies to: 348-349

backend/compact-connect/lambdas/nodejs/tests/sample-records.ts (1)

252-334: Verify the amount values are appropriate for testing.

The sample data uses "100" for all license types. While this is fine for basic testing, consider adding variety in the test data (different amounts for different license types) to better validate that the code correctly handles different fees per license type.

'privilegeFees': [
    {
        'licenseTypeAbbreviation': 'aud',
-       'amount': '100'
+       'amount': '100'
    },
    {
        'licenseTypeAbbreviation': 'slp',
-       'amount': '100'
+       'amount': '125'
    }
],
backend/compact-connect/lambdas/python/custom-resources/tests/function/test_handlers/test_compact_configuration_uploader.py (1)

227-232: Inconsistent deprecation comment.

There's an inconsistency in the deprecation comment, using "when frontend is updated" instead of the standard GitHub issue reference used elsewhere.

For consistency with other comments in the codebase, consider changing:

-                    # deprecated - will be removed when frontend is updated
+                    # deprecated - will be removed as part of https://github.com/csg-org/CompactConnect/issues/636
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd9abdb and ba657e0.

📒 Files selected for processing (30)
  • backend/compact-connect/common_constructs/stack.py (1 hunks)
  • backend/compact-connect/compact-config/aslp/kentucky.yml (1 hunks)
  • backend/compact-connect/compact-config/aslp/nebraska.yml (1 hunks)
  • backend/compact-connect/compact-config/aslp/ohio.yml (1 hunks)
  • backend/compact-connect/compact-config/coun/florida.yml (1 hunks)
  • backend/compact-connect/compact-config/coun/kentucky.yml (1 hunks)
  • backend/compact-connect/compact-config/coun/nebraska.yml (1 hunks)
  • backend/compact-connect/compact-config/coun/ohio.yml (1 hunks)
  • backend/compact-connect/compact-config/octp/alabama.yml (1 hunks)
  • backend/compact-connect/compact-config/octp/arkansas.yml (1 hunks)
  • backend/compact-connect/compact-config/octp/kentucky.yml (1 hunks)
  • backend/compact-connect/compact-config/octp/louisiana.yml (1 hunks)
  • backend/compact-connect/compact-config/octp/mississippi.yml (1 hunks)
  • backend/compact-connect/compact-config/octp/nebraska.yml (1 hunks)
  • backend/compact-connect/compact-config/octp/ohio.yml (1 hunks)
  • backend/compact-connect/lambdas/nodejs/tests/lib/jurisdiction-client.test.ts (2 hunks)
  • backend/compact-connect/lambdas/nodejs/tests/sample-records.ts (2 hunks)
  • backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/__init__.py (2 hunks)
  • backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/api.py (3 hunks)
  • backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/record.py (3 hunks)
  • backend/compact-connect/lambdas/python/common/tests/resources/dynamo/jurisdiction.json (1 hunks)
  • backend/compact-connect/lambdas/python/custom-resources/tests/function/test_handlers/test_compact_configuration_uploader.py (9 hunks)
  • backend/compact-connect/lambdas/python/purchases/purchase_client.py (4 hunks)
  • backend/compact-connect/lambdas/python/purchases/tests/unit/test_purchase_client.py (2 hunks)
  • backend/compact-connect/stacks/api_stack/v1_api/api_model.py (9 hunks)
  • backend/compact-connect/stacks/persistent_stack/compact_configuration_upload.py (3 hunks)
  • backend/compact-connect/tests/resources/snapshots/COMPACT_CONFIGURATION_UPLOADER_BETA_ENV_INPUT.json (6 hunks)
  • backend/compact-connect/tests/resources/snapshots/PURCHASE_PRIVILEGE_OPTIONS_RESPONSE_SCHEMA.json (2 hunks)
  • backend/compact-connect/tests/smoke/purchasing_privileges_smoke_tests.py (1 hunks)
  • backend/compact-connect/tests/smoke/smoke_tests_env_example.json (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/api.py (1)
backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/__init__.py (1)
  • amount (55-56)
backend/compact-connect/lambdas/python/custom-resources/tests/function/test_handlers/test_compact_configuration_uploader.py (1)
backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/__init__.py (4)
  • compact (74-75)
  • jurisdiction_name (66-67)
  • postal_abbreviation (70-71)
  • privilege_fees (84-85)
🔇 Additional comments (56)
backend/compact-connect/common_constructs/stack.py (2)

62-64: Good refactoring to improve property naming clarity.

Renaming the original license_types to license_type_names more clearly indicates that this property returns a flattened list of license type names across all compacts, which is important for the new per-license fee structure.


66-69: Well-structured addition of the raw license types accessor.

The new license_types property provides direct access to the structured dictionary of license types by compact, which will be useful for validating that configurations include fees for all required license types. Good use of the cached_property decorator for performance.

backend/compact-connect/compact-config/octp/kentucky.yml (1)

5-9: Successfully implemented per-license privilege fees.

The new privilegeFees structure correctly defines fees for each license type ("ot" and "ota"), implementing the PR's goal of supporting license-specific fees.

backend/compact-connect/lambdas/python/common/tests/resources/dynamo/jurisdiction.json (1)

9-18: Correctly updated test fixture with new privilegeFees structure.

The test data now includes the new privilegeFees array with appropriate license types and amounts, ensuring that unit tests will properly validate the new fee structure. Good alignment with the configuration changes.

backend/compact-connect/compact-config/octp/mississippi.yml (1)

5-9: Consistently implemented per-license privilege fees.

The privilegeFees structure is implemented consistently with other configuration files, defining the same license types ("ot" and "ota") with appropriate fee amounts.

backend/compact-connect/tests/smoke/smoke_tests_env_example.json (1)

14-15: Review placeholder environment variables and documentation.
You’ve added "CC_TEST_PROVIDER_USER_PASSWORD" and the new "ENVIRONMENT_NAME" entries for smoke tests. Ensure these placeholders are clearly documented (e.g., in README or comments) and that real credentials are never committed. Also verify that the smoke‐test harness actually consumes ENVIRONMENT_NAME and that its value is overridden in CI pipelines.

backend/compact-connect/compact-config/octp/louisiana.yml (1)

5-9: Add privilegeFees for per-license-type fee configuration.
You’ve introduced privilegeFees with entries for "ot" and "ota" in Louisiana’s OCTP config. This aligns with the PR’s goal to move from a single jurisdictionFee to license-specific fees.
Please confirm:

  1. All supported license types for OCTP in Louisiana are represented here.
  2. The compact_configuration_upload logic will flag or log the now-deprecated jurisdictionFee to guide its eventual removal.
backend/compact-connect/compact-config/octp/nebraska.yml (1)

5-9: Introduce privilegeFees and preserve legacy fallback.
Nebraska’s OCTP config now includes privilegeFees for "ot" and "ota". Ensure:

  • This list covers every valid license type for Nebraska’s OCTP compact.
  • The upload/validation step warns about the existing jurisdictionFee so teams can migrate off it cleanly.
backend/compact-connect/compact-config/octp/arkansas.yml (1)

5-9: Validate privilegeFees entries and correct fee amounts.
Arkansas’s OCTP config mirrors jurisdictionFee: 3 with privilegeFees for "ot" and "ota" at amount: 3. Please verify:

  • That 3 is indeed the intended per-license-type fee.
  • No additional license types are missing from this list.
    Also ensure the uploader flags mixed use of jurisdictionFee and privilegeFees.
backend/compact-connect/compact-config/coun/ohio.yml (1)

5-7: Add Ohio privilegeFees for LPC license type.
You’ve added a single privilegeFees entry for "lpc" with amount: 100. Confirm:

  • The COUN compact’s Ohio jurisdiction only requires "lpc".
  • The schema and uploader validation will enforce no missing or extraneous license types.
    Also plan for deprecating jurisdictionFee in upcoming releases.
backend/compact-connect/compact-config/coun/nebraska.yml (1)

5-7: Approve addition of privilegeFees
The new privilegeFees block is correctly structured with licenseTypeAbbreviation: "lpc" and amount: 100, aligning with the updated per‑license fee model.

backend/compact-connect/compact-config/aslp/kentucky.yml (1)

5-9: Approve addition of privilegeFees
The privilegeFees section correctly enumerates the "aud" and "slp" license type fees to replace the deprecated single jurisdictionFee.

backend/compact-connect/compact-config/octp/ohio.yml (1)

5-9: Approve addition of privilegeFees
The privilegeFees entries for "ot" and "ota" are properly defined and match the updated fee schema requirements.

backend/compact-connect/compact-config/aslp/nebraska.yml (1)

5-9: Approve addition of privilegeFees
The privilegeFees list correctly covers the "aud" and "slp" license types in line with the ASLP compact’s per‑license fee update.

backend/compact-connect/compact-config/aslp/ohio.yml (1)

5-9: Approve addition of privilegeFees
The new privilegeFees block defines the "aud" and "slp" license type fees correctly, fully supporting the migration away from the single jurisdictionFee.

backend/compact-connect/compact-config/octp/alabama.yml (1)

5-9: Introduce privilegeFees to support license-type-specific fees
The new privilegeFees list correctly defines fees for the "ot" and "ota" license types. Ensure that these abbreviations align with the compact’s supported license types in the data model and validation logic.

backend/compact-connect/compact-config/coun/florida.yml (1)

5-7: Introduce privilegeFees replacing the single jurisdictionFee
The added privilegeFees entry for license type "lpc" aligns with the new fee model. Confirm that downstream validation and tests account for this per-license-type structure.

backend/compact-connect/compact-config/coun/kentucky.yml (1)

5-7: Add privilegeFees section
The new privilege fee for license type "lpc" is correctly defined. Verify that the compact configuration uploader enforces coverage of every license type required by the Kentucky compact.

backend/compact-connect/lambdas/nodejs/tests/lib/jurisdiction-client.test.ts (4)

26-32: Verify issue reference in deprecation comment
The deprecation comment for jurisdictionFee points to issue #636, but this PR resolves issue #635. Please confirm the correct issue number and update the link for accurate traceability.


30-53: Include privilegeFees in sample data
The privilegeFees array is correctly structured for the first jurisdiction entry. This ensures tests validate per-license-type fees as per the updated data model.


110-113: Verify deprecation comment issue reference
The deprecation comment for the second jurisdiction’s jurisdictionFee also references issue #636. Confirm and align this with the correct issue #635 to maintain consistency.


114-137: Add privilegeFees for the second jurisdiction sample
Appending privilegeFees for Nebraska mirrors the production configuration. Ensure test expectations for the number and content of fee entries match real-world license types.

backend/compact-connect/tests/smoke/purchasing_privileges_smoke_tests.py (1)

66-72: Confirm deprecation comment and expected privilegeFees
The smoke test now expects a privilegeFees array alongside the deprecated jurisdictionFee. Please verify the deprecation link (#636 vs #635) and ensure the license-type entries ("aud" and "slp") comprehensively cover the Kentucky compact’s license types.

backend/compact-connect/tests/resources/snapshots/PURCHASE_PRIVILEGE_OPTIONS_RESPONSE_SCHEMA.json (1)

103-121: The new privilegeFees structure looks good.

The addition of the privilegeFees structure correctly implements the requirement to support different privilege fees based on license type. It's well-structured as an array of objects with appropriate required fields.

backend/compact-connect/tests/resources/snapshots/COMPACT_CONFIGURATION_UPLOADER_BETA_ENV_INPUT.json (2)

224-233: The privilegeFees implementation for Ohio looks good.

The structure matches the schema requirements and contains entries for both license types (aud and slp).


255-264: Consistent implementation of privilegeFees across all jurisdictions.

The implementation is consistent across all jurisdictions, with each jurisdiction defining fees for their respective license types. This aligns well with the PR objective to set different privilege fees depending on license type.

Also applies to: 285-294, 315-324, 345-354, 375-384

backend/compact-connect/lambdas/python/purchases/tests/unit/test_purchase_client.py (2)

119-122: Good implementation for handling privilegeFees in test data.

The updated code correctly iterates through the privilegeFees list to set the fee amount for each license type. This ensures the test data is consistent with the new fee structure while maintaining compatibility with existing tests.


230-231:

✅ Verification successful

Verify that license_type_abbreviation is properly handled.

I notice the license_type_abbreviation parameter is passed through to process_charge_for_licensee_privileges in multiple test cases, which aligns with the new per-license-type fee structure. Ensure the actual implementation of this method correctly filters the privilegeFees array by license type.

To verify the implementation is correct, consider checking if the purchase_client.py logic looks for the matching license type:

Also applies to: 304-305, 357-358, 452-453


🏁 Script executed:

#!/bin/bash
# Search for the relevant code in purchase_client.py that uses license_type_abbreviation to find the appropriate fee
rg -A 5 "def process_charge_for_licensee_privileges" backend/compact-connect/lambdas/python/purchases/purchase_client.py
rg -A 10 "license_type_abbreviation" backend/compact-connect/lambdas/python/purchases/purchase_client.py

Length of output: 6500


License type filtering is correctly implemented

The _calculate_jurisdiction_fee helper uses:

next(
  (fee for fee in jurisdiction.privilege_fees 
    if fee.license_type_abbreviation == license_type_abbr),
  None
)

to select the fee matching the passed‑in license_type_abbreviation, so the existing tests align with the implementation. No further changes required.

backend/compact-connect/lambdas/nodejs/tests/sample-records.ts (2)

248-249: Good documentation of deprecated fields.

The comments clearly indicate that the jurisdictionFee field is deprecated and will be removed in a future issue, providing the issue number for reference. This helps other developers understand the transition plan.

Also applies to: 323-324


252-275: Complete and consistent implementation of privilegeFees in sample data.

The new privilegeFees field is correctly implemented in both the DynamoDB format (with nested 'L' and 'M' types) and the unmarshalled format. The structure matches what's defined in the schema and includes multiple license types, which aligns with the project requirements.

Also applies to: 325-334

backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/__init__.py (3)

44-57: Well-structured data model for privilege fees.

The new JurisdictionPrivilegeFee class provides a clean interface for accessing license fee data with appropriate property accessors. This implementation aligns with existing design patterns in the codebase.


77-81: Appropriate deprecation of jurisdiction_fee property.

Clear documentation with the issue reference helps other developers understand why this field is deprecated and what to use instead.


83-85: Properly implemented privilege_fees property.

The implementation correctly converts raw data into typed objects, providing a consistent access pattern. This supports the new per-license-type fee structure requested by jurisdictions.

backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/record.py (3)

23-26: Well-defined schema for license-specific fees.

The schema correctly defines required fields with appropriate types and constraints, matching the new data model.


38-38: Correctly implemented required privilegeFees field.

The field is properly defined as a required list of nested schema objects, enforcing the new data structure.


61-62: Appropriate handling of deprecated field.

The jurisdictionFee field is correctly marked as optional with a deprecation comment, maintaining backward compatibility while guiding developers toward the new structure.

backend/compact-connect/lambdas/python/common/cc_common/data_model/schema/jurisdiction/api.py (4)

3-3: Updated imports to support new field types.

The import statement has been properly updated to include the List field which is used for the new privilegeFees property.


23-26: Well-structured API response schema for privilege fees.

The schema correctly defines the required fields with appropriate types, aligning with the data model.


38-38: Properly implemented privilegeFees in API response schema.

The field is correctly defined as a required list of nested schema objects, ensuring API responses include the new fee structure.


43-44: Appropriate handling of deprecated field in API response.

The jurisdictionFee field is correctly marked as optional with a deprecation comment, maintaining backward compatibility while indicating future removal.

backend/compact-connect/lambdas/python/custom-resources/tests/function/test_handlers/test_compact_configuration_uploader.py (4)

15-16: Good use of constants for compact abbreviations.

Replacing hardcoded strings with named constants improves code readability and maintainability.


44-52: Well-implemented test data generation for privilege fees.

The updated function correctly generates different license-specific fees based on compact type, accurately reflecting the new data structure requirements.


56-58: Appropriate inclusion of both new and deprecated fee fields in test data.

The test data includes both the new privilegeFees structure and the deprecated jurisdictionFee field with a clear comment, ensuring tests validate backward compatibility.


141-145: Correct test assertions for the new privilege fees structure.

The test expectations have been updated to include the new privilegeFees structure with precise decimal handling, ensuring accurate validation of the configuration uploader's behavior.

backend/compact-connect/stacks/persistent_stack/compact_configuration_upload.py (3)

143-143: Appropriate stack retrieval for license type validation.

The addition of retrieving the current stack instance enables access to license type information needed for validation.


190-194: Good enhancement to validation call.

The function call has been expanded to include the compact abbreviation, jurisdiction object, and license types specific to that compact, which enables more thorough validation.


205-242: Well-implemented jurisdiction fee validation.

The validation logic is thorough, covering several important cases:

  1. Ensuring all license types have corresponding fees defined
  2. Detecting duplicate license type fees
  3. Checking for unknown license types not defined in the compact
  4. Requiring privilege fees to be defined

The implementation is robust and provides clear error messages that will help administrators quickly fix configuration issues.

backend/compact-connect/stacks/api_stack/v1_api/api_model.py (3)

157-157: Correctly updated references to license type names.

All references to self.stack.license_types have been properly updated to self.stack.license_type_names to align with the refactoring in the Stack class, where license types was renamed to represent a flattened list of names.

Also applies to: 528-528, 977-977, 1019-1019, 1156-1156, 1639-1639


819-820: Properly documented deprecation.

The jurisdictionFee property is clearly marked as deprecated with a reference to the corresponding issue for future removal, which follows good practices for API versioning.

Also applies to: 834-838


839-850: Well-structured schema for new privilege fees.

The new privilegeFees property is correctly implemented as an array of objects, each containing a license type abbreviation and an amount. The schema definition is consistent with the rest of the API model and includes all necessary fields.

backend/compact-connect/lambdas/python/purchases/purchase_client.py (6)

44-46: Well-documented function signature update.

The _calculate_jurisdiction_fee function's signature has been updated to include the license type abbreviation parameter, and the docstring has been properly updated to document this change.

Also applies to: 51-52, 54-55


57-71: Robust implementation of license type-specific fee calculation.

The implementation efficiently finds the matching fee for the specified license type using a generator expression with next(). It includes proper error handling and logging when a fee for the specified license type is not found.


72-82: Correctly updated military discount logic.

The military discount logic has been updated to apply to the license type-specific fee rather than a generic jurisdiction fee, maintaining the discount functionality with the new fee structure.


132-149: Well-documented parameter propagation in privilege cost calculation.

The _get_total_privilege_cost function has been updated to include the license type abbreviation parameter and properly passes it to _calculate_jurisdiction_fee. The docstring has been updated to reflect this change.

Also applies to: 152-156


355-359: Consistently updated payment processing.

The payment processing code has been updated to pass the license type abbreviation to the fee calculation function, ensuring consistent application of the new fee structure.


409-414: Proper propagation of license type parameter in fee calculation.

The _get_total_privilege_cost call has been updated to include the license type abbreviation parameter, ensuring the correct total cost calculation.

@landonshumway-ia landonshumway-ia changed the title Setting license fee per license type Feat/Setting Privilege Fee Per License Type Apr 21, 2025
Copy link
Collaborator

@jusdino jusdino left a comment

Choose a reason for hiding this comment

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

Looks good! Only one super minor nit.

@landonshumway-ia
Copy link
Collaborator Author

@jlkravitz This is ready for your review. Thanks

Copy link
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 self-requested a review April 23, 2025 17:10
@isabeleliassen isabeleliassen merged commit 540c1ff into csg-org:development Apr 23, 2025
1 check 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.

fee per each license type backend
4 participants