This reverts commit 5e9ab0cf02 (Removed screen and firmware struct attachment replace behavior, 2026-08-03) because you can't reliably have link:https://shrinerb.com[Shrine] upload a replacable image. We still need to have distinct methods for `#replace` and `#upload`.
This also prevents duplicate images being created.
Milestone: patch
We can safely remove the `#remove` method in favor of using `#upload` for everything now that we conditionally destroy the record only if found and the `*_data` key exists. This also updates firmware attachment behavior to mimic screen attachment behavior in order to improve consistency.
Milestone: minor
link:https://github.com/simplecov-ruby/simplecov/blob/main/CHANGELOG.md#100-2026-07-12[Details]. This includes the following:
* My long standing bug has been fixed which allows for implicit elses to be ignored. This cleans up code related to using monads with pattern matching which is nice to see.
* We still can't enable ERB code coverage (this is why the templates are skipped). I've logged a few more new bugs on the SimpleCov side to tackle. This might take a while because I noticed Erik Berlin logged issues with Ruby core in order to make this possible.
* Use of the *strict* profile ensures all code committed to this project must be 100%. This also cleans up having to be explicit about this.
Milestone: patch
When header information is invalid or missing, we'll emphasize that the device's API key must be used. This helps clear up any ambiguity when resolving the issue.
Milestone: minor
Now that the model (payload) knows how to incorporate the device's API key, we'll use the API key in the response to ensure the response is always the same (especially when the device can be found).
Milestone: minor
No longer necessary now that we can use the Setup API to set the API key for a device. This means you can use either the model ID or, soon, the API key.
Issue: 347
Milestone: minor
As with done with the Display API, we'll delegate to the model to compute the MAC address when provisioning a device. This required refactoring the action to use a private provision device method.
The `HTTP_ID` missing header spec was deleted since this header is optional now.
Milestone: minor
These attributes were originally used for the Core proxy feature (and device provisioning) but are no longer needed. These changes completely remove these attributes (including the migration for removing from the `device` table).
Issue: 326
Milestone: minor
Applies the following:
* Renames the method to be consistent with other attribute-based methods.
* Adds missing Display API attributes.
* Ensures the attributes surface user settings as stored in the database.
Milestone: minor
Cleans up the error objects so they are in the same namespace for quick lookup. This includes renaming `ProblemDetail` as `Problem` and using `petail` for `Petail` to clarify the differences.
Milestone: patch
The original thought was that multiple models would be a top-level namespace within the `app` folder but, in practice, it makes more sense to keep these whole value objects associated with the correct aspect.
Milestone: patch
Necessary to reduce duplication by using the firmware header parser so we don't have to maintain a custom contract for this action. This also relaxes the requirements for having firmware version and model information. Only the HTTP ID header is important.
Milestone: patch
Necessary to be in sync with the UI by supporting default palettes via the API. This also removes the use of palette names since using the default palette is preferred now.
Issue: 303
Milestone: minor
Improves consistency and also ensure the reponse status is the same status as set by the problem detail.
Reek has been updated to account for feature envy since Reek is overly zealous about two messages to the same object (which is fine for these situations).
Milestone: patch
Ensures the API answers HTTP Conflict (409) problem details when a unique contraint is encountered. This improves the user experience while also giving detailed information on how to correct.
Reek has been updated as follows:
* *Data Clump*: This can't be avoided without additional effort since there'd need to be a more advanced error routing system to account for the clumping of the request, response, and error objects. This might be worth exploring more in the future.
* *Feature Envy*: Reek doesn't like more than one call to the same object. This is a known issue since this is too strict for use cases like this.
Milestone: minor
Necessary so folks can force a screen to be dithered if desired. This is especially important working with contant that is artistic or more photography focused in general.
Issue: 294
Milestone: minor
Base64 encryption was a carry over from the early days of this project when moving away from Sinatra. This is safe to remove since our Firmware doesn't make (or need) API requests with Base64 encoding enabled.
Issue: 290
Milestone: minor
Necessary to reduce duplication by using the same model name transformer as used by the `Terminus::Aspects::Firmware::Headers::Parser`. This also _requires_ all the following HTTP headers to be present to improve model lookup:
* `HTTP_FW_VERSION`
* `HTTP_ID`
* `HTTP_MODEL`
As mentioned when originally adding the `ModelName` transformer, all of this is a _best guess_ with a fallback to `og_png` when we can't match what the Firmware provides for us via the `HTTP_MODEL` header because the Firmware provides so little information.
Milestone: minor