Repository: bcgov/lear
Pull request #3490: 21881 added a is_competent_authority function to authz, removed ...
Author: login: BrandonSharratt
Created: 2025-05-12T23:04:44Z | Merged: 2025-05-21T14:56:42Z

... receipt from CA users response (ca can't file a receipt and should never see one)

*Issue #:* /bcgov/entity#21881

*Description of changes:*
Added a funciton in authz to check for CA and simplified existing checks to use that function
Check if user is a CA before adding receipt to the document responses as CA shouldn't be able to see the receipts ever

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the lear license (Apache 2.0).



Diff:
diff --git a/legal-api/src/legal_api/config.py b/legal-api/src/legal_api/config.py
index a5ae44d5e9..8a741d741a 100644
--- a/legal-api/src/legal_api/config.py
+++ b/legal-api/src/legal_api/config.py
@@ -317,6 +317,18 @@ class TestConfig(_Config):  # pylint: disable=too-few-public-methods
     # determines which version of NAICS data will be used to drive NAICS search
     NAICS_VERSION = 1
 
+    LEGAL_API_BASE_URL="https://LEGAL_API_BASE_URL/api/v2/businesses"
+    PAYMENT_SVC_URL="https://PAY_SVC_URL/api/v1/payment-requests"
+
+    BUSINESS_SCHEMA_ID = os.getenv("BUSINESS_SCHEMA_ID", "TEST_BUSINESS_SCHEMA_ID")
+    BUSINESS_CRED_DEF_ID = os.getenv("BUSINESS_CRED_DEF_ID", "TEST_BUSINESS_SCHEMA_ID")
+
+    TRACTION_API_URL = os.getenv("TRACTION_API_URL", "https://TRACTION_API_URL")
+    TRACTION_TENANT_ID = os.getenv("TRACTION_TENANT_ID", "TRACTION_TENANT_ID")
+    TRACTION_API_KEY = os.getenv("TRACTION_API_KEY", "TRACTION_API_KEY")
+    TRACTION_PUBLIC_SCHEMA_DID = os.getenv("TRACTION_PUBLIC_SCHEMA_DID", "TRACTION_PUBLIC_SCHEMA_DID")
+    TRACTION_PUBLIC_ISSUER_DID = os.getenv("TRACTION_PUBLIC_ISSUER_DID", "TRACTION_PUBLIC_ISSUER_DID")
+
 
 class ProdConfig(_Config):  # pylint: disable=too-few-public-methods
     """Production environment configuration."""
diff --git a/legal-api/src/legal_api/core/filing.py b/legal-api/src/legal_api/core/filing.py
index 8b65927ceb..3e972a0464 100644
--- a/legal-api/src/legal_api/core/filing.py
+++ b/legal-api/src/legal_api/core/filing.py
@@ -30,7 +30,7 @@
 from legal_api.models import Filing as FilingStorage  # noqa: I001
 from legal_api.models import UserRoles
 from legal_api.services import VersionedBusinessDetailsService  # noqa: I005
-from legal_api.services.authz import has_roles  # noqa: I005
+from legal_api.services.authz import has_roles, is_competent_authority  # noqa: I005
 from legal_api.utils.datetime import date, datetime  # noqa: I005
 
 from .constants import REDACTED_STAFF_SUBMITTER
@@ -522,7 +522,10 @@ def get_document_list(business,  # pylint: disable=too-many-locals disable=too-m
         if filing.storage and filing.storage.filing_type in no_output_filings:
             return documents
 
-        # return a receipt for filings completed in our system
+        user_is_ca = is_competent_authority(jwt)
+
+        # return a receipt for filings completed in our system (but not for ca users
+        # see https://github.com/bcgov/entity/issues/21881
         if filing.storage and filing.storage.payment_completion_date:
             if filing.filing_type == 'courtOrder' and \
                     (filing.storage.documents.filter(
@@ -552,6 +555,8 @@ def get_document_list(business,  # pylint: disable=too-many-locals disable=too-m
                  ):
             documents['documents']['legalFilings'] = \
                 [{filing.filing_type: f'{base_url}{doc_url}/{filing.filing_type}'}, ]
+            if user_is_ca:
+                del documents['documents']['receipt']
             return documents
 
         if filing.status in (
@@ -603,4 +608,6 @@ def get_document_list(business,  # pylint: disable=too-many-locals disable=too-m
                     if static_docs := FilingMeta.get_static_documents(filing.storage, f'{base_url}{doc_url}/static'):
                         documents['documents']['staticDocuments'] = static_docs
 
+        if user_is_ca:
+            del documents['documents']['receipt']
         return documents
diff --git a/legal-api/src/legal_api/services/authz.py b/legal-api/src/legal_api/services/authz.py
index 59afaaa354..50a7490938 100644
--- a/legal-api/src/legal_api/services/authz.py
+++ b/legal-api/src/legal_api/services/authz.py
@@ -582,8 +582,7 @@ def is_allowed(business: Business,
 
 def get_could_files(jwt: JwtManager, business_type: str, business_state: str):
     """Get allowable actions."""
-    is_competent_authority = has_product('CA_SEARCH', jwt.get_token_auth_header())
-    if is_competent_authority:
+    if is_competent_authority(jwt):
         allowed_filings = []
     else:
         allowed_filings = get_could_file(business_type, business_state, jwt)
@@ -598,8 +597,7 @@ def get_could_files(jwt: JwtManager, business_type: str, business_state: str):
 
 def get_allowable_actions(jwt: JwtManager, business: Business):
     """Get allowable actions."""
-    is_competent_authority = has_product('CA_SEARCH', jwt.get_token_auth_header())
-    if is_competent_authority:
+    if is_competent_authority(jwt):
         allowed_filings = []
     else:
         allowed_filings = get_allowed_filings(business, business.state, business.legal_type, jwt)
@@ -614,7 +612,7 @@ def get_allowable_actions(jwt: JwtManager, business: Business):
         },
         'digitalBusinessCard': are_digital_credentials_allowed(business, jwt),
         'digitalBusinessCardPreconditions': get_digital_credentials_preconditions(business, jwt),
-        'viewAll': is_competent_authority
+        'viewAll': is_competent_authority(jwt)
     }
     return result
 
@@ -1008,3 +1006,7 @@ def has_product(code: str, token: str) -> bool:
         return False
 
     return any(p['code'] == code and p['subscriptionStatus'] == 'ACTIVE' for p in user_products)
+
+def is_competent_authority(jwt: JwtManager) -> bool:
+    """Return if the user has the active ca_search subscription."""
+    return has_product('CA_SEARCH', jwt.get_token_auth_header())
diff --git a/legal-api/tests/unit/resources/v2/test_business_documents.py b/legal-api/tests/unit/resources/v2/test_business_documents.py
index 2854a00e18..952f921719 100644
--- a/legal-api/tests/unit/resources/v2/test_business_documents.py
+++ b/legal-api/tests/unit/resources/v2/test_business_documents.py
@@ -76,6 +76,26 @@ def test_get_business_documents(session, client, jwt):
     assert docs_json['documents']
     assert docs_json['documents']['summary']
 
+def test_get_business_documents_ca(requests_mock, session, client, jwt):
+    """Assert that business summary is not returned."""
+    # setup
+    identifier = 'CP7654321'
+    factory_business(identifier)
+    requests_mock.get(
+        f"{current_app.config.get('AUTH_SVC_URL')}/orgs/123456/products?include_hidden=true",
+        json=[{"code": "CA_SEARCH", "subscriptionStatus": "ACTIVE"}],
+    )
+    # test
+    rv = client.get(f'/api/v2/businesses/{identifier}/documents',
+                    headers=create_header(jwt, [STAFF_ROLE], identifier, **{'Account-Id': '123456'})
+                    )
+    # check
+    assert rv.status_code == HTTPStatus.OK
+    docs_json = rv.json
+    assert docs_json['documents']
+    assert docs_json['documents']['summary']
+    assert not docs_json['documents'].get('receipt', False)
+
 
 def test_get_document_invalid_authorization(session, client, jwt):
     """Assert that business summary is not returned."""
diff --git a/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py b/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py
index 0b885ec5ce..12853489ca 100644
--- a/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py
+++ b/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py
@@ -1650,6 +1650,49 @@ def test_get_receipt_request_mock(session, client, jwt, requests_mock):
     assert requests_mock.called_once
 
 
+def test_get_receipt_no_receipt_ca(session, client, jwt, requests_mock):
+    """Assert that a receipt is generated."""
+    from legal_api.resources.v2.business.business_filings.business_documents import _get_receipt
+
+    # Setup
+    identifier = 'CP7654321'
+    business = factory_business(identifier)
+    filing_name = 'incorporationApplication'
+    payment_id = '12345'
+
+    filing_json = copy.deepcopy(FILING_HEADER)
+    filing_json['filing']['header']['name'] = filing_name
+    filing_json['filing'][filing_name] = INCORPORATION
+    filing_json['filing'].pop('business')
+
+    filing_date = datetime.utcnow()
+    filing = factory_filing(business, filing_json, filing_date=filing_date)
+    filing.skip_status_listener = True
+    filing._status = 'PAID'
+    filing._payment_token = payment_id
+    filing._payment_completion_date = filing_date
+    filing.save()
+
+    requests_mock.post(f"{current_app.config.get('PAYMENT_SVC_URL')}/{payment_id}/receipts",
+                       json={'foo': 'bar'},
+                       status_code=HTTPStatus.CREATED)
+
+    requests_mock.get(
+        f"{current_app.config.get('AUTH_SVC_URL')}/orgs/123456/products?include_hidden=true",
+        json=[{"code": "CA_SEARCH", "subscriptionStatus": "ACTIVE"}],
+    )
+
+    rv = client.get(f'/api/v2/businesses/{identifier}/filings/{filing.id}/documents',
+                    headers=create_header(jwt,
+                                          [],
+                                          identifier,
+                                          **{'accept': 'application/pdf', 'Account-Id': '123456'})
+                    )
+
+    assert rv.status_code == HTTPStatus.OK
+    assert not rv.json.get('documents').get('receipt', False)
+
+
 @pytest.mark.parametrize('test_name, temp_identifier, entity_type, expected_msg, expected_http_code', [
     ('now_ia_paid', 'Tb31yQIuBw', Business.LegalTypes.BCOMP.value,
      {'documents': {'receipt': f'{base_url}/api/v2/businesses/Tb31yQIuBw/filings/1/documents/receipt',


Reviews:
user: login: kialj876
body: Looks good to me, I have a couple suggestions. Also, can you add a unit test covering the competent auth user?
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T15:03:39Z
user: login: BrandonSharratt
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T19:38:58Z
user: login: BrandonSharratt
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T19:39:03Z
user: login: argush3
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-15T13:40:20Z
user: login: kialj876
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-15T14:45:17Z
user: login: BrandonSharratt
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-15T18:00:03Z
user: login: argush3
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-15T22:38:50Z
user: login: BrandonSharratt
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-16T19:23:51Z
user: login: argush3
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-16T19:38:45Z
user: login: kialj876
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-21T13:50:07Z

Review comments:
diff_hunk: @@ -1008,3 +1006,6 @@ def has_product(code: str, token: str) -> bool:
         return False
 
     return any(p['code'] == code and p['subscriptionStatus'] == 'ACTIVE' for p in user_products)
+
+def is_competent_authority(token: str) -> bool:
+    return has_product('CA_SEARCH', token)
path: legal-api/src/legal_api/services/authz.py
user: login: kialj876
body: If you change this to
```
    return has_product('CA_SEARCH', jwt.get_token_auth_header())
```
then you don't need to do `jwt.get_token_auth_header()` everywhere its called
created_at: 2025-05-13T14:57:07Z
author_association: COLLABORATOR
diff_hunk: @@ -522,13 +522,17 @@ def get_document_list(business,  # pylint: disable=too-many-locals disable=too-m
         if filing.storage and filing.storage.filing_type in no_output_filings:
             return documents
 
-        # return a receipt for filings completed in our system
-        if filing.storage and filing.storage.payment_completion_date:
-            if filing.filing_type == 'courtOrder' and \
-                    (filing.storage.documents.filter(
-                        Document.type == DocumentType.COURT_ORDER.value).one_or_none()):
-                documents['documents']['uploadedCourtOrder'] = f'{base_url}{doc_url}/uploadedCourtOrder'
-            documents['documents']['receipt'] = f'{base_url}{doc_url}/receipt'
+        user_is_ca = is_competent_authority(jwt.get_token_auth_header())
+
+        # return a receipt for filings completed in our system (but not for ca users
+        # see https://github.com/bcgov/entity/issues/21881
+        if not(user_is_ca):
+            if filing.storage and filing.storage.payment_completion_date:
path: legal-api/src/legal_api/core/filing.py
user: login: kialj876
body: Ruff will want it like this instead of the nested if
```
if not user_is_ca and filing.storage and filing.storage.payment_completion_date:
```
created_at: 2025-05-13T14:57:21Z
author_association: COLLABORATOR
diff_hunk: @@ -1008,3 +1006,6 @@ def has_product(code: str, token: str) -> bool:
         return False
 
     return any(p['code'] == code and p['subscriptionStatus'] == 'ACTIVE' for p in user_products)
+
+def is_competent_authority(token: str) -> bool:
+    return has_product('CA_SEARCH', token)
path: legal-api/src/legal_api/services/authz.py
user: login: BrandonSharratt
body: Changed
created_at: 2025-05-13T19:38:58Z
author_association: COLLABORATOR
diff_hunk: @@ -522,13 +522,17 @@ def get_document_list(business,  # pylint: disable=too-many-locals disable=too-m
         if filing.storage and filing.storage.filing_type in no_output_filings:
             return documents
 
-        # return a receipt for filings completed in our system
-        if filing.storage and filing.storage.payment_completion_date:
-            if filing.filing_type == 'courtOrder' and \
-                    (filing.storage.documents.filter(
-                        Document.type == DocumentType.COURT_ORDER.value).one_or_none()):
-                documents['documents']['uploadedCourtOrder'] = f'{base_url}{doc_url}/uploadedCourtOrder'
-            documents['documents']['receipt'] = f'{base_url}{doc_url}/receipt'
+        user_is_ca = is_competent_authority(jwt.get_token_auth_header())
+
+        # return a receipt for filings completed in our system (but not for ca users
+        # see https://github.com/bcgov/entity/issues/21881
+        if not(user_is_ca):
+            if filing.storage and filing.storage.payment_completion_date:
path: legal-api/src/legal_api/core/filing.py
user: login: BrandonSharratt
body: Changed
created_at: 2025-05-13T19:39:03Z
author_association: COLLABORATOR
diff_hunk: @@ -522,8 +522,11 @@ def get_document_list(business,  # pylint: disable=too-many-locals disable=too-m
         if filing.storage and filing.storage.filing_type in no_output_filings:
             return documents
 
-        # return a receipt for filings completed in our system
-        if filing.storage and filing.storage.payment_completion_date:
+        user_is_ca = is_competent_authority(jwt)
+
+        # return a receipt for filings completed in our system (but not for ca users
+        # see https://github.com/bcgov/entity/issues/21881
+        if not user_is_ca and filing.storage and filing.storage.payment_completion_date:
path: legal-api/src/legal_api/core/filing.py
user: login: argush3
body: I think this will skip a court order related doc for a competent authority.  Is this intended?
created_at: 2025-05-15T13:40:20Z
author_association: COLLABORATOR
diff_hunk: @@ -522,8 +522,11 @@ def get_document_list(business,  # pylint: disable=too-many-locals disable=too-m
         if filing.storage and filing.storage.filing_type in no_output_filings:
             return documents
 
-        # return a receipt for filings completed in our system
-        if filing.storage and filing.storage.payment_completion_date:
+        user_is_ca = is_competent_authority(jwt)
+
+        # return a receipt for filings completed in our system (but not for ca users
+        # see https://github.com/bcgov/entity/issues/21881
+        if not user_is_ca and filing.storage and filing.storage.payment_completion_date:
path: legal-api/src/legal_api/core/filing.py
user: login: kialj876
body: Hmm I think we probably need it right @BrandonSharratt?
created_at: 2025-05-15T14:45:17Z
author_association: COLLABORATOR
diff_hunk: @@ -522,8 +522,11 @@ def get_document_list(business,  # pylint: disable=too-many-locals disable=too-m
         if filing.storage and filing.storage.filing_type in no_output_filings:
             return documents
 
-        # return a receipt for filings completed in our system
-        if filing.storage and filing.storage.payment_completion_date:
+        user_is_ca = is_competent_authority(jwt)
+
+        # return a receipt for filings completed in our system (but not for ca users
+        # see https://github.com/bcgov/entity/issues/21881
+        if not user_is_ca and filing.storage and filing.storage.payment_completion_date:
path: legal-api/src/legal_api/core/filing.py
user: login: BrandonSharratt
body: I've added it back, I've moved the user_is_ca check to right before the 2 places that return the documents and it deletes the key
created_at: 2025-05-15T18:00:03Z
author_association: COLLABORATOR
diff_hunk: @@ -76,6 +76,26 @@ def test_get_business_documents(session, client, jwt):
     assert docs_json['documents']
     assert docs_json['documents']['summary']
 
+def test_get_business_documents_ca(requests_mock, session, client, jwt):
+    """Assert that business summary is not returned."""
+    # setup
+    identifier = 'CP7654321'
+    factory_business(identifier)
+    requests_mock.get(
+        f"{current_app.config.get('AUTH_SVC_URL')}/orgs/123456/products?include_hidden=true",
+        json=[{"code": "CA_SEARCH", "subscriptionStatus": "ACTIVE"}],
+    )
+    # test
+    rv = client.get(f'/api/v2/businesses/{identifier}/documents',
+                    headers=create_header(jwt, [STAFF_ROLE], identifier, **{'Account-Id': '123456'})
+                    )
+    # check
+    assert rv.status_code == HTTPStatus.OK
+    docs_json = rv.json
+    assert docs_json['documents']
+    assert docs_json['documents']['summary']
+    assert not docs_json['documents'].get('receipt', False)
+
path: legal-api/tests/unit/resources/v2/test_business_documents.py
user: login: argush3
body: Don't believe business level documents have receipts.

You'll probably want to add a test to [test_filing_documents.py](https://github.com/bcgov/lear/blob/main/legal-api/tests/unit/resources/v2/test_business_filings/test_filing_documents.py) to see if receipts are excluded for a given filing when a CA is making the call.
created_at: 2025-05-15T22:38:50Z
author_association: COLLABORATOR
diff_hunk: @@ -76,6 +76,26 @@ def test_get_business_documents(session, client, jwt):
     assert docs_json['documents']
     assert docs_json['documents']['summary']
 
+def test_get_business_documents_ca(requests_mock, session, client, jwt):
+    """Assert that business summary is not returned."""
+    # setup
+    identifier = 'CP7654321'
+    factory_business(identifier)
+    requests_mock.get(
+        f"{current_app.config.get('AUTH_SVC_URL')}/orgs/123456/products?include_hidden=true",
+        json=[{"code": "CA_SEARCH", "subscriptionStatus": "ACTIVE"}],
+    )
+    # test
+    rv = client.get(f'/api/v2/businesses/{identifier}/documents',
+                    headers=create_header(jwt, [STAFF_ROLE], identifier, **{'Account-Id': '123456'})
+                    )
+    # check
+    assert rv.status_code == HTTPStatus.OK
+    docs_json = rv.json
+    assert docs_json['documents']
+    assert docs_json['documents']['summary']
+    assert not docs_json['documents'].get('receipt', False)
+
path: legal-api/tests/unit/resources/v2/test_business_documents.py
user: login: BrandonSharratt
body: Added another
created_at: 2025-05-16T19:23:51Z
author_association: COLLABORATOR

PR comments:
user: login: BrandonSharratt
created_at: 2025-05-13T19:38:50Z
body: Linting is complaining about a file that is unchanged in this PR so those will be ignored
author_association: COLLABORATOR
user: login: codecov[bot]
created_at: 2025-05-14T21:05:06Z
body: ## [Codecov](https://app.codecov.io/gh/bcgov/lear/pull/3490?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) Report
Attention: Patch coverage is `84.21053%` with `3 lines` in your changes missing coverage. Please review.
> Project coverage is 76.11%. Comparing base [(`a9be147`)](https://app.codecov.io/gh/bcgov/lear/commit/a9be147a3ca006c543d83ad65fa77a1d228c8c7b?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) to head [(`3e0933d`)](https://app.codecov.io/gh/bcgov/lear/commit/3e0933d4b2ef4f7091fb72dbfa9f5c7df0c20efa?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov).
> Report is 84 commits behind head on main.

| [Files with missing lines](https://app.codecov.io/gh/bcgov/lear/pull/3490?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) | Patch % | Lines |
|---|---|---|
| [legal-api/src/legal\_api/core/filing.py](https://app.codecov.io/gh/bcgov/lear/pull/3490?src=pr&el=tree&filepath=legal-api%2Fsrc%2Flegal_api%2Fcore%2Ffiling.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov#diff-bGVnYWwtYXBpL3NyYy9sZWdhbF9hcGkvY29yZS9maWxpbmcucHk=) | 66.66% | [1 Missing and 1 partial :warning: ](https://app.codecov.io/gh/bcgov/lear/pull/3490?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) |
| [legal-api/src/legal\_api/services/authz.py](https://app.codecov.io/gh/bcgov/lear/pull/3490?src=pr&el=tree&filepath=legal-api%2Fsrc%2Flegal_api%2Fservices%2Fauthz.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov#diff-bGVnYWwtYXBpL3NyYy9sZWdhbF9hcGkvc2VydmljZXMvYXV0aHoucHk=) | 75.00% | [0 Missing and 1 partial :warning: ](https://app.codecov.io/gh/bcgov/lear/pull/3490?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #3490      +/-   ##
==========================================
+ Coverage   66.60%   76.11%   +9.51%     
==========================================
  Files         268      203      -65     
  Lines       18651    13596    -5055     
  Branches     2571     2320     -251     
==========================================
- Hits        12423    10349    -2074     
+ Misses       5496     2583    -2913     
+ Partials      732      664      -68     
```

| [Flag](https://app.codecov.io/gh/bcgov/lear/pull/3490/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) | Coverage Δ | |
|---|---|---|
| [colinapi](https://app.codecov.io/gh/bcgov/lear/pull/3490/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) | `?` | |
| [entityemailer](https://app.codecov.io/gh/bcgov/lear/pull/3490/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) | `?` | |
| [legalapi](https://app.codecov.io/gh/bcgov/lear/pull/3490/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) | `76.11% <84.21%> (+0.15%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Files with missing lines](https://app.codecov.io/gh/bcgov/lear/pull/3490?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov) | Coverage Δ | |
|---|---|---|
| [legal-api/src/legal\_api/config.py](https://app.codecov.io/gh/bcgov/lear/pull/3490?src=pr&el=tree&filepath=legal-api%2Fsrc%2Flegal_api%2Fconfig.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov#diff-bGVnYWwtYXBpL3NyYy9sZWdhbF9hcGkvY29uZmlnLnB5) | `95.15% <100.00%> (+0.90%)` | :arrow_up: |
| [legal-api/src/legal\_api/services/authz.py](https://app.codecov.io/gh/bcgov/lear/pull/3490?src=pr&el=tree&filepath=legal-api%2Fsrc%2Flegal_api%2Fservices%2Fauthz.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov#diff-bGVnYWwtYXBpL3NyYy9sZWdhbF9hcGkvc2VydmljZXMvYXV0aHoucHk=) | `96.39% <75.00%> (+0.80%)` | :arrow_up: |
| [legal-api/src/legal\_api/core/filing.py](https://app.codecov.io/gh/bcgov/lear/pull/3490?src=pr&el=tree&filepath=legal-api%2Fsrc%2Flegal_api%2Fcore%2Ffiling.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov#diff-bGVnYWwtYXBpL3NyYy9sZWdhbF9hcGkvY29yZS9maWxpbmcucHk=) | `86.52% <66.66%> (-0.41%)` | :arrow_down: |

... and [72 files with indirect coverage changes](https://app.codecov.io/gh/bcgov/lear/pull/3490/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=bcgov)

</details>
<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE
user: login: BrandonSharratt
created_at: 2025-05-14T21:14:15Z
body: Test added and passing now
author_association: COLLABORATOR