From 7ba31325eb4b016d29bbc755d8e0d2eafedd5d3e Mon Sep 17 00:00:00 2001 From: akhdanre Date: Sat, 24 May 2025 15:00:19 +0700 Subject: [PATCH] fix: subject add data and some documentation --- app/controllers/subject_controller.py | 4 +- .../requests/subject/create_subject_schema.py | 10 +- docs/rest_api_docs.yaml | 326 +++++++++++++----- 3 files changed, 245 insertions(+), 95 deletions(-) diff --git a/app/controllers/subject_controller.py b/app/controllers/subject_controller.py index 6f080e4..2dbc17f 100644 --- a/app/controllers/subject_controller.py +++ b/app/controllers/subject_controller.py @@ -1,5 +1,6 @@ from app.services.subject_service import SubjectService from app.helpers import make_response, make_error_response +from app.schemas.requests import SubjectCreateRequest class SubjectController: @@ -8,7 +9,8 @@ class SubjectController: def create(self, req_body): try: - new_id = self.service.create_subject(req_body) + data = SubjectCreateRequest(**req_body) + new_id = self.service.create_subject(data) return make_response(message="Subject created", data={"id": new_id}) except Exception as e: return make_error_response(e) diff --git a/app/schemas/requests/subject/create_subject_schema.py b/app/schemas/requests/subject/create_subject_schema.py index 628ab33..9ed643e 100644 --- a/app/schemas/requests/subject/create_subject_schema.py +++ b/app/schemas/requests/subject/create_subject_schema.py @@ -1,10 +1,8 @@ -from pydantic import BaseModel, Field +from pydantic import BaseModel from typing import Optional class SubjectCreateRequest(BaseModel): - name: str = Field(..., example="Ilmu Pengetahuan ALam") - alias: str = Field(..., examples="IPA", alias="short_name") - description: Optional[str] = Field( - None, example="Pelajaran tentang angka dan logika" - ) + name: str + alias: str + description: Optional[str] diff --git a/docs/rest_api_docs.yaml b/docs/rest_api_docs.yaml index b9dbe6b..b67f74a 100644 --- a/docs/rest_api_docs.yaml +++ b/docs/rest_api_docs.yaml @@ -5,9 +5,9 @@ info: version: 1.0.0 servers: - - url: http://127.0.0.1:5000/api/v1 + - url: http://127.0.0.1:5000/api description: Local Server - - url: http://api.example.com/api/v1 + - url: http://api.example.com/api description: Production Server tags: @@ -17,9 +17,12 @@ tags: description: User data endpoints - name: Quiz description: Quiz endpoints - # - name: Answer - name: History + description: Quiz history endpoints - name: Subject + description: Subject management endpoints + - name: Session + description: Session management endpoints paths: /login: @@ -108,11 +111,7 @@ paths: type: string example: "60f6c2d2e1f1c4567a123abc" "400": - description: Bad Request - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorMessage" + $ref: "#/components/responses/BadRequest" /quiz/{id}: get: @@ -141,11 +140,7 @@ paths: meta: type: object "404": - description: Quiz not found - content: - application/json: - schema: - $ref: "#/components/schemas/NotFoundResponse" + $ref: "#/components/responses/NotFound" /quiz/user/{user_id}: get: @@ -181,23 +176,9 @@ paths: items: $ref: "#/components/schemas/QuizDetails" meta: - type: object - properties: - total: - type: integer - example: 25 - page: - type: integer - example: 1 - per_page: - type: integer - example: 10 + $ref: "#/components/schemas/PaginationMeta" "404": - description: No quizzes found for user - content: - application/json: - schema: - $ref: "#/components/schemas/NotFoundResponse" + $ref: "#/components/responses/NotFound" /quiz/recomendation: get: @@ -205,18 +186,8 @@ paths: description: Returns a list of recommended quizzes for the user tags: [Quiz] parameters: - - name: page - in: query - required: false - schema: - type: integer - example: 1 - - name: limit - in: query - required: false - schema: - type: integer - example: 4 + - $ref: "#/components/parameters/PageParam" + - $ref: "#/components/parameters/LimitParam" responses: "200": description: Successfully retrieved recommendation quiz list @@ -245,18 +216,8 @@ paths: schema: type: string example: Sejarah - - name: page - in: query - required: false - schema: - type: integer - example: 1 - - name: limit - in: query - required: false - schema: - type: integer - example: 4 + - $ref: "#/components/parameters/PageParam" + - $ref: "#/components/parameters/LimitParam" responses: "200": description: Search result @@ -274,6 +235,7 @@ paths: $ref: "#/components/schemas/RecommendedQuiz" meta: $ref: "#/components/schemas/SearchMeta" + /quiz/ai: post: summary: Generate labeling quiz from passage @@ -305,13 +267,8 @@ paths: type: array items: $ref: "#/components/schemas/LabeledQuestion" - "400": - description: Bad Request - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorMessage" + $ref: "#/components/responses/BadRequest" /quiz/answer: post: @@ -330,17 +287,9 @@ paths: content: application/json: schema: - type: object - properties: - message: - type: string - example: Quiz answers submitted successfully + $ref: "#/components/schemas/SuccessResponse" "400": - description: Bad Request - content: - application/json: - schema: - $ref: "#/components/schemas/ErrorMessage" + $ref: "#/components/responses/BadRequest" /quiz/answer/session: post: @@ -373,13 +322,8 @@ paths: example: Successfully retrieved the answer data: $ref: "#/components/schemas/UserAnswerSession" - "404": - description: Answer session not found - content: - application/json: - schema: - $ref: "#/components/schemas/NotFoundResponse" + $ref: "#/components/responses/NotFound" /history/{user_id}: get: @@ -408,13 +352,8 @@ paths: type: array items: $ref: "#/components/schemas/AnswerHistoryItem" - "404": - description: No history found - content: - application/json: - schema: - $ref: "#/components/schemas/NotFoundResponse" + $ref: "#/components/responses/NotFound" /history/detail/{answer_id}: get: @@ -441,6 +380,7 @@ paths: example: success retrive detail history data data: $ref: "#/components/schemas/AnswerDetailData" + /subject: get: summary: Get all subjects @@ -462,7 +402,118 @@ paths: items: $ref: "#/components/schemas/Subject" + post: + summary: Create a new subject + tags: [Subject] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + example: Teknik Kimia + alias: + type: string + example: KIM + description: + type: string + example: basic Kimia + required: + - name + - alias + - description + responses: + "200": + description: Subject successfully created + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: Subject created + data: + type: object + properties: + id: + type: string + example: 683178ffac911e8a9d04bb0e + meta: + type: object + nullable: true + example: null + + /session: + post: + summary: Create a new quiz session + tags: [Session] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + quiz_id: + type: string + example: 6815da9f37a1ce472ba72819 + host_id: + type: string + example: 680f0e63180b5c19b3751d42 + limit_participan: + type: integer + example: 2 + required: + - quiz_id + - host_id + - limit_participan + responses: + "200": + description: Successfully created a session + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: succes create room + data: + type: object + properties: + session_id: + type: string + example: 68317a6a48d97464ec3aaf1c + session_code: + type: string + example: AE5AFE + meta: + type: object + nullable: true + example: null + components: + parameters: + PageParam: + name: page + in: query + required: false + schema: + type: integer + example: 1 + + LimitParam: + name: limit + in: query + required: false + schema: + type: integer + example: 4 + requestBodies: LoginRequest: required: true @@ -470,18 +521,21 @@ components: application/json: schema: $ref: "#/components/schemas/Login" + GoogleLoginRequest: required: true content: application/json: schema: $ref: "#/components/schemas/GoogleLogin" + RegisterRequest: required: true content: application/json: schema: $ref: "#/components/schemas/Register" + UpdateUserRequest: required: true content: @@ -500,6 +554,7 @@ components: token: type: string example: + BadRequestLogin: description: Bad Request content: @@ -508,6 +563,7 @@ components: $ref: "#/components/schemas/ErrorMessage" example: message: Invalid email or password + BadRequestGoogleLogin: description: Bad Request content: @@ -516,6 +572,7 @@ components: $ref: "#/components/schemas/ErrorMessage" example: message: Invalid token + LogoutSuccess: description: OK content: @@ -524,6 +581,7 @@ components: $ref: "#/components/schemas/SuccessMessage" example: message: Logout successfully + UserCreated: description: OK content: @@ -532,6 +590,7 @@ components: $ref: "#/components/schemas/SuccessMessage" example: message: User created successfully + UserExists: description: Conflict content: @@ -540,12 +599,14 @@ components: $ref: "#/components/schemas/ErrorMessage" example: message: Email already registered + UserData: description: OK content: application/json: schema: $ref: "#/components/schemas/User" + UserUpdated: description: OK content: @@ -555,6 +616,22 @@ components: example: message: User updated successfully + BadRequest: + description: Bad Request + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorMessage" + + NotFound: + description: Not Found + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorMessage" + example: + message: Resource not found + schemas: Login: type: object @@ -565,122 +642,175 @@ components: password: type: string example: rahasia + GoogleLogin: type: object properties: token_id: type: string example: + Register: type: object properties: email: type: string + example: user@example.com password: type: string + example: secure_password name: type: string + example: John Doe birth_date: type: string + example: 1990-01-01 + UpdateUser: type: object properties: email: type: string example: newemail@example.com + User: type: object properties: id: - type: integer + type: string + example: 680f0e63180b5c19b3751d42 name: type: string + example: John Doe email: type: string + example: user@example.com + SuccessMessage: type: object properties: message: type: string + + SuccessResponse: + type: object + properties: + message: + type: string + example: Operation completed successfully + ErrorMessage: type: object properties: message: type: string + example: An error occurred + + PaginationMeta: + type: object + properties: + total: + type: integer + example: 25 + page: + type: integer + example: 1 + per_page: + type: integer + example: 10 + QuizCreateRequest: type: object properties: title: type: string + example: Sejarah Indonesia description: type: string + example: Kuis tentang sejarah Indonesia is_public: type: boolean + example: true author_id: type: string + example: 680f0e63180b5c19b3751d42 subject_id: type: string + example: 68131eac43a09ed7dbb2cf44 questions: type: array items: $ref: "#/components/schemas/QuizQuestion" + QuizQuestion: type: object properties: index: type: integer + example: 1 question: type: string + example: Siapakah ketua Wali Songo yang juga dikenal sebagai Sunan Gresik? target_answer: oneOf: - type: string - type: boolean - type: integer + example: Maulana Malik Ibrahim duration: type: integer + example: 30 type: type: string enum: [fill_the_blank, true_false, option] + example: fill_the_blank options: type: array items: type: string nullable: true + example: null + QuizDetails: type: object properties: id: type: string + example: 68283dc9806020760d14e963 author_id: type: string + example: 680f0e63180b5c19b3751d42 subject_id: type: string + example: 68131eac43a09ed7dbb2cf44 subject_alias: type: string + example: IPA title: type: string + example: Sejarah Indonesia - Proklamasi dan Kemerdekaan description: type: string + example: Kuis ini membahas peristiwa penting seputar proklamasi dan kemerdekaan Indonesia serta tokoh-tokoh terkait. is_public: type: boolean + example: true date: type: string + example: 17-May-2025 time: type: string + example: 14:30 total_quiz: type: integer + example: 10 limit_duration: type: integer + example: 300 question_listings: type: array items: $ref: "#/components/schemas/QuizQuestion" - NotFoundResponse: - type: object - properties: - message: - type: string - example: Quiz not found RecommendedQuiz: type: object @@ -760,6 +890,7 @@ components: date: type: string example: 2025-05-18 19:02:02 + QuizAnswerSubmission: type: object properties: @@ -792,6 +923,7 @@ components: - type: string - type: boolean - type: integer + example: Maulana Malik Ibrahim is_correct: type: boolean example: true @@ -847,6 +979,7 @@ components: type: type: string enum: [fill_the_blank, true_false, option] + example: fill_the_blank options: type: array items: @@ -858,6 +991,7 @@ components: - type: string - type: boolean - type: integer + example: Maulana Malik Ibrahim is_correct: type: boolean example: true @@ -871,23 +1005,31 @@ components: properties: answer_id: type: string + example: 6828bcddb5418bf21ab424b2 quiz_id: type: string + example: 68283dc9806020760d14e963 title: type: string + example: Sejarah Indonesia - Proklamasi dan Kemerdekaan description: type: string + example: Kuis ini membahas peristiwa penting seputar proklamasi dan kemerdekaan Indonesia serta tokoh-tokoh terkait. author_id: type: string + example: 680f0e63180b5c19b3751d42 answered_at: type: string example: 17-May-2025 total_correct: type: integer + example: 8 total_score: type: integer + example: 80 total_solve_time: type: number + example: 240.5 question_listings: type: array items: @@ -898,30 +1040,38 @@ components: properties: index: type: integer + example: 1 question: type: string + example: Siapakah ketua Wali Songo yang juga dikenal sebagai Sunan Gresik? type: type: string enum: [fill_the_blank, true_false, option] + example: fill_the_blank target_answer: oneOf: - type: string - type: boolean - type: integer + example: Maulana Malik Ibrahim user_answer: oneOf: - type: string - type: boolean - type: integer + example: Maulana Malik Ibrahim is_correct: type: boolean + example: true time_spent: type: number + example: 25.3 options: type: array items: type: string nullable: true + example: null Subject: type: object