Skip to content

Commit 09ffcff

Browse files
ELI-578 consumer_id - campaign_config mapping
1 parent 30f6e37 commit 09ffcff

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from typing import NewType
2+
3+
from pydantic import RootModel
4+
5+
from eligibility_signposting_api.model.campaign_config import CampaignID
6+
7+
ConsumerId = NewType("ConsumerId", str)
8+
9+
class ConsumerMapping(RootModel[dict[str, list[CampaignID]]]):
10+
def get(self, key: str, default: list[CampaignID] | None = None) -> list[CampaignID] | None:
11+
return self.root.get(key, default)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import json
2+
from typing import Annotated, NewType
3+
4+
from botocore.client import BaseClient
5+
from wireup import Inject, service
6+
7+
from eligibility_signposting_api.model.campaign_config import CampaignID
8+
from eligibility_signposting_api.model.consumer_mapping import ConsumerMapping, ConsumerId
9+
10+
BucketName = NewType("BucketName", str)
11+
12+
13+
@service
14+
class ConsumerMappingRepo:
15+
"""Repository class for Campaign Rules, which we can use to calculate a person's eligibility for vaccination.
16+
17+
These rules are stored as JSON files in AWS S3."""
18+
19+
def __init__(
20+
self,
21+
s3_client: Annotated[BaseClient, Inject(qualifier="s3")],
22+
bucket_name: Annotated[BucketName, Inject(param="rules_bucket_name")],
23+
) -> None:
24+
super().__init__()
25+
self.s3_client = s3_client
26+
self.bucket_name = bucket_name
27+
28+
def get_sanctioned_campaign_ids(self, consumer_id: ConsumerId) -> list[CampaignID] | None:
29+
consumer_mappings = self.s3_client.list_objects(Bucket=self.bucket_name)["Contents"][0]
30+
response = self.s3_client.get_object(Bucket=self.bucket_name, Key=f"{consumer_mappings['Key']}")
31+
body = response["Body"].read()
32+
return ConsumerMapping.model_validate(json.loads(body)).get(consumer_id)

src/eligibility_signposting_api/services/eligibility_services.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from wireup import service
44

55
from eligibility_signposting_api.model import eligibility_status
6+
from eligibility_signposting_api.model.campaign_config import CampaignConfig
67
from eligibility_signposting_api.repos import CampaignRepo, NotFoundError, PersonRepo
8+
from eligibility_signposting_api.repos.consumer_mapping_repo import ConsumerMappingRepo
79
from eligibility_signposting_api.services.calculators import eligibility_calculator as calculator
810

911
logger = logging.getLogger(__name__)
@@ -24,28 +26,38 @@ def __init__(
2426
person_repo: PersonRepo,
2527
campaign_repo: CampaignRepo,
2628
calculator_factory: calculator.EligibilityCalculatorFactory,
29+
consumer_mapping_repo: ConsumerMappingRepo
2730
) -> None:
2831
super().__init__()
2932
self.person_repo = person_repo
3033
self.campaign_repo = campaign_repo
3134
self.calculator_factory = calculator_factory
35+
self.consumer_mapping = consumer_mapping_repo
3236

3337
def get_eligibility_status(
3438
self,
3539
nhs_number: eligibility_status.NHSNumber,
3640
include_actions: str,
3741
conditions: list[str],
3842
category: str,
43+
consumer_id: str,
3944
) -> eligibility_status.EligibilityStatus:
4045
"""Calculate a person's eligibility for vaccination given an NHS number."""
4146
if nhs_number:
4247
try:
4348
person_data = self.person_repo.get_eligibility_data(nhs_number)
4449
campaign_configs = list(self.campaign_repo.get_campaign_configs())
50+
consumer_mappings = self.consumer_mapping.get_sanctioned_campaign_ids(consumer_id)
51+
sanctioned_campaign_ids: list[CampaignConfig] = [
52+
campaign for campaign in campaign_configs
53+
if campaign.id in consumer_mappings
54+
]
55+
4556
except NotFoundError as e:
4657
raise UnknownPersonError from e
4758
else:
48-
calc: calculator.EligibilityCalculator = self.calculator_factory.get(person_data, campaign_configs)
59+
calc: calculator.EligibilityCalculator = self.calculator_factory.get(person_data,
60+
sanctioned_campaign_ids)
4961
return calc.get_eligibility_status(include_actions, conditions, category)
5062

5163
raise UnknownPersonError # pragma: no cover

src/eligibility_signposting_api/views/eligibility.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ def check_eligibility(
5454
query_params["includeActions"],
5555
query_params["conditions"],
5656
query_params["category"],
57+
request.headers.get("X-Correlation-ID"),
5758
)
5859
except UnknownPersonError:
5960
return handle_unknown_person_error(nhs_number)

0 commit comments

Comments
 (0)