@@ -12,6 +12,7 @@ use axum::{
1212 response:: IntoResponse ,
1313} ;
1414use bson:: { doc, oid:: ObjectId } ;
15+ use futures:: StreamExt ;
1516use mongodb:: { Collection , Database } ;
1617use serde:: { Deserialize , Serialize } ;
1718use std:: { str:: FromStr , sync:: Arc } ;
@@ -128,3 +129,91 @@ pub async fn update_member_status(
128129 }
129130 ( StatusCode :: OK , Json ( "" . to_string ( ) ) )
130131}
132+
133+ pub async fn update_member_impression (
134+ Extension ( db) : Extension < Arc < Mutex < Database > > > ,
135+ user : UserData ,
136+ Path ( id) : Path < String > ,
137+ Path ( member_id) : Path < String > ,
138+ Json ( update) : Json < UpdateActivityMemberImpression > ,
139+ ) -> impl IntoResponse {
140+ let db = db. lock ( ) . await ;
141+ let collection: Collection < Activity > = db. collection ( "activities" ) ;
142+ let activity_id = ObjectId :: from_str ( & id. as_str ( ) ) ;
143+ if let Err ( _) = activity_id {
144+ return create_error ( StatusCode :: BAD_REQUEST , "Invalid activity ID" . to_string ( ) ) ;
145+ }
146+ let activity_id = activity_id. unwrap ( ) ;
147+ let member_id = ObjectId :: from_str ( & member_id. as_str ( ) ) ;
148+ if let Err ( _) = member_id {
149+ return create_error ( StatusCode :: BAD_REQUEST , "Invalid member ID" . to_string ( ) ) ;
150+ }
151+ let member_id = member_id. unwrap ( ) ;
152+ if member_id. to_string ( ) != user. id {
153+ return create_error ( StatusCode :: FORBIDDEN , "Permission denied" . to_string ( ) ) ;
154+ }
155+ let pipeline = vec ! [
156+ doc! { "$match" : { "_id" : activity_id} } ,
157+ doc! { "$unwind" : "$members" } ,
158+ doc! { "$match" : { "members._id" : member_id} } ,
159+ doc! { "$project" : { "members" : 1 } } ,
160+ ] ;
161+ let activity = collection. aggregate ( pipeline, None ) . await ;
162+ if let Err ( _) = activity {
163+ return create_error (
164+ StatusCode :: INTERNAL_SERVER_ERROR ,
165+ "Failed to find activity" . to_string ( ) ,
166+ ) ;
167+ }
168+ let activity = activity. unwrap ( ) . collect :: < Vec < _ > > ( ) . await [ 0 ] . clone ( ) ;
169+ if let Err ( e) = activity {
170+ return create_error (
171+ StatusCode :: NOT_FOUND ,
172+ "Activity not found" . to_string ( ) + & e. to_string ( ) ,
173+ ) ;
174+ }
175+ let member = bson:: from_document :: < ActivityMember > ( activity. unwrap ( ) ) ;
176+ if let Err ( _) = member {
177+ return create_error (
178+ StatusCode :: INTERNAL_SERVER_ERROR ,
179+ "Failed to find member" . to_string ( ) ,
180+ ) ;
181+ }
182+ let member = member. unwrap ( ) ;
183+ if member. status == ActivityMemberStatus :: Effective
184+ || member. status == ActivityMemberStatus :: Refused
185+ {
186+ return create_error (
187+ StatusCode :: FORBIDDEN ,
188+ "Cannot update member impression" . to_string ( ) ,
189+ ) ;
190+ }
191+ let result = collection
192+ . update_one (
193+ doc ! { "_id" : activity_id, "members._id" : member_id} ,
194+ doc ! { "$set" : { "members.$.impression" : update. impression} } ,
195+ None ,
196+ )
197+ . await ;
198+ if let Err ( _) = result {
199+ return create_error (
200+ StatusCode :: INTERNAL_SERVER_ERROR ,
201+ "Failed to update member impression" . to_string ( ) ,
202+ ) ;
203+ }
204+ let result = result. unwrap ( ) ;
205+ if result. modified_count != 1 {
206+ return create_error (
207+ StatusCode :: INTERNAL_SERVER_ERROR ,
208+ "Failed to update member impression" . to_string ( ) ,
209+ ) ;
210+ }
211+ let response: SuccessResponse < Vec < ActivityMember > , ( ) > = SuccessResponse {
212+ status : ResponseStatus :: Success ,
213+ code : 200 ,
214+ data : vec ! [ ] ,
215+ metadata : None ,
216+ } ;
217+ let response = serde_json:: to_string ( & response) . unwrap ( ) ;
218+ ( StatusCode :: OK , Json ( response) )
219+ }
0 commit comments