Skip to content

Add publish flow for new versions (v2+)#31

Open
leotrs wants to merge 12 commits intomainfrom
prs-eou.2
Open

Add publish flow for new versions (v2+)#31
leotrs wants to merge 12 commits intomainfrom
prs-eou.2

Conversation

@leotrs
Copy link
Copy Markdown
Contributor

@leotrs leotrs commented Mar 27, 2026

Summary

  • Support uploading new versions via ?revises={url_hash} query parameter on the upload page
  • Pre-fill metadata (title, authors, abstract, keywords, subject, license) from parent scroll
  • Publish flow assigns correct version number (max + 1), inherits scroll_series_id, slug, and publication_year from the series
  • Allow same content re-upload within the same series for metadata-only version updates
  • Reject duplicate content across different series (existing behavior preserved)

Test plan

  • 12 unit tests covering all version publish scenarios
  • Test uploading v2 with revises param pre-fills metadata from v1
  • Test publishing v2 increments version, inherits series fields
  • Test v3 increments correctly (version = 3)
  • Test identical content within same series is allowed
  • Test identical content to different series is rejected
  • Test only scroll owner can upload a new version

Generated with Claude Code

Support uploading new versions of existing scrolls via ?revises={url_hash}
query parameter. The upload page pre-fills metadata from the parent scroll,
and the publish flow assigns the correct version number, inherits
scroll_series_id/slug/publication_year from the series, and handles
duplicate content detection for metadata-only version updates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

Deploy Preview

https://scroll-press-pr-31.fly.dev

This preview will be destroyed when the PR is closed.

leotrs and others added 2 commits March 27, 2026 08:42
Truncate base content_hash before appending nonce so the combined
value stays within the 64-character column limit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The nonce-appended url_hash was not being truncated to fit within
the 20-character column limit. Truncate the base url_hash to
(20 - nonce_length - 1) characters before appending the nonce.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@leotrs
Copy link
Copy Markdown
Contributor Author

leotrs commented Mar 27, 2026

Needs human review

What changed: Added a version publishing flow — users can upload v2+ of a scroll via ?revises={url_hash}, with metadata pre-filled from the previous version. Version numbering, series inheritance, and duplicate content handling within a series are all new.

Review checklist:

  1. Open the deploy preview from CI checks
  2. Log in and publish a scroll (v1) — verify it publishes normally with version=1
  3. On the published scroll page, find/construct a link to /upload?revises={url_hash} using the scroll's URL hash
  4. Verify the upload form pre-fills title, authors, abstract, keywords, subject, and license from v1
  5. Upload new content and publish — verify it gets version=2, same slug, same year as v1
  6. Try uploading the exact same HTML content as v1 via the revises flow — verify it succeeds (metadata-only update)
  7. Try uploading v1's identical content as a brand new scroll (no revises param) — verify it's rejected with "already been published"
  8. Log in as a different user and try /upload?revises={v1_hash} for a scroll you don't own — verify the form does NOT pre-fill and session has no revises_scroll

What to look for:

  • Correct version numbers (v2 = 2, v3 = 3, etc.)
  • Series URL stays consistent across versions (same year/slug)
  • Pre-fill data matches v1 exactly (no missing fields)
  • Session cleanup: after publishing v2, revises_scroll should be cleared
  • No way for a non-owner to revise someone else's scroll
  • Duplicate content error message still works for cross-series duplicates

@leotrs
Copy link
Copy Markdown
Contributor Author

leotrs commented Mar 27, 2026

On the published scroll page, find/construct a link to /upload?revises={url_hash} using the scroll's URL hash

how exactly am I supposed to do this? I have no way to get the published scroll's hash.

Scroll owners now see a "New Version" button in the scroll details
modal that links to /upload?revises={url_hash}, making it easy to
start a new version without needing to know the url_hash.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@leotrs
Copy link
Copy Markdown
Contributor Author

leotrs commented Mar 27, 2026

Needs human review

What changed: Added a "New Version" button on published scroll pages (owner-only) and a complete version publish flow — uploading via ?revises={url_hash} pre-fills metadata from the parent scroll, and publishing assigns incremented version numbers while inheriting series identity (slug, publication_year, scroll_series_id).

Review checklist:

  1. Open the production/preview deploy
  2. Log in and navigate to a scroll you own
  3. Click the info/details modal — verify a "New Version" button appears next to "Download HTML"
  4. Click "New Version" — verify the upload page pre-fills title, authors, abstract, keywords, subject, and license from the original scroll
  5. Upload a new HTML file and publish — verify the new version gets version=2, same slug/year URL, and the series is linked
  6. Log out (or use incognito) and view the same scroll — verify the "New Version" button is NOT visible
  7. Log in as a different user and view the scroll — verify the "New Version" button is NOT visible
  8. Try uploading identical content as a new version of the same scroll — should succeed (metadata-only update)
  9. Try uploading that same content as a brand new scroll (not a revision) — should be rejected with duplicate content error

What to look for:

  • "New Version" button styling consistent with other modal action buttons
  • Pre-filled form fields are correct and editable
  • Version number increments correctly (v2, v3, etc.)
  • Published URL uses the same year/slug as the original (not a new slug)
  • No "New Version" link leaks to non-owners or anonymous users
  • Session cleanup: after publishing, the revises_scroll session key should be cleared (no stale state on subsequent uploads)

@leotrs
Copy link
Copy Markdown
Contributor Author

leotrs commented Mar 27, 2026

Needs human review

What changed: Added a "New Version" button on published scroll pages (owner-only) that launches a pre-filled upload flow for publishing v2+ with correct version numbering, series inheritance, and duplicate-content handling within the same series.

Review checklist:

  1. Open the deploy preview from the CI checks
  2. Log in as a user who owns a published scroll
  3. Navigate to that published scroll's page
  4. Click the scroll info/details area — verify a "New Version" button appears in the modal actions
  5. Click "New Version" — verify the upload page opens with ?revises=<hash> in the URL
  6. Confirm the form is pre-filled with the original scroll's title, authors, abstract, keywords, subject, and license
  7. Upload a new HTML file and submit — verify the preview works and publishing assigns version 2
  8. After publishing, verify the new version shares the same year/slug URL as v1 (e.g., /2026/neural-networks)
  9. Log in as a different user — verify the "New Version" button does NOT appear on the same scroll
  10. View the scroll while logged out — verify "New Version" does NOT appear
  11. Try uploading identical content as a brand new scroll (no revises) — verify it's rejected as duplicate
  12. Try uploading identical content via the "New Version" flow — verify it's allowed (metadata-only update)

What to look for:

  • "New Version" button only visible to scroll owner, never to other users or anonymous visitors
  • Pre-filled metadata matches the parent scroll exactly
  • Version number increments correctly (v2, v3, etc.)
  • Published URL uses the same year/slug as the original series
  • No regression in normal v1 publish flow (upload without ?revises=)
  • Session state (revises_scroll) is properly cleaned up after publishing

@leotrs
Copy link
Copy Markdown
Contributor Author

leotrs commented Mar 27, 2026

Steps 1-6 worked correctly. Then I tried to upload the same HTML file, the preview worked BUT it didn't say anywhere that "this will be v2". Then, I clicked publish and received a 500 error.

The preview page now indicates "This will be published as v2" (or v3, etc.)
when a scroll is being uploaded as a new version via the revises flow. Also
adds a full integration test for publishing same-content v2 scrolls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@leotrs
Copy link
Copy Markdown
Contributor Author

leotrs commented Mar 27, 2026

Needs human review

What changed: Added a publish flow for new versions (v2+) of scrolls — owners see a "New Version" button on published scrolls, the upload page pre-fills metadata from the parent version, and the preview page shows the upcoming version number (e.g., "v2").

Review checklist:

  1. Open the Fly.io preview deployment
  2. Log in and publish a scroll (v1)
  3. On the published scroll page, open the details modal and verify you see the "New Version" button
  4. Click "New Version" — verify the upload form pre-fills title, authors, abstract, keywords, subject, and license from v1
  5. Upload new content and verify the preview banner says "PREVIEW MODE - This will be published as v2"
  6. Confirm publish and verify the new version has the same slug/year URL as v1
  7. Log out and view the same scroll — verify the "New Version" button is NOT visible
  8. Log in as a different user and verify the "New Version" button is NOT visible on another user's scroll

What to look for:

  • "New Version" button only appears for the scroll owner, never for other users or anonymous visitors
  • Metadata pre-fill is accurate (all fields match v1)
  • Version number increments correctly (v2, v3, etc.)
  • Published v2 shares the same year/slug URL as v1
  • Same content re-upload within the same series is allowed (metadata-only update)
  • Same content uploaded as a brand new scroll (not a revision) is still rejected
  • Session state (revises_scroll) is properly cleared after publishing

@leotrs
Copy link
Copy Markdown
Contributor Author

leotrs commented Mar 27, 2026

Screenshot 2026-03-27 at 13 42 41

Steps 1-4 worked. Step 5 failed when trying to upload the exact same html as in the first version. There is no error banner, it just fails (see screenshot).

Three fixes for the version publish flow:

1. view_scroll_by_year_slug: query returned MultipleResultsFound when v1
   and v2 shared the same (publication_year, slug). Now orders by version
   DESC with limit 1 to always return the latest version.

2. Upload form: when revising without re-uploading a file, the handler
   now falls back to the parent scroll's HTML content instead of raising
   "HTML file is required". Also pre-fills original_filename in the
   revision form data so the UI shows the existing file state.

3. Upload form: added hx-boost="false" to prevent HTMX from intercepting
   multipart file upload submissions, which caused silent failures when
   the AJAX redirect handling didn't work correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@leotrs
Copy link
Copy Markdown
Contributor Author

leotrs commented Mar 27, 2026

Needs human review

What changed: Added a complete publish flow for uploading new versions (v2+) of existing scrolls, including a "New Version" button on published scroll pages, metadata pre-fill from the parent version, version number assignment, and same-content re-upload support within a series.

Review checklist:

  1. Resolve merge conflicts first (PR is currently in CONFLICTING state)
  2. Log in as a scroll owner and navigate to a published scroll's detail modal
  3. Verify the "New Version" button appears between "Back to Scroll Press" and "Download HTML"
  4. Click "New Version" — verify the upload form pre-fills title, authors, abstract, keywords, subject, and license from v1
  5. Submit without uploading a new file (metadata-only revision) — verify it accepts the parent's HTML content
  6. Submit with a new HTML file — verify it proceeds to preview
  7. On the preview page, verify the banner reads "PREVIEW MODE - This will be published as v2" and metadata shows "Preview (v2)"
  8. Confirm publish — verify the scroll is published as v2 with the same slug, publication_year, and scroll_series_id as v1
  9. Navigate to /{year}/{slug} — verify it shows v2 (latest version), not v1
  10. Log in as a different user — verify the "New Version" button does NOT appear on someone else's scroll
  11. As an anonymous user, verify the "New Version" button does NOT appear
  12. Upload identical content as a new (unrelated) scroll — verify it is still rejected with "already been published"

What to look for:

  • "New Version" button visibility is correctly gated to the scroll owner only
  • Version numbering increments correctly (v2, v3, etc.)
  • The /{year}/{slug} canonical URL always resolves to the latest version, not an older one
  • Metadata pre-fill works for all fields (especially subject dropdown and keywords)
  • No regression on the normal v1 upload flow (no revises param)
  • The hx-boost="false" addition on the upload form doesn't break normal form submission

leotrs and others added 5 commits March 27, 2026 14:38
Resolve conflict in view_scroll_by_year_slug: combine is_owner
(from this branch) with versions/latest_version/is_latest (from main).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The homepage scroll cards now use canonical /{year}/{slug} URLs via
the .scroll-card-link class instead of /scroll/{hash} hrefs. The
footer tests were timing out because a[href^="/scroll/"] matched nothing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… conflict

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant