feat(task-board): redesign the card dialog with autosave, human keys and short links - #6342
Merged
Conversation
Assigns each card a per-org sequence (key_seq) at create time, exposed as a human key (DECO-01) via packages/shared/task-key.ts, with a shareable short link route (/$org/t/DECO-01) that resolves to the board deep link. Adds the 172 migration/backfill, storage retry on raced key_seq inserts, and reworks task-dialog's header to show the new key row. Also fixes list-continuation handling in the markdown editor. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A card written before the key backfill has no key, so the share button falls back to its id — which the /$org/t/ route couldn't parse, sending the link to an empty board. Resolve either shape, so any link already pasted somewhere keeps working. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every debounced save logged its own entry, so writing one paragraph buried the card's history under a dozen identical "updated the description" lines. Coalesce prose edits in `recordActivities`: a repeat of the same action by the same actor within 10 minutes moves the existing entry to now instead of adding one. It lives in storage because that is the single write path, so any client gets it. Every other action stays a discrete event. Client-side, the text debounce goes 700ms -> 2s and blur flushes the pending write, so a sentence costs one request instead of five. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The dialog lost its Save button when editing became autosave, and these three specs still waited 3 minutes for it. Close the dialog instead — that is the flush point now — and assert it unmounted before reading the wire. Escape would be locale-proof but tiptap swallows it while the editor has focus, which is exactly where these tests leave it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The fold's container carried `overflow-hidden` unconditionally, and it starts exactly at the pane's content edge. An image node is only as wide as its image, so its absolutely-positioned remove button reaches ~35px to the LEFT of a 1px image — outside that box, clipped, and unclickable. The e2e caught it as the pane intercepting the click. Clip only when folded, and raise the cap clear of the editor's empty footprint (~364px measured, so 420 folded a description holding one image). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CI found the allocator's real limit: 8 concurrent creates in one org exhausted the 5 retries and the create FAILED, so a card could be lost to contention. The retry only re-read a `max(key_seq)` the next writer was already racing. Take a per-org advisory lock for the length of the insert instead. The read and the write are one critical section, so there is nothing to retry and no ceiling on concurrency. The unique index stays as the backstop. The test now bursts 24 creates, well past what broke the old path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…harder A burst only races if the round trips overlap, and against a loopback Postgres they don't: 50 concurrent creates come out distinct on a laptop even with the retry-on-conflict allocator that CI failed. Bursting to 24 raises the odds but still leaves the test dependent on the runner being slow. Hold one create's transaction open instead, so the second provably reads `max(key_seq)` while the first is uncommitted — the interleaving the lock exists for. Verified red without the lock, green with it. It waits on pg_stat_activity for the blocked backend rather than sleeping a guessed interval. Also namespace the lock key (`task-board-key-seq:<org>`) and cast it, matching ensure-user-organization and sandbox-runner-state: hashing the bare org id shares a lock space with any other feature that hashes the same id.
decocms Bot
pushed a commit
that referenced
this pull request
Aug 20, 2026
PR: #6342 feat(task-board): redesign the card dialog with autosave, human keys and short links Bump type: minor - decocms (apps/api/package.json): 4.248.5 -> 4.249.0 - @decocms/native (apps/native/package.json): 4.248.5 -> 4.249.0 - @decocms/e2e (packages/e2e/package.json): 1.41.1 -> 1.42.0 - @decocms/shared (packages/shared/package.json): 0.47.0 -> 0.48.0 Deploy-Scope: both
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.
What is this contribution about?
Adds a per-org, human-readable key to each task board card (e.g.
DECO-01), derived from a newkey_seqcolumn assigned at create time (with retry on raced inserts) and exposed viapackages/shared/task-key.ts. Adds a shareable short link route (/$org/t/DECO-01) that resolves the key to a card and forwards to the board's deep link. Reworks the task dialog header to show the new key row, and fixes list-continuation handling in the markdown editor.How did you verify your code works?
Added unit tests for
task-key.ts(prefix derivation, key formatting, term parsing) and for the markdown editor'sunwrap-list-continuations. Added a Postgres integration test (task-board-key-seq.integration.test.ts) coveringkey_seqassignment and the raced-insert retry path. Updated existing task-board schema/reaction/update/filters/config tests for the newkeySeqfield.Screenshots/Demonstration
N/A — no screenshots captured in this session; the task dialog header now renders the card's
DECO-01-style key.How to Test
bun run --cwd=apps/api migrateto apply migration172-task-board-item-key-seq.DECO-01-style key in the dialog header./$org/t/<key>and confirm it redirects to the board with that card opened.Migration Notes
Requires running the new Kysely migration
apps/api/migrations/172-task-board-item-key-seq.ts, which adds and backfills thekey_seqcolumn ontask_board_items.Review Checklist
Summary by cubic
Redesigns the task dialog with autosave and human task keys plus short links. Old behavior: a Save button and each autosave spammed the timeline; new behavior: a 2s autosave with blur flush and server‑side coalescing that merges repeated title/description edits by the same actor within 10 minutes.
Assigns a per‑org sequence (
key_seq) at create under a per‑org advisory lock, with a unique(organization_id, key_seq)index to prevent duplicates. ExposeskeySeqand renders keys likeDECO-01. Adds/$org/t/DECO-01short links that resolve by human key or raw id and forward to the board; the router preserves ataskparam through the landing redirect; board search matches keys (DECO-07,deco-7, or7). Reworks the dialog: moves actions into a menu (clone, archive, delete, new chat, auto‑fix/rerun), adds copy/share for the key, collapses long descriptions and folds long activity runs, shows PRs as read‑only rows, and clips the description only while folded so image controls stay clickable. Normalizes wrapped list items before parsing so the editor does not drop text. Tests cover Postgres key allocation under lock (forced interleaving) and activity coalescing, key helpers and resolvers, and markdown normalization; e2e closes the dialog to flush autosave.Rollout
172-task-board-item-key-seqto add/backfillkey_seqand create the unique index.DECO-01‑style key and that visiting/$org/t/<key or id>opens that card on the board.Written for commit 68339c3. Summary will update on new commits.