1use actix_web::web::Query;
4use actix_web::{
5 delete, get, patch, post,
6 web::{Json, Path},
7 HttpResponse, Result,
8};
9use uuid::Uuid;
10
11use crate::{
12 config::{
13 auth::user_info::UserInfo,
14 data::{SharedBroadcaster, SharedPool},
15 },
16 model::dto::{
17 actions::{Action, ActionType, UpdateMapGeometryActionPayload},
18 MapSearchParameters, NewMapDto, PageParameters, UpdateMapDto, UpdateMapGeometryDto,
19 },
20 service,
21 service::map_access_control::check_permissions,
22};
23
24#[utoipa::path(
31 context_path = "/api/maps",
32 params(
33 MapSearchParameters,
34 PageParameters
35 ),
36 responses(
37 (status = 200, description = "Fetch or search all maps", body = PageMapDto)
38 ),
39 security(
40 ("oauth2" = [])
41 )
42)]
43#[get("")]
44pub async fn find(
45 search_query: Query<MapSearchParameters>,
46 page_query: Query<PageParameters>,
47 pool: SharedPool,
48) -> Result<HttpResponse> {
49 let response =
50 service::map::find(search_query.into_inner(), page_query.into_inner(), &pool).await?;
51 Ok(HttpResponse::Ok().json(response))
52}
53
54#[utoipa::path(
59 context_path = "/api/maps",
60 responses(
61 (status = 200, description = "Fetch a map by id", body = MapDto)
62 ),
63 security(
64 ("oauth2" = [])
65 )
66)]
67#[get("/{map_id}")]
68pub async fn find_by_id(
69 map_id: Path<i32>,
70 pool: SharedPool,
71 user_info: UserInfo,
72) -> Result<HttpResponse> {
73 let id = map_id.into_inner();
74 check_permissions(id, &pool, user_info).await?;
75 let response = service::map::find_by_id(id, &pool).await?;
76 Ok(HttpResponse::Ok().json(response))
77}
78
79#[utoipa::path(
84 context_path = "/api/maps",
85 request_body = NewMapDto,
86 responses(
87 (status = 201, description = "Create a new map", body = MapDto)
88 ),
89 security(
90 ("oauth2" = [])
91 )
92)]
93#[post("")]
94pub async fn create(
95 new_map_json: Json<NewMapDto>,
96 user_info: UserInfo,
97 pool: SharedPool,
98) -> Result<HttpResponse> {
99 let response = service::map::create(new_map_json.0, user_info.id, &pool).await?;
100 Ok(HttpResponse::Created().json(response))
101}
102
103#[utoipa::path(
108 context_path = "/api/maps",
109 request_body = UpdateMapDto,
110 responses(
111 (status = 200, description = "Update a map", body = MapDto)
112 ),
113 security(
114 ("oauth2" = [])
115 )
116)]
117#[patch("/{map_id}")]
118pub async fn update(
119 map_update_json: Json<UpdateMapDto>,
120 map_id: Path<i32>,
121 user_info: UserInfo,
122 pool: SharedPool,
123) -> Result<HttpResponse> {
124 let id = map_id.into_inner();
125 let user_id = user_info.id;
126 check_permissions(id, &pool, user_info).await?;
127 let response = service::map::update(map_update_json.0, id, user_id, &pool).await?;
128 Ok(HttpResponse::Ok().json(response))
129}
130#[utoipa::path(
135context_path = "/api/maps",
136request_body = UpdateMapDto,
137responses(
138(status = 200, description = "Update a map", body = MapDto)
139),
140security(
141("oauth2" = [])
142)
143)]
144#[patch("/{map_id}/geometry")]
145pub async fn update_geometry(
146 map_update_geometry_json: Json<UpdateMapGeometryDto>,
147 map_id: Path<i32>,
148 user_info: UserInfo,
149 pool: SharedPool,
150 broadcaster: SharedBroadcaster,
151) -> Result<HttpResponse> {
152 let map_id_inner = map_id.into_inner();
153 let user_id = user_info.id;
154 check_permissions(map_id_inner, &pool, user_info).await?;
155
156 let response = service::map::update_geometry(
157 map_update_geometry_json.0.clone(),
158 map_id_inner,
159 user_id,
160 &pool,
161 )
162 .await?;
163
164 broadcaster
165 .broadcast(
166 map_id_inner,
167 Action {
168 action_id: Uuid::new_v4(),
169 user_id,
170 action: ActionType::UpdateMapGeometry(UpdateMapGeometryActionPayload::new(
171 map_update_geometry_json.0,
172 map_id_inner,
173 )),
174 },
175 )
176 .await;
177
178 Ok(HttpResponse::Ok().json(response))
179}
180
181#[utoipa::path(
186 context_path = "/api/maps",
187 responses(
188 (status = 200, description = "Delete a map by id")
189 ),
190 security(
191 ("oauth2" = [])
192 )
193)]
194#[delete("/{map_id}")]
195pub async fn delete_by_id(
196 map_id: Path<i32>,
197 user_info: UserInfo,
198 pool: SharedPool,
199) -> Result<HttpResponse> {
200 let m_id = map_id.into_inner();
201 let user_id = user_info.id;
202 check_permissions(m_id, &pool, user_info).await?;
203 service::map::delete_by_id(m_id, user_id, &pool).await?;
204 Ok(HttpResponse::Ok().finish())
205}