shared/api/endpoints/
course.rs

1//! Endpoints for Course
2use crate::domain::course::{CourseAdminDataUpdatePath, CourseUpdateAdminDataRequest};
3use crate::{
4    api::Method,
5    domain::{
6        course::{
7            CourseBrowsePath, CourseBrowseQuery, CourseBrowseResponse, CourseClonePath,
8            CourseCreatePath, CourseCreateRequest, CourseDeletePath, CourseGetDraftPath,
9            CourseGetLivePath, CourseId, CoursePlayPath, CoursePublishPath, CourseResponse,
10            CourseSearchPath, CourseSearchQuery, CourseSearchResponse, CourseUpdateDraftDataPath,
11            CourseUpdateDraftDataRequest,
12        },
13        CreateResponse,
14    },
15    error::{EmptyError, MetadataNotFound},
16};
17
18pub mod unit;
19
20use super::ApiEndpoint;
21
22/// Create a Course and it's draft and live data copies.
23///
24/// * New Courses are all set to `PrivacyLevel::Unlisted` by default
25///
26/// # Flow:
27/// 1. Create a Course and its two data copies with [`Create`]
28/// 2. Optionally update Course info such as privacy, author with [`Update`]
29/// 3. Make updates to draft data:
30///     a. Patch Course data through [`UpdateDraftData`]
31
32/// 4. Finalize draft changes by calling [`Publish`]
33///
34/// # Authorization
35/// * TokenUser
36/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset`
37pub struct Create;
38impl ApiEndpoint for Create {
39    type Req = CourseCreateRequest;
40    type Res = CreateResponse<CourseId>;
41    type Path = CourseCreatePath;
42    type Err = MetadataNotFound;
43    const METHOD: Method = Method::Post;
44}
45
46/// Get a Course's live data by ID.
47///
48/// # Authorization
49/// * Creator ID of Course
50/// * One of `Admin`, `AdminAsset`,, or `ManageSelfAsset` for owned Courses
51///
52/// # Errors
53///
54pub struct GetLive;
55impl ApiEndpoint for GetLive {
56    type Req = ();
57    type Res = CourseResponse;
58    type Path = CourseGetLivePath;
59    type Err = EmptyError;
60    const METHOD: Method = Method::Get;
61}
62
63/// Get a Course's draft data by ID.
64///
65/// # Authorization
66/// * Creator ID of Course
67/// * One of `Admin`, `AdminAsset`,, or `ManageSelfAsset` for owned Courses
68///
69/// # Errors
70/// * [`Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
71///
72pub struct GetDraft;
73impl ApiEndpoint for GetDraft {
74    type Req = ();
75    type Res = CourseResponse;
76    type Path = CourseGetDraftPath;
77    type Err = EmptyError;
78    const METHOD: Method = Method::Get;
79}
80
81/// Update the draft data of a Course.
82///
83/// Note that a copy of the Course's draft or live data can not be fetched directly, but only as a part
84/// of one of the following routes:
85/// * [`GetLive`] fetches live copies
86/// * [`Search`]
87///
88/// See [`Course Data`](crate::domain::course::CourseData) for the over-the-wire representation.
89///
90/// # Authorization
91/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset` for owned Courses
92pub struct UpdateDraftData;
93impl ApiEndpoint for UpdateDraftData {
94    type Req = CourseUpdateDraftDataRequest;
95    type Res = ();
96    type Path = CourseUpdateDraftDataPath;
97    type Err = MetadataNotFound;
98    const METHOD: Method = Method::Patch;
99}
100
101/// Publish a Course draft to live by copying over the Coursedata.
102///
103/// # Authorization
104/// * Creator ID of Course
105/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset`
106pub struct Publish;
107impl ApiEndpoint for Publish {
108    type Req = ();
109    type Res = ();
110    type Path = CoursePublishPath;
111    type Err = EmptyError;
112    const METHOD: Method = Method::Put;
113}
114
115/// Browse Courses. Returns the draft data copies in the response.
116///
117/// # Authorization
118/// * None
119pub struct Browse;
120impl ApiEndpoint for Browse {
121    type Req = CourseBrowseQuery;
122    type Res = CourseBrowseResponse;
123    type Path = CourseBrowsePath;
124    type Err = EmptyError;
125    const METHOD: Method = Method::Get;
126}
127
128/// Search for Courses.
129///
130/// # Authorization
131/// * None
132pub struct Search;
133impl ApiEndpoint for Search {
134    type Req = CourseSearchQuery;
135    type Res = CourseSearchResponse;
136    type Path = CourseSearchPath;
137    type Err = EmptyError;
138    const METHOD: Method = Method::Get;
139}
140
141/// Delete a Course.
142///
143/// # Authorization
144/// * Creator ID of Course
145/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset` for owned Courses
146pub struct Delete;
147impl ApiEndpoint for Delete {
148    type Req = ();
149    type Res = ();
150    type Path = CourseDeletePath;
151    type Err = EmptyError;
152    const METHOD: Method = Method::Delete;
153}
154
155/// Clone a Course. This clones both the draft and live.
156///
157/// # Authorization
158/// * One of `Admin`, `AdminAsset`, or `ManageSelfAsset`
159///
160/// # Errors
161/// * [`Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
162/// * [`Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
163/// * ['NotFound'](http::StatusCode::NOT_FOUND) if the resource does not exist.
164/// * ['BadRequest'](http::StatusCode::BAD_REQUEST) if the request is malformed or the Course is a draft.
165pub struct Clone;
166impl ApiEndpoint for Clone {
167    type Path = CourseClonePath;
168    type Req = ();
169    type Res = CreateResponse<CourseId>;
170    type Err = EmptyError;
171    const METHOD: Method = Method::Post;
172}
173
174/// Add to play count for a Course
175///
176/// # Authorization
177/// * None
178pub struct Play;
179impl ApiEndpoint for Play {
180    type Req = ();
181    type Res = ();
182    type Path = CoursePlayPath;
183    type Err = EmptyError;
184    const METHOD: Method = Method::Put;
185}
186
187/// Update an admin data for a JIG.
188///
189/// # Authorization
190///
191/// * Standard + [`UserScope::AdminAsset`](crate::domain::user::UserScope)
192///
193/// # Errors
194///
195/// * [`Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
196/// * [`Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
197/// * [`BadRequest`](http::StatusCode::BAD_REQUEST) if the request is missing/invalid.
198pub struct CourseAdminDataUpdate;
199impl ApiEndpoint for CourseAdminDataUpdate {
200    type Path = CourseAdminDataUpdatePath;
201    type Req = CourseUpdateAdminDataRequest;
202    type Res = ();
203    type Err = EmptyError;
204    const METHOD: Method = Method::Patch;
205}