feat: auto-sequence suggestion for duplicate titles (T425984)
Summary
- Title cell editor surfaces a "Convert to sequence — Add
#" inline suggestion when the typed title collides with another stash row OR a Commons file the current user previously published. Accepting rewrites every matching stash row's title to the literal placeholder<basename> #. - New
src/api/sequence.jsresolves placeholders at publish time: queries Commons for the user's existing<basename> N.<ext>files (viaaiprefix+ per-row user filter), finds max N, and assigns each placeholder row N+1, N+2, … in queue order. If no prior owned sequence exists, numbering starts at 1. -
validateTitleLocalallows the<basename> #form as a special case (other uses of#still fail). The Commons uniqueness check skips placeholder titles entirely. Cache-key prefix bumped to-v2because the API call now also fetches the uploader's username so the editor can distinguish own- from someone-else's collisions (suggestion is suppressed for the latter, per spec). - Single-publish and bulk-publish modals show resolved
<basename> Nin their previews and pass the resolved title through topublishOnevia a newresolvedTitleoption, which also patchesbuildWikitextso{{Artwork}}/{{Photograph}}/{{Book}}render the final value rather than the placeholder.
Phabricator
- T425984 — Auto-sequence suggestion: convert duplicate titles into a # numbered sequence (own files only)
Test plan
Cross-stash collision
-
Add two stash rows with the same title (e.g. both
Sunset over Maastricht). Open the title editor on either row. -
Inline suggestion appears: "2 stash rows share this name. Convert to a numbered sequence?" with an "Add
#" button. -
Click the button: both row titles change to
Sunset over Maastricht #. Status shows "Sequence placeholder — the publish step will assign the next number."
Cross-Commons (own-file) collision
-
Edit a stash row's title to match a file you've previously published (e.g. an existing
File:Maastricht railway 1.jpg). - After the uniqueness check resolves, the cell shows a yellow "You already published File:… — convert to a numbered sequence below, or pick a different title" status, and the suggestion strip surfaces below.
-
Accepting rewrites the row to
<basename> #.
Cross-Commons (someone else's file) — should NOT offer
- Edit a stash row to match a Commons file uploaded by someone else.
- The cell shows the standard red "Already exists on Commons — pick a different title" error. No sequence suggestion appears.
Publish-time resolution (single)
-
Stash row with title
Foo #. Open the publish modal. -
"Will be published as" shows a spinner labelled "Resolving sequence number…", then the resolved name (e.g.
File:Foo 8.jpg). -
Wikitext preview shows
Foo 8(notFoo #) inside|title=if the template uses it. -
Click Publish — file lands on Commons as
File:Foo 8.jpg.
Publish-time resolution (bulk)
-
Three stash rows all titled
Bar #. Open bulk-publish modal. - Top of the queue shows "Resolving sequence numbers… (3 placeholder rows)" briefly, then "Sequence resolved for 3 placeholder rows".
-
Each queue row shows the resolved title (e.g.
Bar 1,Bar 2,Bar 3if no prior owned sequence; orBar 5,Bar 6,Bar 7if Commons hasBar 4from this user). - Hovering a row shows "Will publish as File:Bar N.jpg" tooltip.
- Publish all → files land in sequence on Commons.
Edge cases
-
Foo #placeholder + sibling row that's NOT a placeholder but DOES matchFoo→ editor shows the suggestion only when the non-placeholder row is being edited; the placeholder row already shows the "Sequence placeholder" status (no re-suggest). -
Commit a placeholder row, reload the page → the placeholder survives (persisted via
setDraft). -
Title field validation:
Foo #(double space) is rejected (basename ends in whitespace);Foo#(no space) is rejected;Foo # baris rejected (mid-string#). - Wikitext preview modal on a placeholder row shows the placeholder verbatim plus a hint explaining the publish-time substitution.
-
npm run buildpasses (undef-ref scanner clean).