Workflow Design

The question arose: how to define a generic workflow, using XML as the markup language. This web page provides one proposal on how to do this. Sometimes, people think of 'workflow' as a set of 'tasks' that a number of individuals have to accomplish. The discussion starts with a question of 'what is a task?' 'Tasks' are by-products of a process, and are not fundamental to it. You don't need to create schemas for tasks, they come out automatically. At least, that's how I see things.

This point is clearly illustrated in the diagram on the page http://www.vivtek.com/wftk/usage/chair.html Each square in that diagram is a 'state'. The top/left square should be labelled 'start' The other squares on the extreme left & right should be labelled 'closed-rejected', or 'closed-completed' or 'closed-reviewed' The ones in the middle are labeled 'in-process', 'waiting-for-aproval-by-boss', 'waiting-for-aproval-by-purchasing', 'waiting-for-delivery', etc. States are *fundamental* to a process. States are simple: basically, they just have a name. Thats about it.

<state><state:name>SomeDopeyName</state:name></state>
Next, you have the arrows, which connect the states. The top-left arrow is called 'open/new', the next arrow is called 'manager-approval', some of the last few arrows are 'accounting-approval', 'deliver', etc. Arrows have names, and connect pairs of states:
<arrow><arrow:name>Open Issue</arrow:name>
       <arrow:fromstate>Start Here</arrow:fromstate>
       <arrow:tostate>Boss's Desk</arrow:tostate>
       </arrow>
Note that <fromstate> and <totstate> must be *valid* state names.

States are the stages which a 'document' flows through during a process. The document gets routed from desk to desk, gaining signatures, and getting notes stapled to it. Its the document that's always in a certain state:

<document><doc:docname>Jimbo's Chair Request</doc:docname>
          <doc:serialnum>1001</doc:serialnum>
          <doc:currentstate>Boss's Desk</doc:currentstate>
          <note>Hi Boss, hate to bother you but I want a chair.- Jimbo</note>
          <note>Hi Jimbo, I'll talk to you about this next month -Steve</note>
          </document>
Documents typically get a serial number for tracking purposes. Notes have a date attached. Some notes might by cryptographically signed with electronic signatures, etc. Some notes may contain embedded images, embedded html, or references to other documents.

Next, you have permissions. There are two fundamental types: state-permissions, and arrow-permissions. State permissions are "can view" (y/n) i.e. can/not look at the document (or a subset of the document, so that parts of it can remain 'hidden' from some users) and "can appened" (y/n) i.e. can append to the document (i.e. add a new note). e.g. most insiders might have the following state permissions:

<stateperm><stateperm:statename>Boss's Desk</stateperm:statename>
           <stateperm:canview> Yes </stateperm:canview>
           <stateperm:canappend> No </stateperm:canappend>
           </stateperm>
Arrow permissions: has authority to follow this arrow, or not: For example, almost everyone has permission to start a new request:
<arrowperm><arrowperm:arrowname>Open</arrowperm:arrowname>
           <arrowperm:allow> Yes </arrowperm:allow>
           </arrowperm>
A role is a collection of state-perms and arrow-perms:
<role><rolename>Originator</rolename>
      <stateperm><stateperm:statename>Start Here</stateperm:statename>
           <stateperm:canview> Yes </stateperm:canview>
           <stateperm:canappend> Yes </stateperm:canappend>
           </stateperm> 
       
      <stateperm><stateperm:statename>Boss'sDesk</stateperm:statename>
           <stateperm:canview> Yes </stateperm:canview>
           <stateperm:canappend> Yes </stateperm:canappend>
           </stateperm> 
       
     <arrowperm><arrowperm:arrowname>Open</arrowperm:arrowname>
           <arrowperm:allow>Yes</arrowperm:allow>
           </arrowperm>

     <arrowperm><arrowperm:arrowname>ApproveforPurchasing</arrowperm:arrowname>
           <arrowperm:allow> No </arrowperm:allow>
           </arrowperm>
</role>
Notice in the above example that the 'originator' does not have authority to approve. The role 'Boss' would have this authority. That is, the role 'Boss' has almost exactly the same list of permissions, except that the last one would be marked 'Yes' instead of 'No'.

Finally, users and projects: A user is just a collection of project-role pairs; a project is a collection of states, arrows and roles:

<!-- this is an abbreviated example -->
<project><projectname>Chair Purchase</projectname>
         <state>StartHere</state>      
         <state>BossesDesk</state>
         <state>ShippingDock</state>

         <arrow>Open</arrow>
         <arrow>Approve</arrow>
         <arrow>Purchase</arrow>
         <arrow>Deliver</arrow>

         <role>Originator</role>
         <role>Boss</role>
         <role>Finance</role>
         <role>DeliveryBoy</role>
         <role>SuperUser</role>    <!-- can do almost anything -->
</project>
Users are just a collection of roles in different projects: If a role isn't explicitly mentioned, then that person doesn't have the authority to play at the role.
<user><user:username>Steve "the Boss" Jobs</user:username>
      <user:project><user:projectname>Chair Purchase</user:projectname>
                    <user:role>SuperUser</user:role>
      </user:project>
      <user:project><user:projectname>Color Picking</user:projectname>
                    <user:role>Originator</user:role>
                    <user:role>Boss</user:role>
      </user:project>
</user>
That's just about it. One last little feature, before we can see what a task is. The <document> that is circulating: sometimes it can be assigned to an individual, and sometimes it goes into a pool where the next person in line can grab from it. Lets for a moment assume that there's a pool (e.g. *anyone* in purchasing can approve any *particular* chair purchase.)

So, whats a task? Whats a task list? Answer: a search through the database:

Say I logged on as user 'steve'. First, search db for all projects and roles that 'steve' belongs to. Next, search this list of roles for arrows that have <allow>yes</allow>, and put them into a list. This is 'steve's-arrow-list'. Next, crawl over the entire list of all documents: are any of these documents in a <state> that matches the <fromstate> in steve's arrow-list? If so, then we've found a task for Steve. Hopefuly its obivious now why this is a task for steve: its in some state, and steve is allowed to use an arrow to move it out of that state. Ergo, its a task for steve.

In the above examples, I used a 'pool' of tasks waiting for someone to work on them. Tasks can also be assigned to individuals. However, we must first check that users-arrow-list to make sure that the user would have the authority to advance the <document>: its pointless to assign the document to someone who doesn't have the authority to move it on.

Hopefully, you now understand why I said that 'tasks' are not fundamental, but just emerge out of the underlying structure ... Tasks are just transient, ephemeral points in time that correspond to some document being in a persons 'inbox'. They're not database schemas, or at least, I don't see how they could be.

--linas

May 2000

P.S.

Some of the XML markup can be quite wordy, and not terribly human-readable. It might be useful to have some constructive ops, such as 'except': 'user X can play all roles Y except for role Z' or 'all': 'all users can play role O'.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included at the URL http://www.linas.org/fdl.html, the web page titled "GNU Free Documentation License".