Skip to content

Commit 37a6d1f

Browse files
Merge pull request #39 from NHSDigital/feature/eli-135-eligibility_data_store-schema
ELI 135 eligibility repo & service
2 parents 3996aa1 + 92146ae commit 37a6d1f

25 files changed

+1019
-766
lines changed

poetry.lock

Lines changed: 695 additions & 393 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ gitpython = "^3.1.44"
4242
pytest = "^8.3.4"
4343
pytest-asyncio = "^0.25.3"
4444
pytest-cov = "^6.0.0"
45-
#pytest-nhsd-apim = "^3.3.2"
45+
pytest-nhsd-apim = "^5.0.0"
4646
aiohttp = "^3.11.12"
4747
awscli = "^1.37.24"
4848
awscli-local = "^0.22.0"
@@ -82,6 +82,8 @@ log_cli = true
8282
log_cli_level = "DEBUG"
8383
log_format = "%(asctime)s %(levelname)s %(message)s"
8484
log_date_format = "%Y-%m-%d %H:%M:%S"
85+
asyncio_mode = "auto"
86+
asyncio_default_fixture_loop_scope = "function"
8587

8688
[tool.coverage.run]
8789
relative_files = true

src/eligibility_signposting_api/app.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from eligibility_signposting_api import repos, services
1111
from eligibility_signposting_api.config import config, init_logging
1212
from eligibility_signposting_api.error_handler import handle_exception
13-
from eligibility_signposting_api.views import eligibility, hello
13+
from eligibility_signposting_api.views import eligibility_blueprint
1414

1515
init_logging()
1616
logger = logging.getLogger(__name__)
@@ -35,8 +35,7 @@ def create_app() -> Flask:
3535
logger.info("app created")
3636

3737
# Register views & error handler
38-
app.register_blueprint(eligibility, url_prefix="/eligibility")
39-
app.register_blueprint(hello, url_prefix="/hello")
38+
app.register_blueprint(eligibility_blueprint, url_prefix="/eligibility")
4039
app.register_error_handler(Exception, handle_exception)
4140

4241
# Set up dependency injection using wireup
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
from datetime import date
12
from typing import NewType
23

4+
from pydantic import BaseModel
5+
36
NHSNumber = NewType("NHSNumber", str)
7+
DateOfBirth = NewType("DateOfBirth", date)
8+
Postcode = NewType("Postcode", str)
9+
10+
11+
class Eligibility(BaseModel):
12+
processed_suggestions: list[dict]

src/eligibility_signposting_api/model/person.py

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1+
from .eligibility_repo import EligibilityRepo
12
from .exceptions import NotFoundError
2-
from .person_repo import PersonRepo
33

4-
__all__ = ["NotFoundError", "PersonRepo"]
4+
__all__ = ["EligibilityRepo", "NotFoundError"]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import logging
2+
from typing import Annotated, Any
3+
4+
from boto3.dynamodb.conditions import Key
5+
from boto3.resources.base import ServiceResource
6+
from wireup import Inject, service
7+
8+
from eligibility_signposting_api.model.eligibility import NHSNumber
9+
from eligibility_signposting_api.repos.exceptions import NotFoundError
10+
11+
logger = logging.getLogger(__name__)
12+
13+
14+
@service(qualifier="eligibility_table")
15+
def eligibility_table_factory(dynamodb_resource: Annotated[ServiceResource, Inject(qualifier="dynamodb")]) -> Any:
16+
table = dynamodb_resource.Table("eligibility_data_store") # type: ignore[reportAttributeAccessIssue]
17+
logger.info("eligibility_table %r", table, extra={"table": table})
18+
return table
19+
20+
21+
@service
22+
class EligibilityRepo:
23+
def __init__(self, table: Annotated[Any, Inject(qualifier="eligibility_table")]) -> None:
24+
super().__init__()
25+
self.table = table
26+
27+
def get_eligibility_data(self, nhs_number: NHSNumber) -> list[dict[str, Any]]:
28+
response = self.table.query(KeyConditionExpression=Key("NHS_NUMBER").eq(f"PERSON#{nhs_number}"))
29+
logger.debug("response %r for %r", response, nhs_number, extra={"response": response, "nhs_number": nhs_number})
30+
31+
if not (items := response.get("Items")):
32+
message = f"Person not found with nhs_number {nhs_number}"
33+
raise NotFoundError(message)
34+
35+
logger.debug("returning items %s", items, extra={"items": items})
36+
return items

src/eligibility_signposting_api/repos/person_repo.py

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
from .person_services import PersonService, UnknownPersonError
1+
from .eligibility_services import EligibilityService, UnknownPersonError
22

3-
__all__ = ["PersonService", "UnknownPersonError"]
3+
__all__ = ["EligibilityService", "UnknownPersonError"]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import logging
2+
3+
from wireup import service
4+
5+
from eligibility_signposting_api.model.eligibility import Eligibility, NHSNumber
6+
from eligibility_signposting_api.repos import EligibilityRepo, NotFoundError
7+
8+
logger = logging.getLogger(__name__)
9+
10+
11+
class UnknownPersonError(Exception):
12+
pass
13+
14+
15+
@service
16+
class EligibilityService:
17+
def __init__(self, eligibility_repo: EligibilityRepo) -> None:
18+
super().__init__()
19+
self.eligibility_repo = eligibility_repo
20+
21+
def get_eligibility(self, nhs_number: NHSNumber | None = None) -> Eligibility:
22+
if nhs_number:
23+
try:
24+
eligibility_data = self.eligibility_repo.get_eligibility_data(nhs_number)
25+
logger.debug(
26+
"got eligibility_data %r",
27+
eligibility_data,
28+
extra={"eligibility_data": eligibility_data, "nhs_number": nhs_number},
29+
)
30+
except NotFoundError as e:
31+
raise UnknownPersonError from e
32+
else:
33+
# TODO: Apply rules here # noqa: TD002, TD003, FIX002
34+
return Eligibility(processed_suggestions=[])
35+
36+
raise UnknownPersonError

0 commit comments

Comments
 (0)