shared/domain/resource/
curation.rs1use chrono::{DateTime, Utc};
3use macros::make_path_parts;
4use serde::{Deserialize, Serialize};
5
6use crate::api::endpoints::PathPart;
7
8use super::{report::ResourceReport, ResourceId, UserId};
9
10wrap_uuid! {
11 pub struct CommentId
13}
14
15make_path_parts!(ResourceCurationPath => "/v1/resource/{}/curation" => ResourceId);
16
17#[derive(Serialize, Deserialize, Clone, Debug)]
19#[serde(rename_all = "camelCase")]
20pub struct ResourceCurationData {
21 pub resource_id: ResourceId,
23
24 pub fields_done: ResourceCurationFieldsDone,
26
27 pub curation_status: ResourceCurationStatus,
29
30 pub comments: Vec<ResourceCurationComment>,
32
33 pub reports: Vec<ResourceReport>,
35}
36
37#[derive(Serialize, Deserialize, Clone, Debug)]
42#[serde(rename_all = "camelCase")]
43pub struct ResourceCurationFieldsDone {
44 pub display_name: bool,
46
47 pub language: bool,
49
50 pub categories: bool,
52
53 pub description: bool,
55
56 pub age_ranges: bool,
58
59 pub affiliations: bool,
61
62 pub additional_resources: bool,
64}
65
66impl Default for ResourceCurationFieldsDone {
67 fn default() -> Self {
68 Self {
69 display_name: false,
70 language: false,
71 categories: false,
72 description: false,
73 age_ranges: false,
74 affiliations: false,
75 additional_resources: false,
76 }
77 }
78}
79
80#[derive(Serialize, Deserialize, Copy, Clone, Eq, PartialEq, Debug)]
82#[cfg_attr(feature = "backend", derive(sqlx::Type))]
83#[serde(rename_all = "camelCase")]
84#[repr(i16)]
85pub enum ResourceCurationStatus {
86 New = 0,
88
89 NewVersion = 1,
91
92 InProgress = 2,
94
95 Done = 3,
97}
98
99impl Default for ResourceCurationStatus {
100 fn default() -> Self {
101 Self::New
102 }
103}
104
105make_path_parts!(ResourceCurationUpdatePath => "/v1/resource/{}/curation" => ResourceId);
106
107#[derive(Serialize, Deserialize, Clone, Debug, Default)]
109#[serde(rename_all = "camelCase")]
110pub struct ResourceCurationUpdateRequest {
111 #[serde(default)]
113 #[serde(skip_serializing_if = "Option::is_none")]
114 pub display_name: Option<bool>,
115
116 #[serde(default)]
118 #[serde(skip_serializing_if = "Option::is_none")]
119 pub language: Option<bool>,
120
121 #[serde(default)]
123 #[serde(skip_serializing_if = "Option::is_none")]
124 pub categories: Option<bool>,
125
126 #[serde(default)]
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub description: Option<bool>,
130
131 #[serde(default)]
133 #[serde(skip_serializing_if = "Option::is_none")]
134 pub age_ranges: Option<bool>,
135
136 #[serde(default)]
138 #[serde(skip_serializing_if = "Option::is_none")]
139 pub affiliations: Option<bool>,
140
141 #[serde(default)]
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub additional_resources: Option<bool>,
145
146 #[serde(default)]
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub curation_status: Option<ResourceCurationStatus>,
150}
151
152make_path_parts!(ResourceCurationCommentCreatePath => "/v1/resource/{}/curation/comment" => ResourceId);
153
154#[derive(Serialize, Deserialize, Clone, Debug)]
156#[cfg_attr(feature = "backend", derive(sqlx::Type))]
157#[serde(rename_all = "camelCase")]
158pub struct ResourceCurationComment {
159 pub id: CommentId,
161
162 pub resource_id: ResourceId,
164
165 pub value: String,
167
168 pub created_at: DateTime<Utc>,
170
171 pub author_id: UserId,
173}
174
175#[derive(Serialize, Deserialize, Debug)]
177#[serde(rename_all = "camelCase")]
178pub struct ResourceCurationCommentRequest {
179 pub value: String,
181}
182
183make_path_parts!(ResourceCurationCommentGetPath => "/v1/resource/{}/curation/comment/{}" => ResourceId, CommentId);
184
185#[derive(Serialize, Deserialize, Debug)]
187#[serde(rename_all = "camelCase")]
188pub struct ResourceCurationCommentResponse {
189 pub id: CommentId,
191
192 pub resource_id: ResourceId,
194
195 pub value: String,
197
198 pub created_at: Option<DateTime<Utc>>,
200
201 pub author_id: UserId,
203
204 pub author_name: String,
206}