shared/api/endpoints/
jig.rs

1use crate::{
2    api::Method,
3    domain::{
4        jig::{
5            GetJigPlaylistsPath, GetJigPlaylistsResponse, JigAdminDataUpdatePath,
6            JigAdminTransferRequest, JigBrowsePath, JigBrowseQuery, JigBrowseResponse,
7            JigClonePath, JigCountPath, JigCountResponse, JigCoverPath, JigCreatePath,
8            JigCreateRequest, JigDeleteAllPath, JigDeletePath, JigFeaturedPath,
9            JigFeaturedResponse, JigFeaturedUpdateRequest, JigGetDraftPath, JigGetLivePath, JigId,
10            JigLikePath, JigLikedPath, JigLikedResponse, JigPlayPath, JigPublishPath, JigResponse,
11            JigSearchPath, JigSearchQuery, JigSearchResponse, JigTransferAdminPath,
12            JigTrendingPath, JigTrendingResponse, JigUnlikePath, JigUpdateAdminDataRequest,
13            JigUpdateDraftDataPath, JigUpdateDraftDataRequest, ListLikedPath, ListLikedRequest,
14            ListLikedResponse, ListPlayedPath, ListPlayedRequest, ListPlayedResponse,
15        },
16        CreateResponse,
17    },
18    error::{EmptyError, MetadataNotFound},
19};
20
21use super::ApiEndpoint;
22
23/// Endpoints for jig codes.
24pub mod codes;
25
26/// Endpoints for jig curation.
27pub mod curation;
28
29/// Endpoints for jig reports.
30pub mod report;
31
32/// Create a JIG and it's draft and live data copies.
33///
34/// * New jigs are all set to `PrivacyLevel::Unlisted` by default
35///
36/// # Flow:
37/// 1. Create a JIG and its two data copies with [`Create`]
38/// 2. Optionally update JIG info such as privacy, author with [`Update`]
39/// 3. Make updates to draft data:
40///     a. Patch Jig data through [`UpdateDraftData`]
41///     b. Modify modules, through [`module::Update`]
42/// 4. Finalize draft changes by calling [`Publish`]
43///
44/// # Authorization
45/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset`
46pub struct Create;
47impl ApiEndpoint for Create {
48    type Req = JigCreateRequest;
49    type Res = CreateResponse<JigId>;
50    type Path = JigCreatePath;
51    type Err = MetadataNotFound;
52    const METHOD: Method = Method::Post;
53}
54
55/// Get a JIG's live data by ID.
56///
57/// # Authorization
58/// * None
59///
60/// # Errors
61/// * [`NotFound`](http::StatusCode::NOT_FOUND) if the module does not exist, or the parent jig doesn't exist.
62pub struct GetLive;
63impl ApiEndpoint for GetLive {
64    type Req = ();
65    type Res = JigResponse;
66    type Path = JigGetLivePath;
67    type Err = EmptyError;
68    const METHOD: Method = Method::Get;
69}
70
71/// Get a JIG's draft data by ID.
72///
73/// # Authorization
74/// * One of `Admin`, `AdminAsset`,, or `ManageSelfAsset` for owned JIGs
75///
76/// # Errors
77/// * [`Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
78/// * [`NotFound`](http::StatusCode::NOT_FOUND) if the module does not exist, or the parent jig doesn't exist.
79pub struct GetDraft;
80impl ApiEndpoint for GetDraft {
81    type Req = ();
82    type Res = JigResponse;
83    type Path = JigGetDraftPath;
84    type Err = EmptyError;
85    const METHOD: Method = Method::Get;
86}
87
88/// Update the draft data of a JIG.
89///
90/// Note that a copy of the JIG's draft or live data can not be fetched directly, but only as a part
91/// of one of the following routes:
92/// * [`GetLive`] fetches live copies
93/// * [`Search`]
94///
95/// See [`JigData`](crate::domain::jig::JigData) for the over-the-wire representation.
96///
97/// # Authorization
98/// * One of `Admin`, `AdminAsset`,, or `ManageSelfAsset` for owned JIGs
99pub struct UpdateDraftData;
100impl ApiEndpoint for UpdateDraftData {
101    type Req = JigUpdateDraftDataRequest;
102    type Res = ();
103    type Path = JigUpdateDraftDataPath;
104    type Err = MetadataNotFound;
105    const METHOD: Method = Method::Patch;
106}
107
108/// Publish a JIG draft to live by copying over the JIG and module data.
109///
110/// # Authorization
111/// * None
112pub struct Publish;
113impl ApiEndpoint for Publish {
114    type Req = ();
115    type Res = ();
116    type Path = JigPublishPath;
117    type Err = EmptyError;
118    const METHOD: Method = Method::Put;
119}
120
121/// Browse JIGs. Returns the draft data copies in the response.
122///
123/// # Authorization
124/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset`
125// TODO: Think there should be a BrowseLive and a BrowseDraft endpoint.
126pub struct Browse;
127impl ApiEndpoint for Browse {
128    type Req = JigBrowseQuery;
129    type Res = JigBrowseResponse;
130    type Path = JigBrowsePath;
131    type Err = EmptyError;
132    const METHOD: Method = Method::Get;
133}
134
135/// Search for JIGs.
136///
137/// # Authorization
138/// * None
139pub struct Search;
140impl ApiEndpoint for Search {
141    type Req = JigSearchQuery;
142    type Res = JigSearchResponse;
143    type Path = JigSearchPath;
144    type Err = EmptyError;
145    const METHOD: Method = Method::Get;
146}
147
148/// Trending JIGs.
149pub struct Trending;
150impl ApiEndpoint for Trending {
151    type Req = ();
152    type Res = JigTrendingResponse;
153    type Path = JigTrendingPath;
154    type Err = EmptyError;
155    const METHOD: Method = Method::Get;
156}
157
158/// List user's liked JIGs.
159pub struct ListLiked;
160impl ApiEndpoint for ListLiked {
161    type Req = ListLikedRequest;
162    type Res = ListLikedResponse;
163    type Path = ListLikedPath;
164    type Err = EmptyError;
165    const METHOD: Method = Method::Get;
166}
167
168/// List user's played JIGs.
169pub struct ListPlayed;
170impl ApiEndpoint for ListPlayed {
171    type Req = ListPlayedRequest;
172    type Res = ListPlayedResponse;
173    type Path = ListPlayedPath;
174    type Err = EmptyError;
175    const METHOD: Method = Method::Get;
176}
177
178/// Featured JIGs.
179pub struct Featured;
180impl ApiEndpoint for Featured {
181    type Req = ();
182    type Res = JigFeaturedResponse;
183    type Path = JigFeaturedPath;
184    type Err = EmptyError;
185    const METHOD: Method = Method::Get;
186}
187
188/// Update featured JIGs.
189pub struct FeaturedUpdate;
190impl ApiEndpoint for FeaturedUpdate {
191    type Req = JigFeaturedUpdateRequest;
192    type Res = ();
193    type Path = JigFeaturedPath;
194    type Err = EmptyError;
195    const METHOD: Method = Method::Put;
196}
197
198/// Clone a JIG. This clones both the draft and live.
199///
200/// # Authorization
201/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset`
202///
203/// # Errors
204/// * [`Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
205/// * [`Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
206/// * ['NotFound'](http::StatusCode::NOT_FOUND) if the jig does not exist.
207/// * ['BadRequest'](http::StatusCode::BAD_REQUEST) if the request is malformed or the JIG is a draft.
208pub struct Clone;
209impl ApiEndpoint for Clone {
210    type Req = ();
211    type Res = CreateResponse<JigId>;
212    type Path = JigClonePath;
213    type Err = EmptyError;
214    const METHOD: Method = Method::Post;
215}
216
217/// Delete a JIG.
218///
219/// # Authorization
220/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset` for owned JIGs
221pub struct Delete;
222impl ApiEndpoint for Delete {
223    type Req = ();
224    type Res = ();
225    type Path = JigDeletePath;
226    type Err = EmptyError;
227    const METHOD: Method = Method::Delete;
228}
229
230/// Delete all jigs associated with current user.
231///
232/// # Authorization
233/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset` for owned JIGs
234pub struct DeleteAll;
235impl ApiEndpoint for DeleteAll {
236    type Req = ();
237    type Res = ();
238    type Path = JigDeleteAllPath;
239    type Err = EmptyError;
240    const METHOD: Method = Method::Delete;
241}
242
243/// Indicates that a jig has a cover
244///
245/// # Authorization
246/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset` for owned JIGs
247pub struct Cover;
248impl ApiEndpoint for Cover {
249    type Req = ();
250    type Res = ();
251    type Path = JigCoverPath;
252    type Err = EmptyError;
253    const METHOD: Method = Method::Patch;
254}
255
256/// Count of all public JIGs. See [`PrivacyLevel`](crate::domain::jig::PrivacyLevel).
257///
258/// # Authorization
259/// * None
260pub struct Count;
261impl ApiEndpoint for Count {
262    type Req = ();
263    type Res = JigCountResponse;
264    type Path = JigCountPath;
265    type Err = EmptyError;
266    const METHOD: Method = Method::Get;
267}
268
269/// Like a JIG
270///
271/// # Authorization
272/// * Admin, BasicAuth
273pub struct Like;
274impl ApiEndpoint for Like {
275    type Req = ();
276    type Res = ();
277    type Path = JigLikePath;
278    type Err = EmptyError;
279    const METHOD: Method = Method::Put;
280}
281
282/// Unlike a JIG
283///
284/// # Authorization
285/// * Admin, BasicAuth
286pub struct Unlike;
287impl ApiEndpoint for Unlike {
288    type Req = ();
289    type Res = ();
290    type Path = JigUnlikePath;
291    type Err = EmptyError;
292    const METHOD: Method = Method::Delete;
293}
294
295/// Is a JIG liked by a user
296///
297/// # Authorization
298/// * Admin, BasicAuth
299pub struct Liked;
300impl ApiEndpoint for Liked {
301    type Req = ();
302    type Res = JigLikedResponse;
303    type Path = JigLikedPath;
304    type Err = EmptyError;
305    const METHOD: Method = Method::Get;
306}
307
308/// Play a JIG
309///
310/// # Authorization
311/// * None
312pub struct Play;
313impl ApiEndpoint for Play {
314    type Req = ();
315    type Res = ();
316    type Path = JigPlayPath;
317    type Err = EmptyError;
318    const METHOD: Method = Method::Put;
319}
320
321/// Update an admin data for a JIG.
322///
323/// # Authorization
324///
325/// * Standard + [`UserScope::ManageJig`](crate::domain::user::UserScope)
326///
327/// # Errors
328///
329/// * [`Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
330/// * [`Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
331/// * [`BadRequest`](http::StatusCode::BAD_REQUEST) if the request is missing/invalid.
332pub struct JigAdminDataUpdate;
333impl ApiEndpoint for JigAdminDataUpdate {
334    type Req = JigUpdateAdminDataRequest;
335    type Res = ();
336    type Path = JigAdminDataUpdatePath;
337    type Err = EmptyError;
338    const METHOD: Method = Method::Patch;
339}
340
341/// Update an admin data for a JIG.
342///
343/// # Authorization
344///
345/// * Standard + [`UserScope::ManageJig`](crate::domain::user::UserScope)
346///
347/// # Errors
348///
349/// * [`Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
350/// * [`Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
351/// * [`BadRequest`](http::StatusCode::BAD_REQUEST) if the request is missing/invalid.
352pub struct JigAdminTransfer;
353impl ApiEndpoint for JigAdminTransfer {
354    type Req = JigAdminTransferRequest;
355    type Res = ();
356    type Path = JigTransferAdminPath;
357    type Err = EmptyError;
358    const METHOD: Method = Method::Post;
359}
360
361/// Remove resource from jigs algolia
362///
363/// # NOTE
364/// * remove after resources are separated
365///
366/// # Authorization
367/// * Admin
368pub struct RemoveResource;
369impl ApiEndpoint for RemoveResource {
370    type Path = RemoveResourcePath;
371    type Req = ();
372    type Res = ();
373    type Err = EmptyError;
374    const METHOD: Method = Method::Delete;
375}
376use crate::api::endpoints::PathPart;
377macros::make_path_parts!(RemoveResourcePath => "/v1/jig/{}/resources" => JigId);
378
379/// Playlists containing JIG id
380///
381/// # Authorization
382/// * Standard + [`UserScope::ManageJig`](crate::domain::user::UserScope)
383///
384pub struct GetJigPlaylists;
385impl ApiEndpoint for GetJigPlaylists {
386    type Req = ();
387    type Res = GetJigPlaylistsResponse;
388    type Path = GetJigPlaylistsPath;
389    type Err = EmptyError;
390    const METHOD: Method = Method::Get;
391}