Skip to content

fix: send immediate emails for encoded task mentions#4599

Merged
mancinux merged 2 commits into
mainfrom
1219-fix-task-notes-mention
Jun 1, 2026
Merged

fix: send immediate emails for encoded task mentions#4599
mancinux merged 2 commits into
mainfrom
1219-fix-task-notes-mention

Conversation

@mancinux

@mancinux mancinux commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

related to #1219

mancinux added 2 commits June 1, 2026 14:52
Signed-off-by: Luca Mancini <lmancini@operately.com>
Signed-off-by: Luca Mancini <lmancini@operately.com>

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • Consider reusing Operately.Activities.Notifications.MentionedPeople.ids/1 in OperatelyEmail.Emails.TaskAddingEmail.mentioned?/2 instead of calling Operately.RichContent.find_mentioned_ids/2 directly, to keep mention detection logic consistent across notifications and emails.
  • The content_value/2 helper silently returns nil for non-map content, which then results in Task.get/2 being called with a nil id; it may be safer to either pattern-match on a map in notify/3 or explicitly handle the nil case before calling Task.get/2 to avoid surprising failures.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider reusing `Operately.Activities.Notifications.MentionedPeople.ids/1` in `OperatelyEmail.Emails.TaskAddingEmail.mentioned?/2` instead of calling `Operately.RichContent.find_mentioned_ids/2` directly, to keep mention detection logic consistent across notifications and emails.
- The `content_value/2` helper silently returns `nil` for non-map content, which then results in `Task.get/2` being called with a `nil` id; it may be safer to either pattern-match on a map in `notify/3` or explicitly handle the `nil` case before calling `Task.get/2` to avoid surprising failures.

## Individual Comments

### Comment 1
<location path="app/lib/operately_email/emails/task_adding_email.ex" line_range="41-46" />
<code_context>
+  end
+
+  defp mentioned?(person, activity) do
+    mentioned_ids =
+      activity.content
+      |> content_value(:description)
+      |> Operately.RichContent.find_mentioned_ids(:decode_ids)
+
+    person.id in mentioned_ids
+  rescue
+    _ -> false
</code_context>
<issue_to_address>
**suggestion:** Reuse `MentionedPeople.ids/1` for mentioned-id extraction to keep logic consistent with the notification classifier.

This function calls `Operately.RichContent.find_mentioned_ids(:decode_ids)` directly, while `Operately.Notifications.DirectMentionClassifier` now goes through `MentionedPeople.ids/1`. Using two separate code paths for mention ID extraction makes it easier for their behavior to drift over time. Please update this to call `MentionedPeople.ids/1` so all mention detection shares the same abstraction and future fixes.

Suggested implementation:

```
  defp mentioned?(person, activity) do
    mentioned_ids =
      activity.content
      |> content_value(:description)
      |> MentionedPeople.ids()

    person.id in mentioned_ids
  rescue
    _ -> false
  end

```

To complete this change, add an alias for the `MentionedPeople` module at the top of `app/lib/operately_email/emails/task_adding_email.ex`, alongside the other aliases, for example:

```elixir
alias Operately.Notifications.MentionedPeople
```

If this module lives under a different namespace, adjust the alias path accordingly. Ensure there are no name clashes with other `MentionedPeople` modules in this file.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +41 to +46
mentioned_ids =
activity.content
|> content_value(:description)
|> Operately.RichContent.find_mentioned_ids(:decode_ids)

person.id in mentioned_ids

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Reuse MentionedPeople.ids/1 for mentioned-id extraction to keep logic consistent with the notification classifier.

This function calls Operately.RichContent.find_mentioned_ids(:decode_ids) directly, while Operately.Notifications.DirectMentionClassifier now goes through MentionedPeople.ids/1. Using two separate code paths for mention ID extraction makes it easier for their behavior to drift over time. Please update this to call MentionedPeople.ids/1 so all mention detection shares the same abstraction and future fixes.

Suggested implementation:

  defp mentioned?(person, activity) do
    mentioned_ids =
      activity.content
      |> content_value(:description)
      |> MentionedPeople.ids()

    person.id in mentioned_ids
  rescue
    _ -> false
  end

To complete this change, add an alias for the MentionedPeople module at the top of app/lib/operately_email/emails/task_adding_email.ex, alongside the other aliases, for example:

alias Operately.Notifications.MentionedPeople

If this module lives under a different namespace, adjust the alias path accordingly. Ensure there are no name clashes with other MentionedPeople modules in this file.

@mancinux
mancinux merged commit 0e98bc4 into main Jun 1, 2026
4 checks passed
@mancinux
mancinux deleted the 1219-fix-task-notes-mention branch June 1, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant