-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: only send one digest email per org with all team info #27851
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Summary
This PR consolidates multiple team digest emails into a single organization-wide email, improving the notification experience for organizations with multiple teams while maintaining proper access controls.
- Introduced new
OrgDigestReport
andTeamDigestReport
data classes inreport_utils.py
to structure organization-level reporting - Added user-specific report filtering in
periodic_digest.py
to ensure users only see data from teams they have access to and notifications enabled for - Implemented organization-level idempotency using
MessagingRecord
with campaign keys that include period length - Added comprehensive test coverage in
test_periodic_digest.py
for multi-team scenarios, access controls, and notification preferences - Potential memory concern with upfront data loading for large organizations, as noted in PR description
💡 (1/5) You can manually trigger the bot by mentioning @greptileai in a comment!
3 file(s) reviewed, 4 comment(s)
Edit PR Review Bot Settings | Greptile
teams: dict[str, TeamDigestReport] # team_id -> TeamDigestReport | ||
total_digest_items_with_data: int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: teams dict uses string keys but stores integer team_ids. This mixed typing could cause issues. Consider using int keys consistently
team_id=int(next(iter(user_report.teams.keys()))), # Use first team for compatibility | ||
organization_id=org_id, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: using first team arbitrarily could cause issues if that team has different settings or configuration than other teams in the org - consider using a more deterministic selection method
user_teams[user.id] = set() | ||
user_notifications[user.id] = set() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: initializing empty sets for both user_teams and user_notifications could be moved outside the team loop to avoid redundant operations
Going to remove my review and subscribe instead. I can follow the summary, but actually approving code like this is a bit of a stretch for me! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great 🚢
# Check if we've already sent this digest | ||
period_str = period_end.strftime("%Y-%m-%d") | ||
days = (period_end - period_start).days | ||
campaign_key = f"periodic_digest_{period_str}_{days}d" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we want to be careful about allowing end_date=None AND begin_date=some_date
as args for this, as it'll determine this key differently based on the day it runs, but that might be intentional?
Problem
For orgs with multiple teams, sending an email per team was overwhelming.
Changes
I'm somewhat concerned about memory utilization with this approach because we're now keeping a lot more in memory than we were before. So any suggestions there are welcome - otherwise we will just see how it goes.
👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Does this work well for both Cloud and self-hosted?
Should..
How did you test this code?
Updated tests