Skip to content

Return moved card on PUT /cards/:number/board#2849

Merged
flavorjones merged 1 commit into
basecamp:mainfrom
robzolkos:card-move-returns-body
Jun 1, 2026
Merged

Return moved card on PUT /cards/:number/board#2849
flavorjones merged 1 commit into
basecamp:mainfrom
robzolkos:card-move-returns-body

Conversation

@robzolkos

@robzolkos robzolkos commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

The JSON response for PUT /:account_slug/cards/:card_number/board was 204 No Content, which forced clients to make a follow-up GET to see the card on its new board. The Smithy contract the SDKs are generated from already declares MoveCard returns a Card, so the server was out of sync with the documented shape.

Rendering cards/show on the JSON path means the response now carries the moved card (with its new board reference) directly. The HTML redirect behavior is unchanged.

Discovered via a fizzy-cli QA sweep — fizzy card move rendered a zero-valued Card and emitted Card #N "" moved to board X (blank title) because the CLI was parsing the empty 204 body as a Card struct.

Changes

  • app/controllers/cards/boards_controller.rbformat.json { head :no_content }format.json { render "cards/show" }
  • test/controllers/cards/boards_controller_test.rb — "update as JSON" test now asserts id, number, title, and board.id on the returned body
  • docs/api/sections/cards.md — added a section documenting PUT /:account_slug/cards/:card_number/board, which was previously undocumented

Mobile App check

  • Neither mobile app has native client code calling PUT /cards/:number/board
  • Neither mobile app has code paths that depend on this endpoint returning 204 No Content
  • Neither mobile app is affected by this response change to 200 OK with the moved card

The JSON response was `204 No Content`, which forced clients to
make a follow-up GET to see the card on its new board. The Smithy
contract the SDKs are generated from already declares `MoveCard`
returns a Card, so the server was out of sync with the documented
shape.

Render `cards/show` for the JSON format so the response carries
the moved card (with the new `board` reference). The HTML format
is unchanged.

Added assertions on the returned body and added an API doc entry
for the endpoint, which was previously undocumented.
Copilot AI review requested due to automatic review settings April 16, 2026 19:52

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aligns the PUT /:account_slug/cards/:card_number/board server response with the existing Smithy contract by returning the moved card as JSON (instead of 204 No Content), so clients don’t need a follow-up GET to see the updated board reference.

Changes:

  • Return the moved card payload for JSON requests to PUT /cards/:number/board by rendering cards/show.
  • Update the controller test to assert the returned JSON includes key card fields and the new board.id.
  • Document the previously-undocumented PUT /:account_slug/cards/:card_number/board endpoint in the API docs.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
app/controllers/cards/boards_controller.rb Switch JSON response from 204 to rendering the moved card via cards/show.
test/controllers/cards/boards_controller_test.rb Assert 200 + response body includes moved card fields and updated board reference.
docs/api/sections/cards.md Add API documentation section for moving a card to a different board.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/api/sections/cards.md
@flavorjones flavorjones merged commit 49eb3ae into basecamp:main Jun 1, 2026
9 of 10 checks passed
@flavorjones

Copy link
Copy Markdown
Member

Thank you, @robzolkos!

joshyorko pushed a commit to joshyorko/fizzy that referenced this pull request Jun 2, 2026
* Return updated board on PUT /boards/:id (basecamp#2848)

* Return the updated board on PUT /:account_slug/boards/:id

The JSON response was `204 No Content`, forcing clients to make a
follow-up GET to observe their own write. The Smithy contract the
SDKs are generated from already declares `UpdateBoard` returns a
Board, so the server was out of sync with the documented shape.

Render `show` for the JSON format so PUT returns the same payload
as GET. The HTML format is unchanged.

Updated test asserts the returned body matches the updated state.
Updated API docs to show the 200 response shape.

* Handle board update access loss for JSON

* Return no content after self-removal on JSON update

* Update flat JSON board response test

* Document 204 response for board self-removal

* Update dependencies: erb 6.0.4, marcel 1.2.1 (basecamp#2911)

* Upgrade erb 6.0.2 → 6.0.4

* Upgrade marcel 1.1.0 → 1.2.1

* Bump the github-actions group across 1 directory with 7 updates (basecamp#2910)

Bumps the github-actions group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [ruby/setup-ruby](https://github.com/ruby/setup-ruby) | `1.300.0` | `1.310.0` |
| [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.2` | `0.5.6` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.0.0` | `4.1.0` |
| [docker/login-action](https://github.com/docker/login-action) | `4.1.0` | `4.2.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `6.0.0` | `6.1.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `7.1.0` | `7.2.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `4.1.1` | `4.1.2` |



Updates `ruby/setup-ruby` from 1.300.0 to 1.310.0
- [Release notes](https://github.com/ruby/setup-ruby/releases)
- [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb)
- [Commits](ruby/setup-ruby@e65c17d...afeafc3)

Updates `zizmorcore/zizmor-action` from 0.5.2 to 0.5.6
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](zizmorcore/zizmor-action@71321a2...5f14fd0)

Updates `docker/setup-buildx-action` from 4.0.0 to 4.1.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@4d04d5d...d7f5e7f)

Updates `docker/login-action` from 4.1.0 to 4.2.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@4907a6d...650006c)

Updates `docker/metadata-action` from 6.0.0 to 6.1.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](docker/metadata-action@030e881...80c7e94)

Updates `docker/build-push-action` from 7.1.0 to 7.2.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@bcafcac...f9f3042)

Updates `sigstore/cosign-installer` from 4.1.1 to 4.1.2
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](sigstore/cosign-installer@cad07c2...6f9f177)

---
updated-dependencies:
- dependency-name: ruby/setup-ruby
  dependency-version: 1.310.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.5.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/login-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/metadata-action
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/build-push-action
  dependency-version: 7.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: sigstore/cosign-installer
  dependency-version: 4.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump the development-dependencies group across 1 directory with 2 updates (basecamp#2903)

* Bump the development-dependencies group across 1 directory with 2 updates

Bumps the development-dependencies group with 2 updates in the / directory: [faker](https://github.com/faker-ruby/faker) and [selenium-webdriver](https://github.com/SeleniumHQ/selenium).


Updates `faker` from 3.6.1 to 3.8.0
- [Release notes](https://github.com/faker-ruby/faker/releases)
- [Changelog](https://github.com/faker-ruby/faker/blob/main/CHANGELOG.md)
- [Commits](faker-ruby/faker@v3.6.1...v3.8.0)

Updates `selenium-webdriver` from 4.43.0 to 4.44.0
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](SeleniumHQ/selenium@selenium-4.43.0...selenium-4.44.0)

---
updated-dependencies:
- dependency-name: faker
  dependency-version: 3.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: selenium-webdriver
  dependency-version: 4.44.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump jwt from 3.1.2 to 3.2.0 (basecamp#2902)

* Bump jwt from 3.1.2 to 3.2.0

Bumps [jwt](https://github.com/jwt/ruby-jwt) from 3.1.2 to 3.2.0.
- [Release notes](https://github.com/jwt/ruby-jwt/releases)
- [Changelog](https://github.com/jwt/ruby-jwt/blob/main/CHANGELOG.md)
- [Commits](jwt/ruby-jwt@v3.1.2...v3.2.0)

---
updated-dependencies:
- dependency-name: jwt
  dependency-version: 3.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump sqlite3 from 2.9.2 to 2.9.3 (basecamp#2883)

* Bump sqlite3 from 2.9.2 to 2.9.3

Bumps [sqlite3](https://github.com/sparklemotion/sqlite3-ruby) from 2.9.2 to 2.9.3.
- [Release notes](https://github.com/sparklemotion/sqlite3-ruby/releases)
- [Changelog](https://github.com/sparklemotion/sqlite3-ruby/blob/main/CHANGELOG.md)
- [Commits](sparklemotion/sqlite3-ruby@v2.9.2...v2.9.3)

---
updated-dependencies:
- dependency-name: sqlite3
  dependency-version: 2.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump aws-sdk-s3 from 1.218.0 to 1.219.0 (basecamp#2858)

* Bump aws-sdk-s3 from 1.218.0 to 1.219.0

Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.218.0 to 1.219.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.219.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump bootsnap from 1.23.0 to 1.24.3 (basecamp#2900)

* Bump bootsnap from 1.23.0 to 1.24.3

Bumps [bootsnap](https://github.com/rails/bootsnap) from 1.23.0 to 1.24.3.
- [Release notes](https://github.com/rails/bootsnap/releases)
- [Changelog](https://github.com/rails/bootsnap/blob/main/CHANGELOG.md)
- [Commits](rails/bootsnap@v1.23.0...v1.24.3)

---
updated-dependencies:
- dependency-name: bootsnap
  dependency-version: 1.24.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump propshaft from 1.3.1 to 1.3.2 (basecamp#2882)

* Bump propshaft from 1.3.1 to 1.3.2

Bumps [propshaft](https://github.com/rails/propshaft) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/rails/propshaft/releases)
- [Commits](rails/propshaft@v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: propshaft
  dependency-version: 1.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Improve CI output (basecamp#2912)

* Update bundle-drift to handle net-new gems

* Improve CI output

- rubocop simple output
- minitest progress bar

* Return updated user on PUT /users/:id (basecamp#2853)

* Return the updated user on PUT /:account_slug/users/:user_id

The JSON response was `204 No Content`, forcing clients to follow
up with a GET. The Smithy contract the SDKs are generated from
already declares `UpdateUser` returns a User, so the server was
out of sync with the documented shape.

Render `show` for the JSON format so PUT returns the same payload
as GET. The HTML redirect behavior is unchanged. Only name and
avatar are accepted on this endpoint, neither of which affects
the acting user's access, so no access-check branch is needed.

Updated test asserts the returned body matches the updated state.
Updated API docs to describe the 200 response shape.

* Update flat JSON user response test for 200 body

Mirrors the nested-params test in users_controller_test.rb — flat
JSON PUTs now return the updated user as the body instead of 204
No Content.

* Return the updated comment on PUT /:account_slug/cards/:card_number/comments/:comment_id (basecamp#2852)

The JSON response was `204 No Content`, which conflicted with both
the API docs ("Returns the updated comment") and the Smithy
contract the SDKs are generated from (`UpdateCommentResponseContent`).

Render `show` for the JSON format so PUT returns the same payload
as GET. The Turbo Stream format is unchanged.

Docs already describe the correct response shape, so no doc change
is needed here. Tests now assert the returned body content.

* Return updated column on PUT /boards/:id/columns/:id (basecamp#2851)

* Return the updated column on PUT /:account_slug/boards/:board_id/columns/:column_id

The JSON response was `204 No Content`, forcing clients to follow
up with a GET. The Smithy contract that the SDKs are generated
from already declares `UpdateColumn` returns a Column, so the
server was out of sync with the documented shape.

Render `show` for the JSON format so PUT returns the same payload
as GET. The Turbo Stream format is unchanged.

Updated test asserts the returned body matches the updated state.
Updated API docs to describe the 200 response shape.

* Update flat JSON column response test for 200 body

Mirrors the nested-params test in boards/columns_controller_test.rb —
flat JSON PUTs now return the updated column as the body instead
of 204 No Content.

* Return the moved card on PUT /:account_slug/cards/:card_number/board (basecamp#2849)

The JSON response was `204 No Content`, which forced clients to
make a follow-up GET to see the card on its new board. The Smithy
contract the SDKs are generated from already declares `MoveCard`
returns a Card, so the server was out of sync with the documented
shape.

Render `cards/show` for the JSON format so the response carries
the moved card (with the new `board` reference). The HTML format
is unchanged.

Added assertions on the returned body and added an API doc entry
for the endpoint, which was previously undocumented.

* Stub DNS in notification delivery tests (basecamp#2838)

* Stub DNS in notification delivery tests

* Clarify DNS stubbing in notification delivery tests

* Extract shared FCM DNS test helper

* Rename shared DNS test helper for web push

* Add :account_slug prefix to account, my/pins and my/timezone API doc paths (basecamp#2889)

* Add :account_slug prefix to account and my/pins API doc paths

The /account/* routes (settings, join_code, entropy, exports) and
/my/pins are mounted inside the per-account scope (see namespace
:account and namespace :my in config/routes.rb). They are reachable
in production as /:account_slug/account/... and /:account_slug/my/...
— the same convention the surrounding paths in these files already
follow (e.g. POST /:account_slug/cards/:card_number/pin, PUT
/:account_slug/boards/:board_id/entropy, POST
/:account_slug/users/:user_id/data_exports). Without the prefix the
client hits the root web app and gets 302'd to /session/menu, which
in turn yields 406 Not Acceptable when Accept: application/json is
set.

* Add :account_slug prefix to my/timezone API doc path

PATCH /my/timezone is mounted inside the per-account scope alongside
/my/pins (see namespace :my in config/routes.rb). It is reachable in
production as PATCH /:account_slug/my/timezone — without the prefix the
client hits the root web app and gets 302'd to /session/menu, which in
turn yields 406 Not Acceptable when Accept: application/json is set.

Same fix as the previous commit on this branch; this one was missed.

* fix: Add tooltip controller to reactions trigger button (basecamp#2763)

* fix: Add tooltip controller to reactions trigger button

* review

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Rob Zolkos <rob@zolkos.com>
Co-authored-by: Mike Dalessio <mike@37signals.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Rogério Vicente <rogerio@hey.com>
Co-authored-by: Michal Landsman <landsman@insuit.cz>
joshyorko added a commit to joshyorko/fizzy that referenced this pull request Jun 2, 2026
* Return updated board on PUT /boards/:id (basecamp#2848)

* Return the updated board on PUT /:account_slug/boards/:id

The JSON response was `204 No Content`, forcing clients to make a
follow-up GET to observe their own write. The Smithy contract the
SDKs are generated from already declares `UpdateBoard` returns a
Board, so the server was out of sync with the documented shape.

Render `show` for the JSON format so PUT returns the same payload
as GET. The HTML format is unchanged.

Updated test asserts the returned body matches the updated state.
Updated API docs to show the 200 response shape.

* Handle board update access loss for JSON

* Return no content after self-removal on JSON update

* Update flat JSON board response test

* Document 204 response for board self-removal

* Update dependencies: erb 6.0.4, marcel 1.2.1 (basecamp#2911)

* Upgrade erb 6.0.2 → 6.0.4

* Upgrade marcel 1.1.0 → 1.2.1

* Bump the github-actions group across 1 directory with 7 updates (basecamp#2910)

Bumps the github-actions group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [ruby/setup-ruby](https://github.com/ruby/setup-ruby) | `1.300.0` | `1.310.0` |
| [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.2` | `0.5.6` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.0.0` | `4.1.0` |
| [docker/login-action](https://github.com/docker/login-action) | `4.1.0` | `4.2.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `6.0.0` | `6.1.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `7.1.0` | `7.2.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `4.1.1` | `4.1.2` |



Updates `ruby/setup-ruby` from 1.300.0 to 1.310.0
- [Release notes](https://github.com/ruby/setup-ruby/releases)
- [Changelog](https://github.com/ruby/setup-ruby/blob/master/release.rb)
- [Commits](ruby/setup-ruby@e65c17d...afeafc3)

Updates `zizmorcore/zizmor-action` from 0.5.2 to 0.5.6
- [Release notes](https://github.com/zizmorcore/zizmor-action/releases)
- [Commits](zizmorcore/zizmor-action@71321a2...5f14fd0)

Updates `docker/setup-buildx-action` from 4.0.0 to 4.1.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@4d04d5d...d7f5e7f)

Updates `docker/login-action` from 4.1.0 to 4.2.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@4907a6d...650006c)

Updates `docker/metadata-action` from 6.0.0 to 6.1.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](docker/metadata-action@030e881...80c7e94)

Updates `docker/build-push-action` from 7.1.0 to 7.2.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@bcafcac...f9f3042)

Updates `sigstore/cosign-installer` from 4.1.1 to 4.1.2
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](sigstore/cosign-installer@cad07c2...6f9f177)

---
updated-dependencies:
- dependency-name: ruby/setup-ruby
  dependency-version: 1.310.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: zizmorcore/zizmor-action
  dependency-version: 0.5.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/login-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/metadata-action
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/build-push-action
  dependency-version: 7.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: sigstore/cosign-installer
  dependency-version: 4.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump the development-dependencies group across 1 directory with 2 updates (basecamp#2903)

* Bump the development-dependencies group across 1 directory with 2 updates

Bumps the development-dependencies group with 2 updates in the / directory: [faker](https://github.com/faker-ruby/faker) and [selenium-webdriver](https://github.com/SeleniumHQ/selenium).


Updates `faker` from 3.6.1 to 3.8.0
- [Release notes](https://github.com/faker-ruby/faker/releases)
- [Changelog](https://github.com/faker-ruby/faker/blob/main/CHANGELOG.md)
- [Commits](faker-ruby/faker@v3.6.1...v3.8.0)

Updates `selenium-webdriver` from 4.43.0 to 4.44.0
- [Release notes](https://github.com/SeleniumHQ/selenium/releases)
- [Changelog](https://github.com/SeleniumHQ/selenium/blob/trunk/rb/CHANGES)
- [Commits](SeleniumHQ/selenium@selenium-4.43.0...selenium-4.44.0)

---
updated-dependencies:
- dependency-name: faker
  dependency-version: 3.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
- dependency-name: selenium-webdriver
  dependency-version: 4.44.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump jwt from 3.1.2 to 3.2.0 (basecamp#2902)

* Bump jwt from 3.1.2 to 3.2.0

Bumps [jwt](https://github.com/jwt/ruby-jwt) from 3.1.2 to 3.2.0.
- [Release notes](https://github.com/jwt/ruby-jwt/releases)
- [Changelog](https://github.com/jwt/ruby-jwt/blob/main/CHANGELOG.md)
- [Commits](jwt/ruby-jwt@v3.1.2...v3.2.0)

---
updated-dependencies:
- dependency-name: jwt
  dependency-version: 3.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump sqlite3 from 2.9.2 to 2.9.3 (basecamp#2883)

* Bump sqlite3 from 2.9.2 to 2.9.3

Bumps [sqlite3](https://github.com/sparklemotion/sqlite3-ruby) from 2.9.2 to 2.9.3.
- [Release notes](https://github.com/sparklemotion/sqlite3-ruby/releases)
- [Changelog](https://github.com/sparklemotion/sqlite3-ruby/blob/main/CHANGELOG.md)
- [Commits](sparklemotion/sqlite3-ruby@v2.9.2...v2.9.3)

---
updated-dependencies:
- dependency-name: sqlite3
  dependency-version: 2.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump aws-sdk-s3 from 1.218.0 to 1.219.0 (basecamp#2858)

* Bump aws-sdk-s3 from 1.218.0 to 1.219.0

Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.218.0 to 1.219.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.219.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump bootsnap from 1.23.0 to 1.24.3 (basecamp#2900)

* Bump bootsnap from 1.23.0 to 1.24.3

Bumps [bootsnap](https://github.com/rails/bootsnap) from 1.23.0 to 1.24.3.
- [Release notes](https://github.com/rails/bootsnap/releases)
- [Changelog](https://github.com/rails/bootsnap/blob/main/CHANGELOG.md)
- [Commits](rails/bootsnap@v1.23.0...v1.24.3)

---
updated-dependencies:
- dependency-name: bootsnap
  dependency-version: 1.24.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Bump propshaft from 1.3.1 to 1.3.2 (basecamp#2882)

* Bump propshaft from 1.3.1 to 1.3.2

Bumps [propshaft](https://github.com/rails/propshaft) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/rails/propshaft/releases)
- [Commits](rails/propshaft@v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: propshaft
  dependency-version: 1.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* Improve CI output (basecamp#2912)

* Update bundle-drift to handle net-new gems

* Improve CI output

- rubocop simple output
- minitest progress bar

* Return updated user on PUT /users/:id (basecamp#2853)

* Return the updated user on PUT /:account_slug/users/:user_id

The JSON response was `204 No Content`, forcing clients to follow
up with a GET. The Smithy contract the SDKs are generated from
already declares `UpdateUser` returns a User, so the server was
out of sync with the documented shape.

Render `show` for the JSON format so PUT returns the same payload
as GET. The HTML redirect behavior is unchanged. Only name and
avatar are accepted on this endpoint, neither of which affects
the acting user's access, so no access-check branch is needed.

Updated test asserts the returned body matches the updated state.
Updated API docs to describe the 200 response shape.

* Update flat JSON user response test for 200 body

Mirrors the nested-params test in users_controller_test.rb — flat
JSON PUTs now return the updated user as the body instead of 204
No Content.

* Return the updated comment on PUT /:account_slug/cards/:card_number/comments/:comment_id (basecamp#2852)

The JSON response was `204 No Content`, which conflicted with both
the API docs ("Returns the updated comment") and the Smithy
contract the SDKs are generated from (`UpdateCommentResponseContent`).

Render `show` for the JSON format so PUT returns the same payload
as GET. The Turbo Stream format is unchanged.

Docs already describe the correct response shape, so no doc change
is needed here. Tests now assert the returned body content.

* Return updated column on PUT /boards/:id/columns/:id (basecamp#2851)

* Return the updated column on PUT /:account_slug/boards/:board_id/columns/:column_id

The JSON response was `204 No Content`, forcing clients to follow
up with a GET. The Smithy contract that the SDKs are generated
from already declares `UpdateColumn` returns a Column, so the
server was out of sync with the documented shape.

Render `show` for the JSON format so PUT returns the same payload
as GET. The Turbo Stream format is unchanged.

Updated test asserts the returned body matches the updated state.
Updated API docs to describe the 200 response shape.

* Update flat JSON column response test for 200 body

Mirrors the nested-params test in boards/columns_controller_test.rb —
flat JSON PUTs now return the updated column as the body instead
of 204 No Content.

* Return the moved card on PUT /:account_slug/cards/:card_number/board (basecamp#2849)

The JSON response was `204 No Content`, which forced clients to
make a follow-up GET to see the card on its new board. The Smithy
contract the SDKs are generated from already declares `MoveCard`
returns a Card, so the server was out of sync with the documented
shape.

Render `cards/show` for the JSON format so the response carries
the moved card (with the new `board` reference). The HTML format
is unchanged.

Added assertions on the returned body and added an API doc entry
for the endpoint, which was previously undocumented.

* Stub DNS in notification delivery tests (basecamp#2838)

* Stub DNS in notification delivery tests

* Clarify DNS stubbing in notification delivery tests

* Extract shared FCM DNS test helper

* Rename shared DNS test helper for web push

* Add :account_slug prefix to account, my/pins and my/timezone API doc paths (basecamp#2889)

* Add :account_slug prefix to account and my/pins API doc paths

The /account/* routes (settings, join_code, entropy, exports) and
/my/pins are mounted inside the per-account scope (see namespace
:account and namespace :my in config/routes.rb). They are reachable
in production as /:account_slug/account/... and /:account_slug/my/...
— the same convention the surrounding paths in these files already
follow (e.g. POST /:account_slug/cards/:card_number/pin, PUT
/:account_slug/boards/:board_id/entropy, POST
/:account_slug/users/:user_id/data_exports). Without the prefix the
client hits the root web app and gets 302'd to /session/menu, which
in turn yields 406 Not Acceptable when Accept: application/json is
set.

* Add :account_slug prefix to my/timezone API doc path

PATCH /my/timezone is mounted inside the per-account scope alongside
/my/pins (see namespace :my in config/routes.rb). It is reachable in
production as PATCH /:account_slug/my/timezone — without the prefix the
client hits the root web app and gets 302'd to /session/menu, which in
turn yields 406 Not Acceptable when Accept: application/json is set.

Same fix as the previous commit on this branch; this one was missed.

* fix: Add tooltip controller to reactions trigger button (basecamp#2763)

* fix: Add tooltip controller to reactions trigger button

* review

* Enable Kamal GHA build cache

* Use Node 24 GitHub runtime cache action

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Rob Zolkos <rob@zolkos.com>
Co-authored-by: Mike Dalessio <mike@37signals.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Rogério Vicente <rogerio@hey.com>
Co-authored-by: Michal Landsman <landsman@insuit.cz>
Co-authored-by: Josh Yorko <joshyorko@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants