Skip to content

Commit

Permalink
feat: supprimer les traces d'envoi d'emails de plus de 90 jours (#902)
Browse files Browse the repository at this point in the history
## Description

🎸 L'application trace dans `EmailSentTrack` les appels à `brevo` et le
code retour de leur API. Ces objets contiennent des données visées par
le champ de la RGPD. Leur seul objectif est de pouvoir identifier
l'apparition d'un problème lors de l'appel à l'API. Elles ne sont pas
utilisées par ailleurs. Supprimons les au bout de 90 jours.

## Type de changement

🎢 Nouvelle fonctionnalité (changement non cassant qui ajoute une
fonctionnalité).
🚧 technique

### Points d'attention

🦺 creation d'un nouveau logger. sera revu avec la mise en place de
datadog (yc un json formatter)
🦺  ajout d'un filtre dans l'admin sur le `status_code` de l'api `brevo`
  • Loading branch information
vincentporte authored Feb 10, 2025
1 parent dfc378a commit 8abf9ef
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 5 deletions.
1 change: 1 addition & 0 deletions clevercloud/cron.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"*/15 7-21 * * * $ROOT/clevercloud/run_management_command.sh send_messages_notifications asap",
"20 6 * * * $ROOT/clevercloud/run_management_command.sh send_messages_notifications day",
"10 6-22 * * * $ROOT/clevercloud/run_management_command.sh add_user_to_list_when_register",
"0 12 * * 1 $ROOT/clevercloud/run_management_command.sh delete_old_email_sent_tracks",
"30 13 * * 1-5 $ROOT/clevercloud/run_management_command.sh send_notifs_on_unanswered_topics"
]
4 changes: 4 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@
"handlers": ["console"],
"level": os.getenv("DJANGO_LOG_LEVEL", "INFO"),
},
"commands": {
"handlers": ["console"],
"level": os.getenv("COMMANDS_LOG_LEVEL", "INFO"),
},
},
}

Expand Down
2 changes: 1 addition & 1 deletion lacommunaute/notification/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@admin.register(EmailSentTrack)
class EmailSentTrackAdmin(admin.ModelAdmin):
list_display = ("kind", "created", "status_code")
list_filter = ("kind",)
list_filter = ("kind", "status_code")


class BaseNotificationListFilter(admin.SimpleListFilter):
Expand Down
9 changes: 6 additions & 3 deletions lacommunaute/notification/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
from lacommunaute.forum_conversation.factories import AnonymousPostFactory, TopicFactory
from lacommunaute.notification.enums import EmailSentTrackKind, NotificationDelay
from lacommunaute.notification.models import EmailSentTrack, Notification
from lacommunaute.utils.factory_boy import AutoNowAddOverrideMixin


faker = Faker()


class EmailSentTrackFactory(factory.django.DjangoModelFactory):
status_code = faker.pyint()
response = faker.text()
class EmailSentTrackFactory(AutoNowAddOverrideMixin, factory.django.DjangoModelFactory):
created = factory.LazyFunction(timezone.now)
updated = factory.LazyFunction(timezone.now)
status_code = factory.Faker("random_int", min=200, max=500)
response = factory.Faker("text")
datas = {"text": faker.text()}
kind = EmailSentTrackKind.FIRST_REPLY

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from logging import getLogger

from django.core.management.base import BaseCommand

from lacommunaute.notification.models import EmailSentTrack


logger = getLogger("commands")


class Command(BaseCommand):
help = "Supprimer les anciens enregistrements EmailSentTrack"

def handle(self, *args, **options):
nb_deleted = EmailSentTrack.objects.delete_old_records()
logger.info("%s enregistrements EmailSentTrack supprimés", nb_deleted)
10 changes: 10 additions & 0 deletions lacommunaute/notification/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@
from itertools import groupby
from operator import attrgetter

from dateutil.relativedelta import relativedelta
from django.db import models
from django.db.models import F
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from machina.models.abstract_models import DatedModel

from lacommunaute.notification.enums import EmailSentTrackKind, NotificationDelay


class EmailSentTrackQuerySet(models.QuerySet):
def delete_old_records(self):
nb, _ = self.filter(created__lt=timezone.now() - relativedelta(days=90)).delete()
return nb


class EmailSentTrack(DatedModel):
status_code = models.IntegerField(verbose_name="code de retour de l'API")
response = models.TextField(verbose_name="réponse de l'API")
Expand All @@ -18,6 +26,8 @@ class EmailSentTrack(DatedModel):
verbose_name="type", choices=EmailSentTrackKind.choices, max_length=20, null=False, blank=False
)

objects = EmailSentTrackQuerySet().as_manager()

class Meta:
verbose_name = "trace des emails envoyés"
verbose_name_plural = "traces des emails envoyés"
Expand Down
12 changes: 12 additions & 0 deletions lacommunaute/notification/tests/tests_management_commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from dateutil.relativedelta import relativedelta
from django.core.management import call_command
from django.utils import timezone

from lacommunaute.notification.factories import EmailSentTrackFactory
from lacommunaute.notification.models import EmailSentTrack


def test_delete_old_email_sent_tracks(db):
EmailSentTrackFactory(created=timezone.now() - relativedelta(days=90))
call_command("delete_old_email_sent_tracks")
assert EmailSentTrack.objects.count() == 0
14 changes: 13 additions & 1 deletion lacommunaute/notification/tests/tests_models.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import pytest
from dateutil.relativedelta import relativedelta
from django.contrib.auth.models import AnonymousUser
from django.db import IntegrityError
from django.db.models import F
from django.test import TestCase
from django.utils import timezone

from lacommunaute.forum_conversation.factories import TopicFactory
from lacommunaute.notification.enums import EmailSentTrackKind
from lacommunaute.notification.factories import NotificationFactory
from lacommunaute.notification.factories import EmailSentTrackFactory, NotificationFactory
from lacommunaute.notification.models import EmailSentTrack, Notification
from lacommunaute.users.factories import UserFactory


class TestEmailSentTrackQuerySet:
def test_delete_old_records(self, db):
_ = [EmailSentTrackFactory(created=timezone.now() - relativedelta(days=nb_days)) for nb_days in range(89, 92)]

EmailSentTrack.objects.delete_old_records()

email_sent_track = EmailSentTrack.objects.get()
assert email_sent_track.created >= timezone.now() - relativedelta(days=90)


class EmailSentTrackModelTest(TestCase):
def test_str(self):
track = EmailSentTrack(status_code=200)
Expand Down
15 changes: 15 additions & 0 deletions lacommunaute/utils/factory_boy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class AutoNowAddOverrideMixin:
"""This mixin allows you to override fields with `auto_now=True`"""

@classmethod
def _create(cls, model_class, *args, **kwargs):
auto_now_add_desactivated = []
for field in model_class._meta.get_fields():
if getattr(field, "auto_now_add", False) and kwargs.get(field.name):
field.auto_now_add = False
auto_now_add_desactivated.append(field)
try:
return super()._create(model_class, *args, **kwargs)
finally:
for field in auto_now_add_desactivated:
field.auto_now_add = True

0 comments on commit 8abf9ef

Please sign in to comment.