shared/api/endpoints/jig/
codes.rs

1use crate::{
2    api::{ApiEndpoint, Method},
3    domain::jig::codes::{
4        JigCodeListPath, JigCodeListRequest, JigCodeListResponse, JigCodePath, JigCodeResponse,
5        JigCodeSessionsListResponse, JigCodeSessionsPath, JigCodeUpdateRequest,
6        JigPlayerSessionCreatePath, JigPlayerSessionCreateRequest, JigPlayerSessionCreateResponse,
7        JigsWithCodesPath, JigsWithCodesResponse,
8    },
9    error::EmptyError,
10};
11
12/// TODO: update these docs. Out of date.
13/// Create a player session from a jig. Requestor needs permissions over the jig.
14///
15/// # Flow
16///
17/// 1. Author/admin creates a player session using [`POST /v1/jig/player`](Create)
18///     * This is represented by a *session code/index*
19/// 2. Unauthed user instantiates the player session. This creates an instance of a session. [`POST /v1/jig/player/session`](instance::Create) returns:
20///     * A short lived token, which identifies the guest user and the session instance.
21///     * The player session settings.
22///     * `JigId` of the JIG on which the session was created.
23/// 3. Unauthed user posts short lived token to complete the instance. [`POST /v1/jig/player/session/complete`](instance::Complete)
24///     * This increments the play count of the jig.
25///     * Deletes the completed instance from the DB.
26///
27/// The hierarchy here is Jig -> Player Session -> Session Instance, where each arrow is a one-to-many mapping.
28///
29/// Each level is uniquely identified by `JigId` -> `JigCode` -> token.
30///
31/// # Errors
32///
33/// * [`400 - BadRequest`](http::StatusCode::BAD_REQUEST) if the request is malformed.
34/// * [`401 - Unauthorized`](http::StatusCode::UNAUTHORIZED) if authorization is not valid.
35/// * [`403 - Forbidden`](http::StatusCode::FORBIDDEN) if the user does not have sufficient permission to perform the action.
36/// * ['404 - NotFound'](http::StatusCode::NOT_FOUND) if the jig does not exist.
37/// * ['409 - Conflict'](http::StatusCode::CONFLICT) if a code already exists for this jig.
38/// * [`503 - ServiceUnavailable`](http::StatusCode::SERVICE_UNAVAILABLE) if some how we have reached the maximum number of possible session codes.
39///
40/// # Note
41///
42/// The code is computed with the following procedure:
43///
44/// 1. Generate a random code in the range 0..MAX
45pub struct Create;
46impl ApiEndpoint for Create {
47    type Path = JigPlayerSessionCreatePath;
48    type Req = JigPlayerSessionCreateRequest;
49    type Res = JigPlayerSessionCreateResponse;
50    type Err = EmptyError;
51    const METHOD: Method = Method::Post;
52}
53
54/// update a code
55pub struct Update;
56impl ApiEndpoint for Update {
57    type Path = JigCodePath;
58    type Req = JigCodeUpdateRequest;
59    type Res = ();
60    type Err = EmptyError;
61    const METHOD: Method = Method::Patch;
62}
63
64/// List codes creator by user.
65pub struct GetJigCode;
66impl ApiEndpoint for GetJigCode {
67    type Path = JigCodePath;
68    type Req = ();
69    type Res = JigCodeResponse;
70    type Err = EmptyError;
71    const METHOD: Method = Method::Get;
72}
73
74/// List codes creator by user.
75pub struct JigCodeList;
76impl ApiEndpoint for JigCodeList {
77    type Path = JigCodeListPath;
78    type Req = JigCodeListRequest;
79    type Res = JigCodeListResponse;
80    type Err = EmptyError;
81    const METHOD: Method = Method::Get;
82}
83
84/// List codes creator by user.
85pub struct JigsWithCodes;
86impl ApiEndpoint for JigsWithCodes {
87    type Path = JigsWithCodesPath;
88    type Req = ();
89    type Res = JigsWithCodesResponse;
90    type Err = EmptyError;
91    const METHOD: Method = Method::Get;
92}
93
94/// list sessions of code
95pub struct JigCodeSessions;
96impl ApiEndpoint for JigCodeSessions {
97    type Path = JigCodeSessionsPath;
98    type Req = ();
99    type Res = JigCodeSessionsListResponse;
100    type Err = EmptyError;
101    const METHOD: Method = Method::Get;
102}
103
104/// Endpoints for unauthed users to access jig player sessions.
105pub mod instance {
106    use crate::{
107        api::{ApiEndpoint, Method},
108        domain::jig::codes::instance::{
109            PlayerSessionInstanceCompletePath, PlayerSessionInstanceCompleteRequest,
110            PlayerSessionInstanceCreatePath, PlayerSessionInstanceCreateRequest,
111            PlayerSessionInstanceResponse,
112        },
113        error::EmptyError,
114    };
115
116    /// Create a session instance
117    ///
118    /// # Auth
119    /// * No auth
120    /// * Returns a token that needs to be cached. See #Flow section under [`player::Create`](super::Create)
121    ///
122    /// # Errors
123    ///
124    /// * [`400 - BadRequest`](http::StatusCode::BAD_REQUEST) if the request is malformed.
125    /// * ['404 - NotFound'](http::StatusCode::NOT_FOUND) if the jig player session does not exist.
126    pub struct Create;
127    impl ApiEndpoint for Create {
128        type Path = PlayerSessionInstanceCreatePath;
129        type Req = PlayerSessionInstanceCreateRequest;
130        type Res = PlayerSessionInstanceResponse;
131        type Err = EmptyError;
132        const METHOD: Method = Method::Post;
133    }
134
135    /// Complete a session instance and update the jig play count
136    ///
137    /// # Auth
138    /// * Requires the token returned in [`Create`](Create)
139    ///
140    /// # Errors
141    ///
142    /// * [`400 - BadRequest`](http::StatusCode::BAD_REQUEST) if the request is malformed.
143    /// * ['404 - NotFound'](http::StatusCode::NOT_FOUND) if the jig player session instance stored in the token does not exist.
144    pub struct Complete;
145    impl ApiEndpoint for Complete {
146        type Path = PlayerSessionInstanceCompletePath;
147        type Req = PlayerSessionInstanceCompleteRequest;
148        type Res = ();
149        type Err = EmptyError;
150        const METHOD: Method = Method::Post;
151    }
152}