From f0f8188af69e848096e5b65c74920547f8b54185 Mon Sep 17 00:00:00 2001
From: Daniel Bimschas <daniel@bimschas.com>
Date: Tue, 10 Dec 2024 06:43:51 +0100
Subject: [PATCH] HOLI-10718: refactor typesense serialization into event data
 classes

---
 events.py | 35 +++++++++++++++++++++++++++++++++++
 main.py   | 35 +++++------------------------------
 2 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/events.py b/events.py
index 2e19634..be5ab19 100644
--- a/events.py
+++ b/events.py
@@ -1,9 +1,12 @@
 import base64
 import json
 
+# noinspection PyPackageRequirements
 from cloudevents.http.event import CloudEvent
 from dataclasses import dataclass
 
+from typing import Any, TypedDict, Literal
+
 def get_event_type(cloud_event: CloudEvent) -> str:
     return cloud_event.data['message']['attributes']['eventType']
 
@@ -51,6 +54,22 @@ class UserNameUpdatedEvent(UserEvent):
         _validate_event_type(cloud_event, 'UserNameUpdated')
         super().__init__(cloud_event)
 
+    def as_typesense_document(self) -> object:
+        return {
+            'id': f'profile_{self.user.id}',
+            'type': 'profile',
+            'title_de': self.user.name,
+            'title_en': self.user.name,
+            'description_de': None,  # TODO add on sending side
+            'description_en': None,  # TODO add on sending side
+            'location': None,  # TODO add on sending side
+            'location_lat_lng': None,  # TODO add on sending side
+            'image_url': self.user.avatar,
+            'link_locators': {
+                'profile': self.user.id
+            }
+        }
+
 @dataclass
 class UserDeletedEvent(UserEvent):
     def __init__(self, cloud_event: CloudEvent):
@@ -83,6 +102,22 @@ class SpaceEvent:
         self.event_version = get_event_version(cloud_event)
         self.space = SpacePayload(json.loads(base64.b64decode(cloud_event.data['message']['data'])))
 
+    def as_typesense_document(self) -> object:
+        return {
+            'id': f'space_{self.space.id}',
+            'type': 'space',
+            'title_de': self.space.name,
+            'title_en': self.space.name,
+            'description_de': None,  # TODO add on sending side
+            'description_en': None,  # TODO add on sending side
+            'location': None,
+            'location_lat_lng': None,
+            'image_url': self.space.avatar,
+            'link_locators': {
+                'space': self.space.slug
+            }
+        }
+
 @dataclass
 class SpaceCreatedEvent(SpaceEvent):
     def __init__(self, cloud_event: CloudEvent):
diff --git a/main.py b/main.py
index ad19fc6..6314fd7 100644
--- a/main.py
+++ b/main.py
@@ -15,21 +15,7 @@ logger = getLogger(__name__)
 
 def process_user_name_updated_event(client: TypesenseClient, event: UserNameUpdatedEvent):
     logger.debug(f'Processing {event}')
-    document = {
-        'id': f'profile_{event.user.id}',
-        'type': 'profile',
-        'title_de': event.user.name,
-        'title_en': event.user.name,
-        'description_de': None,  # TODO add on sending side
-        'description_en': None,  # TODO add on sending side
-        'location': None,  # TODO add on sending side
-        'location_lat_lng': None,  # TODO add on sending side
-        'image_url': event.user.avatar,
-        'link_locators': {
-            'profile': event.user.id
-        }
-    }
-    client.upsert(document)
+    client.upsert(event.as_typesense_document())
     logger.info(f'Upserted user {event.user.id} in Typesense')
 
 def process_user_deleted_event(client: TypesenseClient, event: UserDeletedEvent):
@@ -39,21 +25,7 @@ def process_user_deleted_event(client: TypesenseClient, event: UserDeletedEvent)
 
 def process_space_upserting_event(client: TypesenseClient, event: Union[SpaceCreatedEvent, SpaceUpdatedEvent]):
     logger.debug(f'Processing {event}')
-    document = {
-        'id': f'space_{event.space.id}',
-        'type': 'space',
-        'title_de': event.space.name,
-        'title_en': event.space.name,
-        'description_de': None,  # TODO add on sending side
-        'description_en': None,  # TODO add on sending side
-        'location': None,
-        'location_lat_lng': None,
-        'image_url': event.space.avatar,
-        'link_locators': {
-            'space': event.space.slug
-        }
-    }
-    client.upsert(document)
+    client.upsert(event.as_typesense_document())
     logger.info(f'Upserted space {event.space.id} in Typesense')
 
 def process_space_deleted_event(client: TypesenseClient, event: SpaceDeletedEvent):
@@ -82,6 +54,9 @@ def process_event(client: TypesenseClient, event: CloudEvent):
             process_space_deleted_event(client, SpaceDeletedEvent(event))
             pass
         case (eventType, eventVersion):
+            # UserEmailUpdated: no need to process, it is sufficient to handle UserNameUpdated because this is emitted
+            # during signup and search should not display email addresses (PII)
+            # All other events are assumed to (currently) not be of interest in search
             logger.debug(f'Ignoring {eventType} ({eventVersion}) event.')
             pass
 
-- 
GitLab