diff --git a/apps/api/app/controllers/api/events_controller.rb b/apps/api/app/controllers/api/events_controller.rb index fccb296..b0e40ac 100644 --- a/apps/api/app/controllers/api/events_controller.rb +++ b/apps/api/app/controllers/api/events_controller.rb @@ -4,7 +4,10 @@ class Api::EventsController < ApiController end api :GET, "/api/events", "List all events" - returns code: 200, desc: "Array of events" + returns code: 200, desc: "Array of events" do + property :name, String, desc: "Event name" + property :date, String, desc: "Event date (ISO 8601)" + end def index render json: EventService.new.index end diff --git a/apps/api/app/controllers/api/members_controller.rb b/apps/api/app/controllers/api/members_controller.rb index 27a75d2..d81a2c2 100644 --- a/apps/api/app/controllers/api/members_controller.rb +++ b/apps/api/app/controllers/api/members_controller.rb @@ -4,7 +4,13 @@ class Api::MembersController < ApiController end api :GET, "/api/members", "List all team members" - returns code: 200, desc: "Array of team members" + returns code: 200, desc: "Array of team members" do + property :nick, String, desc: "Nickname" + property :real_nick, String, desc: "Real name" + property :motto, String, desc: "Motto / tagline" + property :avatar_filename, String, desc: "Avatar filename" + property :image_url, String, desc: "Avatar image URL (e.g. /api/image/123)" + end def index render json: MemberService.new.index end diff --git a/apps/api/app/controllers/api/software_controller.rb b/apps/api/app/controllers/api/software_controller.rb index c6275e1..6da6dfb 100644 --- a/apps/api/app/controllers/api/software_controller.rb +++ b/apps/api/app/controllers/api/software_controller.rb @@ -3,8 +3,56 @@ class Api::SoftwareController < ApiController short "Software catalog" end + def_param_group :external_link do + property :ID, Integer, desc: "Link ID" + property :softwareId, Integer, desc: "Parent software ID" + property :label, String, desc: "Link label (e.g. GitHub)" + property :url, String, desc: "Link URL" + end + + def_param_group :software_image do + property :url, String, desc: "Image URL (e.g. /api/image/123)" + property :isDefault, :boolean, desc: "Default image flag" + property :position, Integer, desc: "Display order" + end + + def_param_group :release do + property :ID, Integer, desc: "Release ID" + property :softwareId, Integer, desc: "Parent software ID" + property :version, String, desc: "Version string" + property :cartridgePath, String, desc: "Cartridge file path" + property :sourcePath, String, desc: "Source file path" + property :htmlFolderPath, String, desc: "HTML playable folder path" + property :docsFolderPath, String, desc: "Documentation folder path" + property :downloadCount, Integer, desc: "Download count for this release" + end + api :GET, "/api/software", "List all software entries with releases" - returns code: 200, desc: "Array of software entries with nested releases" + returns code: 200, desc: "Wrapper object with softwares array" do + property :softwares, Array, desc: "Array of software entries" do + property :ID, Integer, desc: "Software ID" + property :name, String, desc: "Internal name" + property :title, String, desc: "Display title" + property :author, String, desc: "Author name" + property :desc, String, desc: "Short description" + property :story, String, desc: "Long description / story" + property :license, String, desc: "License type" + property :platform, String, desc: "Platform (tic80, love, ebitengine, c64)" + property :status, String, desc: "Status (active, inactive)" + property :highlighted, :boolean, desc: "Currently highlighted" + property :imageUrl, String, desc: "Default image URL" + property :externalLinks, Array, desc: "External links" do + property :ID, Integer, desc: "Link ID" + property :label, String, desc: "Link label" + property :url, String, desc: "Link URL" + end + property :images, Array, desc: "Image gallery" do + property :url, String, desc: "Image URL" + property :isDefault, :boolean, desc: "Default image flag" + property :position, Integer, desc: "Display order" + end + end + end def index render json: SoftwareService.new.index end diff --git a/apps/api/app/controllers/api/software_highlighted_controller.rb b/apps/api/app/controllers/api/software_highlighted_controller.rb index 88b7219..35489ef 100644 --- a/apps/api/app/controllers/api/software_highlighted_controller.rb +++ b/apps/api/app/controllers/api/software_highlighted_controller.rb @@ -4,7 +4,33 @@ class Api::SoftwareHighlightedController < ApiController end api :GET, "/api/software/highlighted", "Get currently highlighted software entry" - returns code: 200, desc: "Highlighted software entry with releases" + returns code: 200, desc: "Highlighted software with releases and stats" do + property :software, Hash, desc: "Software entry" do + property :ID, Integer, desc: "Software ID" + property :name, String, desc: "Internal name" + property :title, String, desc: "Display title" + property :author, String, desc: "Author name" + property :desc, String, desc: "Short description" + property :story, String, desc: "Long description / story" + property :license, String, desc: "License type" + property :platform, String, desc: "Platform (tic80, love, ebitengine, c64)" + property :status, String, desc: "Status" + property :highlighted, :boolean, desc: "Highlighted flag" + property :imageUrl, String, desc: "Default image URL" + end + property :releases, Array, desc: "All releases" do + property :ID, Integer, desc: "Release ID" + property :version, String, desc: "Version string" + property :cartridgePath, String, desc: "Cartridge path" + property :sourcePath, String, desc: "Source path" + property :htmlFolderPath, String, desc: "HTML folder path" + property :docsFolderPath, String, desc: "Docs folder path" + property :downloadCount, Integer, desc: "Download count" + end + property :latestRelease, Hash, desc: "Latest release object" + property :webPlayableRelease, Hash, desc: "Web-playable release (if any)" + property :totalDownloads, Integer, desc: "Total download count across all releases" + end error code: 404, desc: "No highlighted software found" def index result = SoftwareHighlightedService.new.index diff --git a/apps/api/app/controllers/api/swagger_controller.rb b/apps/api/app/controllers/api/swagger_controller.rb new file mode 100644 index 0000000..3a1fd43 --- /dev/null +++ b/apps/api/app/controllers/api/swagger_controller.rb @@ -0,0 +1,43 @@ +class Api::SwaggerController < ActionController::Base + layout false + + def index + render html: swagger_html.html_safe + end + + private + + def swagger_html + <<~HTML + + + + + + Teletype Games API + + + + +
+ + + + + HTML + end +end diff --git a/apps/api/app/controllers/api/wiki_controller.rb b/apps/api/app/controllers/api/wiki_controller.rb index 48f7942..d14a403 100644 --- a/apps/api/app/controllers/api/wiki_controller.rb +++ b/apps/api/app/controllers/api/wiki_controller.rb @@ -7,7 +7,24 @@ class Api::WikiController < ApiController param :tag, String, required: false, desc: "Filter by tag (blog, howto)" param :limit, :number, required: false, desc: "Limit number of results" param :body, String, required: false, desc: "Include body content (1 = yes)" - returns code: 200, desc: "Array of wiki pages" + returns code: 200, desc: "Wiki pages response" do + property :tag, String, desc: "Applied tag filter" + property :count, Integer, desc: "Number of pages returned" + property :pages, Array, desc: "Array of wiki pages" do + property :id, String, desc: "Page ID" + property :path, String, desc: "Page path" + property :title, String, desc: "Page title" + property :description, String, desc: "Short description" + property :createdAt, String, desc: "Created date (ISO 8601)" + property :updatedAt, String, desc: "Updated date (ISO 8601)" + property :locale, String, desc: "Locale code" + property :route, String, desc: "URL slug" + property :tags, Array, of: String, desc: "Tags" + property :render, String, desc: "Rendered HTML content" + property :content, String, desc: "Raw markdown content" + end + property :error, String, desc: "Error message (null on success)" + end # GET /api/wiki/pages?tag=blog|howto[&limit=30][&body=1] def index render json: WikiService.new.pages( diff --git a/apps/api/app/controllers/update_controller.rb b/apps/api/app/controllers/update_controller.rb index 051c432..b80d94a 100644 --- a/apps/api/app/controllers/update_controller.rb +++ b/apps/api/app/controllers/update_controller.rb @@ -6,10 +6,10 @@ class UpdateController < ApiController api :GET, "/update", "Update software version in database" param :secret, String, required: true, desc: "Authorization secret" - param :platform, String, required: false, desc: "Platform name" + param :platform, String, required: false, desc: "Platform (tic80, love, ebitengine, c64)" param :name, String, required: false, desc: "Software name" param :version, String, required: true, desc: "Version string" - returns code: 200, desc: "'Updated' on success" + returns code: 200, desc: "Plain text 'Updated'" error code: 401, desc: "Invalid secret" error code: 400, desc: "Version not provided or invalid arguments" error code: 500, desc: "Internal server error" diff --git a/apps/api/config/initializers/apipie.rb b/apps/api/config/initializers/apipie.rb index 11760f6..8746de5 100644 --- a/apps/api/config/initializers/apipie.rb +++ b/apps/api/config/initializers/apipie.rb @@ -11,4 +11,6 @@ Apipie.configure do |config| config.translate = false config.default_version = "1.0" config.app_info = "Teletype Games retro game library API" + config.swagger_content_type_input = :json + config.swagger_json_input_uses_refs = true end diff --git a/apps/api/config/routes.rb b/apps/api/config/routes.rb index 20f4df1..dd7c948 100644 --- a/apps/api/config/routes.rb +++ b/apps/api/config/routes.rb @@ -4,6 +4,7 @@ Rails.application.routes.draw do ActiveAdmin.routes(self) namespace :api do + get "swagger", to: "swagger#index" get "software", to: "software#index" get "software/highlighted", to: "software_highlighted#index" get "events", to: "events#index"