feature/refactor_uuid #1

Merged
Ghasemi merged 9 commits from feature/refactor_uuid into master 2026-07-19 05:49:06 -04:00
59 changed files with 30 additions and 5 deletions
Showing only changes of commit c8b4e67567 - Show all commits

4
.gitignore vendored
View file

@ -5,5 +5,7 @@ media
/delme.py /delme.py
/log/accounts.log /log/accounts.log
/log/errors.log /log/errors.log
__pycache__ **/__pycache__
**/*.pyc
**/*.pyo
.claude .claude

View file

@ -46,6 +46,7 @@ class MattermostClient:
"debug": False, "debug": False,
} }
) )
self._driver.login()
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# Internal helpers — username and email are deterministic from UUID # Internal helpers — username and email are deterministic from UUID
@ -68,6 +69,16 @@ class MattermostClient:
# with identifying fields surfaced beyond this layer. # with identifying fields surfaced beyond this layer.
# ------------------------------------------------------------------ # ------------------------------------------------------------------
def _ensure_team_member(self, mm_user_id: str) -> None:
if not self._team_id:
return
try:
self._driver.teams.add_user_to_team(
self._team_id, options={"team_id": self._team_id, "user_id": mm_user_id}
)
except Exception:
pass # already a member or team not configured — not fatal
def get_or_create_user(self, user_id: UUID) -> str: def get_or_create_user(self, user_id: UUID) -> str:
""" """
Ensure a Mattermost account exists for the given external UUID. Ensure a Mattermost account exists for the given external UUID.
@ -77,7 +88,9 @@ class MattermostClient:
try: try:
user = self._driver.users.get_user_by_username(username) user = self._driver.users.get_user_by_username(username)
return user["id"] mm_user_id = user["id"]
self._ensure_team_member(mm_user_id)
return mm_user_id
except ResourceNotFound: except ResourceNotFound:
pass pass
except Exception as exc: except Exception as exc:
@ -91,13 +104,17 @@ class MattermostClient:
"password": self._random_password(), "password": self._random_password(),
} }
) )
return user["id"] mm_user_id = user["id"]
self._ensure_team_member(mm_user_id)
return mm_user_id
except Exception as exc: except Exception as exc:
# Guard against a concurrent request having created the account # Guard against a concurrent request having created the account
# between our lookup and our create attempt. # between our lookup and our create attempt.
try: try:
user = self._driver.users.get_user_by_username(username) user = self._driver.users.get_user_by_username(username)
return user["id"] mm_user_id = user["id"]
self._ensure_team_member(mm_user_id)
return mm_user_id
except Exception: except Exception:
pass pass
raise MattermostError(f"User creation failed: {exc}") from exc raise MattermostError(f"User creation failed: {exc}") from exc

View file

@ -20,7 +20,7 @@ class MessageService:
publishers: list | None = None, publishers: list | None = None,
): ):
self._account = account_service or AccountService() self._account = account_service or AccountService()
self._storage = storage_service or StorageService() self._storage_override = storage_service # lazy: only instantiate when needed
self._mm = mattermost_client or MattermostClient() self._mm = mattermost_client or MattermostClient()
self._publishers = ( self._publishers = (
publishers publishers
@ -28,6 +28,12 @@ class MessageService:
else [WebSocketPublisher(), PushPublisher(), LongPollPublisher()] else [WebSocketPublisher(), PushPublisher(), LongPollPublisher()]
) )
@property
def _storage(self) -> StorageService:
if self._storage_override is None:
self._storage_override = StorageService()
return self._storage_override
def send( def send(
self, self,
conversation_id, conversation_id,