diff --git a/openapi.json b/openapi.json index 40153c1..b7c62d7 100644 --- a/openapi.json +++ b/openapi.json @@ -577,61 +577,17 @@ } } }, - "/integrations/geo-points-svc/v1/public/event_types": { + "/integrations/geo-points-svc/v1/public/daily_questions/{nullifier}": { "get": { "tags": [ - "Event types" + "Daily Questions" ], - "summary": "List event types", - "description": "Returns public configuration of all event types.\nBasically, it is event static metadata (model `EventStaticMeta`)\nfor each event type in the system.\n", - "operationId": "getEventTypes", - "parameters": [ - { - "$ref": "#/components/parameters/headerLang" - }, - { - "in": "query", - "name": "filter[name]", - "description": "Filter by type name. Possible values should be hard-coded in the client.", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "example": "passport_scan" - } - } - }, - { - "in": "query", - "name": "filter[name][not]", - "description": "Inverted filter by type name: excludes provided values\n", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "example": "referral_specific" - } - } - }, + "summary": "Get daily question", + "description": "Get a daily question. The user must be \nauthorized and verified (passport scanned, \nverified field is true).\n", + "operationId": "getDailyQuestion", + "security": [ { - "in": "query", - "name": "filter[flag]", - "description": "Filter by configuration flags. Values are disjunctive (OR).", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "active", - "not_started", - "expired", - "disabled" - ] - } - } + "BearerAuth": [] } ], "responses": { @@ -646,16 +602,49 @@ ], "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EventType" - } + "$ref": "#/components/schemas/DailyQuestions" } } } } } }, + "400": { + "$ref": "#/components/responses/invalidParameter" + }, + "401": { + "$ref": "#/components/responses/invalidAuth" + }, + "403": { + "description": "Questions unavailable, try later", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, + "404": { + "description": "There is no question in current day.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, + "409": { + "description": "User already answer current day question.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, "500": { "$ref": "#/components/responses/internalError" } @@ -663,13 +652,17 @@ }, "post": { "tags": [ - "Event types" + "Daily Questions" + ], + "summary": "Answer question", + "description": "Answer question. The user must be \nauthorized and verified (passport scanned, \nverified field is true).\n", + "operationId": "answerDailyQuestion", + "security": [ + { + "BearerAuth": [] + } ], - "summary": "Create event type", - "description": "Creates a new event type. Requires **admin** role in JWT.\nThe type must not be present in the system.\n", - "operationId": "createEventType", "requestBody": { - "required": true, "content": { "application/vnd.api+json": { "schema": { @@ -679,7 +672,7 @@ ], "properties": { "data": { - "$ref": "#/components/schemas/EventType" + "$ref": "#/components/schemas/DailyQuestionAnswers" } } } @@ -687,8 +680,23 @@ } }, "responses": { - "204": { - "description": "No content" + "200": { + "description": "Success", + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/DailyQuestionAnswers" + } + } + } + } + } }, "400": { "$ref": "#/components/responses/invalidParameter" @@ -696,8 +704,8 @@ "401": { "$ref": "#/components/responses/invalidAuth" }, - "409": { - "description": "Event type already exists", + "404": { + "description": "User haven't active question or deadline already passed.", "content": { "application/vnd.api+json": { "schema": { @@ -712,26 +720,17 @@ } } }, - "/integrations/geo-points-svc/v1/public/event_types/{name}": { + "/integrations/geo-points-svc/v1/public/daily_questions/{nullifier}/status": { "get": { "tags": [ - "Event types" + "Daily Questions" ], - "summary": "Get event type", - "description": "Returns public configuration of event type by its unique name", - "operationId": "getEventType", - "parameters": [ - { - "$ref": "#/components/parameters/headerLang" - }, + "summary": "Daily question status", + "description": "Get the status of questions. The user must be \nauthorized and verified (passport scanned, \nverified field is true). \nReturns NotFound if next question absent.\n", + "operationId": "dailyQuestionsStatus", + "security": [ { - "in": "path", - "name": "name", - "required": true, - "schema": { - "type": "string", - "example": "meetup_participation" - } + "BearerAuth": [] } ], "responses": { @@ -746,47 +745,46 @@ ], "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EventType" - } + "$ref": "#/components/schemas/DailyQuestionsStatus" } } } } } }, + "401": { + "$ref": "#/components/responses/invalidAuth" + }, "404": { - "$ref": "#/components/responses/notFound" + "description": "Next question not exist.", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } }, "500": { "$ref": "#/components/responses/internalError" } } - }, - "put": { + } + }, + "/integrations/geo-points-svc/v1/public/daily_questions/admin": { + "post": { "tags": [ - "Event types" + "Daily Questions" ], - "summary": "Update event type", - "description": "Update an existing event type. Requires **admin** role in JWT.\n**All attributes** except QR code, Poll Event ID and Poll Contract are\nupdated, ensure to pass every existing field too.\nAlthough this is not JSON:API compliant, it is much easier to work with\nin Go, because differentiating between `{}` and `{\"field\": null}`\nrequires custom unmarshalling implementation.\n", - "operationId": "updateEventType", - "parameters": [ - { - "$ref": "#/components/parameters/headerLang" - }, + "summary": "Create daily question", + "description": "Create Daily Question user must be superuser\n", + "operationId": "createDailyQuestion", + "security": [ { - "in": "path", - "name": "name", - "required": true, - "schema": { - "type": "string", - "example": "meetup_participation" - } + "BearerAuth": [] } ], "requestBody": { - "required": true, "content": { "application/vnd.api+json": { "schema": { @@ -796,7 +794,7 @@ ], "properties": { "data": { - "$ref": "#/components/schemas/EventType" + "$ref": "#/components/schemas/DailyQuestionCreate" } } } @@ -815,10 +813,7 @@ ], "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EventType" - } + "$ref": "#/components/schemas/DailyQuestionDetails" } } } @@ -831,77 +826,82 @@ "401": { "$ref": "#/components/responses/invalidAuth" }, - "404": { - "$ref": "#/components/responses/notFound" + "403": { + "description": "Correct answer option outside the range of answer options", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, + "409": { + "description": "On this day, the daily question already exists", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } }, "500": { "$ref": "#/components/responses/internalError" } } - } - }, - "/integrations/geo-points-svc/v1/public/event_types/qr": { + }, "get": { "tags": [ - "Event types" + "Daily Questions" ], - "summary": "List QR event types", - "description": "Returns configuration of all event types with QR-code.\nBasically, it is event static metadata (model `EventStaticMeta`)\nfor each event type in the system.\nRequires **admin** role in JWT.\n", - "operationId": "getQREventTypes", - "parameters": [ - { - "in": "query", - "name": "count", - "description": "Іpecifies whether to return the number of uses of the event", - "required": false, - "schema": { - "type": "bool", - "example": true - } - }, + "summary": "Filter Daily Question by start", + "description": "Filtering of daily questions by their activation time\n", + "operationId": "filterStartAtDailyQuestion", + "security": [ { - "in": "query", - "name": "filter[name]", - "description": "Filter by type name. Possible values should be hard-coded in the client.", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "example": "passport_scan" - } - } - }, - { - "in": "query", - "name": "filter[name][not]", - "description": "Inverted filter by type name: excludes provided values\n", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "example": "referral_specific" + "BearerAuth": [] + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DailyQuestionDetails" + } + } + } + } } } }, + "500": { + "$ref": "#/components/responses/internalError" + } + } + } + }, + "/integrations/geo-points-svc/v1/public/daily_questions/admin/{question_id}": { + "delete": { + "tags": [ + "Daily Questions" + ], + "summary": "Delete daily question", + "description": "Delete Daily Question user must be superuser\n", + "operationId": "deleteDailyQuestion", + "security": [ { - "in": "query", - "name": "filter[flag]", - "description": "Filter by configuration flags. Values are disjunctive (OR).", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "active", - "not_started", - "expired", - "disabled" - ] - } - } + "BearerAuth": [] } ], "responses": { @@ -916,30 +916,47 @@ ], "properties": { "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EventType" - } + "$ref": "#/components/schemas/DailyQuestionDetails" } } } } } }, + "204": { + "description": "No content" + }, + "400": { + "$ref": "#/components/responses/invalidParameter" + }, + "404": { + "description": "Question with ID not found", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, "500": { "$ref": "#/components/responses/internalError" } } }, - "post": { + "patch": { "tags": [ - "Event types" + "Daily Questions" + ], + "summary": "Edit daily question", + "description": "Edit Daily Question user must be superuser\n", + "operationId": "editDailyQuestion", + "security": [ + { + "BearerAuth": [] + } ], - "summary": "Create event type", - "description": "Creates a new event type. Requires **admin** role in JWT.\nThe type must not be present in the system.\n", - "operationId": "createEventType", "requestBody": { - "required": true, "content": { "application/vnd.api+json": { "schema": { @@ -949,7 +966,7 @@ ], "properties": { "data": { - "$ref": "#/components/schemas/EventType" + "$ref": "#/components/schemas/DailyQuestionEdit" } } } @@ -957,17 +974,42 @@ } }, "responses": { + "200": { + "description": "Success", + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/DailyQuestionDetails" + } + } + } + } + } + }, "204": { "description": "No content" }, "400": { "$ref": "#/components/responses/invalidParameter" }, - "401": { - "$ref": "#/components/responses/invalidAuth" + "403": { + "description": "Correct answer option outside the range of answer options", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } }, "409": { - "description": "Event type already exists", + "description": "On this day, the daily question already exists", "content": { "application/vnd.api+json": { "schema": { @@ -982,91 +1024,61 @@ } } }, - "/integrations/geo-points-svc/v1/public/events": { + "/integrations/geo-points-svc/v1/public/event_types": { "get": { "tags": [ - "Events" + "Event types" ], - "summary": "List events", - "description": "Returns events for a single user.", - "operationId": "getEvents", + "summary": "List event types", + "description": "Returns public configuration of all event types.\nBasically, it is event static metadata (model `EventStaticMeta`)\nfor each event type in the system.\n", + "operationId": "getEventTypes", "parameters": [ - { - "$ref": "#/components/parameters/filterNullifier" - }, { "$ref": "#/components/parameters/headerLang" }, { "in": "query", - "name": "filter[status]", - "description": "Filter by event status, which is:\n - `open` - you need to do something on the platform\n - `fulfilled` - you have done something and are eligible to claim the reward\n - `claimed` - you have claimed the reward\n", + "name": "filter[name]", + "description": "Filter by type name. Possible values should be hard-coded in the client.", "required": false, "schema": { "type": "array", "items": { "type": "string", - "enum": [ - "open", - "fulfilled", - "claimed" - ] + "example": "passport_scan" } } }, { "in": "query", - "name": "filter[meta.static.name]", - "description": "Filter by event type name. Possible values should be hard-coded in the client.", + "name": "filter[name][not]", + "description": "Inverted filter by type name: excludes provided values\n", "required": false, "schema": { "type": "array", "items": { "type": "string", - "example": "passport_scan" + "example": "referral_specific" } } }, { "in": "query", - "name": "filter[meta.static.name][not]", - "description": "Inverted filter by event type name: excludes provided values\n", + "name": "filter[flag]", + "description": "Filter by configuration flags. Values are disjunctive (OR).", "required": false, "schema": { "type": "array", "items": { "type": "string", - "example": "referral_specific" + "enum": [ + "active", + "not_started", + "expired", + "disabled" + ] } } - }, - { - "in": "query", - "name": "filter[has_expiration]", - "description": "Filter events by type which has or hasn't expiration.", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "in": "query", - "name": "count", - "description": "Count total number of events for a single user, applying filters.", - "required": false, - "schema": { - "type": "boolean", - "example": true - } - }, - { - "$ref": "#/components/parameters/pageLimit" - }, - { - "$ref": "#/components/parameters/pageNumber" - }, - { - "$ref": "#/components/parameters/pageOrder" } ], "responses": { @@ -1083,20 +1095,7 @@ "data": { "type": "array", "items": { - "$ref": "#/components/schemas/Event" - } - }, - "meta": { - "type": "object", - "required": [ - "events_count" - ], - "properties": { - "events_count": { - "type": "integer", - "description": "Appears when `count=true` is specified", - "example": 18 - } + "$ref": "#/components/schemas/EventType" } } } @@ -1104,37 +1103,81 @@ } } }, + "500": { + "$ref": "#/components/responses/internalError" + } + } + }, + "post": { + "tags": [ + "Event types" + ], + "summary": "Create event type", + "description": "Creates a new event type. Requires **admin** role in JWT.\nThe type must not be present in the system.\n", + "operationId": "createEventType", + "requestBody": { + "required": true, + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/EventType" + } + } + } + } + } + }, + "responses": { + "204": { + "description": "No content" + }, "400": { "$ref": "#/components/responses/invalidParameter" }, "401": { "$ref": "#/components/responses/invalidAuth" }, + "409": { + "description": "Event type already exists", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, "500": { "$ref": "#/components/responses/internalError" } } } }, - "/integrations/geo-points-svc/v1/public/events/{id}": { + "/integrations/geo-points-svc/v1/public/event_types/{name}": { "get": { "tags": [ - "Events" + "Event types" ], - "summary": "Get event", - "description": "Returns a single event by ID.", - "operationId": "getEvent", + "summary": "Get event type", + "description": "Returns public configuration of event type by its unique name", + "operationId": "getEventType", "parameters": [ { "$ref": "#/components/parameters/headerLang" }, { "in": "path", - "name": "id", + "name": "name", "required": true, "schema": { "type": "string", - "example": "059c81dd-2a54-44a8-8142-c15ad8f88949" + "example": "meetup_participation" } } ], @@ -1150,19 +1193,16 @@ ], "properties": { "data": { - "$ref": "#/components/schemas/Event" + "type": "array", + "items": { + "$ref": "#/components/schemas/EventType" + } } } } } } }, - "400": { - "$ref": "#/components/responses/invalidParameter" - }, - "401": { - "$ref": "#/components/responses/invalidAuth" - }, "404": { "$ref": "#/components/responses/notFound" }, @@ -1171,24 +1211,24 @@ } } }, - "patch": { + "put": { "tags": [ - "Events" + "Event types" ], - "summary": "Claim points for event", - "description": "Update event status to _claimed_ and accrue points.\nUser must be authorized, and event must be _fulfilled_ by him.\n", - "operationId": "claimEvent", - "parameters": [ - { + "summary": "Update event type", + "description": "Update an existing event type. Requires **admin** role in JWT.\n**All attributes** except QR code, Poll Event ID and Poll Contract are\nupdated, ensure to pass every existing field too.\nAlthough this is not JSON:API compliant, it is much easier to work with\nin Go, because differentiating between `{}` and `{\"field\": null}`\nrequires custom unmarshalling implementation.\n", + "operationId": "updateEventType", + "parameters": [ + { "$ref": "#/components/parameters/headerLang" }, { "in": "path", - "name": "id", + "name": "name", "required": true, "schema": { "type": "string", - "example": "059c81dd-2a54-44a8-8142-c15ad8f88949" + "example": "meetup_participation" } } ], @@ -1203,7 +1243,7 @@ ], "properties": { "data": { - "$ref": "#/components/schemas/ClaimEventKey" + "$ref": "#/components/schemas/EventType" } } } @@ -1212,23 +1252,19 @@ }, "responses": { "200": { - "description": "Event claimed, points accrued", + "description": "Success", "content": { "application/vnd.api+json": { "schema": { "type": "object", "required": [ - "data", - "included" + "data" ], "properties": { "data": { - "$ref": "#/components/schemas/Event" - }, - "included": { "type": "array", "items": { - "$ref": "#/components/schemas/Balance" + "$ref": "#/components/schemas/EventType" } } } @@ -1242,16 +1278,6 @@ "401": { "$ref": "#/components/responses/invalidAuth" }, - "403": { - "description": "This event type was disabled and cannot be claimed", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/Errors" - } - } - } - }, "404": { "$ref": "#/components/responses/notFound" }, @@ -1261,43 +1287,70 @@ } } }, - "/integrations/geo-points-svc/v1/public/events/{id}/qrcode": { - "patch": { + "/integrations/geo-points-svc/v1/public/event_types/qr": { + "get": { "tags": [ - "Events" + "Event types" ], - "summary": "Fulfill QR code event", - "description": "Fulfill QR code event", - "operationId": "fulfillQREvent", + "summary": "List QR event types", + "description": "Returns configuration of all event types with QR-code.\nBasically, it is event static metadata (model `EventStaticMeta`)\nfor each event type in the system.\nRequires **admin** role in JWT.\n", + "operationId": "getQREventTypes", "parameters": [ { - "in": "path", - "name": "id", - "required": true, + "in": "query", + "name": "count", + "description": "Іpecifies whether to return the number of uses of the event", + "required": false, "schema": { - "type": "string", - "example": "059c81dd-2a54-44a8-8142-c15ad8f88949" + "type": "bool", + "example": true } - } - ], - "requestBody": { - "required": true, - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "$ref": "#/components/schemas/FulfillQREvent" - } - } + }, + { + "in": "query", + "name": "filter[name]", + "description": "Filter by type name. Possible values should be hard-coded in the client.", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "example": "passport_scan" + } + } + }, + { + "in": "query", + "name": "filter[name][not]", + "description": "Inverted filter by type name: excludes provided values\n", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "example": "referral_specific" + } + } + }, + { + "in": "query", + "name": "filter[flag]", + "description": "Filter by configuration flags. Values are disjunctive (OR).", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "active", + "not_started", + "expired", + "disabled" + ] } } } - }, + ], "responses": { "200": { "description": "Success", @@ -1310,51 +1363,28 @@ ], "properties": { "data": { - "$ref": "#/components/schemas/EventClaimingState" + "type": "array", + "items": { + "$ref": "#/components/schemas/EventType" + } } } } } } }, - "400": { - "$ref": "#/components/responses/invalidParameter" - }, - "401": { - "$ref": "#/components/responses/invalidAuth" - }, - "403": { - "description": "This event type was disabled and cannot be fulfilled", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/Errors" - } - } - } - }, - "404": { - "$ref": "#/components/responses/notFound" - }, "500": { "$ref": "#/components/responses/internalError" } } - } - }, - "/integrations/geo-points-svc/v1/public/events/poll": { + }, "post": { "tags": [ - "Events" - ], - "summary": "Fulfill poll event", - "description": "Fulfill event for voting in Georgian poll by sending proof of voting", - "operationId": "fulfillPollEvent", - "security": [ - { - "BearerAuth": [] - } + "Event types" ], + "summary": "Create event type", + "description": "Creates a new event type. Requires **admin** role in JWT.\nThe type must not be present in the system.\n", + "operationId": "createEventType", "requestBody": { "required": true, "content": { @@ -1366,7 +1396,7 @@ ], "properties": { "data": { - "$ref": "#/components/schemas/FulfillPollEvent" + "$ref": "#/components/schemas/EventType" } } } @@ -1374,23 +1404,8 @@ } }, "responses": { - "200": { - "description": "Success", - "content": { - "application/vnd.api+json": { - "schema": { - "type": "object", - "required": [ - "data" - ], - "properties": { - "data": { - "$ref": "#/components/schemas/EventClaimingState" - } - } - } - } - } + "204": { + "description": "No content" }, "400": { "$ref": "#/components/responses/invalidParameter" @@ -1398,8 +1413,8 @@ "401": { "$ref": "#/components/responses/invalidAuth" }, - "403": { - "description": "This event type was disabled and cannot be fulfilled", + "409": { + "description": "Event type already exists", "content": { "application/vnd.api+json": { "schema": { @@ -1408,36 +1423,807 @@ } } }, - "404": { - "$ref": "#/components/responses/notFound" + "500": { + "$ref": "#/components/responses/internalError" + } + } + } + }, + "/integrations/geo-points-svc/v1/public/events": { + "get": { + "tags": [ + "Events" + ], + "summary": "List events", + "description": "Returns events for a single user.", + "operationId": "getEvents", + "parameters": [ + { + "$ref": "#/components/parameters/filterNullifier" + }, + { + "$ref": "#/components/parameters/headerLang" + }, + { + "in": "query", + "name": "filter[status]", + "description": "Filter by event status, which is:\n - `open` - you need to do something on the platform\n - `fulfilled` - you have done something and are eligible to claim the reward\n - `claimed` - you have claimed the reward\n", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "open", + "fulfilled", + "claimed" + ] + } + } + }, + { + "in": "query", + "name": "filter[meta.static.name]", + "description": "Filter by event type name. Possible values should be hard-coded in the client.", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "example": "passport_scan" + } + } + }, + { + "in": "query", + "name": "filter[meta.static.name][not]", + "description": "Inverted filter by event type name: excludes provided values\n", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "example": "referral_specific" + } + } + }, + { + "in": "query", + "name": "filter[has_expiration]", + "description": "Filter events by type which has or hasn't expiration.", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "count", + "description": "Count total number of events for a single user, applying filters.", + "required": false, + "schema": { + "type": "boolean", + "example": true + } + }, + { + "$ref": "#/components/parameters/pageLimit" + }, + { + "$ref": "#/components/parameters/pageNumber" + }, + { + "$ref": "#/components/parameters/pageOrder" + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Event" + } + }, + "meta": { + "type": "object", + "required": [ + "events_count" + ], + "properties": { + "events_count": { + "type": "integer", + "description": "Appears when `count=true` is specified", + "example": 18 + } + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/invalidParameter" + }, + "401": { + "$ref": "#/components/responses/invalidAuth" + }, + "500": { + "$ref": "#/components/responses/internalError" + } + } + } + }, + "/integrations/geo-points-svc/v1/public/events/{id}": { + "get": { + "tags": [ + "Events" + ], + "summary": "Get event", + "description": "Returns a single event by ID.", + "operationId": "getEvent", + "parameters": [ + { + "$ref": "#/components/parameters/headerLang" + }, + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string", + "example": "059c81dd-2a54-44a8-8142-c15ad8f88949" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/Event" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/invalidParameter" + }, + "401": { + "$ref": "#/components/responses/invalidAuth" + }, + "404": { + "$ref": "#/components/responses/notFound" + }, + "500": { + "$ref": "#/components/responses/internalError" + } + } + }, + "patch": { + "tags": [ + "Events" + ], + "summary": "Claim points for event", + "description": "Update event status to _claimed_ and accrue points.\nUser must be authorized, and event must be _fulfilled_ by him.\n", + "operationId": "claimEvent", + "parameters": [ + { + "$ref": "#/components/parameters/headerLang" + }, + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string", + "example": "059c81dd-2a54-44a8-8142-c15ad8f88949" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/ClaimEventKey" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Event claimed, points accrued", + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data", + "included" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/Event" + }, + "included": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Balance" + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/invalidParameter" + }, + "401": { + "$ref": "#/components/responses/invalidAuth" + }, + "403": { + "description": "This event type was disabled and cannot be claimed", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, + "404": { + "$ref": "#/components/responses/notFound" + }, + "500": { + "$ref": "#/components/responses/internalError" + } + } + } + }, + "/integrations/geo-points-svc/v1/public/events/{id}/qrcode": { + "patch": { + "tags": [ + "Events" + ], + "summary": "Fulfill QR code event", + "description": "Fulfill QR code event", + "operationId": "fulfillQREvent", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string", + "example": "059c81dd-2a54-44a8-8142-c15ad8f88949" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/FulfillQREvent" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/EventClaimingState" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/invalidParameter" + }, + "401": { + "$ref": "#/components/responses/invalidAuth" + }, + "403": { + "description": "This event type was disabled and cannot be fulfilled", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, + "404": { + "$ref": "#/components/responses/notFound" + }, + "500": { + "$ref": "#/components/responses/internalError" + } + } + } + }, + "/integrations/geo-points-svc/v1/public/events/poll": { + "post": { + "tags": [ + "Events" + ], + "summary": "Fulfill poll event", + "description": "Fulfill event for voting in Georgian poll by sending proof of voting", + "operationId": "fulfillPollEvent", + "security": [ + { + "BearerAuth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/FulfillPollEvent" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Success", + "content": { + "application/vnd.api+json": { + "schema": { + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/components/schemas/EventClaimingState" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/invalidParameter" + }, + "401": { + "$ref": "#/components/responses/invalidAuth" + }, + "403": { + "description": "This event type was disabled and cannot be fulfilled", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, + "404": { + "$ref": "#/components/responses/notFound" + }, + "409": { + "description": "Event already fulfilled", + "content": { + "application/vnd.api+json": { + "schema": { + "$ref": "#/components/schemas/Errors" + } + } + } + }, + "500": { + "$ref": "#/components/responses/internalError" + } + } + } + } + }, + "components": { + "schemas": { + "ActivateBalance": { + "allOf": [ + { + "$ref": "#/components/schemas/ActivateBalanceKey" + }, + { + "type": "object", + "x-go-is-request": true, + "required": [ + "attributes" + ], + "properties": { + "attributes": { + "type": "object", + "required": [ + "referred_by" + ], + "properties": { + "referred_by": { + "type": "string", + "description": "Referral code from the link", + "example": "rCx18MZ4" + } + } + } + } + } + ] + }, + "ActivateBalanceKey": { + "type": "object", + "required": [ + "id", + "type" + ], + "properties": { + "id": { + "type": "string", + "description": "Nullifier of the points owner", + "example": "0x123...abc", + "pattern": "^0x[0-9a-fA-F]{64}$" + }, + "type": { + "type": "string", + "enum": [ + "activate_balance" + ] + } + } + }, + "Balance": { + "allOf": [ + { + "$ref": "#/components/schemas/BalanceKey" + }, + { + "type": "object", + "required": [ + "attributes" + ], + "properties": { + "attributes": { + "type": "object", + "required": [ + "amount", + "created_at", + "updated_at", + "level" + ], + "properties": { + "amount": { + "type": "integer", + "format": "int64", + "description": "Amount of points", + "example": 580 + }, + "is_disabled": { + "type": "boolean", + "description": "Whether the user was not referred with some code. If it wasn't - balance\nis disabled and very limited in functionality.\n", + "example": false + }, + "created_at": { + "type": "integer", + "description": "Unix timestamp of balance creation", + "example": 1706531218 + }, + "updated_at": { + "type": "integer", + "description": "Unix timestamp of the last points accruing", + "example": 1706531218 + }, + "rank": { + "type": "integer", + "format": "int", + "description": "Rank of the user in the full leaderboard. Returned only for the single user.", + "example": 294 + }, + "referral_codes": { + "type": "array", + "description": "Referral codes. Returned only for the single active balance.", + "items": { + "$ref": "#/components/schemas/ReferralCode" + } + }, + "referred_users_count": { + "type": "integer", + "format": "int", + "description": "Number of invited users. Returned only for the single active balance.", + "example": 13 + }, + "rewarded_referred_users_count": { + "type": "integer", + "format": "int", + "description": "Number of users for whom the reward was received. Returned only for the single active balance.", + "example": 5 + }, + "level": { + "type": "integer", + "format": "int", + "description": "The level indicates user permissions and features", + "example": 2 + }, + "is_verified": { + "type": "boolean", + "description": "Whether the user has scanned passport. Returned only for the single user.\n" + } + } + } + } + } + ] + }, + "BalanceKey": { + "type": "object", + "required": [ + "id", + "type" + ], + "properties": { + "id": { + "type": "string", + "description": "Nullifier of the points owner", + "example": "0x123...abc", + "pattern": "^0x[0-9a-fA-F]{64}$" + }, + "type": { + "type": "string", + "enum": [ + "balance" + ] + } + } + }, + "ClaimEventKey": { + "type": "object", + "required": [ + "id", + "type" + ], + "properties": { + "id": { + "type": "string", + "example": "059c81dd-2a54-44a8-8142-c15ad8f88949" + }, + "type": { + "type": "string", + "enum": [ + "claim_event" + ] + } + } + }, + "CreateBalance": { + "allOf": [ + { + "$ref": "#/components/schemas/CreateBalanceKey" + }, + { + "type": "object", + "x-go-is-request": true, + "required": [ + "attributes" + ], + "properties": { + "attributes": { + "type": "object", + "properties": { + "referred_by": { + "type": "string", + "description": "Referral code from the link. Supply it to create the active balance,\notherwise disabled balance is created, and it can be activated later.\n\nDisabled balance is only allowed to verify passport and get.\n", + "example": "rCx18MZ4" + } + } + } + } + } + ] + }, + "CreateBalanceKey": { + "type": "object", + "required": [ + "id", + "type" + ], + "properties": { + "id": { + "type": "string", + "description": "Nullifier of the points owner", + "example": "0x123...abc", + "pattern": "^0x[0-9a-fA-F]{64}$" + }, + "type": { + "type": "string", + "enum": [ + "create_balance" + ] + } + } + }, + "DailyQuestionAnswers": { + "allOf": [ + { + "$ref": "#/components/schemas/DailyQuestionsKey" + }, + { + "type": "object", + "required": [ + "attributes" + ], + "properties": { + "attributes": { + "type": "object", + "required": [ + "answer" + ], + "properties": { + "answer": { + "type": "integer", + "format": "int64", + "description": "Selected/correct answer option" + } + } + } + } + } + ] + }, + "DailyQuestionCreate": { + "allOf": [ + { + "$ref": "#/components/schemas/DailyQuestionEditKey" }, - "409": { - "description": "Event already fulfilled", - "content": { - "application/vnd.api+json": { - "schema": { - "$ref": "#/components/schemas/Errors" + { + "type": "object", + "required": [ + "attributes" + ], + "properties": { + "attributes": { + "type": "object", + "required": [ + "title", + "reward", + "options", + "correct_answer", + "time_for_answer", + "starts_at" + ], + "properties": { + "title": { + "type": "string", + "description": "Question title", + "example": "Georgian capital" + }, + "reward": { + "type": "integer", + "format": "int64", + "description": "Reward for a correct answer" + }, + "options": { + "type": "array", + "description": "Answer options. Minimum 2, maximum 6", + "items": { + "$ref": "#/components/schemas/DailyQuestionOptions" + }, + "example": [ + { + "id": 0, + "title": "" + }, + { + "id": 1, + "title": "" + }, + { + "id": 2, + "title": "" + } + ] + }, + "correct_answer": { + "type": "integer", + "format": "int64", + "description": "Correct answer ID" + }, + "time_for_answer": { + "type": "integer", + "format": "int64", + "description": "Time for answer" + }, + "starts_at": { + "type": "string", + "description": "Start date when this question is available, hours and minutes are always 0", + "example": "2024-08-23" + } } } } + } + ] + }, + "DailyQuestionCreateKey": { + "type": "object", + "required": [ + "id", + "type" + ], + "properties": { + "id": { + "type": "string", + "description": "Question id" }, - "500": { - "$ref": "#/components/responses/internalError" + "type": { + "type": "string", + "enum": [ + "daily_questions" + ] } } - } - } - }, - "components": { - "schemas": { - "ActivateBalance": { + }, + "DailyQuestionDel": { "allOf": [ { - "$ref": "#/components/schemas/ActivateBalanceKey" + "$ref": "#/components/schemas/DailyQuestionDelKey" }, { "type": "object", - "x-go-is-request": true, "required": [ "attributes" ], @@ -1445,13 +2231,13 @@ "attributes": { "type": "object", "required": [ - "referred_by" + "title" ], "properties": { - "referred_by": { + "title": { "type": "string", - "description": "Referral code from the link", - "example": "rCx18MZ4" + "description": "Question title", + "example": "Georgian capital" } } } @@ -1459,7 +2245,7 @@ } ] }, - "ActivateBalanceKey": { + "DailyQuestionDelKey": { "type": "object", "required": [ "id", @@ -1468,22 +2254,20 @@ "properties": { "id": { "type": "string", - "description": "Nullifier of the points owner", - "example": "0x123...abc", - "pattern": "^0x[0-9a-fA-F]{64}$" + "description": "Question id" }, "type": { "type": "string", "enum": [ - "activate_balance" + "daily_questions" ] } } }, - "Balance": { + "DailyQuestionDetails": { "allOf": [ { - "$ref": "#/components/schemas/BalanceKey" + "$ref": "#/components/schemas/DailyQuestionDetailsKey" }, { "type": "object", @@ -1494,67 +2278,168 @@ "attributes": { "type": "object", "required": [ - "amount", + "title", + "reward", + "options", + "correct_answer", + "time_for_answer", + "starts_at", "created_at", - "updated_at", - "level" + "num_correct_answers", + "num_incorrect_answers", + "num_all_participants" ], "properties": { - "amount": { + "title": { + "type": "string", + "description": "Question title", + "example": "Georgian capital" + }, + "reward": { "type": "integer", "format": "int64", - "description": "Amount of points", - "example": 580 + "description": "Reward for a correct answer" }, - "is_disabled": { - "type": "boolean", - "description": "Whether the user was not referred with some code. If it wasn't - balance\nis disabled and very limited in functionality.\n", - "example": false + "options": { + "type": "array", + "description": "Answer options. Minimum 2, maximum 6", + "items": { + "$ref": "#/components/schemas/DailyQuestionOptions" + }, + "example": [ + { + "id": 0, + "title": "" + }, + { + "id": 1, + "title": "" + }, + { + "id": 2, + "title": "" + } + ] + }, + "correct_answer": { + "type": "integer", + "format": "int64", + "description": "Correct answer ID" + }, + "time_for_answer": { + "type": "integer", + "format": "int64", + "description": "Time for answer" + }, + "starts_at": { + "type": "string", + "description": "Start date when this question is available, hours and minutes are always 0", + "example": "2024-08-26T00:00:00Z" }, "created_at": { + "type": "string", + "description": "Start date when this question was create", + "example": "2024-08-26T00:00:00Z" + }, + "num_correct_answers": { "type": "integer", - "description": "Unix timestamp of balance creation", - "example": 1706531218 + "format": "int64", + "description": "Number of correct answers" }, - "updated_at": { + "num_incorrect_answers": { "type": "integer", - "description": "Unix timestamp of the last points accruing", - "example": 1706531218 + "format": "int64", + "description": "Number of incorrect answers" }, - "rank": { + "num_all_participants": { "type": "integer", - "format": "int", - "description": "Rank of the user in the full leaderboard. Returned only for the single user.", - "example": 294 + "format": "int64", + "description": "Users who received the question, those who answered and\nthose who did not answer in the time given to them\n" + } + } + } + } + } + ] + }, + "DailyQuestionDetailsKey": { + "type": "object", + "required": [ + "id", + "type" + ], + "properties": { + "id": { + "type": "string", + "description": "Question id" + }, + "type": { + "type": "string", + "enum": [ + "daily_questions" + ] + } + } + }, + "DailyQuestionEdit": { + "allOf": [ + { + "$ref": "#/components/schemas/DailyQuestionEditKey" + }, + { + "type": "object", + "required": [ + "attributes" + ], + "properties": { + "attributes": { + "type": "object", + "properties": { + "title": { + "type": "string", + "description": "Question title", + "example": "Georgian capital" }, - "referral_codes": { + "reward": { + "type": "integer", + "format": "int64", + "description": "Reward for a correct answer" + }, + "options": { "type": "array", - "description": "Referral codes. Returned only for the single active balance.", + "description": "Answer options. Minimum 2, maximum 6", "items": { - "$ref": "#/components/schemas/ReferralCode" - } - }, - "referred_users_count": { - "type": "integer", - "format": "int", - "description": "Number of invited users. Returned only for the single active balance.", - "example": 13 + "$ref": "#/components/schemas/DailyQuestionOptions" + }, + "example": [ + { + "id": 0, + "title": "" + }, + { + "id": 1, + "title": "" + }, + { + "id": 2, + "title": "" + } + ] }, - "rewarded_referred_users_count": { + "correct_answer": { "type": "integer", - "format": "int", - "description": "Number of users for whom the reward was received. Returned only for the single active balance.", - "example": 5 + "format": "int64", + "description": "Correct answer ID" }, - "level": { + "time_for_answer": { "type": "integer", - "format": "int", - "description": "The level indicates user permissions and features", - "example": 2 + "format": "int64", + "description": "Time for answer" }, - "is_verified": { - "type": "boolean", - "description": "Whether the user has scanned passport. Returned only for the single user.\n" + "starts_at": { + "type": "string", + "description": "Start date when this question is available, hours and minutes are always 0", + "example": "2024-08-23" } } } @@ -1562,7 +2447,7 @@ } ] }, - "BalanceKey": { + "DailyQuestionEditKey": { "type": "object", "required": [ "id", @@ -1571,19 +2456,85 @@ "properties": { "id": { "type": "string", - "description": "Nullifier of the points owner", - "example": "0x123...abc", - "pattern": "^0x[0-9a-fA-F]{64}$" + "description": "Question id" }, "type": { "type": "string", "enum": [ - "balance" + "daily_questions" ] } } }, - "ClaimEventKey": { + "DailyQuestionOptions": { + "type": "object", + "required": [ + "id", + "title" + ], + "properties": { + "id": { + "type": "integer", + "format": "int", + "description": "Answer number for the question" + }, + "title": { + "type": "string", + "description": "Answer text" + } + } + }, + "DailyQuestions": { + "allOf": [ + { + "$ref": "#/components/schemas/DailyQuestionsKey" + }, + { + "type": "object", + "required": [ + "attributes" + ], + "properties": { + "attributes": { + "type": "object", + "required": [ + "title", + "options" + ], + "properties": { + "title": { + "type": "string", + "description": "Question title", + "example": "Georgian capital" + }, + "options": { + "type": "array", + "description": "Answer options. Minimum 2, maximum 6", + "items": { + "$ref": "#/components/schemas/DailyQuestionOptions" + }, + "example": [ + { + "id": 0, + "title": "" + }, + { + "id": 1, + "title": "" + }, + { + "id": 2, + "title": "" + } + ] + } + } + } + } + } + ] + }, + "DailyQuestionsKey": { "type": "object", "required": [ "id", @@ -1592,35 +2543,52 @@ "properties": { "id": { "type": "string", - "example": "059c81dd-2a54-44a8-8142-c15ad8f88949" + "description": "Question id" }, "type": { "type": "string", "enum": [ - "claim_event" + "daily_questions" ] } } }, - "CreateBalance": { + "DailyQuestionsStatus": { "allOf": [ { - "$ref": "#/components/schemas/CreateBalanceKey" + "$ref": "#/components/schemas/DailyQuestionsStatusKey" }, { "type": "object", - "x-go-is-request": true, "required": [ "attributes" ], "properties": { "attributes": { "type": "object", + "required": [ + "next_question_date", + "time_for_answer", + "reward" + ], "properties": { - "referred_by": { - "type": "string", - "description": "Referral code from the link. Supply it to create the active balance,\notherwise disabled balance is created, and it can be activated later.\n\nDisabled balance is only allowed to verify passport and get.\n", - "example": "rCx18MZ4" + "next_question_date": { + "type": "timestamp", + "format": "int64", + "description": "Time when the next question will be available. \nIf the time is in the past, then there is a question \non this day and the user has not yet answered it. \nIf the time is in the future, then the user has either \nalready answered the question on the current day or \nthere was no question on the current day.\n", + "example": 1725018539 + }, + "time_for_answer": { + "type": "integer", + "format": "int64", + "description": "The time within which the user has to answer this question after receiving it.", + "example": 30 + }, + "reward": { + "type": "integer", + "format": "int64", + "description": "The number of points the user will receive if they answer the question correctly.", + "example": 5 } } } @@ -1628,7 +2596,7 @@ } ] }, - "CreateBalanceKey": { + "DailyQuestionsStatusKey": { "type": "object", "required": [ "id", @@ -1637,14 +2605,12 @@ "properties": { "id": { "type": "string", - "description": "Nullifier of the points owner", - "example": "0x123...abc", - "pattern": "^0x[0-9a-fA-F]{64}$" + "description": "Question id" }, "type": { "type": "string", "enum": [ - "create_balance" + "daily_questions_status" ] } } diff --git a/openapi.yaml b/openapi.yaml index 48b99a8..318ce9e 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -386,6 +386,292 @@ paths: $ref: '#/components/schemas/Errors' '500': $ref: '#/components/responses/internalError' + '/integrations/geo-points-svc/v1/public/daily_questions/{nullifier}': + get: + tags: + - Daily Questions + summary: Get daily question + description: | + Get a daily question. The user must be + authorized and verified (passport scanned, + verified field is true). + operationId: getDailyQuestion + security: + - BearerAuth: [] + responses: + '200': + description: Success + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestions' + '400': + $ref: '#/components/responses/invalidParameter' + '401': + $ref: '#/components/responses/invalidAuth' + '403': + description: 'Questions unavailable, try later' + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '404': + description: There is no question in current day. + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '409': + description: User already answer current day question. + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '500': + $ref: '#/components/responses/internalError' + post: + tags: + - Daily Questions + summary: Answer question + description: | + Answer question. The user must be + authorized and verified (passport scanned, + verified field is true). + operationId: answerDailyQuestion + security: + - BearerAuth: [] + requestBody: + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestionAnswers' + responses: + '200': + description: Success + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestionAnswers' + '400': + $ref: '#/components/responses/invalidParameter' + '401': + $ref: '#/components/responses/invalidAuth' + '404': + description: User haven't active question or deadline already passed. + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '500': + $ref: '#/components/responses/internalError' + '/integrations/geo-points-svc/v1/public/daily_questions/{nullifier}/status': + get: + tags: + - Daily Questions + summary: Daily question status + description: | + Get the status of questions. The user must be + authorized and verified (passport scanned, + verified field is true). + Returns NotFound if next question absent. + operationId: dailyQuestionsStatus + security: + - BearerAuth: [] + responses: + '200': + description: Success + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestionsStatus' + '401': + $ref: '#/components/responses/invalidAuth' + '404': + description: Next question not exist. + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '500': + $ref: '#/components/responses/internalError' + /integrations/geo-points-svc/v1/public/daily_questions/admin: + post: + tags: + - Daily Questions + summary: Create daily question + description: | + Create Daily Question user must be superuser + operationId: createDailyQuestion + security: + - BearerAuth: [] + requestBody: + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestionCreate' + responses: + '200': + description: Success + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestionDetails' + '400': + $ref: '#/components/responses/invalidParameter' + '401': + $ref: '#/components/responses/invalidAuth' + '403': + description: Correct answer option outside the range of answer options + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '409': + description: 'On this day, the daily question already exists' + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '500': + $ref: '#/components/responses/internalError' + get: + tags: + - Daily Questions + summary: Filter Daily Question by start + description: | + Filtering of daily questions by their activation time + operationId: filterStartAtDailyQuestion + security: + - BearerAuth: [] + responses: + '200': + description: Success + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + type: array + items: + $ref: '#/components/schemas/DailyQuestionDetails' + '500': + $ref: '#/components/responses/internalError' + '/integrations/geo-points-svc/v1/public/daily_questions/admin/{question_id}': + delete: + tags: + - Daily Questions + summary: Delete daily question + description: | + Delete Daily Question user must be superuser + operationId: deleteDailyQuestion + security: + - BearerAuth: [] + responses: + '200': + description: Success + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestionDetails' + '204': + description: No content + '400': + $ref: '#/components/responses/invalidParameter' + '404': + description: Question with ID not found + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '500': + $ref: '#/components/responses/internalError' + patch: + tags: + - Daily Questions + summary: Edit daily question + description: | + Edit Daily Question user must be superuser + operationId: editDailyQuestion + security: + - BearerAuth: [] + requestBody: + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestionEdit' + responses: + '200': + description: Success + content: + application/vnd.api+json: + schema: + type: object + required: + - data + properties: + data: + $ref: '#/components/schemas/DailyQuestionDetails' + '204': + description: No content + '400': + $ref: '#/components/responses/invalidParameter' + '403': + description: Correct answer option outside the range of answer options + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '409': + description: 'On this day, the daily question already exists' + content: + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Errors' + '500': + $ref: '#/components/responses/internalError' /integrations/geo-points-svc/v1/public/event_types: get: tags: @@ -1112,6 +1398,355 @@ components: type: string enum: - create_balance + DailyQuestionAnswers: + allOf: + - $ref: '#/components/schemas/DailyQuestionsKey' + - type: object + required: + - attributes + properties: + attributes: + type: object + required: + - answer + properties: + answer: + type: integer + format: int64 + description: Selected/correct answer option + DailyQuestionCreate: + allOf: + - $ref: '#/components/schemas/DailyQuestionEditKey' + - type: object + required: + - attributes + properties: + attributes: + type: object + required: + - title + - reward + - options + - correct_answer + - time_for_answer + - starts_at + properties: + title: + type: string + description: Question title + example: Georgian capital + reward: + type: integer + format: int64 + description: Reward for a correct answer + options: + type: array + description: 'Answer options. Minimum 2, maximum 6' + items: + $ref: '#/components/schemas/DailyQuestionOptions' + example: + - id: 0 + title: '' + - id: 1 + title: '' + - id: 2 + title: '' + correct_answer: + type: integer + format: int64 + description: Correct answer ID + time_for_answer: + type: integer + format: int64 + description: Time for answer + starts_at: + type: string + description: 'Start date when this question is available, hours and minutes are always 0' + example: '2024-08-23' + DailyQuestionCreateKey: + type: object + required: + - id + - type + properties: + id: + type: string + description: Question id + type: + type: string + enum: + - daily_questions + DailyQuestionDel: + allOf: + - $ref: '#/components/schemas/DailyQuestionDelKey' + - type: object + required: + - attributes + properties: + attributes: + type: object + required: + - title + properties: + title: + type: string + description: Question title + example: Georgian capital + DailyQuestionDelKey: + type: object + required: + - id + - type + properties: + id: + type: string + description: Question id + type: + type: string + enum: + - daily_questions + DailyQuestionDetails: + allOf: + - $ref: '#/components/schemas/DailyQuestionDetailsKey' + - type: object + required: + - attributes + properties: + attributes: + type: object + required: + - title + - reward + - options + - correct_answer + - time_for_answer + - starts_at + - created_at + - num_correct_answers + - num_incorrect_answers + - num_all_participants + properties: + title: + type: string + description: Question title + example: Georgian capital + reward: + type: integer + format: int64 + description: Reward for a correct answer + options: + type: array + description: 'Answer options. Minimum 2, maximum 6' + items: + $ref: '#/components/schemas/DailyQuestionOptions' + example: + - id: 0 + title: '' + - id: 1 + title: '' + - id: 2 + title: '' + correct_answer: + type: integer + format: int64 + description: Correct answer ID + time_for_answer: + type: integer + format: int64 + description: Time for answer + starts_at: + type: string + description: 'Start date when this question is available, hours and minutes are always 0' + example: '2024-08-26T00:00:00Z' + created_at: + type: string + description: Start date when this question was create + example: '2024-08-26T00:00:00Z' + num_correct_answers: + type: integer + format: int64 + description: Number of correct answers + num_incorrect_answers: + type: integer + format: int64 + description: Number of incorrect answers + num_all_participants: + type: integer + format: int64 + description: | + Users who received the question, those who answered and + those who did not answer in the time given to them + DailyQuestionDetailsKey: + type: object + required: + - id + - type + properties: + id: + type: string + description: Question id + type: + type: string + enum: + - daily_questions + DailyQuestionEdit: + allOf: + - $ref: '#/components/schemas/DailyQuestionEditKey' + - type: object + required: + - attributes + properties: + attributes: + type: object + properties: + title: + type: string + description: Question title + example: Georgian capital + reward: + type: integer + format: int64 + description: Reward for a correct answer + options: + type: array + description: 'Answer options. Minimum 2, maximum 6' + items: + $ref: '#/components/schemas/DailyQuestionOptions' + example: + - id: 0 + title: '' + - id: 1 + title: '' + - id: 2 + title: '' + correct_answer: + type: integer + format: int64 + description: Correct answer ID + time_for_answer: + type: integer + format: int64 + description: Time for answer + starts_at: + type: string + description: 'Start date when this question is available, hours and minutes are always 0' + example: '2024-08-23' + DailyQuestionEditKey: + type: object + required: + - id + - type + properties: + id: + type: string + description: Question id + type: + type: string + enum: + - daily_questions + DailyQuestionOptions: + type: object + required: + - id + - title + properties: + id: + type: integer + format: int + description: Answer number for the question + title: + type: string + description: Answer text + DailyQuestions: + allOf: + - $ref: '#/components/schemas/DailyQuestionsKey' + - type: object + required: + - attributes + properties: + attributes: + type: object + required: + - title + - options + properties: + title: + type: string + description: Question title + example: Georgian capital + options: + type: array + description: 'Answer options. Minimum 2, maximum 6' + items: + $ref: '#/components/schemas/DailyQuestionOptions' + example: + - id: 0 + title: '' + - id: 1 + title: '' + - id: 2 + title: '' + DailyQuestionsKey: + type: object + required: + - id + - type + properties: + id: + type: string + description: Question id + type: + type: string + enum: + - daily_questions + DailyQuestionsStatus: + allOf: + - $ref: '#/components/schemas/DailyQuestionsStatusKey' + - type: object + required: + - attributes + properties: + attributes: + type: object + required: + - next_question_date + - time_for_answer + - reward + properties: + next_question_date: + type: timestamp + format: int64 + description: | + Time when the next question will be available. + If the time is in the past, then there is a question + on this day and the user has not yet answered it. + If the time is in the future, then the user has either + already answered the question on the current day or + there was no question on the current day. + example: 1725018539 + time_for_answer: + type: integer + format: int64 + description: The time within which the user has to answer this question after receiving it. + example: 30 + reward: + type: integer + format: int64 + description: The number of points the user will receive if they answer the question correctly. + example: 5 + DailyQuestionsStatusKey: + type: object + required: + - id + - type + properties: + id: + type: string + description: Question id + type: + type: string + enum: + - daily_questions_status Errors: description: 'Standard JSON:API error' type: object