fix: three small defects with consequences out of proportion to their size - #111
Merged
Conversation
… size
**An overlong feature name made every later cloud save fail, permanently.**
Command labels interpolate user text (`Edit ${value.name}`) and the Name
field has no `maxLength`, so a long enough name pushed the revision past
the 500-character bound the account enforces on every write. That is a
400 no retry can fix, and the client maps an unrecognised failure to
`offline` — so a permanently unsaveable document presented as a network
problem. On reload `normalizeDocument` filtered the offending revision
out silently, taking that save point with it, and re-editing the same
feature reintroduced it. `appendRevision` now clamps with the shared
constant, truncating rather than replacing so the label still says what
it was.
**A command that changed nothing burned an undo slot and rebuilt the
model.** `runTransaction` and `applyDocumentEdit` both refuse a no-op;
`execute` did not. `moveFeature` returns its input for an out-of-range
index — what ArrowUp on the first row produces — so each press appended a
"Reorder" revision, pushed a dead undo entry, and bumped `version`, which
is part of the geometry sync key, posting a whole-document WASM rebuild.
About a hundred presses evicted the user's real undo history. Guarded in
`execute`; the Sidebar also clamps, so a keypress that cannot do anything
no longer travels that far to find out.
**Row controls were invisible but still tappable on touch.** These are
revealed by `:hover`, and a touch device resolves neither `:hover` nor
`:focus-visible` on a tap, so they stayed at `opacity: 0` while remaining
laid out and hit-testable: on an iPad the first tap near a row's right
edge hit an unseen button. The report named `.row-delete`; the file has
four controls with the same defect, and suppress and rollback are nearly
as destructive as delete, so all four are fixed. Revealing them is right
rather than `pointer-events: none` — a touch user has no hover to reach
them with. Same fix as `.sharing-row-action` in modals.css.
All three regression tests fail against the unmodified source.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
openzcad | 8368398 | Aug 27 2026, 08:56 PM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three items from the "Refinements" tier that are not cosmetic — each one costs a user something real.
1. An overlong feature name made every later cloud save fail, permanently
packages/document-core/src/index.ts:2898Command labels interpolate user text (
Edit ${value.name}), and the feature Name field has nomaxLength. A long enough name pushes the revision past the 500-character bound the account enforces on every write — a 400 that no retry can fix.The client maps an unrecognised failure to
offline(it names 409/413/403/401 explicitly), so a permanently unsaveable document presents as a network problem. On reloadnormalizeDocumentfilters the offending revision out silently, taking that save point with it — and re-editing the same feature brings it straight back.Clamped in
appendRevisionwith the shared constant, truncating rather than replacing so the label still says what it was.2. A command that changed nothing burned an undo slot and rebuilt the model
packages/command-system/src/index.ts—execute()runTransactionandapplyDocumentEditboth refuse a command that returns the same document.executedid not.moveFeaturereturns its input for an out-of-range index — exactly what ArrowUp on the first row produces. So each press appended a "Reorder" revision, pushed a dead undo entry, and bumpedversion, which is part of the geometry sync key, posting a whole-document WASM rebuild. Around a hundred presses evicts the user's real undo history.Guarded in
execute; the Sidebar also clamps, so a keypress that cannot do anything no longer travels through the command layer to find out.3. Row controls were invisible but still tappable on touch
apps/web/src/styles/components/sidebar.cssThese are revealed by
:hover, and a touch device resolves neither:hovernor:focus-visibleon a tap — so they sat atopacity: 0while remaining laid out and hit-testable. On an iPad the first tap near a row's right edge hits an unseen button.The report named
.row-delete. Reading the file, four controls share the defect: delete, Tweak-expose, suppress/rollback, and the drag grip. Rolling the timeline back by accident is nearly as bad as deleting, so all four are fixed rather than the one that was reported.Revealing them is the right fix rather than
pointer-events: none— a touch user has no hover with which to reach them at all. Same fix and reasoning as.sharing-row-actioninmodals.css.Verification
All three regression tests fail against the unmodified source.
lint (0 errors, 22 pre-existing advisory warnings), typecheck, 1991 + 748 unit tests, parity corpus 170, build (no budget failures), e2e 155 passed / 0 failed at
--workers=2.check-css-classesclean: 208 files against 707 classes.🤖 Generated with Claude Code