Closed jdickey closed 8 years ago
Another interesting bit of our current design is that the decision on what type of Contribution
object to create (and therefore later save) is made by the repository. Look at Prolog::UseCases::ProposeEditContribution#updated_contribution
:
def updated_contribution
@contribution ||= contribution_repo.create form_object.to_h
end
We dump the form object's attributes as a Hash, shovel them to the Contribution repository's #create
method, and let it figure out what to do.
Is that the best, purest approach? Likely not; better might be some intermediate object that exists because it knows the difference between a Proposed and Accepted Contribution in this context and just Does The Right Thing. The argument for the current approach, however, is that the repository class, and very possibly only that class' #create
method, knows what an EditContribution::Proposed
, EditContribution::Accepted
, or EditContribution::WhateverElse
is. That sort of conceptual containment can be a Very Good Thing, rescuing us from too much haphazard knowledge scattered about the system.
tl;dr There's no "second happy path" for successful creation of a Contribution by the Article Author; all the create-proposal logic is exactly the same as for an arbitrary other Member. If anyone can point out cases where that's not the case, we're certainly willing to be corrected — but we seriously doubt that we will be.
Now that we've cleared that up (see Commit 42ce558), all that's left is handling the known possible failure modes and, oh yeah, considering the known issues with the current implementation.
Once we take Markdown out of the picture, does the cross-block Edit Contribution constraint still apply?
Taking "Markdown out of the picture" says that we trust the user to produce valid, well-formed HTML as a result of her proposed contribution. If the markup produced by replacing the selection with the proposed replacement yields invalid HTML, the proposal will be rejected (preferably at the edit stage, where it'll simply redisplay the UI with errors reported). Definitely not 1.0-quality work; HTML and casual users coexist as peacefully as petrol under pressure and a roaring fire.
Actually, the question above was meant to confirm that the decision to defer Rule 6 above "Contributions affecting multiple sequential paragraphs will be disallowed, requiring individual Proposals for each paragraph" was not based on Markdown or interpretation of blank line separation as different paragraphs.
No; that should better be phrased as
If the contribution as entered by the Member, when replacing the selected original content, produces invalid HTML markup, then entry of the proposal will not be accepted. In an interactive UI such as a Web environment, the Member will be prompted to enter a corrected, valid proposal.
Does that cover it?
Overview
Class
ProposeEditContribution
is the next in our continuing series of use cases, which allows for the submission of a request that the author of an Article approve a change to its content.Its inputs are (in no particular order or separation here):
That's a total of _s_even inputs, which just feels like a lot. They're all needed, as far as we can tell, because this "use case" is a high-level "supervisor" for several actions:
Problems
Are there problems with this? Of course! The obvious one is a race condition; in high-use environments for popular articles, there's a virtual certainty that two proposals can attempt to select the same (or overlapping) content and be assigned the same contribution ID. We could add a locked-by/unlocked state to the Article and immediately persist a locked-by-proposer entity to the Article Repository on entry, and an unlocked one on completion, but that simply adds two persistence calls to the workflow, which are prime opportunities for race conditions themselves. At some point well before 1.0, we're going to have to rethink this.
And One More Thing…
Remember that edit-contribution proposals by the author of an Article are always immediately accepted; we need to think up the least hackish yet sufficiently rapid-to-implement way to accomplish this.