Why are Workflows not content items?

Topics: Core
Developer
Jun 19, 2013 at 11:13 AM
I'm wondering. (Copied over from this issue.)

Advantages:
  • Simpler import/export (would still need the necessary driver method written of course)
  • Content events (to use programmatically or even from other workflows)
  • Versioning (or at least basic audit trail to see who modified a workflows and when)
  • Extensibility (Want to add a hint to workflows for your admins? How about a field?)
  • Extended permission handling (specific roles can only edit specific workflows). BTW the need for having a separate permission for editing Workflows instead of using SiteOwner will quickly arise, just as it did with Projector.
  • What have I forgot?
Disadvantage: performance. But really? If the theoretical WorkflowPart would be eagerly loaded with a query hint (something safe to assume, since workflows are run from inside the Workflows module) then the only thing that can have a measurable performance impact is having to join in multiple tables (that are always joined in with content items).

Records also make the whole module a lot less flexible: workflows are saved directly to records, not going through a service, but then the WorkflowManager service uses those records... Meaning you can't change the core of implementation by just swapping out a service, unlike it is in many other parts of Orchard.
Coordinator
Jun 19, 2013 at 6:05 PM
Content Items will help for import/export, but just help, not enable, and by the way it's done now.

Then, Events can be implemented without content items, and event are not "really" needed on Workflow Definitions.
Making sense of versioning would also imply handling versioning for workflow instances.
Why would you want to add fields to Workflow definitions ? BTW the workflow editor is not using parts, how would it work.
Why should Workflow Definitions have content item permissions ? Let's create a permission for them, though it might be a security risk at it can lead to escalated priviledges. And we could even have dynamic permissions to handle specific definitions.

Using a service might be nice for aesthetics only. This module is not meant to be extended this way. The extensibility points are for creating Tasks, Events and their respective editors and displayed shapes. There is no need to extend the engine per se. But yes it could be refactored in order to hide these records.

Not everything should be content items. Workflow definitions are not content, they are plumbing. If we made the mistake of creating content items where we shouldn't have, this should not be repeated.
Developer
Jun 19, 2013 at 6:51 PM
To clarify when I've written "workflow" what I really meant was "workflow definition" (i.e. what is in WorkflowDefinitionRecord), my mistake.

Yes, it would only help import/export. Sipke has done it by creating an import step, an export step and a recipe handler. Although this is a really nice demonstration of how to hook into these services it could be much simpler by using content items.

Events can be done by creating new events naturally but the content item pipeline would give multiple well-known ones already.

Full versioning would be probably too complex because of the many record-to-record relationships but simply having CommonPart on the Workflow Definition type would allow seeing who and when modified a specific workflow definition.

"Why would you want to add fields to Workflow definitions ?"
See the example about having a hint for workflows: it could be a hint per workflow (e.g. with TextField) or a hint for all workflows (with HintField).

"BTW the workflow editor is not using parts, how would it work. "
Have a WorkflowDefinitionPart containing what's now in WorkflowDefinitionRecord and the corresponding editor and editor-related logic in the appropriate places as with any part.

"Why should Workflow Definitions have content item permissions ? Let's create a permission for them, though it might be a security risk at it can lead to escalated priviledges. And we could even have dynamic permissions to handle specific definitions."
Well why not? Why do we have content item permissions at all? :-) It's a legitimate scenario to allow certain users to only edit certain workflow definitions. Also see my last paragraph.

"Using a service might be nice for aesthetics only. This module is not meant to be extended this way. The extensibility points are for creating Tasks, Events and their respective editors and displayed shapes. There is no need to extend the engine per se. But yes it could be refactored in order to hide these records."
I understand the idea but in my opinion what makes Orchard's concepts beautiful is that you don't have to specifically think about the future re-use of your module's code as you can just leave all options for extending it open. Not using records directly from the controller would serve as not closing a point of extensibility.
I could only create the Combinator module because I could extend and override the ResourceManager service. If resources would have been stored somewhere else (as an unrealistic example: in records) directly I would have to do much more than just intercepting IResourceManager calls (and would have, probably, failed).

This is the question of the future of course but my bet would be on that as people will start to use Workflows they will have all kind of crazy (in the good sense) ideas wanting to extend it and hook into its inner workings (much like they have for anything in Orchard): now there's a big deal of extensibility points already there for content items, well known; on the other hand I see no real added overhead or complexity associated with storing workflow definitions as content items instead of records. Of course any type of extensibility point could be added to Worklflows later similar to what content items already have without using content items like dynamic permissions but I don't understand why not use content items then.
Coordinator
Jun 19, 2013 at 9:30 PM
Apart from all the technical reasons that Sébastien gave, there is the problem of semantics. Workflows are not semantically content items, they are processes.
Coordinator
Jun 20, 2013 at 7:00 PM
Where is the line between Content and Configuration ?
Jun 20, 2013 at 7:47 PM
Edited Jun 20, 2013 at 7:47 PM
It recalls me the Russell paradox with the barber in a village shaving all bearded men (?) who don't shave themselves
Developer
Jul 5, 2013 at 6:07 PM
I consider everything content (and think that they should be handled in the form of content items) that is volatile data directly editable or viewable by users. This includes pages, blog posts, media, site settings, users, Projector queries, and, in my opinion, workflows too.

This doesn't mean these should have everything inside them (like activities for workflows) stored as content items separately but I definitely find it logical to store the "hub" of these entities (e.g. the workflow definition) as content items.
Coordinator
Jul 6, 2013 at 2:00 AM
And content types, too, then? I disagree. Not everything should be subject to the overhead of a dynamic composition engine.
Developer
Jul 6, 2013 at 7:25 AM
Content types of course not because there should be a point where everything begins naturally but if there would be some kind of similar other system I'd definitely vote for content items.

I still don't see the overhead. Performance overhead? I've written about this in the original post. Development overhead? Also in the original post, quite on the contrary.

On the other hand using content items would provide the advantages I listed.
Coordinator
Jul 6, 2013 at 8:03 AM
All of the above, plus just complexity. Look, you are not going to ever display a workflow on the front-end, because it's not content. As such, lots of things are just not going to make sense. It's not going to get used in the same context at all. We made the mistake in the past of promoting something to content just because we wanted import/export whereas the right thing to do was to enable import/export on things that are not content. If you feel workflows could benefit from this or that aspect of content items, maybe the right thing to do is to bring that aspect to workflows, but it doesn't mean that workflows are content.
Developer
Jul 14, 2013 at 7:11 PM
I fail to see the points of overhead above neither the case of added complexity. I've listed several scenarios where the modelling as content would be beneficial - to re-iterate from my first post: audit trail and fine-grained permissions being the strongest advantages - including ones where using content items reduces complexity and development overhead.

I elaborated points why it makes sense to have workflows as content items and although one would most likely never list workflows on the frontend (something that I never mentioned BTW) even listing them on the admin would be easier with content items: copy-pasting the (albeit short) display markup and logic is the way to go now (instead of building display with ContentManager.BuildDisplay()). Not to mention that the base editor logic is there for content items too.

BTW now I've seen that Image Profiles are also content items that are even more technical than Workflows. Since Projector queries are also content items even the examples from inside Orchard doesn't counter the idea of having Workflows as content items: that's why I got confused when I've seen Workflows being an exception.
Coordinator
Jul 14, 2013 at 11:32 PM
I don't think image profiles and projection queries should be content items. I do see how audit trails and fine-grained permissions could be useful to all those and workflows however. Maybe what we need is something that enables all those scenarios without necessarily enabling you to put client-side comments on image profiles or such other nonsensical scenarios. Maybe we need a lighter-weight type of object that does not necessarily have all that content types have, but allows for such extensibility.
Maybe it's the wrong way to take the problem, and maybe it's cross-cutting concerns such as audit trails and fine-grained permissions that should be implemented as services that can apply equally to true content items and to processes and queries.
Now that seems to be a more interesting discussion. What do you think?
Developer
Jul 15, 2013 at 10:34 AM
Using a special kind of content types would enable all this without having to re-invent such services or completely de-couple them from contents:

If I remember correctly we had a Skype conversation with Sebastien about a concept enabling such scenarios: being able to mark entities (items and types) as "system". This was done before with the media taxonomy but could be required for queries as well. This is something needed for taxonomy term content types too:

The concept is that if a content type is marked as "system" it can be modified by users (or probably only users lacking the site owner permission) in a limited way. Particularly such types can't be removed (this would be needed for taxonomy terms). Also probably type parts could be marked as "system" too, preventing removal in the same way while maintaining the ability to re-use them by being attachable (non-attachable parts can't be removed from the UI already).

To sum it up the ability to mark content types as "system" and thus preventing non-site owner users from being able to delete them would enable developers to leverage the flexibility and services of content types, without the danger of users breaking them by mistake.

In the case of workflows this would enable users to e.g. attach ContentPermissionsPart to configure access to certain workflows and by having CommonPart to enable audit trail.
Coordinator
Jul 15, 2013 at 8:08 PM
This is interesting but only a partial answer.
Developer
Jul 15, 2013 at 10:11 PM
Please elaborate.
Coordinator
Jul 15, 2013 at 11:34 PM
I already did.
Developer
Jul 16, 2013 at 10:25 AM
You described what you think would be a good solution but you haven't elaborated why.

The question is: why have something similar to content types and refactor several services to work without content types when we can have content types? Why create something new to only enable certain scenarios what we already have with contents, to have a stripped-down version of what's already there? Not every feature contents provide makes sense for every content type anyway: why is it an issue that if e.g. workflows are contents you can attach CommentsPart to them, what is something hardly justifiable, when there are multiple services existing for contents that make perfectly sense?
Jul 16, 2013 at 4:30 PM
Edited Jul 16, 2013 at 4:31 PM
Perhaps we should start collecting concrete, valid user scenarios where WorkFlows would definitely need to be content items.
For each argument there's something to say. However, workflow definitions are configuration data, representing a process, and it goes too far to say that workflows are content items.
Content items can be rendered using drivers. This is of no use to Workflows. Import/Export is of use to Workflows.
Obviously, the same goes for Queries and Layers, and yet they are content items.

Therefore I like Bertrand's suggestion to think in terms of cross-cutting concerns or thinking about a "common base", where ultimately there is a Content Item which inherits from this base, and another type of entity which could represent a Query, Workflow, Layer, etc.

In other words, we could think about defining a base interface, e.g. ISeed, IContent and IProcess.

ISeed
---IContent
---IProcess

This way, Orchard services can cut directly at the appropriate layer: Rendering targets IContent, processing queries and workflows targets IProcess.
Import/Export would work for ISeed, so anything can be imported/exported.
Rendering would work for IContent, as it does today.

To make this more concrete, we would have to come up with a couple of real world scenarios.
Coordinator
Jul 16, 2013 at 6:41 PM
I've repeated at least three times my arguments. I understand that you disagree with them but I'm not going to repeat myself one more time. Sipke makes a good summary of some of the issues. We'll discuss it at the meeting in 20 minutes.