Tech Docs Home | Back | Repo Link | Jira Link |
work - a thing or process that has a ‘standard’ life-cycle (uses stage and status) and is categorized by a group and dept. *Work will need to remain in the same collection for the entire workflow.
workflow - a set of instructions on when to start watching, what to watch for, task required (the flow), and information linking to work
const aworkflow = { // a workflow
id: { type: String, default: '' },
name: { type: String, default: '' },
dept: { type: String, default: '' },
group: { type: String, default: '' },
work: { type: String, default: '' },
directives:{
ApproveProject:[
{route:'SUBMITnewwork',runif:{},packmap:{"id":"id"}}
]
},
watchers: { type: Array, default: [] }, // people responsible for the overall flow
flow: { type: Array, default: [] }
}
flow - a set of tasks to finish in order to ‘complete’ the workflow.
flow task - the description and rules for a flow task. It is defined so not to be confused with a task document described below.
task - an item (mongo document) that needs be done for a piece of work. There will be many different types of tasks that can behave in different ways.
const aflowtask = { // A flow task for a piece work
startdate: { type: Date, default: Date.now()},
duedate: { type: Date, default: ''},
finishdate: { type: Date, default: ''},
complete: { type: Boolean, default: false},
level: { type: String, default: '0'},//0-5
workflow: {type: String, default: ''}, // id of workflow
flow: { type: String, default: ''}, // id of flow in workflow
group: { type: String, default: '' }, // referring to database
work: { type: String, default: '' }, // referring to the collection
dept: { type: String, default: ''},
ref: { type: String, default: '' }, // referring to an item in the collection
type: { type: String, default: ''}, // to identify the type
assignees: { type: Array, default: [] },
checks: { type: Object, default: {} }, // for specific review checks
followup: { type: Boolean, default: false },
employees: { type: Array, default: [] },
notes: { type: String, default: '' },
notify: { type: Array, default: [] },
comments: { type: Array, default: [] },
logs: { // this is datelog in projects, should we align?
type: Array,
default: [{
date: Date.now,
msg: 'Review Created'
}]
}
}
todo - a list of items before work can be completed. It is stored separately, but matches the tasks in a workflow flow.
bump; bumping (a piece of work) - to check a piece of work against the associated workflow and ensure everything is up to date. It is just on the work as it sits in the database, and not effected by un-saved data.
todo-watching - a document linked to a workflow that monitors all the work being watched.
const atodowatching = { // a todo-watching
type: 'watching', // must be
workflow: (workflow.id) // unique for type = 'watching'
list: {type: Array, default: [] }// holding all work being watched (there is a type='work' tied to work)
}
todo-work - a document that monitors a specific piece of work. Can be found in the related todo-watching list.
const atodowork = { // a todo-work
type: 'work', // must be
workflow: (workflow.id)
ref: (work.id)
todo: {
[flow.id]: 'watching' | 'pending' | 'active' | 'finished' | 'na' | 0-100 (for percentage)
}
}
This system manages tasks for declared work using workflows. There is only one workflow per declared piece of work. It describes what needs to be done (tasks) in order to complete. New work will be submitted to the task manager, a todo list is created, and the ‘watching’ begins. Work attached to any workflow is ‘modified’ through the task manager. This allows clients to have a simple and easy way to edit work, and the task manager to bump the workflow on success.
On the submittal of work, most tasks will be ‘watching.’ In watching, This means that the work has not become relevant to that part of the flow, and the system has not created an actual task yet. When it does become relevant, the status of that task changes to ‘pending’ and exposes it to those responsible. Once exposed the user can start the task when ready, which the task manager takes and stores.
From here the task can be worked on and saved as needed. Any editing will be handled by the system, updating the todo list along the way. Tasks themselves can act in many different ways, and therefore interacted with in different ways. Common behavior is a task’s relation to the work’s Stage and Status. When it comes down to it, it’s always Stage and Status. In the flow, Stage and Status are described as ‘ranges,’ meaning a task can be relevant for a long period of time. In these ranges a task will become available. More important is the ‘blockstage’ AND/OR ‘blockstatus’ which says what stage and/or status the work can NOT be before the task is completed. This is why the task manager assumes the responsibility to edit the work for the client.
The completion of tasks will vary with the type of task. For example, reviews require the user to fill out checks about the piece of work, once done the work can be finished. There could also be a need for an ‘autotask’ that can be completed by checking work data through a given set of rules. The completion of a task does not necessarily complete the work (there could be a flag for ‘final’ task, that is the last task in the flow and on completion the work can be considered complete). If a task becomes “re-relevant” (meaning the work leaves and hits the taskflow stage), a new task is created with a reference to the finished task, and/or and option to bring the other task back. This way, if the task was re-created in error, the user can re-check the work or dismiss the task.
When/how-ever the work is finally completed, it can be submitted to the task manager and, if successful (meaning all tasks are done), complete the associated todo. Finised work is removed from the todo-watching list and the todo-work is removed (archived in someway maybe. moved to a work finished list within todo-watching maybe).
Completion of all tasks (for a period in flow) will allow the piece of work to move to the next step in the life-cycle. It does not mean the work is finished with its own life-cycle. As a goal we want the task manager to be responsible for monitoring work through to just before it’s archived (it will not be responsible for archiving).
common argument definitions. Unless otherwise described, these will stand as definitions for use in all routes.
Only a successful route result will be consistently given. If the result is a complicated structure it will be referenced to instead of fully laid out. Below are some standard parts for all responses:
{
success:Boolean,
msg:'Various helpers to possible issues'
}
Used to setup a todo for a new piece of work. The work and workflow needs to to exist for the submission to fully go through. If they do, the work will be added to the todo watching list for that workflow, and a todo work item created with default task statuses (dependent of flow items in the workflow).
ARGUMENTS:
REQUEST SAMPLE
{
workflow:'01',
workid:'R38460'
}
RETURNS - the newly created work todo
RESPONSE SAMPLE
{
success: true,
msg: 'Work was added to watch list',
result: {
workflow: '01',
type: 'work',
ref: 'R38460',
todo: { installReview: 'watching' }
}
}
gets a workflow
This is used to get a list of work and tasks that a user needs todo. It is required to pass a user responsible, but not a specific workflow. The result is then an array of the different associated workflows and any tasks and work along with it. You will only get a reference to a task that is status ‘pending’ and ‘active’. To get the whole task call GETworktasks. The work will not be sent in full either, but can be requested through GETworktasks as well.
ARGUMENTS:
workflow (String | Array) |
REQUEST SAMPLE:
{// Find all user task in a certain workflow
workflow:'01',
responsible:'VOGCH'
}
RESPONSE SAMPLE:
{
workflow: '01',
todo: [
{ ref: 'R38460', todo: [Array] },
{ ref: 'R38514', todo: [Array] }
],
work: [
{
_id: '64f9f3bbe054e26c7faef8dd',
id: 'R38460',
name: 'Hayden, Al',
status: 'complete',
address:''
},
{
_id: '64f9f3bae054e26c7faef8c9',
id: 'R38514',
name: 'Northington, Paul',
status: 'complete',
address: ''
}
]
}
Creates a new task for a todo item in ‘pending’. It will not create the new task if:
ARGUMENTS:
REQUEST SAMPLE
{
workflow:'01',
task:{
flow:'installReview',
ref:'R38461'
}
}
RESPONSE SAMPLE
{
task:{newly created task},
work:{work associated with task}
}
With the given arguments, finds the tasks (and work). The route does not organize the task in any way, and the entire query is returned in one ‘tasks’ array. in the case that the call is for one task, the withwork=true return work:work. No matter if the withwork=true, it will be ignored if the query returns more than one task. To find one task you can pass workflow, ref, and flow. By default only ‘ActiveTask’ is queried. If ‘FinishedTask’ needs to be search it can be passed as pool=’finished’. In the same, if both pools are needed, pool=’both’.
ARGUMENTS
workflow (String | Array) |
pool (String) ‘active’(default) | ‘finished’ | ‘both’ |
REQUEST SAMPLE
{// Find one task
workflow:'01',
ref:'R38658',
flow:'installReview'
}
{//all finished task for a user
workflow:'01',
responsible:'VOGCH',
pool:'finished'
}
RESPONSE SAMPLE
{
tasks:[{found task(s)}]
work:{found work} | null
}
This is the means in which work tasks are edited. There are only 3 options available through ‘method’:
ARGUMENTS
method (String) - ‘save’ | ‘delete’ | ‘finish’ |
REQUEST SAMPLE
{
workflow:'01',
task:{task object with flow and ref}
}
RESPONSE SAMPLE
{//Save
success: true,
msg: 'Item was saved',
result: {
acknowledged: true,
modifiedCount: 1,
upsertedId: null,
upsertedCount: 0,
matchedCount: 1
}
}
{//Delete
success: false,
msg: 'Task was deleted',
result: { acknowledged: true, deletedCount: 1 }
}
{//Finish
success: true,
msg: 'Task was Finished',
result: {
_id: '65984d85c2360e1287ae5142',
startdate: '2024-01-05T14:08:11.576Z',
duedate: null,
finishdate: 1704780912580,
complete: false,
level: '0',
workflow: '01',
flow: 'installReview',
group: 'Replacement',
work: 'Project',
dept: '350',
ref: 'R38587',
type: 'review',
assignees: [ 'VOGCH' ],
followup: false,
employees: [],
notes: '',
notify: [],
comments: [],
logs: [ [Object], [Object] ],
__v: 0,
completed: true
}4
}
The work is the only reason for the task manager. To qualify as work, items must use a stage and status life-cycle. This life-cycle must be of some order and sense. It will be possible to setup a worflow to accommodate most needs, but for now it’s better to be simple. As a rule of thumb no stage should repeat, and no status should repeat in the same stage.
For general consistency the work must also include the following properties:
We need the department (whatever that means to the company) because it is possible for a company to have more than one type of the same/similar work. This also requires the id to be unique between departments.
To include in the system, attach the database, collection and dept to a workflow as group, work and dept to the group. It is then not possible for a single workflow to manage work across collections. It would not be necessary because you would just have another workflow created for that.
It is important to note that the work does not know what type of work it is (meaning it doesn’t know where it’s stored) OR what group it’s a part of (the database). If the work is moved from the collection without the task manager knowing it, it will disturb the accuracy of the data.
Step Indicator(s): Stage, Status
Department(s): VHC, BEE, 450
“Project” is the work type most commonly associated with Replacement departments (ie. VHC, BEE). These are more oriented towards “sales” as opposed to service’s “service-provided” orientation. In short, there is a Bid / Quote process to be considered on these workflows, making them more involved than other work types. This also causes a “split” to happen in the workflow. Projects that are sold move on and go through the whole “Job” stage. Projects that are not sold stay as “Quotes” perpetually until they are removed / archived / stored, and may move to the archiving steps directly.
Step Indicator(s):
Department(s): 300, 400
“Service” is the work type most commonly associated with Service departments (ie. 300, 400). These are more oriented to the single service that is provided to the client. It is requested and performed, with very little “selling” involved, making them a shorter workflow than those like Projects.
A workflow can be described as a group, work and dept. The primary job for the workflow is to control the progress of work through the life-cycle. Secondary would be to monitor the progress and who is in charge of that. To control this movement will be the flow array. It is an array because it may benefit us to consider the array as the order. At the moment, the array is not considered as the order.
Flow and task are synonymous in many ways and may be used close to each other. To clarify, Flow in this context is the flow array (group of task rules) for a workflow. A flow task would describe an item in that array. A task on its own will describe an item created using a flow task, and is attached to a piece of work.
A flow will have an id unique to that workflow. This id will be attached to the todo watching object and the task. Any given flow will have the following statuses to use:
If ‘required’ is true, that task will use all of the status except ‘na’. In the reverse, required false allows for an ‘na’ status be equal to ‘finished’.
Since the flow holds the actual rules of control for each work task it is referenced often when validating status changes on work or deciding when a task is ready to start (status: ‘pending’). To know when a task is ready to start, the ‘stage’, ‘status’, and ‘blocks[]’ are always used. Steps for these checks are:
1) check work for matching flow.stage value
In some cases the above are not enough, and a different type of trigger is needed. The flow.workchecks is available to check for specific values in the work object. If all of the checks in the object are met, the work becomes ready to start. By default, this check will be in addition to the standard checks. If they need to override the standard checks, or the standard checks don’t apply, set ‘nostdcheck’=true.
If these checks are passed the task will be set to flow.startstat (default ‘pending’), and eligible for creation. If ‘autocreate’ is true a task will be created when ready with the status set to ‘startstat’. In either case, the task becomes ‘pending’, and assigned to no one. A task is officially ‘active’ when a user from flow.responsible[] opens the task for the first time, and that user becomes the first assignee on the task.
While active, the task will rarely refer to its flow task unless it uses flow.checks. flow.checks is a schema for a input form. The task has a matching checks object with the values saved from the form. By doing this we can change the required checks and have them update tasks as they are saved. If a task does not get caught by a save the schema can be used later to know whats missing.
If task manager is responsible for the checks, flow.selfcheck is used. By default the value is null, and selfcheck is ignored. To use you can create an object to map and check certain values in the work. Mapping works by giving the path to the desired value. ‘’
Finally flow is used to ensure work does not move forward. It does so through flow.blockstatus. ‘blockstatus’ is an array holding statuses that can not be moved to if the task is not ‘finished’ or ‘na’ (given required=false). The choice of an array was due to our loose task flow. We do not want to lock ourselves into one value if the work could “jump” status.
Task will be an item based on the flow and attached to the work. Task won’t be necessary in all types of flow. Some situations may not need to store any information allowing the task manager to perform a certain check (maybe ensuring a property in work is valid) automatically and change todo statuses accordingly. Cases where there is a checklist to perform on the work, a task will be used.
Assignees and responsible are important to define further. Those responsible (flow.responsible) are able to see all matching tasks, and will be able to see who is working on what. If a user opens a task they are added to task.assignees[]. This way a manager can see who of those responsible was involved in a specific task.
Task are stored in two different collections ActiveTask and FinishedTask. The names of each reflect the status in most cases. A perfect cycle is: 1) Task is created and put in ActiveTask, then the status is ‘active’. 2) Task finished, the task is moved to FinishedTask turning the status to ‘finished’.
In some weird cases the status could turn back to ‘pending’ but stay in ActiveTask. Something like this could result from the work assuming a status previous to the flow’s ‘status’ range (if you think of the array like that). It would sit and wait to be picked up again by the user. Most cases the task will only move forward. When needed, and the flow allows, it will be possible to re-open a task moving it back to ActiveTask.
The way task behave is dependent on the type (like the flows). This types are as follows:
In a review there is a
Todos are managed in a mixed collections. Docs with the type=’watching’ contains a list of work with an active todo list. There will only be as many of these as there are workflows. The other type is ‘work’. Docs with the type ‘work’ are linked to a specific piece of work and hold the status of the piece of work. On new work creation, the ref to work id is pushed onto a watching list and a todo list is created. When the work is deemed finished, both the ref and todo list are removed (ref popped, and todo list archived or something). During the works life-cycle, the todo list can be used to understand what ‘status’ all the tasks are at.
todo-work - needs to store the most updated work ‘stage’ and ‘status’. This will allow the system to vet any changes made to the work (‘stage’ or ‘status’ specifically)
In most cases the todo list will be enough because the task is a check on work’s data, the todo just holds the result of the check. These types will carry a % done in the todo list. Some types of tasks are different, and need their own item. These tasks will be stored in either an ‘active’ or ‘finished’ collection. The todo list will hold (reflect) the status of the task.
Status
Flows can behave in different ways based on the type and settings, but the major two are ‘autobump’ OR not. If flow.autobump=true, the work task will be watched to ensure the task stays relevant. This means that when a workflow bump is called the associated flow is checked for a stage and/or status that matches the work’s stage and/or status. If it does, the associated task is ensured atleast status of ‘pending’ OR ‘active’ (depending on the flow.startstat)
All tasks, across all types, from all work, for all workflows will share these collections and flow.
in props ‘group’,’work’,’dept’. ‘Group’ and ‘work’ are used to describe the ‘db’ and ‘collect’ of the database. Dept is used to further define a piece of work, and allow different types of work to live in the same collection. Workflows will only be valid between a period in the works life-cycle (defined in portal settings. need to ask Ryan how to id and attach them to workflow), in which the piece of work will be monitored by the task manager.
The system can be reached