Skip to content

Conversation

@OlhaZahoruiko
Copy link
Contributor

@OlhaZahoruiko OlhaZahoruiko commented Oct 20, 2025

Fixes #500

Changes

  • Add ReferentielijstenConfig singletonmodel

    • Add enabled field (default false)
    • Add service field
    • Add tabel_code field (CharField to indicate which tabel contains the Kanalen)
    • Display-only: show at least the HTTP status code (preferably also the list of items) when performing a GET with this tabel__code (similar to zgw_consumers.Service status check)
    • On model save, validate that all existing Klantcontact.kanaal in the database are present in the linked tabel
  • Create a ReferentielijstenClient in src/referentielijsten/client.py that subclasses zgw_consumers.NLXClient

    • Add a method get_items_by_tabel_code that does a GET on /items?tabel__code={code}
    • Add another method that calls the above method and caches the result for a configurable amount of time (default 5 minutes)
  • Add a validator to Klantcontact

    • Return early if ReferentielijstenConfig.enabled == False
    • Instantiate a ReferentielijstenClient based on ReferentielijstenConfig.service
    • Call the cached version of get_items_by_tabel_code and raise a ValidationError if the supplied Kanaal is not found (validation error should list all valid kanalen)
  • Add a configuration step to load this config via setup_configuration

  • Add a page in the docs under Manual explaining this optional integration

@codecov-commenter
Copy link

codecov-commenter commented Oct 20, 2025

Codecov Report

❌ Patch coverage is 91.70507% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.55%. Comparing base (4855701) to head (9d7226c).

Files with missing lines Patch % Lines
src/openklant/config/models.py 59.25% 11 Missing ⚠️
...lant/components/klantinteracties/api/validators.py 80.00% 5 Missing ⚠️
...racties/api/tests/test_kanaal_referentielijsten.py 97.77% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #530      +/-   ##
==========================================
- Coverage   97.66%   97.55%   -0.11%     
==========================================
  Files         214      221       +7     
  Lines       12438    12655     +217     
==========================================
+ Hits        12147    12346     +199     
- Misses        291      309      +18     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@OlhaZahoruiko OlhaZahoruiko marked this pull request as ready for review October 20, 2025 13:14
@OlhaZahoruiko OlhaZahoruiko force-pushed the feature/500-Using-the-Referentielijsten-API-to-validate-the-kanalen branch from afe0c2a to 4cedbda Compare October 21, 2025 07:50
@OlhaZahoruiko OlhaZahoruiko force-pushed the feature/500-Using-the-Referentielijsten-API-to-validate-the-kanalen branch 2 times, most recently from 363609e to a132559 Compare October 28, 2025 10:14
@stevenbal stevenbal self-requested a review October 28, 2025 13:10
Copy link
Collaborator

@stevenbal stevenbal left a comment

Choose a reason for hiding this comment

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

@OlhaZahoruiko a general remark: make sure to also test this locally with runserver and the Referentielijsten docker-compose instance. Currently it seems like it's not possible to save the config admin, so I cannot test the implementation locally either


@my_vcr.use_cassette("get_items_by_tabel_code.yaml")
def test_get_items_by_tabel_code(self):
items = self._get_items_from_fixture("KANAAL")
Copy link
Collaborator

Choose a reason for hiding this comment

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

These tests don't actually seem to make use of the ReferentielijstenClient?

I think you should build a client for the configured service and then test the methods that client provides

@@ -0,0 +1,148 @@
import json
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's move this file to src/openklant/components/klantinteracties/api/test_klantcontact_referentielijsten_kanalen.py

Copy link
Contributor Author

@OlhaZahoruiko OlhaZahoruiko Oct 30, 2025

Choose a reason for hiding this comment

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

to tests/ or just api/ src/openklant/components/klantinteracties/api/tests?

@OlhaZahoruiko OlhaZahoruiko force-pushed the feature/500-Using-the-Referentielijsten-API-to-validate-the-kanalen branch from f53da53 to 6232f86 Compare November 3, 2025 09:22
Copy link
Collaborator

@stevenbal stevenbal left a comment

Choose a reason for hiding this comment

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

@OlhaZahoruiko there are two remaining checkbox items in the original issue (about documentation and showing the response code in the config model admin), but since this PR is quite big already let's put those in a separate PR when this one is merged

@@ -0,0 +1,21 @@
# Generated by Django 5.2.7 on 2025-10-30 10:32
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you make sure these migrations are collapsed into one (only 0001?). You can do this locally by running src/manage.py migrate config zero, deleting all three files and running makemigrations again.

That way we keep the number of migrations small

notification_delivery_retry_backoff: 2
notification_delivery_retry_backoff_max: 3

referentielijsten_config_enable: true
Copy link
Collaborator

Choose a reason for hiding this comment

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

You'll have to add ReferentielijstenConfigurationStep to the SETUP_CONFIGURATION_STEPS in base.py to make sure it is run when calling setup_configuration

referentielijsten_config:
enabled: true
service_identifier: referentielijsten-api
tabel_code: KANAAL
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
tabel_code: KANAAL
kanalen_tabel_code: KANAAL


networks:
open-klant-dev:
name: referentielijsten-dev
Copy link
Collaborator

Choose a reason for hiding this comment

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

The name of the network has to be the same as the network in docker-compose.yml to make sure the containers can reach eachother over HTTP

Suggested change
name: referentielijsten-dev
name: open-klant-dev

Comment on lines 70 to 74
api_type: brc
auth_type: zgw
client_id: open-klant-referentielijsten
user_id: open-klant-referentielijsten
secret: open-klant-referentielijsten-secret
Copy link
Collaborator

Choose a reason for hiding this comment

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

Referentielijsten doesn't have any API authentication/authorization, so this can be left empty. The API type is technically "orc" ("overige"), but it doesn't really matter in practice afaik

Suggested change
api_type: brc
auth_type: zgw
client_id: open-klant-referentielijsten
user_id: open-klant-referentielijsten
secret: open-klant-referentielijsten-secret
api_type: orc
auth_type: no_auth

Comment on lines 34 to 35
self.assertIn("email", codes)
self.assertIn("phone", codes)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
self.assertIn("email", codes)
self.assertIn("phone", codes)
self.assertEqual(codes, ["email", "phone"])

Comment on lines 16 to 17
def _get_items_from_fixture(self, tabel_code: str):
return self.client.get_cached_items_by_tabel_code(tabel_code)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of defining this as a custom method, let's just call self.client.get_cached_items_by_tabel_code directly where this is used instead

Suggested change
def _get_items_from_fixture(self, tabel_code: str):
return self.client.get_cached_items_by_tabel_code(tabel_code)

first = self._get_items_from_fixture("KANAAL")
second = self._get_items_from_fixture("KANAAL")
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be nice if this test also verifies that only one network call happens (because it's cached by the underlying method). I don't fully remember how to check this, but I think maybe with something like self.vcr._current_cassette.requests you could check this

@@ -0,0 +1,59 @@
from pathlib import Path
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you move this file to src/openklant/components/klantinteracties/api/tests/test_kanaal_referentielijsten.py?

Comment on lines 44 to 59
def test_validation_succeeds_for_valid_kanaal(self):
validator = KanaalValidator()
try:
validator("email")
except ValidationError:
self.fail("KanaalValidator raised ValidationError unexpectedly for 'email'")

def test_validation_fails_for_invalid_kanaal(self):
validator = KanaalValidator()

with self.assertRaises(ValidationError) as cm:
validator("fax")

self.assertIn("'fax' is not a valid kanaal", str(cm.exception))
self.assertIn("email", str(cm.exception))
self.assertIn("phone", str(cm.exception))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of testing this by calling the validator directly, could you test this by making API calls (POST/PUT/PATCH) to /klantcontacten?

I think it would also be good to have a test for the behavior of the API if:

  1. referentielijsten returns a 400 or 500 error
  2. a requestexception or timeout occurs (you could use https://maykin-django-common.readthedocs.io/en/latest/reference/vcr.html#maykin_common.vcr.VCRMixin.vcr_raises for this)

@OlhaZahoruiko OlhaZahoruiko force-pushed the feature/500-Using-the-Referentielijsten-API-to-validate-the-kanalen branch 2 times, most recently from 744fe77 to 848fa94 Compare November 7, 2025 08:51
@OlhaZahoruiko OlhaZahoruiko force-pushed the feature/500-Using-the-Referentielijsten-API-to-validate-the-kanalen branch from b13979a to 9d7226c Compare November 11, 2025 11:24
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.

Gebruikmaken van de Referentielijsten API voor het valideren van de gebruikte kanalen voor klantcontacten

5 participants