Here are some steps to follow when planning out an online form.
Create a Group to "Own" the Form Separate From Approvers
A good practice to follow is have one group "own" the form and other groups for the approval processes. For example, a two-step workflow for ordering office supplies might look like this:
User submits order
Someone in the approval group approves the purchase and orders the supplies
In this case you might create two groups:
"Office Supplies Order - Form Owners" to manage the HTML form itself and workflow steps
"Office Supplies Order - Approvers" to approve purchase requests
You would build the form using the owners group. Step 1 of the workflow would allow anyone to fill it out (unless you wanted to restrict who can even place an order) while step 2 would be assigned to the approvers group. This way the person who created the form (probably you, dear reader) doesn't get an email every time a new office supply request came in.
Map Out Sections
Start with the basics of what information you are going to collect and from who.
Each set of information from a given party should be a separate section of the form.
Determine which sections are optional and under what criteria.
For each section where a user assigns to a particular group, locate where on the form earlier in the lifecycle that assignment will take place. Usually this is a drop-down menu earlier in the workflow, often from the original submitter. If a drop-down doesn't exist see Assigning Sections to a Group for code to create one.
An Individual a User Chooses
For each section where a user assigns to another particular user, locate where on the form earlier in the lifecycle that assignment will take place. If assignment doesn't currently take place earlier in the lifecycle, consider adding an intermediate routing step where that assignment can take place. E.g., a form might submit to an advising office based on the school selected but a dispatcher at that office might assign an adviser to sign the form. This routing section can be hidden from the original submitting user when Managing Section Visibility.
A section, not including the first, may have its user or group inherited from a previous section. For a group this may be useful when an approving group needs to do a final review of a form after all other sections have been completed. For an individual this may be useful to have the form route back to the original submitter for further action or review on their part.
The forms system has a number of default alerts, particularly for when a section arrives in a user's active form queue or when some final action has taken place (see When Default Email Alerts Occur for the complete list). It may be useful to have custom alerts at certain points in the workflow. Some examples:
Informing the original submitter every time their form moves forward in workflow
Informing a previous approver when a form is rejected further on in the workflow
Sending the original submitter a "final approval" email even though other "office use only" sections still need completion (in this case you should also suppress the default final approval email)
See Configuring Email Alerts for complete instructions. Often implementation of email alerts can wait until all other parts of the workflow are settled.
Determine Any External Processes that Need to Take Place
Occasional an external process needs to take place before a form should move forward
External Human Processes
Sometimes processing should stop while some human-driven function is taken care of. For example, in the case of a student declaring a major the department may want to add them to a listserv or Canvas site. In this case you can create an intermediate step that only gets approved once the business process takes place. Again, this can be hidden from the original submitting user with visibility rules and have the assignment inherit from a previous section
External Automated Processes
If you have some automated process that needs to be invoked the engine supports Webhooks or HTTP Callbacks between sections by inserting a service section. This section can be invisible to the user or include fields populated by the external web service. Use of this feature relies on custom programming on the part of the form creator and a server to respond to the service call.