Commit Graph

69 Commits

Author SHA1 Message Date
Jeremy Daer a52b6f1c87 Add explicit wrap_parameters to all controllers (#2680)
* Add explicit wrap_parameters to controllers for flat JSON API support

Virtual attributes (has_rich_text, has_one_attached, delegated setters,
ActiveModel attrs) are not in Model.attribute_names, so wrap_parameters
auto-detection silently drops them from flat JSON requests. Add explicit
include: lists matching each controller's permitted params.

* Convert short-form wrap_parameters to explicit include: lists

Defense-in-depth: these controllers only have real-column params today,
so auto-detection works, but explicit lists prevent future regressions
if virtual attributes are added.

* Add flat JSON param tests for all wrap_parameters controllers

17 new tests covering every controller with wrap_parameters, verifying
that flat (unwrapped) JSON payloads are correctly wrapped and processed.
Focuses on virtual attributes that would be silently dropped without
explicit include: lists.
2026-03-09 21:47:05 -07:00
Jeremy Daer 723c8180b4 Add JSON response format for full SDK/CLI coverage (#2675)
* Add JSON response format to void-response controller actions

Add respond_to blocks with JSON format to 14 controllers that
previously only rendered HTML or Turbo Stream responses. JSON
callers get head :no_content (or :created/:ok for push
subscriptions, distinguishing new vs existing).

Covers: board involvements, board/account entropies, column
reordering, card readings, card publishing, user roles, user
avatars, account settings, notification settings, join codes
(with 422 error branch), and push subscriptions.

* Add steps index endpoint with JSON view

Add index action to Cards::StepsController so SDK/CLI callers
can list all steps for a card. Reuses the existing _step.json
partial.

* Add JSON views for paginated card list endpoints

Add show.json.jbuilder for stream, not-now, and closed column
endpoints. No controller changes needed — set_page_and_extract_
portion_from and fresh_when already work format-agnostically.

* Add JSON search endpoint with distinct-card pagination

JSON search paginates distinct Card records (via the existing
Card.mentioning scope with .distinct) rather than Search::Record
objects. This ensures page boundaries, Link headers, and counts
reflect unique cards — no short pages from post-pagination dedup.

ID-match searches return a uniform single-element Card[] array
through the same pagination path.

* Add JSON views for settings and configuration endpoints

Add show.json.jbuilder for account settings (name), join codes
(code, usage_count, usage_limit, url, active), and notification
settings (bundle_email_frequency). Tests for show and update
were added in the void-response commit.

* Add JSON response format to data exports

Create returns 201 with export id, status, and created_at so
callers can poll. Show returns any-status exports for JSON (not
just completed) with a download_url when ready, or 404 for
missing/other-user exports.

* Extend access token JSON API

Add index.json and _access_token.json partial for listing tokens.
Add JSON format to destroy. Include id and created_at in the
create response alongside the existing token/description/permission
fields.

* Fix ambiguous precedence warning in export JSON view

* Assert X-Total-Count pagination header in streams JSON test

* Address review feedback

- Guard steps index against HTML requests (redirect to card)
- Normalize created_at to UTC in access token and export JSON
- Add deterministic ordering (.latest) to search JSON pagination

* Return 406 for HTML requests to steps index instead of redirect

* Add wrap_parameters for flat SDK JSON payload compatibility

Five controllers infer the wrong wrapper key from their class
name, so flat JSON bodies like {"role":"admin"} fail with 400.
Add explicit wrap_parameters declarations:

- Users::RolesController → :user
- Notifications::SettingsController → :user_settings
- Account::JoinCodesController → :account_join_code
- Account::SettingsController → :account
- Boards::EntropiesController → :board

Add integration tests that send flat (unwrapped) JSON payloads
for all seven param-bearing endpoints to prove SDK compatibility.

* Address PR review feedback

- Use 201 Created (not 204) for all create actions: publishes, readings,
  left/right positions, push subscriptions
- Simplify push subscription to always return :created (no 200/201 variance)
- Remove superfluous respond_to block from steps#index
- Merge exports#show into single respond_to block
- Move export download_url conditional out of inline args
- Ensure join code active is explicitly boolean
- Remove extra parens from search controller assignment
- Add blank lines between format blocks for readability

* Return JSON bodies on create actions

Create actions for boards, cards, columns, comments, and steps now
render the resource as JSON (via their show views) instead of returning
empty 201 responses with only a Location header. SDKs expect a JSON
body they can deserialize into the created resource.

* Return JSON bodies on reaction create actions

Card and comment reaction creates now render the reaction as JSON
instead of returning empty 201 responses, consistent with the other
resource-creating endpoints.

* Allow access tokens API without account scope

Access tokens are identity-level (not account-scoped), so the
controller needs to work with bearer token auth and no account slug
in the URL. Skip require_account so the bearer token auth path
can proceed.

Also fix involvement test to send params in JSON body (not query
string) to match real SDK usage.
2026-03-09 11:39:49 -07:00
Jorge Manrubia f58a1aeb31 Use a dedicated resource for showing cards in draft mode
Mobile team needs this. Also, this lets us get rid from some conditionals for handling
both modes with a single template.

https://3.basecamp.com/2914079/buckets/44843469/messages/9437287330
2026-01-08 10:40:21 +01:00
Jorge Manrubia 85bfa7aa48 Rename method 2026-01-05 16:01:25 +01:00
Jorge Manrubia 5f38e8957e Reapply "Make sure new card drafts are refreshed when reused"
This reverts commit 045ddf78f3.
2026-01-05 15:58:29 +01:00
Jorge Manrubia 045ddf78f3 Revert "Make sure new card drafts are refreshed when reused"
This reverts commit 3008011175.
2026-01-05 15:58:16 +01:00
Jorge Manrubia 3008011175 Make sure new card drafts are refreshed when reused
To deal with old timestamps messing with card ordering and so.

https://app.fizzy.do/5986089/cards/3495
2026-01-05 15:57:48 +01:00
Rosa Gutierrez 641e67dc2e Remove status from allowed parameters in CardsController#update
We don't allow changing the status via this action, and it's confusing
and can lead to cases where someone can set someone's else card as
draft, effectively hiding it.
2025-12-19 22:35:30 +01:00
Rosa Gutierrez 1e640643e9 Remove unused tag_ids parameter from CardsController#update
This is no longer used in the normal flow of the app. The tags are added
via `Cards::TaggingsController`.
2025-12-19 11:16:20 +01:00
Jankees van Woezik 78fc80cf35 API: Allow updates to last_active_at (#2076)
* Allow Card#last_updated_at to be set

This is useful when doing an import from another system. I'm currently
working on a script to import our Github issues into Fizzy.

This is discussed in
https://github.com/basecamp/fizzy/pull/2056#discussion_r2609560246

* Add nil fallback and expand test coverage for last_active_at

Adds a safety fallback to Time.current if created_at is unexpectedly nil
during card creation.

Test coverage to verify:
* last_active_at defaults to created_at when not provided
* last_active_at can be updated via API on existing cards
* import workflow where last_active_at is restored after comments
* publishing doesn't overwrite explicit last_active_at values

---------

Co-authored-by: Jeremy Daer <jeremy@37signals.com>
2025-12-11 19:06:03 -08:00
Jankees van Woezik 477b4d65f2 API: Support created_at for API card and comment creation (#2056)
* Add support to set `created_at`

Discussed in
https://github.com/basecamp/fizzy/pull/1766#issuecomment-3637846074,
this allows users to import cards from another system with entries from
the past. For instance I'm importing all our Github issues (including
the closed onces) to Fizzy.

* Iron out published state tracking

---------

Co-authored-by: Jeremy Daer <jeremy@37signals.com>
2025-12-10 19:57:38 -08:00
Stanko K.R. 235a94355e Add card update & delete actions 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson ae0eaadcdf Publish any API card as soon as it is created 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 983a19fd8a Create cards via API 2025-12-10 09:23:52 +01:00
Mike Dalessio b05ecb7809 Update card buttons dynamically
User flows when editing a card look like:
- Click "Edit" → the closure buttons are replaced by "Save changes"
- Submit card form → Saves and restores closure buttons
- Press ESC while editing → Cancels and restores closure buttons

Also, renamed for clarity:
- _title.html.erb → _content.html.erb

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 12:14:39 -05:00
David Heinemeier Hansson c606de7b41 Instead of trying to suppress from the wrong layer of the stick, just don't touch until published? 2025-11-18 15:35:40 +01:00
Mike Dalessio f5305b2fe6 Use Card number as the model param
instead of the UUID `id`
2025-11-17 09:12:41 -05:00
Jorge Manrubia a1bc6b7939 Do not use HTTP caching since the page is full of forms, and can result in 422s due to CSRF tokens
https://app.fizzy.do/5986089/cards/2977
2025-11-17 13:55:23 +01:00
Jorge Manrubia 3b34703db3 Make sure that only admins or card creators can delete cards 2025-11-05 16:37:43 +01:00
Jorge Manrubia 03a345609e Baseline replacing collection with board across code 2025-11-05 13:31:54 +01:00
Jorge Manrubia 9d4dd3b00e Remove "save as draft"
Removes the creating status completely as well as the abandoned cards system. It will
always resume drafts if they exist, for a given collection and user.

https://app.box-car.com/5986089/cards/2489
2025-11-03 09:32:29 +01:00
Jorge Manrubia be6708065e No need to invalidate cache on columns since we load those with turbo frame now 2025-10-31 10:40:44 +01:00
Jorge Manrubia b0e5a5ccb5 Some fixes for HTTP caching not being invalidated properly 2025-10-31 10:40:26 +01:00
Jorge Manrubia 2a79cb413e Remove cacheable concern, inline cache helper 2025-10-31 10:38:52 +01:00
David Heinemeier Hansson 5b70320a6b We don't need to be fancy here
Redirect should be fine
2025-10-30 14:42:48 +01:00
David Heinemeier Hansson 217b860bb8 Style 2025-10-30 14:41:07 +01:00
Jorge Manrubia d6c7fb2084 Remove unused constants / controller
This came from the previous 3-column times
2025-10-25 18:50:37 +02:00
David Heinemeier Hansson eebda8bfd2 No longer used 2025-10-24 12:58:34 -07:00
Jason Zimdars ed9cede24b These use the old collection link format 2025-10-22 17:12:43 -07:00
Jorge Manrubia 4527dcbeda Remove unnecessary filtering code
After removing collections from the filtering menu, there was quite a good cleanup here pending
2025-10-03 10:56:34 +02:00
Jorge Manrubia 0d6333f8ba Use frame-based pagination for the activity timeline 2025-10-02 15:07:52 +02:00
Jorge Manrubia 5f8457ad9d Don't broadcast updates of cards unless published
To prevent https://fizzy.37signals.com/5986089/cards/1631
2025-10-02 14:19:21 +02:00
Jorge Manrubia d0003e6e94 Columns does not exist anyymore! 2025-09-30 14:51:04 +02:00
Jorge Manrubia e3e051d4c1 Initial cards view 2025-09-26 17:19:11 +02:00
Jorge Manrubia 2f6a639682 Prepare entropy code for the new auto postpone approach 2025-09-24 16:22:42 +02:00
Jorge Manrubia cd025447f2 Add basic column models and script to migrate 2025-09-24 13:15:03 +02:00
Jorge Manrubia b5ed5d8fd3 Remove unused module 2025-09-18 21:22:47 +02:00
Jorge Manrubia 375b16b26e Introduce columns and column entity
To refactor some messy code used to render the cards index screen
2025-09-18 11:41:28 +02:00
Jorge Manrubia 690734d8ab Fix several caching issues when viewing card permas 2025-09-18 10:58:09 +02:00
Jorge Manrubia 9e5108bcae Touch user on modification to invalidate cache
For the new "add card" in the cards screen
2025-09-12 18:59:18 +02:00
Jorge Manrubia 4580ed5e0d Invalidate cache when filter changes
https://fizzy.37signals.com/5986089/cards?collection_ids%5B%5D=2
2025-09-12 17:10:58 +02:00
Jorge Manrubia 39e9b54d9d Reduce page size to reduce load for processing local times on initial page load 2025-09-12 11:01:56 +02:00
Jorge Manrubia 312c5c7331 Fix some cache invalidation problems
- https://fizzy.37signals.com/5986089/cards/1585
- https://fizzy.37signals.com/5986089/cards/1616
2025-09-10 17:37:13 +02:00
Jorge Manrubia 4e72566856 Flatten card resource
We only need the parent collection for creating cards. Carrying it in the
rest of actions is a hassle.
2025-09-10 11:24:23 +02:00
Jorge Manrubia 209e8b61b8 Add caching and http caching for rendering the card perma 2025-09-09 12:07:32 +02:00
Jorge Manrubia 1366ccc8df Add caching and http caching to the cards index screen 2025-09-09 12:05:16 +02:00
Jorge Manrubia 5896a21499 Support filter by collection in different screens
We want to filter in the same screen for cards/events but not when viewing a card or from other screens. This adds a controller action to flag the actions where this is supported
2025-08-21 14:19:13 +02:00
Jason Zimdars aa13853ae4 Add a third, "On deck" column in Collections 2025-08-12 17:58:12 -05:00
Jorge Manrubia 0cb3648785 Extract concern with common column-related code 2025-06-12 12:48:10 +02:00
Jorge Manrubia 28d1f104fd Basic rendering for public collections 2025-06-09 13:09:32 +02:00