From 7b30ca203e0892931c63f6323142041bb7dc0f73 Mon Sep 17 00:00:00 2001 From: "Stanko K.R." Date: Tue, 9 Dec 2025 17:03:27 +0100 Subject: [PATCH] Add index actions for Comments and Columns Also, fix crash when a deactivated user is serialized (they don't have an identity). --- app/controllers/boards/columns_controller.rb | 5 + app/controllers/cards/comments_controller.rb | 4 + app/views/boards/columns/index.json.jbuilder | 1 + app/views/cards/comments/index.json.jbuilder | 1 + app/views/users/_user.json.jbuilder | 2 +- docs/API.md | 108 +++++++++++++++++- .../boards/columns_controller_test.rb | 9 ++ .../cards/comments_controller_test.rb | 9 ++ 8 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 app/views/boards/columns/index.json.jbuilder create mode 100644 app/views/cards/comments/index.json.jbuilder diff --git a/app/controllers/boards/columns_controller.rb b/app/controllers/boards/columns_controller.rb index 1532d76dc..4f6770e28 100644 --- a/app/controllers/boards/columns_controller.rb +++ b/app/controllers/boards/columns_controller.rb @@ -3,6 +3,11 @@ class Boards::ColumnsController < ApplicationController before_action :set_column, only: %i[ show update destroy ] + def index + @columns = @board.columns.sorted + fresh_when etag: @columns + end + def show set_page_and_extract_portion_from @column.cards.active.latest.with_golden_first.preloaded fresh_when etag: @page.records diff --git a/app/controllers/cards/comments_controller.rb b/app/controllers/cards/comments_controller.rb index c38181862..d353930ee 100644 --- a/app/controllers/cards/comments_controller.rb +++ b/app/controllers/cards/comments_controller.rb @@ -4,6 +4,10 @@ class Cards::CommentsController < ApplicationController before_action :set_comment, only: %i[ show edit update destroy ] before_action :ensure_creatorship, only: %i[ edit update destroy ] + def index + set_page_and_extract_portion_from @card.comments.chronologically + end + def create @comment = @card.comments.create!(comment_params) diff --git a/app/views/boards/columns/index.json.jbuilder b/app/views/boards/columns/index.json.jbuilder new file mode 100644 index 000000000..4142996de --- /dev/null +++ b/app/views/boards/columns/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @columns, partial: "columns/column", as: :column diff --git a/app/views/cards/comments/index.json.jbuilder b/app/views/cards/comments/index.json.jbuilder new file mode 100644 index 000000000..7e261ccc7 --- /dev/null +++ b/app/views/cards/comments/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @page.records, partial: "cards/comments/comment", as: :comment diff --git a/app/views/users/_user.json.jbuilder b/app/views/users/_user.json.jbuilder index 6a49bd1de..0884f225a 100644 --- a/app/views/users/_user.json.jbuilder +++ b/app/views/users/_user.json.jbuilder @@ -1,7 +1,7 @@ json.cache! user do json.(user, :id, :name, :role, :active) - json.email_address user.identity.email_address + json.email_address user.identity&.email_address json.created_at user.created_at.utc json.url user_url(user) diff --git a/docs/API.md b/docs/API.md index da347025d..8673cf37b 100644 --- a/docs/API.md +++ b/docs/API.md @@ -351,7 +351,7 @@ __Request:__ "name": "Updated board name", "auto_postpone_period": 14, "public_description": "This is a **public** description of the board.", - all_access: false, + "all_access": false, "user_ids": [ "03f5v9zppzlksuj4mxba2nbzn", "03f5v9zjw7pz8717a4no1h8a7" @@ -594,6 +594,37 @@ Returns `204 No Content` on success. Comments are attached to cards and support rich text. +#### `GET /:account_slug/cards/:card_number/comments` + +Returns a paginated list of comments on a card, sorted chronologically (oldest first). + +__Response:__ + +```json +[ + { + "id": "03f5v9zo9qlcwwpyc0ascnikz", + "created_at": "2025-12-05T19:36:35.534Z", + "updated_at": "2025-12-05T19:36:35.534Z", + "body": { + "plain_text": "This looks great!", + "html": "
This looks great!
" + }, + "creator": { + "id": "03f5v9zjw7pz8717a4no1h8a7", + "name": "David Heinemeier Hansson", + "role": "owner", + "active": true, + "email_address": "david@example.com", + "created_at": "2025-12-05T19:36:35.401Z", + "url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7" + }, + "reactions_url": "http://fizzy.localhost:3006/897362094/cards/3/comments/03f5v9zo9qlcwwpyc0ascnikz/reactions", + "url": "http://fizzy.localhost:3006/897362094/cards/3/comments/03f5v9zo9qlcwwpyc0ascnikz" + } +] +``` + #### `GET /:account_slug/cards/:card_number/comments/:comment_id` Returns a specific comment. @@ -679,6 +710,31 @@ Returns `204 No Content` on success. Reactions are short - 16 character long - responses to comments. +#### `GET /:account_slug/cards/:card_number/comments/:comment_id/reactions` + +Returns a list of reactions on a comment. + +__Response:__ + +```json +[ + { + "id": "03f5v9zo9qlcwwpyc0ascnikz", + "content": "👍", + "reacter": { + "id": "03f5v9zjw7pz8717a4no1h8a7", + "name": "David Heinemeier Hansson", + "role": "owner", + "active": true, + "email_address": "david@example.com", + "created_at": "2025-12-05T19:36:35.401Z", + "url": "http://fizzy.localhost:3006/897362094/users/03f5v9zjw7pz8717a4no1h8a7" + }, + "url": "http://fizzy.localhost:3006/897362094/cards/3/comments/03f5v9zo9qlcwwpyc0ascnikz/reactions/03f5v9zo9qlcwwpyc0ascnikz" + } +] +``` + #### `POST /:account_slug/cards/:card_number/comments/:comment_id/reactions` Adds a reaction to a comment. @@ -785,6 +841,29 @@ Returns `204 No Content` on success. Columns represent stages in a workflow on a board. Cards move through columns as they progress. +#### `GET /:account_slug/boards/:board_id/columns` + +Returns a list of columns on a board, sorted by position. + +__Response:__ + +```json +[ + { + "id": "03f5v9zkft4hj9qq0lsn9ohcm", + "name": "Recording", + "color": "var(--color-card-default)", + "created_at": "2025-12-05T19:36:35.534Z" + }, + { + "id": "03f5v9zkft4hj9qq0lsn9ohcn", + "name": "Published", + "color": "var(--color-card-4)", + "created_at": "2025-12-05T19:36:35.534Z" + } +] +``` + #### `GET /:account_slug/boards/:board_id/columns/:column_id` Returns the specified column. @@ -1017,3 +1096,30 @@ Marks all unread notifications as read. __Response:__ Returns `204 No Content` on success. + +### Tags + +Tags are labels that can be applied to cards for organization and filtering. + +#### `GET /:account_slug/tags` + +Returns a list of all tags in the account, sorted alphabetically. + +__Response:__ + +```json +[ + { + "id": "03f5v9zo9qlcwwpyc0ascnikz", + "title": "bug", + "created_at": "2025-12-05T19:36:35.534Z", + "url": "http://fizzy.localhost:3006/897362094/cards?tag_ids[]=03f5v9zo9qlcwwpyc0ascnikz" + }, + { + "id": "03f5v9zo9qlcwwpyc0ascnilz", + "title": "feature", + "created_at": "2025-12-05T19:36:35.534Z", + "url": "http://fizzy.localhost:3006/897362094/cards?tag_ids[]=03f5v9zo9qlcwwpyc0ascnilz" + } +] +``` diff --git a/test/controllers/boards/columns_controller_test.rb b/test/controllers/boards/columns_controller_test.rb index 2bc96357c..d7542da27 100644 --- a/test/controllers/boards/columns_controller_test.rb +++ b/test/controllers/boards/columns_controller_test.rb @@ -37,6 +37,15 @@ class Boards::ColumnsControllerTest < ActionDispatch::IntegrationTest end end + test "index as JSON" do + board = boards(:writebook) + + get board_columns_path(board), as: :json + + assert_response :success + assert_equal board.columns.count, @response.parsed_body.count + end + test "show as JSON" do column = columns(:writebook_in_progress) diff --git a/test/controllers/cards/comments_controller_test.rb b/test/controllers/cards/comments_controller_test.rb index 8fc0289be..138fada59 100644 --- a/test/controllers/cards/comments_controller_test.rb +++ b/test/controllers/cards/comments_controller_test.rb @@ -28,6 +28,15 @@ class Cards::CommentsControllerTest < ActionDispatch::IntegrationTest assert_response :forbidden end + test "index as JSON" do + card = cards(:logo) + + get card_comments_path(card), as: :json + + assert_response :success + assert_equal card.comments.count, @response.parsed_body.count + end + test "create as JSON" do card = cards(:logo)