From 6e7ed33b7830acb54fb7e810881a16e8cce9e8d2 Mon Sep 17 00:00:00 2001 From: b0ink <40929320+b0ink@users.noreply.github.com> Date: Thu, 2 Jul 2026 11:15:55 +1000 Subject: [PATCH] feat: correctly define swagger schema --- Gemfile | 1 + Gemfile.lock | 4 ++++ app/api/api_root.rb | 3 ++- app/api/entities/inbox_task_entity.rb | 23 +++++++++++++++++++++++ app/api/entities/task_summary_entity.rb | 9 +++++++++ app/api/tasks_api.rb | 7 +++++-- app/api/units_api.rb | 6 ++++-- app/models/unit.rb | 7 ++++++- 8 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 app/api/entities/inbox_task_entity.rb create mode 100644 app/api/entities/task_summary_entity.rb diff --git a/Gemfile b/Gemfile index b367b8222..913c9bc27 100644 --- a/Gemfile +++ b/Gemfile @@ -78,6 +78,7 @@ gem 'rails-latex' gem 'grape' gem 'grape-entity' gem 'grape-swagger' +gem 'grape-swagger-entity' gem 'grape-swagger-rails' # Miscellaneous diff --git a/Gemfile.lock b/Gemfile.lock index 9df7ab4c0..c9db06833 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -192,6 +192,9 @@ GEM grape-swagger (2.1.2) grape (>= 1.7, < 3.0) rack-test (~> 2) + grape-swagger-entity (0.7.1) + grape-entity (~> 1) + grape-swagger (~> 2) grape-swagger-rails (0.6.0) ostruct railties (>= 6.0.6.1) @@ -586,6 +589,7 @@ DEPENDENCIES grape grape-entity grape-swagger + grape-swagger-entity grape-swagger-rails hirb icalendar diff --git a/app/api/api_root.rb b/app/api/api_root.rb index 3dbc68229..8c842ecd0 100644 --- a/app/api/api_root.rb +++ b/app/api/api_root.rb @@ -1,5 +1,6 @@ require 'grape' require 'grape-swagger' +require 'grape-swagger/entity' class ApiRoot < Grape::API helpers AuthorisationHelpers @@ -165,7 +166,7 @@ class ApiRoot < Grape::API add_swagger_documentation \ base_path: nil, doc_version: 'v11.0.0', - hide_documentation_path: true, + hide_documentation_path: false, info: { title: 'Doubtfire API Documentation', description: 'Doubtfire is a modern, lightweight learning management system.', diff --git a/app/api/entities/inbox_task_entity.rb b/app/api/entities/inbox_task_entity.rb new file mode 100644 index 000000000..503b6a81a --- /dev/null +++ b/app/api/entities/inbox_task_entity.rb @@ -0,0 +1,23 @@ +module Entities + class InboxTaskEntity < Grape::Entity + expose :id, documentation: { type: Integer } + expose :unit_id, documentation: { type: Integer } + expose :project_id, documentation: { type: Integer } + expose :task_definition_id, documentation: { type: Integer } + expose :tutorial_id, documentation: { type: Integer, required: false, nullable: true } + + expose :status, documentation: { type: String } + + expose :completion_date, documentation: { type: DateTime, required: false, nullable: true } + expose :submission_date, documentation: { type: DateTime, required: false, nullable: true } + + expose :times_assessed, documentation: { type: Integer, required: false, nullable: true } + expose :grade, documentation: { type: String, required: false, nullable: true } + expose :quality_pts, documentation: { type: Float, required: false, nullable: true } + + expose :num_new_comments, documentation: { type: Integer } + expose :similarity_flag, documentation: { type: 'boolean' } + expose :pinned, documentation: { type: 'boolean' } + expose :has_extensions, documentation: { type: 'boolean' } + end +end diff --git a/app/api/entities/task_summary_entity.rb b/app/api/entities/task_summary_entity.rb new file mode 100644 index 000000000..356bf7410 --- /dev/null +++ b/app/api/entities/task_summary_entity.rb @@ -0,0 +1,9 @@ +module Entities + class TaskSummaryEntity < Grape::Entity + expose :id, documentation: { type: Integer } + expose :task_definition_id, documentation: { type: Integer } + expose :status, documentation: { type: String } + expose :tutorial_id, documentation: { type: Integer, required: false } + expose :tutorial_stream_id, documentation: { type: Integer, required: false } + end +end diff --git a/app/api/tasks_api.rb b/app/api/tasks_api.rb index afd9851fe..c33a9dd3d 100644 --- a/app/api/tasks_api.rb +++ b/app/api/tasks_api.rb @@ -12,7 +12,9 @@ class TasksApi < Grape::API # # Tasks only used for the task summary stats view... # - desc "Get all the current user's tasks" + desc "Get all the current user's tasks", + success: Entities::TaskSummaryEntity, + is_array: true params do requires :unit_id, type: Integer, desc: 'Unit to fetch the task details for' end @@ -45,7 +47,8 @@ class TasksApi < Grape::API } end - present result, with: Grape::Presenters::Presenter + # present result, with: Grape::Presenters::Presenter + present result, with: Entities::TaskSummaryEntity end desc 'Refresh the most frequently changed task details for a project - allowing easy refresh of student details' diff --git a/app/api/units_api.rb b/app/api/units_api.rb index 411065f97..e22cf6fbe 100644 --- a/app/api/units_api.rb +++ b/app/api/units_api.rb @@ -313,7 +313,9 @@ class UnitsApi < Grape::API present unit.tasks_as_hash(tasks), with: Grape::Presenters::Presenter end - desc 'Download the tasks that should be listed under the task inbox' + desc 'Download the tasks that should be listed under the task inbox', + success: Entities::InboxTaskEntity, + is_array: true params do optional :my_students_only, type: Boolean, desc: 'Show tasks from all tutorials or just the ones you teach' end @@ -327,7 +329,7 @@ class UnitsApi < Grape::API my_students_only = params[:my_students_only] || false tasks = unit.tasks_for_task_inbox(current_user, my_students_only) - present unit.tasks_as_hash(tasks), with: Grape::Presenters::Presenter + present unit.tasks_as_hash(tasks), with: Entities::InboxTaskEntity end desc 'Get tasks ready for moderation' diff --git a/app/models/unit.rb b/app/models/unit.rb index 671bb2325..7fd4b2923 100644 --- a/app/models/unit.rb +++ b/app/models/unit.rb @@ -2305,7 +2305,12 @@ def tasks_as_hash(data) num_new_comments: t.number_unread, similarity_flag: t.similar_to_count > 0, pinned: t.pinned, - has_extensions: t.has_extensions + has_extensions: t.has_extensions, + unit: { + id: id, + code: code, + name: name + } } end end