Skip to main content

max / makenotwork

1.8 KB · 59 lines History Blame Raw
1 //! mention reads, and username resolution confined to one community
2
3 use super::{PgPool, Uuid};
4
5 /// Batch-check which threads have at least one *live* mention of the given user.
6 ///
7 /// Only live posts count (`p.is_active`, migration 034), matching the
8 /// `has_mention` flag in `list_tracked_threads`. Both drive a badge that sends
9 /// the reader to a thread to find the mention, and a badge naming content that
10 /// is no longer there is worse than no badge.
11 #[tracing::instrument(skip_all)]
12 pub async fn get_threads_with_mentions_for_user(
13 pool: &PgPool,
14 user_id: Uuid,
15 thread_ids: &[Uuid],
16 ) -> Result<Vec<Uuid>, sqlx::Error> {
17 if thread_ids.is_empty() {
18 return Ok(Vec::new());
19 }
20 sqlx::query_scalar!(
21 "SELECT DISTINCT p.thread_id
22 FROM post_mentions pm
23 JOIN posts p ON p.id = pm.post_id
24 WHERE pm.mentioned_user_id = $1
25 AND p.thread_id = ANY($2)
26 AND p.is_active",
27 user_id,
28 thread_ids,
29 )
30 .fetch_all(pool)
31 .await
32 }
33
34 /// Resolve usernames to user IDs, filtered to community members.
35 #[tracing::instrument(skip_all)]
36 pub async fn resolve_usernames_in_community(
37 pool: &PgPool,
38 community_id: Uuid,
39 usernames: &[String],
40 ) -> Result<std::collections::HashMap<String, Uuid>, sqlx::Error> {
41 if usernames.is_empty() {
42 return Ok(std::collections::HashMap::new());
43 }
44 let rows = sqlx::query!(
45 "SELECT u.username, u.mnw_account_id
46 FROM users u
47 WHERE u.username = ANY($1)
48 AND u.mnw_account_id IN (SELECT user_id FROM memberships WHERE community_id = $2)",
49 usernames,
50 community_id,
51 )
52 .fetch_all(pool)
53 .await?;
54 Ok(rows
55 .into_iter()
56 .map(|r| (r.username, r.mnw_account_id))
57 .collect())
58 }
59