diff --git a/app/dao/templates_dao.py b/app/dao/templates_dao.py index 7a35702dc..be91394c5 100644 --- a/app/dao/templates_dao.py +++ b/app/dao/templates_dao.py @@ -1,10 +1,12 @@ from datetime import datetime +from functools import lru_cache import uuid from flask import current_app -from sqlalchemy import asc, desc +from sqlalchemy import asc, desc, func +from sqlalchemy.orm.exc import NoResultFound -from app import db +from app import db, redis_store from app.models import ( LETTER_TYPE, SECOND_CLASS, @@ -20,6 +22,9 @@ from app.dao.dao_utils import ( from app.dao.users_dao import get_user_by_id +SEVEN_DAYS_IN_SECONDS = 604_800 + + @transactional @version_class( VersionOptions(Template, history_class=TemplateHistory) @@ -49,7 +54,7 @@ def dao_create_template(template): def dao_update_template(template): if template.archived: template.folder = None - + redis_store.delete(f'template-{template.id}-version') db.session.add(template) @@ -92,6 +97,33 @@ def dao_redact_template(template, user_id): db.session.add(template.template_redacted) +def dao_get_template_version(template_id): + + cache_key = f'template-{template_id}-version' + version = redis_store.get(cache_key) + + if not version: + + version = db.session.query( + func.max(TemplateHistory.version) + ).filter_by( + id=template_id, + hidden=False, + ).scalar() + + if not version: + raise NoResultFound + + redis_store.set(cache_key, version, ex=SEVEN_DAYS_IN_SECONDS) + + return version + + +@lru_cache(maxsize=1024) +def dao_get_template_by_id_and_service_id_and_version(*, template_id, service_id, version): + return dao_get_template_by_id_and_service_id(template_id, service_id, version) + + def dao_get_template_by_id_and_service_id(template_id, service_id, version=None): if version is not None: return TemplateHistory.query.filter_by( diff --git a/app/notifications/validators.py b/app/notifications/validators.py index 3b9cf6c62..0c270d175 100644 --- a/app/notifications/validators.py +++ b/app/notifications/validators.py @@ -140,9 +140,10 @@ def check_notification_content_is_not_empty(template_with_content): def validate_template(template_id, personalisation, service, notification_type): try: - template = templates_dao.dao_get_template_by_id_and_service_id( + template = templates_dao.dao_get_template_by_id_and_service_id_and_version( template_id=template_id, - service_id=service.id + service_id=service.id, + version=templates_dao.dao_get_template_version(template_id), ) except NoResultFound: message = 'Template not found'