Guard SkillMD submissions against duplicate creation#204
Open
stanleyoz wants to merge 1 commit into
Open
Conversation
A rapid multi-click on the /skills Submit button created three identical rows for one submission (react-hooks/set-state-in-effect notwithstanding, useActionState's `pending` only flips true after React commits a render, which lags a fast click by at least one frame — enough of a gap to fire multiple form submissions before the button disables). Two-layer fix, matching the idempotency-key pattern this registry's own StreamPay listing is built around: - Client: a synchronous ref-based guard on the form's onSubmit blocks re-entrant submits before React's pending state has a chance to propagate. - Server: findRecentDuplicate() in submitSkill rejects an identical (name + source) submission within a 15s window and returns the existing row instead of inserting a new one — defense in depth against a genuine double POST (retry, slow network) that the client guard can't see. Verified: npx tsc --noEmit and eslint pass on all three changed files (one pre-existing, unrelated lint error in submit-form.tsx confirmed present on main before this change too). No DB credentials available in this environment to exercise findRecentDuplicate against live Neon — worth a manual double-submit test before merge. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014LVcSKyucSnxaoSxd3ccXh
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
Fixes the duplicate-submission bug reported in #203 — one Submit click
on
/skillscreated three identical rows for the same SkillMD.Why
useActionState'spendingboolean only flipstrueafter Reactcommits a render, which lags a fast click by at least one frame — a
gap wide enough for multiple form submissions to fire before the
button actually disables. Ran into this firsthand re-registering the
StreamPay skill after a hosting migration (see #203).
What changed
Two-layer fix:
submit-form.tsx): a synchronoususeRefguard on theform's
onSubmitblocks re-entrant submits immediately, withoutwaiting on React's
pendingstate to propagate.actions.ts+skills.ts):findRecentDuplicate()rejects an identical
(name, source_url/content)submission withina 15-second window in
submitSkill, returning the existing rowinstead of inserting a new one. This is defense in depth against a
genuine double POST (retry, slow network) that the client guard
can't see — the same idempotency-key shape the StreamPay listing
itself is built around.
Verification
No
DATABASE_URL/Neon credentials available in the environment thiswas written in, so
findRecentDuplicatecouldn't be exercised againstthe live DB — worth a manual double-submit test on
/skillsbeforemerging.
Related
Closes the duplicate-cleanup half of #203 going forward (doesn't
retroactively remove the existing duplicate rows — that still needs a
manual DB cleanup as requested there).