Add Phase 2 restore: polls with vote replay, tags, membership #559
No reviewers
Labels
No labels
antville.org
bug
compatibility
dependency
duplicate
enhancement
help wanted
invalid
java
javascript
major
needs feedback
needs work
no-issue-activity
runtime
security
urgent
usability
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
antville/antville!559
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "phase2-polls-tags-membership"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Stacked on #558 — Phase 2 of the importer rewrite: polls (with real vote replay, not just choice definitions), tags, and membership. Completes the importer's coverage of every entity type
Exporterproduces.What's here
Poll.add({question, title_array, save}, site)—Poll.prototype.updatecreates oneChoicepertitle_arrayentry in the same order they're passed, so choices are mapped back to the originalchoices[].idby that order, lettingvotes.jsonreplay real ballots against the correctChoiceafterward.tagged_idthrough the sameidMap.content/idMap.imagesbuilt in Phase 1, callsaddTagper row — no new resolution logic needed.idMap.accountsmechanism as every other entity's creator (a membership row's owncreator_id/creator_nameis the member, not an editor — see PR #558's design notes).Bugs found by actually running it (ct 3998, see
~/.claude/plans/kind-sauteeing-goblet.md)Vote.addhardcodessession.userdirectly (no user parameter at all) — null during the background/cron-driven restore, same underlying cause as PR #558'sres.handlers.sitefix.session.userisn't a writable property (it's a Java-backedSessionBean, confirmed live), so this usessession.login(user)instead of assigning to it.Pollhas no metadata collection wired up at all, unlike every other restored prototype —poll.setMetadata(...)throws"No metadata collection defined for prototype Poll".Exporter'saddMetadatastill queries the raw metadata table directly for export (so exports don't break), but there's nothing to write back on import, so this restore just doesn't call it.Membership.addthrows"already contained in the collection"restoring into any freshly created target site — Root'screateaction already adds the creating user asOWNERautomatically, so the export's own membership row for that same account collides with the one that already exists. Fixed by updating the existing membership in place instead of assuming the target never has one — this also means restore-in-place and migrating into a site you already belong to both just work, not only the brand-new-empty-site case.Verified end-to-end
Created a poll with 3 choices and cast a vote, tagged the fixture story, exported, imported into a fresh target site: poll choices and vote tally came back correct (matching choice had exactly 1 vote, others 0), the tag was restored and visible, and the pre-existing auto-created owner membership was updated in place rather than duplicated or erroring.
Known gaps
tools/antclick), not the MariaDB path production actually runs.Importer.restoreAccount, looping these same per-entity helpers over every site insites.json) is Phase 3, still deferred.Test plan
Poll.add({question, title_array, save}, site) restores the poll and its choices (Poll.prototype.update creates one Choice per title_array entry, in order — mapped back to the original choices[].id by that same order so votes.json can be replayed against the right Choice). Tags resolve tagged_id through idMap.content/idMap.images, same pattern as everything else. Membership resolves the member through the shared idMap.accounts mechanism (a membership row's own creator_id/creator_name is the member, not an editor) rather than any separate matching logic. All three found real bugs once actually run against the disposable test instance (ct 3998, see ~/.claude/plans/kind-sauteeing-goblet.md): - Vote.add hardcodes session.user directly (no user param at all) to set creator/creator_name — null during a background/cron restore, same underlying cause as the res.handlers.site fix in the previous commit. session.user isn't a writable property (it's a Java-backed SessionBean), so log the importing user in via session.login(user) instead of assigning to it. - Poll has no metadata collection wired up at all (unlike every other restored prototype) — poll.setMetadata throws. Exporter's addMetadata still queries the raw metadata table directly for export, but there's nothing to write back on import, so this restore just doesn't call it. - Membership.add throws "already contained in the collection" restoring into any freshly created target site: Root's create action already adds the creating user as OWNER automatically, so the export's own membership row for that same account collides. Update the existing membership in place instead of assuming the target never has one. Verified end-to-end: poll choices and vote tally correct, tag restored and visible, and the pre-existing owner membership correctly updated in place rather than duplicated or erroring. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0177qdRkssL6kBk5ngMDHwnP9eaaa23aa9toeac56e7447View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.