refactor: enhance event payload structure with actor and room details for improved clarity
ZhenYi committed
Modified lib/auth/src/server/auth_svc.rs lib/auth/src/server/auth_svc.rs +31 −2 View lib/auth/src/server/auth_svc.rs
@@ -14,6 +14,27 @@
1414
1515const EVENT_PUBLISH_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);
1616
17async fn actor_details(
18 conn: &impl sea_orm::ConnectionTrait,
19 labels: &Labels,
20) -> Option<serde_json::Value> {
21 use sea_orm::EntityTrait;
22
23 let uid = labels.get("user_id")?.parse::<i64>().ok()?;
24 let user = crate::models::users::users::Entity::find_by_id(uid)
25 .one(conn)
26 .await
27 .ok()??;
28 Some(serde_json::json!({
29 "id": user.id,
30 "username": user.username,
31 "display_name": user.displayname,
32 "email": user.email,
33 "is_admin": user.is_admin,
34 "bot": user.bot,
35 }))
36}
37
1738#[derive(Clone)]
1839pub struct AuthSvc {
1940 db: DbConn,
@@ -146,11 +167,15 @@
146167 .map(str::to_owned)
147168 .or_else(crate::envelope::context::request_id)
148169 .unwrap_or_default();
170 let mut payload = serde_json::to_value(&payload).unwrap_or(serde_json::Value::Null);
171 if let Some(actor) = actor_details(self.db.write(), &labels).await {
172 payload["actor"] = actor;
173 }
149174 let enqueued = crate::events::outbox::enqueue_at(
150175 self.db.write(),
151176 event,
152177 labels.clone(),
153 payload.clone(),
178 &payload,
154179 &trace_id,
155180 chrono::Utc::now(),
156181 request_id,
@@ -188,11 +213,15 @@
188213 .map(str::to_owned)
189214 .or_else(crate::envelope::context::request_id)
190215 .unwrap_or_default();
216 let mut payload = serde_json::to_value(&payload).unwrap_or(serde_json::Value::Null);
217 if let Some(actor) = actor_details(conn, &labels).await {
218 payload["actor"] = actor;
219 }
191220 crate::events::outbox::enqueue_at(
192221 conn,
193222 event,
194223 labels,
195 payload,
224 &payload,
196225 &trace_id,
197226 chrono::Utc::now(),
198227 request_id,
Modified lib/chat/src/handlers/attachments.rs lib/chat/src/handlers/attachments.rs +1 −1 View lib/chat/src/handlers/attachments.rs
@@ -1,9 +1,9 @@
11use export::http::{Json, Path, Query, Response, State};
22use export::rest::{AppResponseData, NoData};
33use imaging::layout::ImageVariant;
4use serde::Deserialize;
45use token::Session;
56use token::share::session;
6use serde::Deserialize;
77use utoipa::{IntoParams, ToSchema};
88use uuid::Uuid;
99
Modified lib/chat/src/handlers/voice.rs lib/chat/src/handlers/voice.rs +2 −2 View lib/chat/src/handlers/voice.rs
@@ -1,10 +1,10 @@
11use export::http::{HeaderMap, Json, Path, Query, State};
22use export::rest::{AppResponseData, NoData};
3use token::Session;
4use token::share::session;
53use livekit_api::access_token::TokenVerifier;
64use livekit_api::webhooks::WebhookReceiver;
75use serde::Deserialize;
6use token::Session;
7use token::share::session;
88use uuid::Uuid;
99
1010use crate::errors::ApiError;
Modified lib/chat/src/services/service.rs lib/chat/src/services/service.rs +1 −1 View lib/chat/src/services/service.rs
@@ -18,7 +18,7 @@
1818
1919impl ChatService {
2020 pub fn new(state: AppState) -> Self {
21 let realtime = Realtime::new(state.database.write().clone());
21 let realtime = Realtime::new(state.clone());
2222 Self { state, realtime }
2323 }
2424
Modified lib/chat/src/share/events.rs lib/chat/src/share/events.rs +110 −11 View lib/chat/src/share/events.rs
@@ -1,5 +1,8 @@
1use sea_orm::DatabaseConnection;
2use serde_json::Value;
1use export::AppState;
2use models::chat::messages;
3use models::room::rooms;
4use sea_orm::EntityTrait;
5use serde_json::{Value, json};
36use uuid::Uuid;
47
58use crate::errors::ChatError;
@@ -76,7 +79,7 @@
7679 }
7780}
7881
79pub async fn enqueue_room(db: &DatabaseConnection, event: &RoomEvent) -> Result<(), ChatError> {
82pub async fn enqueue_room(state: &AppState, event: &RoomEvent) -> Result<(), ChatError> {
8083 let mut labels = queue::Labels::new().with("room_id", event.room_id());
8184 if let Some(actor) = room_actor(event) {
8285 labels.insert("user_id", actor);
@@ -91,22 +94,38 @@
9194 labels.insert("request_id", request_id);
9295 }
9396
97 let mut payload =
98 serde_json::to_value(event).map_err(|error| ChatError::Internal(error.to_string()))?;
99 if let Some(room) = room_detail(state, event.room_id()).await {
100 payload["room"] = room;
101 }
102 if let Some(actor) = room_actor(event)
103 && let Some(actor) = user_detail(state, actor).await
104 {
105 payload["actor"] = actor;
106 }
107 if let Some(message_id) = room_message_id(event)
108 && !matches!(
109 event,
110 RoomEvent::MessagePublished { .. } | RoomEvent::MessageEdited { .. }
111 )
112 && let Some(message) = message_detail(state, message_id).await
113 {
114 payload["message"] = message;
115 }
116
94117 export::events::enqueue(
95 db,
118 state.database.write(),
96119 room_kind(event),
97120 labels,
98 event,
121 &payload,
99122 format!("chat:room:{}", event.room_id()),
100123 )
101124 .await?;
102125 Ok(())
103126}
104127
105pub async fn enqueue_user(
106 db: &DatabaseConnection,
107 uid: i64,
108 event: &Value,
109) -> Result<(), ChatError> {
128pub async fn enqueue_user(state: &AppState, uid: i64, event: &Value) -> Result<(), ChatError> {
110129 let Some(kind) = user_kind(event) else {
111130 let unknown = event
112131 .get("kind")
@@ -124,6 +143,86 @@
124143 labels.insert("request_id", request_id);
125144 }
126145
127 export::events::enqueue(db, kind, labels, event, format!("chat:user:{uid}")).await?;
146 let mut payload = event.clone();
147 if let Some(room_id) = event
148 .get("room_id")
149 .and_then(Value::as_str)
150 .and_then(|value| Uuid::parse_str(value).ok())
151 && let Some(room) = room_detail(state, room_id).await
152 {
153 payload["room"] = room;
154 }
155 if let Some(message_id) = event
156 .get("message_id")
157 .and_then(Value::as_str)
158 .and_then(|value| Uuid::parse_str(value).ok())
159 && let Some(message) = message_detail(state, message_id).await
160 {
161 if let Some(author_id) = message.get("author_id").and_then(Value::as_i64)
162 && let Some(actor) = user_detail(state, author_id).await
163 {
164 payload["actor"] = actor;
165 }
166 payload["message"] = message;
167 }
168
169 export::events::enqueue(
170 state.database.write(),
171 kind,
172 labels,
173 &payload,
174 format!("chat:user:{uid}"),
175 )
176 .await?;
128177 Ok(())
129178}
179
180async fn room_detail(state: &AppState, room_id: Uuid) -> Option<Value> {
181 let room = rooms::Entity::find_by_id(room_id)
182 .one(state.database.read())
183 .await
184 .ok()??;
185 Some(json!({
186 "id": room.id,
187 "space_id": room.space_id,
188 "kind": room.kind,
189 "name": room.name,
190 "topic": room.topic,
191 }))
192}
193
194async fn message_detail(state: &AppState, message_id: Uuid) -> Option<Value> {
195 let message = messages::Entity::find_by_id(message_id)
196 .one(state.database.read())
197 .await
198 .ok()??;
199 let mut detail = json!({
200 "id": message.id,
201 "room_id": message.room_id,
202 "author_id": message.author_id,
203 "author_type": message.author_type,
204 "content": message.content,
205 "message_type": message.message_type,
206 "mentions": message.mentions,
207 "attachments": message.attachments,
208 "embeds": message.embeds,
209 "seq": message.seq,
210 "created_at": message.created_at,
211 "edited_at": message.edited_at,
212 "deleted_at": message.deleted_at,
213 });
214 if let Some(actor) = user_detail(state, message.author_id).await {
215 detail["author"] = actor;
216 }
217 Some(detail)
218}
219
220async fn user_detail(state: &AppState, uid: i64) -> Option<Value> {
221 let user = export::users::get_public_user(state, uid).await.ok()??;
222 Some(json!({
223 "id": user.user_id,
224 "username": user.username,
225 "display_name": user.displayname,
226 "avatar_url": export::resolve_user_avatar_url(user.user_id, &user.avatar_url),
227 }))
228}
Modified lib/chat/src/share/realtime.rs lib/chat/src/share/realtime.rs +5 −5 View lib/chat/src/share/realtime.rs
@@ -115,23 +115,23 @@
115115/// KenEvent(MQ → socket),本服务只负责把"发生了什么"持久化下来。
116116#[derive(Clone)]
117117pub struct Realtime {
118 db: sea_orm::DatabaseConnection,
118 state: export::AppState,
119119}
120120
121121impl Realtime {
122 pub fn new(db: sea_orm::DatabaseConnection) -> Self {
123 Self { db }
122 pub fn new(state: export::AppState) -> Self {
123 Self { state }
124124 }
125125
126126 pub async fn publish_room(&self, event: &RoomEvent) {
127 if let Err(error) = crate::share::events::enqueue_room(&self.db, event).await {
127 if let Err(error) = crate::share::events::enqueue_room(&self.state, event).await {
128128 tracing::warn!(%error, room_id = %event.room_id(), "chat room event enqueue failed");
129129 }
130130 }
131131
132132 pub async fn publish_user<T: Serialize>(&self, uid: i64, event: &T) {
133133 if let Ok(value) = serde_json::to_value(event)
134 && let Err(error) = crate::share::events::enqueue_user(&self.db, uid, &value).await
134 && let Err(error) = crate::share::events::enqueue_user(&self.state, uid, &value).await
135135 {
136136 tracing::warn!(%error, %uid, "chat user event enqueue failed");
137137 }
Modified lib/events/src/handler.rs lib/events/src/handler.rs +1 −1 View lib/events/src/handler.rs
@@ -150,7 +150,7 @@
150150 let request_id = envelope::context::request_id();
151151 let properties = envelope.properties(Some(&payload), request_id.as_deref());
152152 let topic = self.publisher.topic(&route.area);
153 let body = envelope.summary_body(&route.tag)?;
153 let body = envelope.encode()?;
154154
155155 self.publisher
156156 .publish(
Modified lib/events/src/outbox.rs lib/events/src/outbox.rs +1 −3 View lib/events/src/outbox.rs
@@ -291,9 +291,7 @@
291291 }
292292 let route = queue::route::route(&envelope.kind).map_err(|error| error.to_string())?;
293293 let topic = publisher.topic(&route.area);
294 let body = envelope
295 .summary_body(&route.tag)
296 .map_err(|error| error.to_string())?;
294 let body = envelope.encode().map_err(|error| error.to_string())?;
297295 let payload = serde_json::to_value(&envelope.payload).ok();
298296 publisher
299297 .publish(
Modified lib/export/src/notify.rs lib/export/src/notify.rs +16 −5 View lib/export/src/notify.rs
@@ -20,10 +20,21 @@
2020 // Enqueueing here — rather than at each of the nine writers — is what makes
2121 // "websocket fan-out and push fan-out never drift" true by construction.
2222 if event.get("kind").and_then(Value::as_str) == Some("notification") {
23 if let Some(notification) = event.get("notification")
24 && let Some(job) = crate::push::PushJob::from_notification(uid, notification)
25 {
26 crate::push::enqueue(redis, &job).await;
23 let mut event = event.clone();
24 if let Some(notification) = event.get_mut("notification") {
25 if let Some(actor_id) = notification.get("actor_id").and_then(Value::as_i64)
26 && let Ok(Some(actor)) = crate::users::get_public_user(state, actor_id).await
27 {
28 notification["actor"] = serde_json::json!({
29 "id": actor.user_id,
30 "username": actor.username,
31 "display_name": actor.displayname,
32 "avatar_url": crate::resolve_user_avatar_url(actor.user_id, &actor.avatar_url),
33 });
34 }
35 if let Some(job) = crate::push::PushJob::from_notification(uid, notification) {
36 crate::push::enqueue(redis, &job).await;
37 }
2738 }
2839 let labels = Labels::new()
2940 .with("user_id", uid)
@@ -32,7 +43,7 @@
3243 state.database.write(),
3344 "notify.notification.create",
3445 labels,
35 event,
46 &event,
3647 format!("notify:user:{uid}"),
3748 )
3849 .await
Modified lib/issues/src/handlers/boards/create_board.rs lib/issues/src/handlers/boards/create_board.rs +1 −1 View lib/issues/src/handlers/boards/create_board.rs
@@ -5,8 +5,8 @@
55use crate::errors::ApiError;
66use crate::services::boards::{BoardDto, CreateBoardCmd};
77use crate::services::service::IssueService;
8use space::services::spaces::SpaceNamePath;
89use token::share::session;
9use space::services::spaces::SpaceNamePath;
1010
1111#[utoipa::path(
1212 post,
Modified lib/issues/src/handlers/boards/list_boards.rs lib/issues/src/handlers/boards/list_boards.rs +1 −1 View lib/issues/src/handlers/boards/list_boards.rs
@@ -5,8 +5,8 @@
55use crate::errors::ApiError;
66use crate::services::boards::{BoardPage, ListBoardQuery};
77use crate::services::service::IssueService;
8use space::services::spaces::SpaceNamePath;
89use token::share::session;
9use space::services::spaces::SpaceNamePath;
1010
1111#[utoipa::path(
1212 get,
Modified lib/issues/src/services/service.rs lib/issues/src/services/service.rs +26 −2 View lib/issues/src/services/service.rs
@@ -6,9 +6,10 @@
66use export::database::AppDatabase;
77use i18n;
88use models::issue::issue_event_line::{self, IssueEventType};
9use models::issue::issue_item;
910use models::space::spaces;
1011use models::users::user_notifications::{self, NotificationType};
11use sea_orm::{ActiveModelTrait, ConnectionTrait, Set};
12use sea_orm::{ActiveModelTrait, ConnectionTrait, EntityTrait, Set};
1213use space::services::spaces::UserDto;
1314use time::OffsetDateTime;
1415use uuid::Uuid;
@@ -104,7 +105,7 @@
104105 new_title,
105106 content,
106107 } = detail;
107 let payload = serde_json::json!({
108 let mut payload = serde_json::json!({
108109 "issue_id": issue_id,
109110 "user_id": user_id,
110111 "event_type": event_type,
@@ -113,6 +114,29 @@
113114 "new_title": &new_title,
114115 "content": &content,
115116 });
117 if let Ok(Some(issue)) = issue_item::Entity::find_by_id(issue_id).one(txn).await {
118 payload["issue"] = serde_json::json!({
119 "id": issue.id,
120 "number": issue.autoincrement_id,
121 "collection_id": issue.collection_id,
122 "author_id": issue.author_id,
123 "title": &issue.title,
124 "description": &issue.description,
125 "priority": issue.priority,
126 "milestone_id": issue.milestone_id,
127 "created_at": issue.created_at,
128 "updated_at": issue.updated_at,
129 "closed_at": issue.closed_at,
130 });
131 }
132 if let Ok(Some(actor)) = export::users::get_public_user(&self.state, user_id).await {
133 payload["actor"] = serde_json::json!({
134 "id": actor.user_id,
135 "username": actor.username,
136 "display_name": actor.displayname,
137 "avatar_url": export::resolve_user_avatar_url(actor.user_id, &actor.avatar_url),
138 });
139 }
116140 issue_event_line::ActiveModel {
117141 id: Set(Uuid::now_v7()),
118142 issue_id: Set(Some(issue_id)),
Modified lib/pulls/src/handlers/relations/unlink_issue_pull.rs lib/pulls/src/handlers/relations/unlink_issue_pull.rs +1 −1 View lib/pulls/src/handlers/relations/unlink_issue_pull.rs
@@ -1,8 +1,8 @@
11use export::http::{Path, State};
22use export::rest::{AppResponseData, NoData};
33use issues::services::issues::IssuePath;
4use sea_orm::EntityTrait;
45use token::Session;
5use sea_orm::EntityTrait;
66use uuid::Uuid;
77
88use crate::errors::{ApiError, PullError};
Modified lib/pulls/src/services/changes.rs lib/pulls/src/services/changes.rs +1 −0 View lib/pulls/src/services/changes.rs
@@ -145,6 +145,7 @@
145145 let updated = model.update(self.db_write()).await?;
146146 if moved {
147147 write_event(
148 &self.state,
148149 self.db_write(),
149150 &updated,
150151 actor,
Modified lib/pulls/src/services/events.rs lib/pulls/src/services/events.rs +41 −1 View lib/pulls/src/services/events.rs
@@ -1,3 +1,4 @@
1use export::AppState;
12use export::pagination::{Page, PageQuery};
23use models::pull_request::{pull_request_event_line, pull_requests};
34use sea_orm::ActiveValue::Set;
@@ -48,6 +49,7 @@
4849pub type EventPage = Page<PullEventDto>;
4950
5051pub async fn write_event(
52 state: &AppState,
5153 db: &impl ConnectionTrait,
5254 pull: &pull_requests::Model,
5355 actor: Option<i64>,
@@ -59,13 +61,50 @@
5961 Some(actor) => actor,
6062 None => pull.author_id,
6163 };
62 let payload = serde_json::json!({
64 let mut payload = serde_json::json!({
6365 "pull_request_id": pull.id,
6466 "user_id": actor,
6567 "event_type": event_type,
6668 "commit_sha": &commit_sha,
6769 "content": &content,
70 "pull_request": {
71 "id": pull.id,
72 "repo_id": pull.repo_id,
73 "issue_id": pull.issue_id,
74 "number": pull.autoincrement_id,
75 "author_id": pull.author_id,
76 "title": &pull.title,
77 "body": &pull.body,
78 "head_branch": &pull.head_branch,
79 "head_sha": &pull.head_sha,
80 "head_label": &pull.head_label,
81 "base_branch": &pull.base_branch,
82 "base_sha": &pull.base_sha,
83 "is_draft": pull.is_draft,
84 "merge_method": pull.merge_method,
85 "has_merged": pull.has_merged,
86 "merged_commit_sha": &pull.merged_commit_sha,
87 "squash_commit_sha": &pull.squash_commit_sha,
88 "auto_merge": pull.auto_merge,
89 "additions": pull.additions,
90 "deletions": pull.deletions,
91 "files_changed": pull.files_changed,
92 "merger_id": pull.merger_id,
93 "merged_at": pull.merged_at,
94 "is_locked": pull.is_locked,
95 "created_at": pull.created_at,
96 "updated_at": pull.updated_at,
97 "closed_at": pull.closed_at,
98 },
6899 });
100 if let Ok(Some(actor)) = export::users::get_public_user(state, actor).await {
101 payload["actor"] = serde_json::json!({
102 "id": actor.user_id,
103 "username": actor.username,
104 "display_name": actor.displayname,
105 "avatar_url": export::resolve_user_avatar_url(actor.user_id, &actor.avatar_url),
106 });
107 }
69108 let row = pull_request_event_line::ActiveModel {
70109 id: Set(Uuid::now_v7()),
71110 pull_request_id: Set(pull.id),
@@ -124,6 +163,7 @@
124163 content: Option<String>,
125164 ) -> Result<(), PullError> {
126165 write_event(
166 &self.state,
127167 self.db_write(),
128168 pull,
129169 actor,
Modified lib/pulls/src/services/pulls.rs lib/pulls/src/services/pulls.rs +1 −0 View lib/pulls/src/services/pulls.rs
@@ -402,6 +402,7 @@
402402 };
403403 let pull = created.insert(&txn).await?;
404404 write_event(
405 &self.state,
405406 &txn,
406407 &pull,
407408 Some(caller),
Modified lib/pulls/src/services/reviewers.rs lib/pulls/src/services/reviewers.rs +2 −0 View lib/pulls/src/services/reviewers.rs
@@ -128,6 +128,7 @@
128128 added.push(uid);
129129 }
130130 write_event(
131 &self.state,
131132 self.db_write(),
132133 pull,
133134 Some(caller),
@@ -161,6 +162,7 @@
161162 .exec(self.db_write())
162163 .await?;
163164 write_event(
165 &self.state,
164166 self.db_write(),
165167 pull,
166168 Some(caller),
Modified lib/pulls/src/services/reviews.rs lib/pulls/src/services/reviews.rs +1 −0 View lib/pulls/src/services/reviews.rs
@@ -138,6 +138,7 @@
138138 }
139139 if state != ReviewState::Pending {
140140 write_event(
141 &self.state,
141142 &txn,
142143 pull,
143144 Some(caller),
Modified lib/pulls/src/services/service.rs lib/pulls/src/services/service.rs +1 −1 View lib/pulls/src/services/service.rs
@@ -1,13 +1,13 @@
11use config::AppConfig;
22use export::AppState;
33use git::service::GitService;
4use token::Session;
54use models::pull_request::pull_requests;
65use models::repo::repos;
76use sea_orm::ActiveValue::Set;
87use sea_orm::{
98 ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, PaginatorTrait, QueryFilter,
109};
10use token::Session;
1111use uuid::Uuid;
1212
1313use crate::errors::PullError;
Modified lib/pulls/src/share/lookup.rs lib/pulls/src/share/lookup.rs +1 −1 View lib/pulls/src/share/lookup.rs
@@ -1,8 +1,8 @@
11use git::context::facade::GitContext;
22use git::share::access;
3use token::Session;
43use models::pull_request::pull_requests;
54use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
5use token::Session;
66use uuid::Uuid;
77
88use crate::errors::PullError;
Modified lib/queue/src/envelope.rs lib/queue/src/envelope.rs +0 −19 View lib/queue/src/envelope.rs
@@ -238,31 +238,12 @@
238238 .map(Bytes::from)
239239 .map_err(QueueError::from)
240240 }
241
242 pub fn summary_body(&self, summary: &str) -> QueueResult<Bytes> {
243 serde_json::to_vec(&Summary {
244 id: self.id,
245 kind: &self.kind,
246 occurred_at: &self.occurred_at,
247 summary,
248 })
249 .map(Bytes::from)
250 .map_err(QueueError::from)
251 }
252241}
253242
254243impl<T: DeserializeOwned> Envelope<T> {
255244 pub fn decode(payload: &[u8]) -> QueueResult<Self> {
256245 serde_json::from_slice(payload).map_err(QueueError::from)
257246 }
258}
259
260#[derive(Serialize)]
261struct Summary<'a> {
262 id: Uuid,
263 kind: &'a str,
264 occurred_at: &'a DateTime<Utc>,
265 summary: &'a str,
266247}
267248
268249fn field_text(value: &Value, key: &str) -> Option<String> {
Modified lib/space/src/handlers/get_group.rs lib/space/src/handlers/get_group.rs +1 −1 View lib/space/src/handlers/get_group.rs
@@ -1,7 +1,7 @@
11use export::http::{Path, State};
22use export::rest::{AppResponseData, NoData};
3use serde::Deserialize;
34use token::Session;
4use serde::Deserialize;
55use utoipa::{IntoParams, ToSchema};
66use uuid::Uuid;
77
Modified lib/space/src/handlers/get_member.rs lib/space/src/handlers/get_member.rs +1 −1 View lib/space/src/handlers/get_member.rs
@@ -1,7 +1,7 @@
11use export::http::{Path, State};
22use export::rest::{AppResponseData, NoData};
3use serde::Deserialize;
34use token::Session;
4use serde::Deserialize;
55use utoipa::{IntoParams, ToSchema};
66
77use crate::errors::ApiError;
Modified lib/space/src/handlers/get_space_dir_tree.rs lib/space/src/handlers/get_space_dir_tree.rs +1 −1 View lib/space/src/handlers/get_space_dir_tree.rs
@@ -1,7 +1,7 @@
11use export::http::{Path, Query, State};
22use export::rest::{AppResponseData, NoData};
3use serde::Deserialize;
34use token::Session;
4use serde::Deserialize;
55
66use crate::errors::ApiError;
77use crate::services::dir::DirNodeDto;
Modified lib/space/src/handlers/get_space_image_file.rs lib/space/src/handlers/get_space_image_file.rs +1 −1 View lib/space/src/handlers/get_space_image_file.rs
@@ -1,8 +1,8 @@
11use actix_web::http::header;
22use export::http::{Path, Query, Response, State};
33use imaging::layout::ImageVariant;
4use serde::Deserialize;
45use token::Session;
5use serde::Deserialize;
66use utoipa::{IntoParams, ToSchema};
77
88use crate::errors::ApiError;
Modified lib/space/src/handlers/revoke_invite.rs lib/space/src/handlers/revoke_invite.rs +1 −1 View lib/space/src/handlers/revoke_invite.rs
@@ -1,7 +1,7 @@
11use export::http::{Path, State};
22use export::rest::{AppResponseData, NoData};
3use serde::Deserialize;
34use token::Session;
4use serde::Deserialize;
55use utoipa::{IntoParams, ToSchema};
66use uuid::Uuid;
77
Modified lib/space/src/handlers/set_dir_group_overwrite.rs lib/space/src/handlers/set_dir_group_overwrite.rs +1 −1 View lib/space/src/handlers/set_dir_group_overwrite.rs
@@ -1,7 +1,7 @@
11use export::http::{Json, Path, State};
22use export::rest::{AppResponseData, NoData};
3use serde::Deserialize;
34use token::Session;
4use serde::Deserialize;
55use utoipa::{IntoParams, ToSchema};
66use uuid::Uuid;
77
Modified lib/space/src/handlers/set_dir_user_overwrite.rs lib/space/src/handlers/set_dir_user_overwrite.rs +1 −1 View lib/space/src/handlers/set_dir_user_overwrite.rs
@@ -1,7 +1,7 @@
11use export::http::{Json, Path, State};
22use export::rest::{AppResponseData, NoData};
3use serde::Deserialize;
34use token::Session;
4use serde::Deserialize;
55use utoipa::{IntoParams, ToSchema};
66use uuid::Uuid;
77
Modified lib/space/src/handlers/unassign_group.rs lib/space/src/handlers/unassign_group.rs +1 −1 View lib/space/src/handlers/unassign_group.rs
@@ -1,7 +1,7 @@
11use export::http::{Path, State};
22use export::rest::{AppResponseData, NoData};
3use serde::Deserialize;
34use token::Session;
4use serde::Deserialize;
55use utoipa::{IntoParams, ToSchema};
66use uuid::Uuid;
77
Modified lib/space/src/services/rooms.rs lib/space/src/services/rooms.rs +61 −2 View lib/space/src/services/rooms.rs
@@ -226,6 +226,18 @@
226226 })
227227 .await?;
228228
229 let actor = export::users::get_public_user(&self.state, caller)
230 .await
231 .ok()
232 .flatten()
233 .map(|user| {
234 serde_json::json!({
235 "id": user.user_id,
236 "username": user.username,
237 "display_name": user.displayname,
238 "avatar_url": export::resolve_user_avatar_url(user.user_id, &user.avatar_url),
239 })
240 });
229241 export::events::enqueue_chat_users(
230242 self.db().write(),
231243 "chat.membership.create",
@@ -235,7 +247,24 @@
235247 .filter(|uid| *uid != caller)
236248 .collect::<Vec<_>>(),
237249 room_id,
238 &serde_json::json!({ "kind": "room_added", "room_id": room_id }),
250 &serde_json::json!({
251 "kind": "room_added",
252 "room_id": room_id,
253 "room": {
254 "id": inserted.id,
255 "space_id": inserted.space_id,
256 "kind": inserted.kind,
257 "name": &inserted.name,
258 "topic": &inserted.topic,
259 },
260 "space": {
261 "id": space.id,
262 "lower_name": &space.lower_name,
263 "name": &space.name,
264 "avatar_url": &space.avatar_url,
265 },
266 "actor": actor,
267 }),
239268 )
240269 .await?;
241270
@@ -262,6 +291,25 @@
262291 return Err(SpaceError::NotFound);
263292 }
264293
294 let actor = export::users::get_public_user(&self.state, caller)
295 .await
296 .ok()
297 .flatten()
298 .map(|user| {
299 serde_json::json!({
300 "id": user.user_id,
301 "username": user.username,
302 "display_name": user.displayname,
303 "avatar_url": export::resolve_user_avatar_url(user.user_id, &user.avatar_url),
304 })
305 });
306 let room_detail = serde_json::json!({
307 "id": room.id,
308 "space_id": room.space_id,
309 "kind": room.kind,
310 "name": &room.name,
311 "topic": &room.topic,
312 });
265313 let now = OffsetDateTime::now_utc();
266314 let mut am: rooms::ActiveModel = room.into();
267315 am.is_active = Set(false);
@@ -272,7 +320,18 @@
272320 self.db().write(),
273321 "chat.room.update",
274322 room_id,
275 serde_json::json!({ "room_id": room_id, "deleted": true }),
323 serde_json::json!({
324 "room_id": room_id,
325 "deleted": true,
326 "room": room_detail,
327 "space": {
328 "id": space.id,
329 "lower_name": &space.lower_name,
330 "name": &space.name,
331 "avatar_url": &space.avatar_url,
332 },
333 "actor": actor,
334 }),
276335 )
277336 .await?;
278337