shared/api/endpoints/image/user.rs
1//! Routes for the user image library
2
3use crate::{
4 api::{ApiEndpoint, Method},
5 domain::{
6 image::{
7 user::{
8 UserImageCreatePath, UserImageCreateRequest, UserImageDeletePath, UserImageGetPath,
9 UserImageListPath, UserImageListQuery, UserImageListResponse, UserImageResponse,
10 UserImageUploadPath, UserImageUploadRequest, UserImageUploadResponse,
11 },
12 ImageId,
13 },
14 CreateResponse,
15 },
16 error::EmptyError,
17};
18
19/// List user library images.
20///
21/// # Notes
22/// * Request includes an optional query, called as a query string.
23pub struct List;
24impl ApiEndpoint for List {
25 type Path = UserImageListPath;
26 type Req = UserImageListQuery;
27 type Res = UserImageListResponse;
28 type Err = EmptyError;
29 const METHOD: Method = Method::Get;
30}
31
32/// Get an user library image by ID.
33///
34/// # Errors
35/// * [`NotFound`](http::StatusCode::NOT_FOUND) if the image with the requested ID is not found for the user.
36/// Note that it will still return NOT_FOUND if an user image with the ID exists but is not owner by the
37/// requesting user.
38/// * TODO other errors here...
39pub struct Get;
40impl ApiEndpoint for Get {
41 type Path = UserImageGetPath;
42 type Req = ();
43 type Res = UserImageResponse;
44 type Err = EmptyError;
45 const METHOD: Method = Method::Get;
46}
47
48/// Create an user library image.
49pub struct Create;
50impl ApiEndpoint for Create {
51 type Path = UserImageCreatePath;
52 type Req = UserImageCreateRequest;
53 type Res = CreateResponse<ImageId>;
54 type Err = EmptyError;
55 const METHOD: Method = Method::Post;
56}
57
58/// Upload an image to the user image library.
59/// # Flow:
60///
61/// 1. User requests an upload session URI directly to Google Cloud Storage
62/// a. User uploads to processing bucket
63/// 2. Firestore is notified of `processing = true, ready = false` status at document `uploads/media/user/{id}`
64/// 3. Animation is processed and uploaded to the final bucket
65/// 4. Firestore is notified of `processing = true, ready = true` status at document `uploads/media/user/{id}`
66///
67/// # Notes:
68///
69/// * Can be used to update the raw data associated with the image.
70/// * If the client wants to re-upload an image after it has been successfully processed, it must repeat
71/// the entire flow instead of uploading to the same session URI.
72///
73/// # Errors:
74///
75/// * [`401 - Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
76/// * [`403 - Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
77/// * [`501 - NotImplemented`](http::StatusCode::NOT_IMPLEMENTED) when the s3/gcs service is disabled.
78pub struct Upload;
79impl ApiEndpoint for Upload {
80 type Path = UserImageUploadPath;
81 // raw bytes
82 type Req = UserImageUploadRequest;
83 type Res = UserImageUploadResponse;
84 type Err = EmptyError;
85 const METHOD: Method = Method::Put;
86}
87
88/// Delete an image from the user library.
89///
90/// # Errors
91/// * [`NotFound`](http::StatusCode::NOT_FOUND) if the image with the requested ID is not found for the user.
92/// Note that it will still return NOT_FOUND if an user image with the ID exists but is not owner by the
93/// requesting user.
94/// * TODO other errors here...
95pub struct Delete;
96impl ApiEndpoint for Delete {
97 type Path = UserImageDeletePath;
98 type Req = ();
99 type Res = ();
100 type Err = EmptyError;
101 const METHOD: Method = Method::Delete;
102}