workflow-patterns

Installation
SKILL.md

Frappe Workflow Patterns

Reference for designing Frappe workflows, aligned with the team's edu_quality conventions: workflow_state added via Custom Field in the customizations sub-app (not source DocType edits), pragmatic use of db_set over apply_workflow for programmatic transitions, and willingness to build a custom DocType + Page when stock Workflow doesn't fit.

Team conventions

These are the rules the existing codebase follows. New workflows should follow them; deviations need a reason.

  1. Add workflow_state via Custom Field in sc_customizations (or equivalent customizations sub-app), not by editing the source DocType JSON. Keeps customizations isolated from upstream apps.
  2. Custom Field JSON for workflow_state uses these settings: fieldtype: "Link", options: "Workflow State", default: "Approved" (or your default state), hidden: 1, no_copy: 1, allow_on_submit: 1. See the example in sc_customizations/custom_field/Fees-workflow_state.json.
  3. Use db_set("workflow_state", "X") for programmatic transitions in most code paths. Pragmatic — bypasses transition validation, runs no condition, fires no email — but matches what the codebase does today (e.g. refund_request.py:208, scan_receipts.py:17). Use apply_workflow only when you specifically want the role check + condition + notification.
  4. Always wrap db_set calls with hasattr(doc, "workflow_state") as a defensive check. The Custom Field may not be applied in every site; the code should still work.
  5. When stock Workflow doesn't fit, build a custom workflow DocType plus a Frappe Page for the UI. We have precedent: Funnel Workflow for student application funnel, fee_workflow Page for fee operations. Don't try to bend Workflow to fit funnels or multi-doc orchestration.

When to use a stock Workflow

Installs
6
GitHub Stars
21
First Seen
May 15, 2026
workflow-patterns — unityappsuite/frappe-claude