User:OliverCharles/NGS Edit Stash
The NGS edit stash is a new feature planned for the "next generation" MusicBrainz server. The goal is to allow people to enter partial edits, and save them to continue work on them later. The edit is private for the user, until they final submit the edit in full.
What needs to be stored
We need to store:
- The Catalyst action the user is entering data for.
- E.g. /artist/create
- This does not necessarily have to be textual, we could map integers to actions (like we map edit type ids to an edit class)
- It also needs to store any captures. E.g. action=/artist/edit, gid=some-artist-gid-here
- The data in the form
- Without validation, just a literal copy from every field.
- The user has a list of all edits they have stashed away and select one to restore.
- The server grabs the stash from the database, and does a HTTP redirect to the stored URI/captures, with "restoreStash=id" as a GET parameter.
- The server gets the redirect and restores the form, populates it with parameters from the stash, and the user is free to continue editing.
- Implementation notes:
- This is fairly simple with method wrappers in Moose. We need to split every edit action into 2 methods, the action itself and one to create the form. We then use a parameterized Moose role (MusicBrainz::Server::Controller::Role::StashRestore) that adds: after 'edit_artist_form' and populates it, restorting the stash.
- We need a way to populate a form but NOT run validation.
Client side operations
- When an input change event is fired, we store the input name and the new value.
- When the user clicks save, or navigates out of the page, the list of changes is sent to server (asynchronous operation)
- The server will receive a HTTP request at some end-point (ie, /stash-changes)
- The server stores the HTTP referer variable as to where to restore the stash to.
- The server looks up this referer uri and the editor id in the database, fetching a stash row (possibly)
- The server stores all parameters received in the stash. If a stash already exists, it merges changes into this stash, always using the newer version in any merge conflicts.
CREATE TABLE stash ( id INT, last_updated TIMESTAMP, created TIMESTAMP, stash XML or TEXT?, editor_id INT, edit_url VARCHAR ); CREATE UNIQUE INDEX stash_idx stash (editor_id, edit_url);
- Should we store original values at the time of edit? (conflicts)
- For example, the user goes to edit an artist and changes the artist type from NULL (unknown) to Male. They stash changes, and later another editor changes the gender to Female, and the edit is passed. Now, the original user restores his edit from the stash, and the fact that gender has been changed is now "hidden" as their edit will be immediately applied over the top.
- Possible solutions:
- We store original values in the stash. This is costly and uses a lot of space. Often most of the data will be redundant.
- We have a "out of date" flag for stash entries. In the above example, when the artist was edited, any stashes pointing to this artist will be flagged as "potentially out of date." We then alert the user about this when they restore the stash entry. We won't be able to say exactly what the problem is, but should provide a note for the editor to carefully check all their changes.
- Do we ever expire stash entries. E.g. after a month of inactivity?