Making Workflows Work for You
CC Attribution 3.0 Germany:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Richter, Stephan
Stephan will describe the Zope-based workflow technologies he is currently working on. The Zope/Plone community has tried multiple times to make use of formal workflow standards to drive online workflow processes and UIs, without much success. In this talk Stephan will analyze the situation and try to identify why not. His current company, Shoobx, has finally been successful in creating BPMN-based workflows using Python- and Zope-based technologies, which they extended and which are available for everyone to use. Some of the hard problems that were solved: fully automated UI generation, wizard generation, ability to revert to any point, exception handling, simulations and QA testing. He'll also provide a quick update on what he has been up to for the last 10 years since he presented at PloneConf 2006 Seattle!
 So I'm going to talk today about how to make workflows work for you, which is more or less an introduction to the Zope and Plone workflow story and actually the workflow stories. It's intended for a pretty general audience, even so the talk says it's intermediate, but developers will definitely also get something out of it of what we have been up to, some really interesting technical pieces. So my name is Stefan Richter and I have been involved in the Zope community since 1999. I was there at the first sprints. I developed large parts of Zope 3 and I also have to admit I am the creator of C3C4 which you all love to hate. I've heard this conference. So today I'm going to talk a little bit about workflows and hopefully give you some historical context. The last time I thought I talked at PloneConf in Seattle till several people here told me that I actually was at 2008 in Washington DC as well, which had been completely erased out of my mind and somebody even told me that I gave a talk that year. Unfortunately that was the first talk after the party and I have zero recollection of this talk and I have been told the talk was pretty awful. So apologies for that, I really thought it was 2006 that I gave last a talk. What happened since 2006? I had two kids, Tessan's, Anton is now nine and Conrad is already six, which is great but it also means I have less time to play around with the technical stuff. A couple years back, about seven years back, I had some cardio problems and I decided I need to work out a little bit more and of course because I do everything in the extreme for the people who know me, I decided to do a couple of iron man's and trained up for that and completed that. In 2007 I also decided to leave the consulting business and try start-up life and so I have been involved in four start-ups. Kiosk was in the healthcare industry, they tried to improve people's lives. I had a broadband, they had Comcast as a large customer, I developed a multicast IPTV program, at Cipher Health we did some ObamaCare related stuff and now I'm since three years at Shubox where we handle all of the governance of early stage companies from incorporation to equity management, board management. If you have a small corporation or in Germany, in Argy, you know that there's just a lot of overhead with maintaining that and so Shubox does a lot of this for you. All right, now enough about me. So here's a sort of the history of ZOPE and in that sense also Plown's workflow story. It all started in February 2001, really with the first commit to the CMF and I dig this up, the atresivas did that, commit was already a reference to CMF core workflow core and I remember the story actually quite nicely. Somebody in the community was excited about CMF coming out because ZOPE core for a long time or digital equations had for a long time announced that it would be coming and everybody said like, but there's no workflow. You have all this workflow core definition and there is none and ZOPE core said like, well, you should, community, you should develop your own workflow and everybody is like, no, but we don't want to. And eventually digital equations got pressured into releasing their internal workflow to a based on CMF core called DC workflow that Shane first publicly committed in June 2001. So it didn't take too long for the community pressure digital equations into that and it filled out all the functionality and as I have learned this week DC workflow is still in production and running, which is quite interesting if you think how old it is. Actually now I think by that time it was called ZOPE core paid ZOPE core in the con was paid to develop another workflow product and basically it was for the Navy and they required all these very stringent government processes and that didn't really fit well in the DC workflow story. So then looked around and found the WFMC standard for which editors existed and developed a workflow engine on top of this, which is known as ZOPE.WFMC and he tried to attempt to standardize this so multiple communities could share sort of this sort of workflow approach. Clearly with the departure of ZOPE core doing this type of work, it died in 2011 and actually the story around this is that Jim likes to tell Paul likes to tell Paul Everett is the Navy paid ZOPE core a lot of money to put workflows into the system, but then they didn't like and didn't want to actually follow the process and they paid them a lot of money to rip it all back out. So ZOPE WFMC never really saw it in saw production life for a long time in ZOPE core world. So the last sensible commit was in 2011. As a reaction to ZOPE WFMC because it was the only ZOPE 3 story, oh wait I didn't turn this on, it was the only ZOPE 3 story, is that, I get an echo here. Can you guys hear me back there? Okay, so I'll leave the mic off, that's better. I don't know whether you guys remember, I remember this vividly, Martin Fawzen ran around the community and said like everything is too complicated in ZOPE 3, all these adapters, these utilities, that's crazy. And he had this tick for a couple of months to develop the hurry namespace, everything is done in a hurry and very simple. And one of the outcomes was that he wanted to reproduce what DC workflow does for ZOPE 2, he create a hurry.workflow for ZOPE 3. I checked, he didn't seem to use it anymore, doesn't seem to use it anymore and it ended up dying in 2013 was at least the last real bugfix that I commit. Well, along came my new startup shoebox and it was a perfect match for workflow engine, so we decided to resurrect ZOPE.WFMC and see what we could do with it. And this talk is mostly about what we were able to do with the base and where we went and the problems we solved. But let's go back. So what is DC workflow and hurry workflow? It is known as a state-based workflow, right? That's what the community usually calls this. And the way it works is you have a target, in your case usually a content object in PLONE or document and you store, you have a single attribute where you store the state of that object and then really the workflow engine consists out of defining transitions between these states and including permissions and all this kind of good stuff that belongs to it. So the state machine, I want to really call it a state machine, manages the state and the transitions and then the progression of the states and enforces the rules of the transitions. Right? And it's very simple. It's very like, I think, hurry.workflow is only 150 lines of code which really represents the core of such a state machine. So I went to the PLONE documentation and I found this example that I had seen already 15 plus years ago as the example for how to publish things on PLONE and it's still in the documentation so I just redrew it and put it up here. So here's how it works, right? A state-based workflow. You have three states, draft, pending and published and you define the transitions which are represented by the errors and I put the actors or participants, the role or the roles that can execute that action here as well to simulate the security. Now really the start and finish here makes no sense. I just did it so you know how to read it and that it goes from left to right because you really maneuvering states, right? You don't think really about activities. It's also very interesting. You can then take a published object and put it, retract it back to the draft. So this is what you guys, if you use PLONE, do all day long. You might adjust this at more steps or more states, more transitions, less transitions but that's basically how it works. Now the reality is state-based workflows are not really workflows and there are two big problems with this. First of all, you can only manage a single target like a single content object and you can really only maintain one state at a time unless you define a second attribute and play this entire game again. And I was asking actually all week around here how is it done, especially the single target that really bothers me as a limitation and I was really hoping for the answer that somebody tells me, well really we create like a folder-ish object and dump all our resources like images and so on that belong to an article or blog post and publish that but nobody gave me this answer. So it was all about like, ah we open it, transaction, we push both all the artifacts through and then we commit the transaction. It all works out. So sort of that was the answer. And I was like sort of disappointed. I thought it had gone a little bit further than that in the last 10 years since I have been paying attention. And now then I thought like, you know what, I really think we invented state-based workflows. So I went out there and looked for state-based workflows and ironically the dot net world especially Microsoft SharePoint and even the Java world have picked up this term but I have not found a reference prior to 2001. So are we to blame of having invented state-based workflows? Probably so. It's quite ironic. There are lots of things in the Python and large attack community that were actually invented by the zop and clone community that people now just accept as a fact of life. We start with the term sprint that was taken by Trecevers and it ends with relative and absolute imports in Python which were definitely a ZCML invention. Even so, Guido will never admit it. I was in the room when he picked us up. So let's talk about activity-based workflows. Clearly at ZopWMC is an example and it is really based on BPMN. And BPMN is a graphical representation of processes and it is widely used in many, many different industries. So for example, I was in China a few years back and of course at a manufacturing company for electronics and there of course all ISO 9001 certified which is a quality assurance standard. And what do I see? A gigantic wall with a gigantic process looking exactly like this. Oops. Let me see that I can turn this off. There's a gigantic list of these boxes there describing how the quality assurance process works. And non-surprising if you talk to companies like IBM, Siemens, Deloitte, any of those big IT companies, when they talk about workflow they mean that and they all have super sophisticated tools to run these type of processes in any sort of industry whether it's manufacturing, doing data warehousing, whatnot and execute these workflows. So let's get back a little bit to the history. So BPMN exists for a long time and it was mostly meant so everybody speaks a common language like everybody knows how to read a construction plan, you want to read a workflow. That's what BPMN was. The problem was people wanted to automate these processes but BPMN 1.0 did not define a serialization format. So a bunch of the big players got together and created the WFMC, the workflow management coalition and defined an XML based serialization format called XPDL. And so XPDL was then used by all the early workflow engines as the input format. Now in the last few years BPMN 2.0 was released and it finally specified an XML serialization format of its own. It's part of the BPMN 2.0 standard. So in some sense XPDL is now obsolete. But there are so many processes out there still using it that it will be around for a very long time. Now the reason Jim also chose XPDL is because back then even in 2004 there was already an editor around called the Java workflow editor. Was known as Java. Sometimes also we find references together workflow that can edit these XPDL files including the ones that Zope WFMC could digest. And here you see a screenshot of such an editor with one of our more complicated or usual workflows loaded up. And the nice thing about a Java workflow editor is it's highly customizable because it is intended to be white labeled in for large corporations. So the guys have a lot of bank customers and other highly structured organizations. Get to this in a bit. So let's convert our state based workflow into an activity based workflow. You will see a few differences. So these are our actors here and these lanes are known as swim lanes. And you basically and you always almost always have a system swim lane where the back end executes something. And basically instead of describing states and transitions you only describe activity things that you do like more like the transition. But it's very different right. So you create a draft of your article. Then you ask the reviewer or the manager or the editor to review the article and then publish it. And you can see publish is already a system step that is not even a human interaction. That happens once the article has been reviewed. This little diamond with the X is called an OR gate in BPMN. And it's basically just a simple if statement. You can have multiple more than two coming out of this. At Chewbox we always make it a Boolean decision because it makes it much much easier to read and follow the workflows over time. And you can say no. Then we go back into draft stage and we do yes. Then we publish it. I also added here if the creator wants to retract his article he can use an exception flow that's why it's red. They can retract it. So you can have multiple end points. I just wanted to demonstrate that as well. Are there questions about this because we're building up on this example for a little bit. Yeah. No exactly it's not. You see that look how I did not use nouns. We read in Chewbox is part of our quality insurance that these boxes are never announced. They're always verbs. It's create draft review publish. So these are actions. So I have not made a single statement about what artifacts this workflow creates. Does it create one document. Does it create a document with lots of images. Does it create emails. All sorts of artifacts. I have made no statements about that yet. So there's actually no state from a content point of view involved here. And trust me I have when I started this in 2013 again I had to retrain myself too. It is very very hard to make the transition initially. But once you get it then it's easy. But it's yeah. So instead of just saying create draft you could just say create. Yes. Review publish. And you could if you wanted to throw a noun in there you could just say create thingy. Right. Whatever it is. Right exactly. But we specifically want to stay with our publication workflow and publishing an article. So let's keep that in mind. Yeah. Because well let's let's look at the issues of this high level workflow. This workflow as I wrote it is too high level to be useful. It is very very hard to write machine executable code based on that workflow that actually will execute anything sensible because it leaves too much open. And that's and that means the engine provides really trivial value. So there was almost no point in writing a workflow engine just for doing that. And that's I think the reason why Zop WFMC didn't survive initially is because it was way too high level for people to do anything useful with it. And really the only benefit now we get right that you didn't have with a prone workflows or the DC workflow is a graphical representation. But the graphical representation of that high level is so trivial that how much does it explain to you what you wouldn't have understood before. So now I actually took that very trivial translation of the state based workflow and actually implemented it as it would be runnable in shoebox. So I created that workflow and stuck it into our system. And this is what I had to come up with. First of all we never talked about who the creator and the real are. So the first thing is you need to assign them several workflow systems hook their workflow engines up to LDAP and they auto detect these things. We have found that doing that implicitly was not a good idea. So we have switched completely off assigning these swim lanes manually. And a sign a creator basically says, hey assign this lane to the person who initiated the process. And the reviewer because we are a legal processes thing is I assigned to the president of the company. Only the president of the company can approve these articles. It's simply so it fits in the system nicely. We don't have a good concept of managers yet so it wasn't that easy to. So I changed the language a little bit to say author article which basically means enter the title, the lead in and the description. I will show you this in a second. Just because I provided the data, this is just a simple form input similar to what you would auto generate with all the nice prone tools. You then have to generate the article. In our case these are mostly PDF documents so in my case I create a simple PDF document for review. And then let's skip that incoming orgate. And then why? Because the creator never saw the generated article. I need a review step. So I need to give the, do I have actually, oh I have even laser points so I can sort it further away. So you want to give the user the ability to review the article and potentially go back. And we do have capabilities to step back. So we skip this for now and then this is an endgate which means execute things in parallel because we send things off to approval to the reviewer to approve the article but you know what we don't want the creator to just sit there and not know what's going on. Because this approval in our, in Chewboxes, in our real cases is many, many steps long because first the lawyers have to review it, then the board might have to review a document, then you know who knows who else have to give a sign off that's all depending on policy. So you want to give the creator some feedback and this work item rates until this activity rates until that activity completes. And then this gate rates until both errors, both transitions arrive. Okay, then it goes on and depending on what the approval was like, if it was not approved we go back to review. That's why we have to reset the rejection reason, right? So we have to clear it out so it doesn't go to no all the time. And then you go to yes and you see yes is orange which means it is the default flow. So if nothing, if it doesn't find anything or this, if any of the conditions are false then it always, it's like the else statement, that's basically the else. And then it's a system step to publish the article. In our case this means setting a finalized tag to it, assign certain tags to put it in the right folder, et cetera, et cetera. And then you really don't want to let the creator go from way to approval to nothing else, you're going to tell him, hey, your article is now published, you can now do x, y, z. So it is a convention at Chewbox to always have a next steps where we explain to you what happened afterwards. The other thing that we are doing is we are defining wizards as you will see in a moment and I want to point this out here so you can pay, so we see this and I'm working in the system. So we say this, this, this and this work item are in one wizard, you just say you will have a wizard and so you will see that for those four steps we have a nicely created wizard on top and it auto generates that all just by us putting a little marker on there, you have a wizard, you have a wizard, you have a wizard, you have a wizard, you have a wizard. It scans the process definition, figures all this out. This also has a wizard. So I ran all, so I ran through this and I thought like I created a great Chewbox process. Well, all QA failed because there's even one more step missing here. How does a reviewer even know that he has to review or she has to review an article? Well there should be probably an email step somewhere here that is only sent the first time that says, hey, an article is ready for you, review. So I hope you get a sense to what level of granularity you have to get to to make these workflows really useful. I want to turn on my screen so I can see. So I need to be behind the Pult now anyways because I want to show you a demo. And so all our Chewbox example are modeled after Silicon Valley with Pied Piper and all its characters. So if you watch the show, you will get the references. If not, it will just be normal. So Erlek is, he's a wannabe president of the company, but he's not as you know if you saw the show. But he is allowed to publish an article. So this is our interface. I can explain more of this later. Come to me after the talk if you're interested in some of the other things we did. But we want to publish the article and from now on everything is defined by the workflow definition we saw. You can see the visit here. You see all the same titles show up and I can just now type in BroomeConf article in, it's 2016 so I won't forget. And some text. And this is super trivial, right? You will also notice I can discard a process at any time. So we made that possible as well. So we continue. I can now review my article. I can download the PDF. I'm not going to open this right now. But we can also view the article in HTML because we can generate out of our XML document templates and we can, for example, change the title. We can move to the next section, et cetera, et cetera. So I save this and now I said, okay, my article is perfect. I send it off. And I didn't put a nice message here. Usually we put a really nice message here, but you get a rate step. You're notified that you're waiting for somebody to approve this. We even put the person here with the approval and whatnot. But on the other side of things, there is Richard Hendricks, who is actually the president of PipePiper. And he already, and we are using, yes, we're using web sockets to push things through. He now sees he has an article to approve. He can get a little quick overview or he sees, oh, it comes from Ehrlich, et cetera, et cetera. The document, unfortunately, is not showing up here because I didn't assign a certain tag, I have been told. But we can go in here and he can now approve the article. A couple cool things. Our document templates can be rendered into a visual format. So any condition, any loops have a visual representation. So our lawyers can review even just the template. If you would have multiple versions, we can even visualize version differences. And we ended up developing our own XML diffing library based on the famous white paper for this. So we continue. And Richard is done. Unfortunately, he doesn't get the next steps. So that would be probably another QA thing that would pop up. But if we see due to the push, thanks to the push, the next steps show up. Every time we press continue, we send actually a task for salary. And if the tasks take a long time, there's a spin out that will push back and tell you what it is currently working on. So there's a lot of cool web socket based technology and async technology and all of this. So we can go to the next. Unfortunately, Ehrlich is not privileged enough to see these documents. So we go back to Richard and we can see if he go to his documents. So we can go to articles. The ChromeConf article showed now up. And it didn't show, I should have shown that, it didn't show up before it wasn't published because certain tags get set. So we have actually this concept of states as well. But we just call them tags that are namespaced. And we just have multiple tags on one attribute and we manage them through our workflows. OK. Other questions about that example? Cool. So yeah. You mentioned the OR gate. Yeah. But there's, you didn't elaborate on it. You said, we'll move on from that. Yeah. OK. Sure. So yeah. We have learned over time that OR gates always come in pairs. Most often come in pairs. Because you say XOR, but then you usually with one, you go back. And you have to join together. While the XP.DL standard allows for many transitions to come into a main activity, because this is also just an activity, several other not so sophisticated editors do not allow it. And it is much easier to reason about your workflows and read them if you make another OR gate there. So OR gate only means it only waits for one incoming transition and not for both. The end gate is exactly the opposite. It always does set of both, not just one, and it waits for both. Or for N. It can be any amount. And we have some where we do five or six things at the same time. All right. Any other questions? Cool. So just a little summary of what did we, what are the big things that we had to build in order to make all this work? Security but Plone has that too. Check. We are using the Zope libraries after all. We use Zope security, of course, and Zope security policy. So we have exactly the same type of capabilities as they are in Plone today. Machine executable. DC workflow does that too. This machine executable. Check. Full user interface generation and any other I.O. generation. That only works for DC workflow because it's super, super trivial and you can do one size fits all basically approach, right? Because you only have to show states, the current state, and what other state you can get to. There's very little metadata even around any of this. So and for the publication workflow, you know, that's not that manner. But all of these screens that you saw, they're all standard activity types, applications they are called. So that's that. So you need to implement back and forth. I didn't demonstrate this, but you can go back and forth. You saw the back and forth error, right? Because people expect if they see a wizard, I want to jump to this point. You can also click on the wizard itself and jump to a particular point. And then you want to go forward again. And then the problem that arises out of this is, well, you should really remember the data that I typed in in the past and in the future, which is also not necessarily trivial, especially if you now make changes in the past that affect the future. So you have to be very careful of what data you retain. Discarding and of course, discarding with cleanup. So you say, I don't want this workflow. It was a crap shoot. Ignore it. So you want to make sure all the articles and everything gets deleted. Exceptional handling. That was what broke the WFMC's neck originally. And then migrations. Migrations are super, super important as we upgrade our applications and our processes. You know, if you update your process, you cannot just run on the new version suddenly. Because where are you? Do you have all the data? So we do a lot of version management and then migrate data very carefully. And that's a big problem. We haven't really fully solved it yet. OK. So we did a bunch of WFMC enhancements. And all of these enhancements are, we put back into the ZOPWFMC core. Unfortunately, not yet in the ZOPFundation repository. It's on our shoebox. We have a clone on shoebox. But if there's interest from the clone community to use ZOPWFMC, we would have certainly good motivation to clean things up, write the necessary tests and documentation, and publish it further. But until now, nobody came along. So we haven't had much willpower to do it. So we, XPDL 2.1, the original one only supported XPDL 1.0, we added extended attributes. So to any activity, to any process, to any participant, you can put any amount of metadata and then entire XML substructures called extended attributes. And that wasn't implemented. We used that heavily to hint the UI, to hint, as you will see, the simulations and the testing and many other things. So this basically our approach to do a lot, a lot of the automation. Candidate support. So let's say you have two presidents of the company, and you might think that's not possible, but yes it is. You can have co-presidents that can approve. So you have multiple people. We have the capability of saying, yes, multiple people can do this, and somebody takes the ball and says, I'm going to do it. So candidate support, which is a very core feature of workflows. We implemented subflows, think about it as macros, like metal macros, task scripts, which are basically arbitrary Python scripts. You did see one with the reset. A data field support, which gives you data typing. Parameters didn't support initial values. Otherwise conditions, the else case that I showed you. Script tag support, because you can specify on a process what scripting language you're using, and arguments to the activities, because, dang it. Uh-oh, you lost it. Do you guys have it over there? Oh, OK. I hope the clicker works far enough, so I come over here. I have been warned that that would happen. So arguments to activities, because you pass in variables, you get variables, are used to be lists, and we converted them to dictionaries, which was a big pain for all migration, because it's much easier if you have key value pairs to do migrations if you get new arguments. Unfortunately, this was thanks to Jim. I didn't tell him about this little thing when we met earlier this week. And then deadline support. You can say, if an activity hasn't been touched for a day, what do you want to do about it? You can raise an exception and take an alternate path through the system. All right. We also enhanced the workflow edit a little bit. We worked with the together workflow guys. They do a lot of stuff in the Java community for banks, especially in Switzerland and Austria. The owner is originally from Austria, but they're all in Thailand. So we paid them to do a couple of things like small bug fixes and larger bug fixes that made it possible to use, how the labels can be positioned, script support, and external editor support. So you can click on anything. And if you specify Python as a script, it opens it up in a temporary file that has a right file extension. So you get the syntax highlighting and all that kind of good stuff in your external editor. We could do a lot more, but we simply haven't gotten around to it yet. OK. So let me talk about a couple of really hard problems that we had to solve. Discarding a workflow. Well, originally, a ZopwMC didn't keep track of any of the activities it had already finished. So we had to start keeping track of all the finished activities. So when you discard it, we could undo them. It requires for all of your activities or these applications that drive these activities to be reversible. Right? You have to be able to say, this generated a document, now we need to remove the document. There are some cases where you have irreversible actions. For example, you created a user. The user has received an email to log in. Well, just because you want to undo your workflow, you don't want to create suddenly a broken link for the user because you deleted the user. So it's better to just leave the user existence. They don't have any access anyway, so it doesn't matter. Therefore, you make the workflow simply nondiscardable. And the prime example of this is, once all parties signed a document, it is legally binding. The document cannot suddenly go away because you discarded your workflow. So in those cases, we make the workflows at that point nondiscardable, which sometimes really makes our users mad because we make it so easy to execute legally documents that they don't even think about it that way. Back and forth, I mentioned that already before. You have to be able to revert the activities. You have to restore the workflow state properly and remember the inputs, as I mentioned. And that's a very, very hard problem. We spent a loan just to solve this. There are six amendments worth of effort in that. The wizard, I mentioned that before. You saw it nicely going up on top. The hard part about it is, it needs to be generated before any workflow state exists. And as more workflow state comes into play, the wizard actually adjusts and finds the path that you're actually going to take. So once you reject, it will readjust, for example, the wizard. This is also a very hard problem to get right, especially because of all the splitting and joining that you can do. We spent roughly at least three, if not four to five, men months just solving the wizard problem. What happened? Whoa. Okay, there it is. Now, if you have a lot of processes, and I don't know how the Plonero does that, I would love to talk to some people how this is done, and I'm running this video, which is a simulation of our workflow. Run in Firefox, fully automated, is testing, right? And so you want to automatically test your workflows. You want to have coverage. So the big part is you have to provide a strategy for completing your applications. And that took us also two to three attempts to do. We ended up writing extended attributes on each activity, on each interactive activity that the user has input to, define how the user would input stuff, and then complete the activity, and then it would keep going. You want to have save points. We have processes that take 10 minutes to run, or large ones like this. If the developer works on the last two work items, you don't want to have them wait nine minutes before they get any feedback. So we create save points that you can create, and you can start the workflow anytime from that spot. Debugging, you can stop at any activity. We can take screenshots at any interactive activity, and we can parameterize all simulations so that we can create very rich setup environments. For example, the Piper example that I showed you, we just completely simulate that. This is never typed in from hand. So let's see what's next. So I don't know how we're doing in time. Almost good. So quality assurance. So I'm going to just show you the quality assurance instead of going over the steps. So we created a very rich dashboard because we deal with lawyers and they have zero tolerance for problems, not just functionally, but also from a language point of view. So we have 98 processes that can be started from the UI. There are about two or 300 of them with all the sub-processes. For those 98 processes, we wrote 300 sims, and then we have all sorts of document templates, and we test all the permutations of these documents. And in those 98 processes, we have 3,500 activities. So that's a lot of stuff to run. And yesterday, our QA dashboard was all green and it was quite boring, but today I have some interesting stuff to show. So we test all our processes on the four major browsers, and then we run also a bunch of QA checks. So I can show you a little bit of output. So let's not take the stock transfer. So for example, it ran in Internet Explorer, this simple workflow. So we get all the Internet Explorer output, including a screenshot for each step of the workflow. In this case, it was just one. So maybe I should choose a really a little bit more interesting example, like the stock transfer. So here you can see Internet Explorer. It tells you it was Internet Explorer 11. And when it ran, and here are all the screenshots of Internet Explorer. And so our UX department can go through these PDFs and check that all the browsers render the stuff correctly. If the simulation was successful, you can also see all the documents that get generated here for your review. We have lots and lots of process controls. So for example, whether it's completed, whether we get the same output as last time, so this is all good. And here's our coverage. So if you want to see how is the process covered, what is it transfer? Transfer certificate. This one is actually 100% covered. But let's say we go to the upload case. Though that's just one simulation. And of course, one simulation can never cover the entire article. So we can, but we can see that simulation went through this specific path. So we have insights of what paths we are actually taken by our simulation. And then basically the top one combines all the simulations, and it's 100% for this particular case. So let me just find actually the one where we have also PQA failure. So here, for example, the long-term stability output change, so we keep track of any state change in the system. And we create a diff, and then we compare the diffs. We use a JSON diff tool to do this. And so we see here, for some reason, this process now has a new email that is being sent and somebody didn't accept that properly. So that's our QA tool and how we keep, make sure that all our processes function all the time. And this is run. We can run this on a database or even more often. It takes about what these days, 45 minutes to complete for full test run. OK, so what's up in the future? I would love to write the shoebox chronicles. That's also something that I tried to do early in the days. With the, in the Zope community, my dream was always to write these rest documents and describe, hey, run something like this in the browser, take a snapshot of the browser and insert a screenshot, and so that we can create support help in an automated way. And then a funny story to this. About two years ago, our customer's success person was really enthusiastic about writing lots of support articles. So she kept writing, and I said there, like, in a few months, you will have to revise all of these. You will have to revise all of these. And no, no, no, we keep writing, we keep writing. We had 72 of them. One month back, we finally did a review. We threw them all away. All 72 were completely thrown away because, of course, they completely bit-rotted. Nothing in those support articles described anything like the system worked. So I would love to just create these support articles via this. And it's not super hard. I would also like to automate video generation, right? Then you could have little self-support videos. And thanks to Selenium, that shouldn't be a big deal. I just have not gotten around to hooking this up. The holy grail for us is to really support the power user. If you can use Excel, or if you are a blown user, not a developer, but a user who can configure a system and create articles, you should be able to create processes in our system. So our idea is that eventually people with legal expertise, lawyers, paralegals can create new processes most easily. That is probably still about five years away because we would have to rewrite or do massive customizations to the editing tool and put a lot of more security in a lot of the Python expression evaluation, et cetera. In the ploneral to your value of what it takes to allow people to enter arbitrary executable code at whatever level. And on a personal note, I would love to bike across the US before I get to Alt. So, OK. You never get to Alt. You just have to go very slow. Yeah, but I also have family. So my goal is to make it in 30 days. Questions, comments, and before I forget, please go to ploncon6feetup.com and rate the talk. Yeah. So as far as actually creating the workload, that was one thing I didn't quite get. So I saw this GUI tool. Yeah. And it looked like you're able to edit the visual representation. Right. And I saw the end result. Yeah. So the web interface. Yeah. So we upload that XPDL file into our system. It's part of our source code. And I did a bunch of other things in the back end, such as creating tags, creating a new folder for this data room, creating an entry for the actions, all these are configuration very much like you used to from the plon world. And then it just works. So I literally wrote zero Python code. Like zero, I did not have to modify our code base, our Python code base, in order to make this work. So that is a very significant goal for us. But high level developers can do this. And I'm more than glad maybe after the talk for people who are interested to show them the editor tool and show you a little bit more of the magic that goes on behind and why the simulation work, why the result shows up, et cetera, et cetera. Yeah. You spoke about having multiple objects that travel together. Yeah. And I wondered if you had, well, what we have is kind of an idea where multiple objects travel together, but they travel through separate workflows that sometimes share states and sometimes some of them will break off and come back. And so what we've got is these cascading workflow guards and rules, but just a way out of control. And I wondered, what did you do? And that is an outcome of the state-based workflow approach. So what we are doing is basically we collect data. So I did not bring up any of our sophisticated processes, like incorporating a company, which generates five documents, for example, post-incorporation. When you set up your board and stuff, creates about 10 documents. So what we are doing is we are collecting the data. We have forms. You could do this in prone very easily with all the machinery that you have. And then we generate these documents in system steps. And we can create many system steps, we create many documents in all sorts of ways. And then we bring them back in. And then we move them along. Because your action is not really, so what's your action? Or what's your goal? A process always achieves a high-level goal, for example, incorporating a company. These documents, if they interact, they are not living in isolation. They move together. Like, for example, I could imagine in the content management world, you have a lot of these things. As I started, you might create an article that has images to it. You might want to, you need to push, you want to publicize this. So you push to some external website. So you have all these versions and artifacts around. But your goal is still to publish an article. But in a case where, give me a concrete example of what you're doing. I'll take from that. In a case where you want to say, okay, we have 10 documents, but the people on the other side are in a real hurry. And they can't see anything until we've published a parent. But we have two that we can't publish yet. But we want to pre-publish. We want to say, this thing is now being published. But the state of the main object is not published. But those eight have been published. And when that comes in, you can see. But these two are still out. So either you can't see them or you can see that they're there, but they're in a different state. So the state of the inside of those 10 is all over the place. But somehow the work for them needs to be able to say, when those two become ready to be published, you need to be able to say, okay, well now publish. And that must occur. So we would create one process instance for each document that gets published. So you create 10 publishing new article processes because you need to move 10. You need to be authored and whatnot. And then we would create, for example, you might have something else that is called pre-published. You can say, oh, let me pre-publish on that. It would just be another process you execute. So we are not thinking of this as necessarily as one workflow, but it's many workflows. So you could publish the main container and you could ask it then to push each of those 10 through its publish and two of them will fail. But you see, you're still thinking very much in terms of state-based workflow because you're thinking about publishing a container or talking about making the container available. I would not even, like, the way I showed is like you wouldn't even think about a container. That's just a site artifact that they live in the same container. Like, for example, the same folder or whatever. What your real goal is to generate these articles, these documents, and that they live eventually at the same, like, I would not make my permissioning based on the container, right? You want to really make your permissioning work against each document itself and then you publish the document one by another and thus you can apply different rules. The code that you said is currently living somewhere else, please, would you let us, I really want to have a look at that. Yeah, absolutely. Actually, one feedback when I did my practice run this morning with the company was that he said like I should have added the links. I'll add the links to the slides and then put it on slide shares and then it should be available or whatever Selly does with the publication and you can look at it and get to it. Thank you. Any more questions? We can talk afterwards. I'm here. So any other questions? Yeah, Carlos. Another question, a comment. Yeah? I saw your historical overview. There was an activity-based workflow for SOAP that was built in Italy. It's called OpenFlow. Right. Oh, yeah. Why didn't you tell me this yesterday? Yeah, absolutely. Yeah, that was OpenFlow. But I think it now really, yeah. It was, for a while, I guess it was used. It used the same symptomatology of the work items and the activities. Yeah, but they didn't use XPDR, I think. No, no, they didn't. They weren't graphical. Right, obviously. Oh, yeah, that's right. David Devencenzo did that one, right? OpenFlow. David Devencenzo developed OpenFlow, I think. I think the names of the developers are Richard Lemmy or something like that. Oh, Ricardo. Oh, Ricardo. Yeah, yeah, yeah. Yeah, yeah, yeah, right. Devencenzo de Barone. Devencenzo de Barone. He's in the... That's why I mixed this up. No, Devencenzo de Barone, no, sorry, sorry. No, disoma. Disoma, disoma. That's right. Yeah, no, that is true. I forgot about that. That was OpenFlow at some point. Well, of course, there's no committance to that. Yeah. That would have been a good one to add. That's true. I tried to use it once and I forgot. I didn't quite use it. I reduced it for a bank. Any other questions? All right. Thank you very much for coming. Thank you.
 So I'm going to talk today about how to make workflows work for you, which is more or less  an introduction to the Zope and Plone workflow story and actually the workflow stories.  It's intended for a pretty general audience, even so the talk says it's intermediate, but  developers will definitely also get something out of it of what we have been up to, some  really interesting technical pieces.  So my name is Stefan Richter and I have been involved in the Zope community since 1999.  I was there at the first sprints.  I developed large parts of Zope 3 and I also have to admit I am the creator of C3C4 which  you all love to hate.  I've heard this conference.  So today I'm going to talk a little bit about workflows and hopefully give you some historical  context.  The last time I thought I talked at PloneConf in Seattle till several people here told  me that I actually was at 2008 in Washington DC as well, which had been completely erased  out of my mind and somebody even told me that I gave a talk that year.  Unfortunately that was the first talk after the party and I have zero recollection of this  talk and I have been told the talk was pretty awful.  So apologies for that, I really thought it was 2006 that I gave last a talk.  What happened since 2006?  I had two kids, Tessan's, Anton is now nine and Conrad is already six, which is great  but it also means I have less time to play around with the technical stuff.  A couple years back, about seven years back, I had some cardio problems and I decided I  need to work out a little bit more and of course because I do everything in the extreme  for the people who know me, I decided to do a couple of iron man's and trained up for  that and completed that.  In 2007 I also decided to leave the consulting business and try start-up life and so I have  been involved in four start-ups.  Kiosk was in the healthcare industry, they tried to improve people's lives.  I had a broadband, they had Comcast as a large customer, I developed a multicast IPTV  program, at Cipher Health we did some ObamaCare related stuff and now I'm since three years  at Shubox where we handle all of the governance of early stage companies from incorporation  to equity management, board management.  If you have a small corporation or in Germany, in Argy, you know that there's just a lot  of overhead with maintaining that and so Shubox does a lot of this for you.  All right, now enough about me.  So here's a sort of the history of ZOPE and in that sense also Plown's workflow story.  It all started in February 2001, really with the first commit to the CMF and I dig this  up, the atresivas did that, commit was already a reference to CMF core workflow core and  I remember the story actually quite nicely.  Somebody in the community was excited about CMF coming out because ZOPE core for a long  time or digital equations had for a long time announced that it would be coming and everybody  said like, but there's no workflow.  You have all this workflow core definition and there is none and ZOPE core said like,  well, you should, community, you should develop your own workflow and everybody is like, no,  but we don't want to.  And eventually digital equations got pressured into releasing their internal workflow to a  based on CMF core called DC workflow that Shane first publicly committed in June 2001.  So it didn't take too long for the community pressure digital equations into that and it  filled out all the functionality and as I have learned this week DC workflow is still  in production and running, which is quite interesting if you think how old it is.  Actually now I think by that time it was called ZOPE core paid ZOPE core in the con was paid  to develop another workflow product and basically it was for the Navy and they required all  these very stringent government processes and that didn't really fit well in the DC  workflow story.  So then looked around and found the WFMC standard for which editors existed and developed a  workflow engine on top of this, which is known as ZOPE.WFMC and he tried to attempt to standardize  this so multiple communities could share sort of this sort of workflow approach.  Clearly with the departure of ZOPE core doing this type of work, it died in 2011 and actually  the story around this is that Jim likes to tell Paul likes to tell Paul Everett is the  Navy paid ZOPE core a lot of money to put workflows into the system, but then they didn't  like and didn't want to actually follow the process and they paid them a lot of money  to rip it all back out.  So ZOPE WFMC never really saw it in saw production life for a long time in ZOPE core world.  So the last sensible commit was in 2011.  As a reaction to ZOPE WFMC because it was the only ZOPE 3 story, oh wait I didn't turn  this on, it was the only ZOPE 3 story, is that, I get an echo here.  Can you guys hear me back there?  Okay, so I'll leave the mic off, that's better.  I don't know whether you guys remember, I remember this vividly, Martin Fawzen ran around  the community and said like everything is too complicated in ZOPE 3, all these adapters,  these utilities, that's crazy.  And he had this tick for a couple of months to develop the hurry namespace, everything  is done in a hurry and very simple.  And one of the outcomes was that he wanted to reproduce what DC workflow does for ZOPE  2, he create a hurry.workflow for ZOPE 3.  I checked, he didn't seem to use it anymore, doesn't seem to use it anymore and it ended  up dying in 2013 was at least the last real bugfix that I commit.  Well, along came my new startup shoebox and it was a perfect match for workflow engine,  so we decided to resurrect ZOPE.WFMC and see what we could do with it.  And this talk is mostly about what we were able to do with the base and where we went  and the problems we solved.  But let's go back.  So what is DC workflow and hurry workflow?  It is known as a state-based workflow, right?  That's what the community usually calls this.  And the way it works is you have a target, in your case usually a content object in  PLONE or document and you store, you have a single attribute where you store the state  of that object and then really the workflow engine consists out of defining transitions  between these states and including permissions and all this kind of good stuff that belongs  to it.  So the state machine, I want to really call it a state machine, manages the state and  the transitions and then the progression of the states and enforces the rules of the transitions.  Right?  And it's very simple.  It's very like, I think, hurry.workflow is only 150 lines of code which really represents  the core of such a state machine.  So I went to the PLONE documentation and I found this example that I had seen already  15 plus years ago as the example for how to publish things on PLONE and it's still in  the documentation so I just redrew it and put it up here.  So here's how it works, right?  A state-based workflow.  You have three states, draft, pending and published and you define the transitions which are  represented by the errors and I put the actors or participants, the role or the roles that  can execute that action here as well to simulate the security.  Now really the start and finish here makes no sense.  I just did it so you know how to read it and that it goes from left to right because you  really maneuvering states, right?  You don't think really about activities.  It's also very interesting.  You can then take a published object and put it, retract it back to the draft.  So this is what you guys, if you use PLONE, do all day long.  You might adjust this at more steps or more states, more transitions, less transitions  but that's basically how it works.  Now the reality is state-based workflows are not really workflows and there are two big  problems with this.  First of all, you can only manage a single target like a single content object and you  can really only maintain one state at a time unless you define a second attribute and play  this entire game again.  And I was asking actually all week around here how is it done, especially the single  target that really bothers me as a limitation and I was really hoping for the answer that  somebody tells me, well really we create like a folder-ish object and dump all our resources  like images and so on that belong to an article or blog post and publish that but nobody gave  me this answer.  So it was all about like, ah we open it, transaction, we push both all the artifacts through and  then we commit the transaction.  It all works out.  So sort of that was the answer.  And I was like sort of disappointed.  I thought it had gone a little bit further than that in the last 10 years since I have  been paying attention.  And now then I thought like, you know what, I really think we invented state-based workflows.  So I went out there and looked for state-based workflows and ironically the dot net world  especially Microsoft SharePoint and even the Java world have picked up this term but I  have not found a reference prior to 2001.  So are we to blame of having invented state-based workflows?  Probably so.  It's quite ironic.  There are lots of things in the Python and large attack community that were actually  invented by the zop and clone community that people now just accept as a fact of life.  We start with the term sprint that was taken by Trecevers and it ends with relative and  absolute imports in Python which were definitely a ZCML invention.  Even so, Guido will never admit it.  I was in the room when he picked us up.  So let's talk about activity-based workflows.  Clearly at ZopWMC is an example and it is really based on BPMN.  And BPMN is a graphical representation of processes and it is widely used in many, many  different industries.  So for example, I was in China a few years back and of course at a manufacturing company  for electronics and there of course all ISO 9001 certified which is a quality assurance  standard.  And what do I see?  A gigantic wall with a gigantic process looking exactly like this.  Oops.  Let me see that I can turn this off.  There's a gigantic list of these boxes there describing how the quality assurance process  works.  And non-surprising if you talk to companies like IBM, Siemens, Deloitte, any of those  big IT companies, when they talk about workflow they mean that and they all have super sophisticated  tools to run these type of processes in any sort of industry whether it's manufacturing,  doing data warehousing, whatnot and execute these workflows.  So let's get back a little bit to the history.  So BPMN exists for a long time and it was mostly meant so everybody speaks a common  language like everybody knows how to read a construction plan, you want to read a workflow.  That's what BPMN was.  The problem was people wanted to automate these processes but BPMN 1.0 did not define  a serialization format.  So a bunch of the big players got together and created the WFMC, the workflow management  coalition and defined an XML based serialization format called XPDL.  And so XPDL was then used by all the early workflow engines as the input format.  Now in the last few years BPMN 2.0 was released and it finally specified an XML serialization  format of its own.  It's part of the BPMN 2.0 standard.  So in some sense XPDL is now obsolete.  But there are so many processes out there still using it that it will be around for a very  long time.  Now the reason Jim also chose XPDL is because back then even in 2004 there was already an  editor around called the Java workflow editor.  Was known as Java.  Sometimes also we find references together workflow that can edit these XPDL files including  the ones that Zope WFMC could digest.  And here you see a screenshot of such an editor with one of our more complicated or usual  workflows loaded up.  And the nice thing about a Java workflow editor is it's highly customizable because it is  intended to be white labeled in for large corporations.  So the guys have a lot of bank customers and other highly structured organizations.  Get to this in a bit.  So let's convert our state based workflow into an activity based workflow.  You will see a few differences.  So these are our actors here and these lanes are known as swim lanes.  And you basically and you always almost always have a system swim lane where the back end  executes something.  And basically instead of describing states and transitions you only describe activity  things that you do like more like the transition.  But it's very different right.  So you create a draft of your article.  Then you ask the reviewer or the manager or the editor to review the article and then  publish it.  And you can see publish is already a system step that is not even a human interaction.  That happens once the article has been reviewed.  This little diamond with the X is called an OR gate in BPMN.  And it's basically just a simple if statement.  You can have multiple more than two coming out of this.  At Chewbox we always make it a Boolean decision because it makes it much much easier to read  and follow the workflows over time.  And you can say no.  Then we go back into draft stage and we do yes.  Then we publish it.  I also added here if the creator wants to retract his article he can use an exception  flow that's why it's red.  They can retract it.  So you can have multiple end points.  I just wanted to demonstrate that as well.  Are there questions about this because we're building up on this example for a little bit.  Yeah.  No exactly it's not.  You see that look how I did not use nouns.  We read in Chewbox is part of our quality insurance that these boxes are never announced.  They're always verbs.  It's create draft review publish.  So these are actions.  So I have not made a single statement about what artifacts this workflow creates.  Does it create one document.  Does it create a document with lots of images.  Does it create emails.  All sorts of artifacts.  I have made no statements about that yet.  So there's actually no state from a content point of view involved here.  And trust me I have when I started this in 2013 again I had to retrain myself too.  It is very very hard to make the transition initially.  But once you get it then it's easy.  But it's yeah.  So instead of just saying create draft you could just say create.  Yes.  Review publish.  And you could if you wanted to throw a noun in there you could just say create thingy.  Right.  Whatever it is.  Right exactly.  But we specifically want to stay with our publication workflow and publishing an article.  So let's keep that in mind.  Yeah.  Because well let's let's look at the issues of this high level workflow.  This workflow as I wrote it is too high level to be useful.  It is very very hard to write machine executable code based on that workflow that actually  will execute anything sensible because it leaves too much open.  And that's and that means the engine provides really trivial value.  So there was almost no point in writing a workflow engine just for doing that.  And that's I think the reason why Zop WFMC didn't survive initially is because it was  way too high level for people to do anything useful with it.  And really the only benefit now we get right that you didn't have with a prone workflows  or the DC workflow is a graphical representation.  But the graphical representation of that high level is so trivial that how much does it  explain to you what you wouldn't have understood before.  So now I actually took that very trivial translation of the state based workflow and actually implemented  it as it would be runnable in shoebox.  So I created that workflow and stuck it into our system.  And this is what I had to come up with.  First of all we never talked about who the creator and the real are.  So the first thing is you need to assign them several workflow systems hook their workflow  engines up to LDAP and they auto detect these things.  We have found that doing that implicitly was not a good idea.  So we have switched completely off assigning these swim lanes manually.  And a sign a creator basically says, hey assign this lane to the person who initiated the  process.  And the reviewer because we are a legal processes thing is I assigned to the president of the  company.  Only the president of the company can approve these articles.  It's simply so it fits in the system nicely.  We don't have a good concept of managers yet so it wasn't that easy to.  So I changed the language a little bit to say author article which basically means enter  the title, the lead in and the description.  I will show you this in a second.  Just because I provided the data, this is just a simple form input similar to what you  would auto generate with all the nice prone tools.  You then have to generate the article.  In our case these are mostly PDF documents so in my case I create a simple PDF document  for review.  And then let's skip that incoming orgate.  And then why?  Because the creator never saw the generated article.  I need a review step.  So I need to give the, do I have actually, oh I have even laser points so I can sort  it further away.  So you want to give the user the ability to review the article and potentially go back.  And we do have capabilities to step back.  So we skip this for now and then this is an endgate which means execute things in parallel  because we send things off to approval to the reviewer to approve the article but you  know what we don't want the creator to just sit there and not know what's going on.  Because this approval in our, in Chewboxes, in our real cases is many, many steps long  because first the lawyers have to review it, then the board might have to review a document,  then you know who knows who else have to give a sign off that's all depending on policy.  So you want to give the creator some feedback and this work item rates until this activity  rates until that activity completes.  And then this gate rates until both errors, both transitions arrive.  Okay, then it goes on and depending on what the approval was like, if it was not approved  we go back to review.  That's why we have to reset the rejection reason, right?  So we have to clear it out so it doesn't go to no all the time.  And then you go to yes and you see yes is orange which means it is the default flow.  So if nothing, if it doesn't find anything or this, if any of the conditions are false  then it always, it's like the else statement, that's basically the else.  And then it's a system step to publish the article.  In our case this means setting a finalized tag to it, assign certain tags to put it in  the right folder, et cetera, et cetera.  And then you really don't want to let the creator go from way to approval to nothing  else, you're going to tell him, hey, your article is now published, you can now do x,  y, z.  So it is a convention at Chewbox to always have a next steps where we explain to you  what happened afterwards.  The other thing that we are doing is we are defining wizards as you will see in a moment  and I want to point this out here so you can pay, so we see this and I'm working in the  system.  So we say this, this, this and this work item are in one wizard, you just say you will have  a wizard and so you will see that for those four steps we have a nicely created wizard  on top and it auto generates that all just by us putting a little marker on there, you  have a wizard, you have a wizard, you have a wizard, you have a wizard, you have a wizard.  It scans the process definition, figures all this out.  This also has a wizard.  So I ran all, so I ran through this and I thought like I created a great Chewbox process.  Well, all QA failed because there's even one more step missing here.  How does a reviewer even know that he has to review or she has to review an article?  Well there should be probably an email step somewhere here that is only sent the first  time that says, hey, an article is ready for you, review.  So I hope you get a sense to what level of granularity you have to get to to make these  workflows really useful.  I want to turn on my screen so I can see.  So I need to be behind the Pult now anyways because I want to show you a demo.  And so all our Chewbox example are modeled after Silicon Valley with Pied Piper and all  its characters.  So if you watch the show, you will get the references.  If not, it will just be normal.  So Erlek is, he's a wannabe president of the company, but he's not as you know if you saw  the show.  But he is allowed to publish an article.  So this is our interface.  I can explain more of this later.  Come to me after the talk if you're interested in some of the other things we did.  But we want to publish the article and from now on everything is defined by the workflow  definition we saw.  You can see the visit here.  You see all the same titles show up and I can just now type in BroomeConf article in,  it's 2016 so I won't forget.  And some text.  And this is super trivial, right?  You will also notice I can discard a process at any time.  So we made that possible as well.  So we continue.  I can now review my article.  I can download the PDF.  I'm not going to open this right now.  But we can also view the article in HTML because we can generate out of our XML document  templates and we can, for example, change the title.  We can move to the next section, et cetera, et cetera.  So I save this and now I said, okay, my article is perfect.  I send it off.  And I didn't put a nice message here.  Usually we put a really nice message here, but you get a rate step.  You're notified that you're waiting for somebody to approve this.  We even put the person here with the approval and whatnot.  But on the other side of things, there is Richard Hendricks, who is actually the president  of PipePiper.  And he already, and we are using, yes, we're using web sockets to push things through.  He now sees he has an article to approve.  He can get a little quick overview or he sees, oh, it comes from Ehrlich, et cetera, et cetera.  The document, unfortunately, is not showing up here because I didn't assign a certain  tag, I have been told.  But we can go in here and he can now approve the article.  A couple cool things.  Our document templates can be rendered into a visual format.  So any condition, any loops have a visual representation.  So our lawyers can review even just the template.  If you would have multiple versions, we can even visualize version differences.  And we ended up developing our own XML diffing library based on the famous white paper for  this.  So we continue.  And Richard is done.  Unfortunately, he doesn't get the next steps.  So that would be probably another QA thing that would pop up.  But if we see due to the push, thanks to the push, the next steps show up.  Every time we press continue, we send actually a task for salary.  And if the tasks take a long time, there's a spin out that will push back and tell you  what it is currently working on.  So there's a lot of cool web socket based technology and async technology and all of  this.  So we can go to the next.  Unfortunately, Ehrlich is not privileged enough to see these documents.  So we go back to Richard and we can see if he go to his documents.  So we can go to articles.  The ChromeConf article showed now up.  And it didn't show, I should have shown that, it didn't show up before it wasn't published  because certain tags get set.  So we have actually this concept of states as well.  But we just call them tags that are namespaced.  And we just have multiple tags on one attribute and we manage them through our workflows.  OK.  Other questions about that example?  Cool.  So yeah.  You mentioned the OR gate.  Yeah.  But there's, you didn't elaborate on it.  You said, we'll move on from that.  Yeah.  OK.  Sure.  So yeah.  We have learned over time that OR gates always come in pairs.  Most often come in pairs.  Because you say XOR, but then you usually with one, you go back.  And you have to join together.  While the XP.DL standard allows for many transitions to come into a main activity, because this  is also just an activity, several other not so sophisticated editors do not allow it.  And it is much easier to reason about your workflows and read them if you make another  OR gate there.  So OR gate only means it only waits for one incoming transition and not for both.  The end gate is exactly the opposite.  It always does set of both, not just one, and it waits for both.  Or for N. It can be any amount.  And we have some where we do five or six things at the same time.  All right.  Any other questions?  Cool.  So just a little summary of what did we, what are the big things that we had to build  in order to make all this work?  Security but Plone has that too.  Check.  We are using the Zope libraries after all.  We use Zope security, of course, and Zope security policy.  So we have exactly the same type of capabilities as they are in Plone today.  Machine executable.  DC workflow does that too.  This machine executable.  Check.  Full user interface generation and any other I.O. generation.  That only works for DC workflow because it's super, super trivial and you can do one size  fits all basically approach, right?  Because you only have to show states, the current state, and what other state you can  get to.  There's very little metadata even around any of this.  So and for the publication workflow, you know, that's not that manner.  But all of these screens that you saw, they're all standard activity types, applications  they are called.  So that's that.  So you need to implement back and forth.  I didn't demonstrate this, but you can go back and forth.  You saw the back and forth error, right?  Because people expect if they see a wizard, I want to jump to this point.  You can also click on the wizard itself and jump to a particular point.  And then you want to go forward again.  And then the problem that arises out of this is, well, you should really remember the data  that I typed in in the past and in the future, which is also not necessarily trivial, especially  if you now make changes in the past that affect the future.  So you have to be very careful of what data you retain.  Discarding and of course, discarding with cleanup.  So you say, I don't want this workflow.  It was a crap shoot.  Ignore it.  So you want to make sure all the articles and everything gets deleted.  Exceptional handling.  That was what broke the WFMC's neck originally.  And then migrations.  Migrations are super, super important as we upgrade our applications and our processes.  You know, if you update your process, you cannot just run on the new version suddenly.  Because where are you?  Do you have all the data?  So we do a lot of version management and then migrate data very carefully.  And that's a big problem.  We haven't really fully solved it yet.  OK.  So we did a bunch of WFMC enhancements.  And all of these enhancements are, we put back into the ZOPWFMC core.  Unfortunately, not yet in the ZOPFundation repository.  It's on our shoebox.  We have a clone on shoebox.  But if there's interest from the clone community to use ZOPWFMC, we would have certainly good  motivation to clean things up, write the necessary tests and documentation, and publish it further.  But until now, nobody came along.  So we haven't had much willpower to do it.  So we, XPDL 2.1, the original one only supported XPDL 1.0, we added extended attributes.  So to any activity, to any process, to any participant, you can put any amount of metadata  and then entire XML substructures called extended attributes.  And that wasn't implemented.  We used that heavily to hint the UI, to hint, as you will see, the simulations and the testing  and many other things.  So this basically our approach to do a lot, a lot of the automation.  Candidate support.  So let's say you have two presidents of the company, and you might think that's not possible,  but yes it is.  You can have co-presidents that can approve.  So you have multiple people.  We have the capability of saying, yes, multiple people can do this, and somebody takes the  ball and says, I'm going to do it.  So candidate support, which is a very core feature of workflows.  We implemented subflows, think about it as macros, like metal macros, task scripts, which  are basically arbitrary Python scripts.  You did see one with the reset.  A data field support, which gives you data typing.  Parameters didn't support initial values.  Otherwise conditions, the else case that I showed you.  Script tag support, because you can specify on a process what scripting language you're  using, and arguments to the activities, because, dang it.  Uh-oh, you lost it.  Do you guys have it over there?  Oh, OK.  I hope the clicker works far enough, so I come over here.  I have been warned that that would happen.  So arguments to activities, because you pass in variables, you get variables, are used  to be lists, and we converted them to dictionaries, which was a big pain for all migration, because  it's much easier if you have key value pairs to do migrations if you get new arguments.  Unfortunately, this was thanks to Jim.  I didn't tell him about this little thing when we met earlier this week.  And then deadline support.  You can say, if an activity hasn't been touched for a day, what do you want to do about it?  You can raise an exception and take an alternate path through the system.  All right.  We also enhanced the workflow edit a little bit.  We worked with the together workflow guys.  They do a lot of stuff in the Java community for banks, especially in Switzerland and Austria.  The owner is originally from Austria, but they're all in Thailand.  So we paid them to do a couple of things like small bug fixes and larger bug fixes that  made it possible to use, how the labels can be positioned, script support, and external  editor support.  So you can click on anything.  And if you specify Python as a script, it opens it up in a temporary file that has a  right file extension.  So you get the syntax highlighting and all that kind of good stuff in your external editor.  We could do a lot more, but we simply haven't gotten around to it yet.  OK.  So let me talk about a couple of really hard problems that we had to solve.  Discarding a workflow.  Well, originally, a ZopwMC didn't keep track of any of the activities it had already finished.  So we had to start keeping track of all the finished activities.  So when you discard it, we could undo them.  It requires for all of your activities or these applications that drive these activities  to be reversible.  Right?  You have to be able to say, this generated a document, now we need to remove the document.  There are some cases where you have irreversible actions.  For example, you created a user.  The user has received an email to log in.  Well, just because you want to undo your workflow, you don't want to create suddenly  a broken link for the user because you deleted the user.  So it's better to just leave the user existence.  They don't have any access anyway, so it doesn't matter.  Therefore, you make the workflow simply nondiscardable.  And the prime example of this is, once all parties signed a document, it is legally binding.  The document cannot suddenly go away because you discarded your workflow.  So in those cases, we make the workflows at that point nondiscardable, which sometimes  really makes our users mad because we make it so easy to execute legally documents that  they don't even think about it that way.  Back and forth, I mentioned that already before.  You have to be able to revert the activities.  You have to restore the workflow state properly and remember the inputs, as I mentioned.  And that's a very, very hard problem.  We spent a loan just to solve this.  There are six amendments worth of effort in that.  The wizard, I mentioned that before.  You saw it nicely going up on top.  The hard part about it is, it needs to be generated before any workflow state exists.  And as more workflow state comes into play, the wizard actually adjusts and finds the  path that you're actually going to take.  So once you reject, it will readjust, for example, the wizard.  This is also a very hard problem to get right, especially because of all the splitting and  joining that you can do.  We spent roughly at least three, if not four to five, men months just solving the wizard  problem.  What happened?  Whoa.  Okay, there it is.  Now, if you have a lot of processes, and I don't know how the Plonero does that, I would  love to talk to some people how this is done, and I'm running this video, which is a simulation  of our workflow.  Run in Firefox, fully automated, is testing, right?  And so you want to automatically test your workflows.  You want to have coverage.  So the big part is you have to provide a strategy for completing your applications.  And that took us also two to three attempts to do.  We ended up writing extended attributes on each activity, on each interactive activity  that the user has input to, define how the user would input stuff, and then complete  the activity, and then it would keep going.  You want to have save points.  We have processes that take 10 minutes to run, or large ones like this.  If the developer works on the last two work items, you don't want to have them wait nine  minutes before they get any feedback.  So we create save points that you can create, and you can start the workflow anytime from  that spot.  Debugging, you can stop at any activity.  We can take screenshots at any interactive activity, and we can parameterize all simulations  so that we can create very rich setup environments.  For example, the Piper example that I showed you, we just completely simulate that.  This is never typed in from hand.  So let's see what's next.  So I don't know how we're doing in time.  Almost good.  So quality assurance.  So I'm going to just show you the quality assurance instead of going over the steps.  So we created a very rich dashboard because we deal with lawyers and they have zero tolerance  for problems, not just functionally, but also from a language point of view.  So we have 98 processes that can be started from the UI.  There are about two or 300 of them with all the sub-processes.  For those 98 processes, we wrote 300 sims, and then we have all sorts of document templates,  and we test all the permutations of these documents.  And in those 98 processes, we have 3,500 activities.  So that's a lot of stuff to run.  And yesterday, our QA dashboard was all green and it was quite boring, but today I have  some interesting stuff to show.  So we test all our processes on the four major browsers, and then we run also a bunch of  QA checks.  So I can show you a little bit of output.  So let's not take the stock transfer.  So for example, it ran in Internet Explorer, this simple workflow.  So we get all the Internet Explorer output, including a screenshot for each step of the  workflow.  In this case, it was just one.  So maybe I should choose a really a little bit more interesting example, like the stock  transfer.  So here you can see Internet Explorer.  It tells you it was Internet Explorer 11.  And when it ran, and here are all the screenshots of Internet Explorer.  And so our UX department can go through these PDFs and check that all the browsers render  the stuff correctly.  If the simulation was successful, you can also see all the documents that get generated  here for your review.  We have lots and lots of process controls.  So for example, whether it's completed, whether we get the same output as last time, so this  is all good.  And here's our coverage.  So if you want to see how is the process covered, what is it transfer?  Transfer certificate.  This one is actually 100% covered.  But let's say we go to the upload case.  Though that's just one simulation.  And of course, one simulation can never cover the entire article.  So we can, but we can see that simulation went through this specific path.  So we have insights of what paths we are actually taken by our simulation.  And then basically the top one combines all the simulations, and it's 100% for this particular  case.  So let me just find actually the one where we have also PQA failure.  So here, for example, the long-term stability output change, so we keep track of any state  change in the system.  And we create a diff, and then we compare the diffs.  We use a JSON diff tool to do this.  And so we see here, for some reason, this process now has a new email that is being  sent and somebody didn't accept that properly.  So that's our QA tool and how we keep, make sure that all our processes function all the  time.  And this is run.  We can run this on a database or even more often.  It takes about what these days, 45 minutes to complete for full test run.  OK, so what's up in the future?  I would love to write the shoebox chronicles.  That's also something that I tried to do early in the days.  With the, in the Zope community, my dream was always to write these rest documents and  describe, hey, run something like this in the browser, take a snapshot of the browser and  insert a screenshot, and so that we can create support help in an automated way.  And then a funny story to this.  About two years ago, our customer's success person was really enthusiastic about writing  lots of support articles.  So she kept writing, and I said there, like, in a few months, you will have to revise all  of these.  You will have to revise all of these.  And no, no, no, we keep writing, we keep writing.  We had 72 of them.  One month back, we finally did a review.  We threw them all away.  All 72 were completely thrown away because, of course, they completely bit-rotted.  Nothing in those support articles described anything like the system worked.  So I would love to just create these support articles via this.  And it's not super hard.  I would also like to automate video generation, right?  Then you could have little self-support videos.  And thanks to Selenium, that shouldn't be a big deal.  I just have not gotten around to hooking this up.  The holy grail for us is to really support the power user.  If you can use Excel, or if you are a blown user, not a developer, but a user who can  configure a system and create articles, you should be able to create processes in our  system.  So our idea is that eventually people with legal expertise, lawyers, paralegals can  create new processes most easily.  That is probably still about five years away because we would have to rewrite or do massive  customizations to the editing tool and put a lot of more security in a lot of the Python  expression evaluation, et cetera.  In the ploneral to your value of what it takes to allow people to enter arbitrary executable  code at whatever level.  And on a personal note, I would love to bike across the US before I get to Alt.  So, OK.  You never get to Alt.  You just have to go very slow.  Yeah, but I also have family.  So my goal is to make it in 30 days.  Questions, comments, and before I forget, please go to ploncon6feetup.com and rate the talk.  Yeah.  So as far as actually creating the workload, that was one thing I didn't quite get.  So I saw this GUI tool.  Yeah.  And it looked like you're able to edit the visual representation.  Right.  And I saw the end result.  Yeah.  So the web interface.  Yeah.  So we upload that XPDL file into our system.  It's part of our source code.  And I did a bunch of other things in the back end, such as creating tags, creating a new  folder for this data room, creating an entry for the actions, all these are configuration  very much like you used to from the plon world.  And then it just works.  So I literally wrote zero Python code.  Like zero, I did not have to modify our code base, our Python code base, in order to make  this work.  So that is a very significant goal for us.  But high level developers can do this.  And I'm more than glad maybe after the talk for people who are interested to show them  the editor tool and show you a little bit more of the magic that goes on behind and  why the simulation work, why the result shows up, et cetera, et cetera.  Yeah.  You spoke about having multiple objects that travel together.  Yeah.  And I wondered if you had, well, what we have is kind of an idea where multiple objects  travel together, but they travel through separate workflows that sometimes share states and  sometimes some of them will break off and come back.  And so what we've got is these cascading workflow guards and rules, but just a way out of control.  And I wondered, what did you do?  And that is an outcome of the state-based workflow approach.  So what we are doing is basically we collect data.  So I did not bring up any of our sophisticated processes, like incorporating a company, which  generates five documents, for example, post-incorporation.  When you set up your board and stuff, creates about 10 documents.  So what we are doing is we are collecting the data.  We have forms.  You could do this in prone very easily with all the machinery that you have.  And then we generate these documents in system steps.  And we can create many system steps, we create many documents in all sorts of ways.  And then we bring them back in.  And then we move them along.  Because your action is not really, so what's your action?  Or what's your goal?  A process always achieves a high-level goal, for example, incorporating a company.  These documents, if they interact, they are not living in isolation.  They move together.  Like, for example, I could imagine in the content management world, you have a lot of  these things.  As I started, you might create an article that has images to it.  You might want to, you need to push, you want to publicize this.  So you push to some external website.  So you have all these versions and artifacts around.  But your goal is still to publish an article.  But in a case where, give me a concrete example of what you're doing.  I'll take from that.  In a case where you want to say, okay, we have 10 documents, but the people on the other  side are in a real hurry.  And they can't see anything until we've published a parent.  But we have two that we can't publish yet.  But we want to pre-publish.  We want to say, this thing is now being published.  But the state of the main object is not published.  But those eight have been published.  And when that comes in, you can see.  But these two are still out.  So either you can't see them or you can see that they're there, but they're in a different  state.  So the state of the inside of those 10 is all over the place.  But somehow the work for them needs to be able to say, when those two become ready to  be published, you need to be able to say, okay, well now publish.  And that must occur.  So we would create one process instance for each document that gets published.  So you create 10 publishing new article processes because you need to move 10.  You need to be authored and whatnot.  And then we would create, for example, you might have something else that is called pre-published.  You can say, oh, let me pre-publish on that.  It would just be another process you execute.  So we are not thinking of this as necessarily as one workflow, but it's many workflows.  So you could publish the main container and you could ask it then to push each of those  10 through its publish and two of them will fail.  But you see, you're still thinking very much in terms of state-based workflow because you're  thinking about publishing a container or talking about making the container available.  I would not even, like, the way I showed is like you wouldn't even think about a container.  That's just a site artifact that they live in the same container.  Like, for example, the same folder or whatever.  What your real goal is to generate these articles, these documents, and that they live eventually  at the same, like, I would not make my permissioning based on the container, right?  You want to really make your permissioning work against each document itself and then you publish  the document one by another and thus you can apply different rules.  The code that you said is currently living somewhere else, please, would you let us,  I really want to have a look at that.  Yeah, absolutely.  Actually, one feedback when I did my practice run this morning with the company was that  he said like I should have added the links.  I'll add the links to the slides and then put it on slide shares and then it should be  available or whatever Selly does with the publication and you can look at it and get to it.  Thank you.  Any more questions?  We can talk afterwards.  I'm here.  So any other questions?  Yeah, Carlos.  Another question, a comment.  Yeah?  I saw your historical overview.  There was an activity-based workflow for SOAP that was built in Italy.  It's called OpenFlow.  Right.  Oh, yeah.  Why didn't you tell me this yesterday?  Yeah, absolutely.  Yeah, that was OpenFlow.  But I think it now really, yeah.  It was, for a while, I guess it was used.  It used the same symptomatology of the work items and the activities.  Yeah, but they didn't use XPDR, I think.  No, no, they didn't.  They weren't graphical.  Right, obviously.  Oh, yeah, that's right.  David Devencenzo did that one, right?  OpenFlow.  David Devencenzo developed OpenFlow, I think.  I think the names of the developers are Richard Lemmy or something like that.  Oh, Ricardo.  Oh, Ricardo.  Yeah, yeah, yeah.  Yeah, yeah, yeah, right.  Devencenzo de Barone.  Devencenzo de Barone.  He's in the...  That's why I mixed this up.  No, Devencenzo de Barone, no, sorry, sorry.  No, disoma.  Disoma, disoma.  That's right.  Yeah, no, that is true.  I forgot about that.  That was OpenFlow at some point.  Well, of course, there's no committance to that.  Yeah.  That would have been a good one to add.  That's true.  I tried to use it once and I forgot.  I didn't quite use it.  I reduced it for a bank.  Any other questions?  All right.  Thank you very much for coming.  Thank you.
Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_0_71.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_72_167.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_168_1499.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_1500_4355.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_4356_10415.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_10416_15839.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_15840_16751.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_16752_21827.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_21828_26999.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_27000_27863.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_27864_29567.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_29568_29807.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_29808_30443.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_30444_35375.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_35376_35615.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_35616_35795.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_35796_36107.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_36108_36635.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_36636_36767.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_36768_37871.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_37872_38603.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_38604_38747.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_38748_39227.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_39228_39395.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_39396_39455.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_39456_40127.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_40128_40247.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_40248_40307.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_40308_40451.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_40452_41099.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_41100_41219.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_41220_41279.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_41280_41387.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_41388_42047.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_42048_42131.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_42132_43955.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_43956_47279.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_47280_50567.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_50568_51551.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_51552_52703.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_52704_54683.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_54684_55199.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_55200_56435.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_56436_58883.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_58884_59159.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_59160_59207.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_59208_60623.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_60624_60719.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_60720_60803.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_60804_60875.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_60876_60971.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_60972_61031.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61032_61079.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61080_61127.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61128_61199.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61200_61247.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61248_61295.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61296_61367.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61368_61463.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61464_61847.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_61848_62039.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_62040_62123.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_62124_62507.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_62508_63071.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_63072_63179.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_63180_63347.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_63348_63887.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_63888_63935.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_63936_64103.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_64104_64355.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_64356_67451.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_67452_75263.png Day_3__Making_Workflows_Work_for_You__by_Stephan_R_BOCg5N7RUjg_75264_78630.png