frappe-workflow-generator

star 19

Generate Frappe Workflows for document state management and approvals. Use when creating approval workflows, state transitions, or multi-step document processes.

Venkateshvenki404224 By Venkateshvenki404224 schedule Updated 6/3/2026

name: frappe-workflow-generator description: Generate Frappe Workflows for document state management and approvals. Use when creating approval workflows, state transitions, or multi-step document processes.

Frappe Workflow Generator

Generate production-ready Frappe Workflows for document state management, approvals, and business process automation.

Global Rules

These Frappe conventions apply to everything this skill generates, and override any conflicting example below.

  • Bench commands: use bare bench (never ./env/bin/bench or a full path). Always pass --site <site> explicitly — never run a bare bench migrate / bench run-tests. Run bench start in the background and only if it isn't already running. Don't run discovery commands (which bench, bench --version).
  • DocType files live at apps/<app>/<app>/<module>/doctype/<name>/<name>.json — the app name appears twice (directory + Python package) — with an empty __init__.py alongside. Never mkdir the folder; write the JSON and run bench --site <site> migrate to create the structure. Don't add creation, modified, owner, modified_by, or docstatus as fields — Frappe manages them.
  • Database & ORM: prefer frappe.qb.get_query() over raw frappe.db.sql(). Use frappe.db.get_all() for server logic (ignores permissions) and frappe.db.get_list() for user-facing APIs (enforces them). Never use frappe.db.set_value() on a field with validation or lifecycle logic — load the doc and doc.save() so controller hooks run. Batch-fetch related records; never query inside a loop (N+1).
  • Never call frappe.db.commit() in controllers, request handlers, background jobs, or patches — Frappe auto-commits on success and rolls back on uncaught errors. Flush manually only to make a write visible to a subsequent frappe.enqueue() (or pass enqueue_after_commit=True).
  • Permissions & APIs: put permission checks inside controller methods (enforced on every call path), not in API wrappers. Type-hint every @frappe.whitelist() parameter so Frappe validates and casts it, and pass methods=[...] to pin the HTTP verb.

When to Use This Skill

Claude should invoke this skill when:

  • User wants to create approval workflows
  • User needs document state transitions
  • User requests multi-step approval processes
  • User mentions workflows, approvals, or document states
  • User wants role-based approval routing
  • User needs to implement document lifecycle management

When a Frappe Workflow Is Warranted

Use a Frappe Workflow only when transitions are role-gated approvals — each transition is granted to specific roles (multi-role sign-off, approve/reject routing). When you only need simple status tracking with no approval gating, a plain status field is lighter and easier to maintain — hand off to frappe-state-machine-helper.

For submittable documents, Workflow states map onto docstatus: 0 Draft, 1 Submitted, 2 Cancelled (set per state via doc_status). Each transition is gated by an allowed role. Do not declare docstatus as a field — Frappe manages it on submittable DocTypes.

Capabilities

1. Workflow JSON Generation

Basic Approval Workflow:

{
  "name": "Sales Invoice Approval",
  "document_type": "Sales Invoice",
  "is_active": 1,
  "workflow_state_field": "workflow_state",
  "states": [
    {
      "state": "Draft",
      "doc_status": "0",
      "allow_edit": "Sales User",
      "update_field": "status",
      "update_value": "Draft"
    },
    {
      "state": "Pending Approval",
      "doc_status": "0",
      "allow_edit": "Sales Manager",
      "update_field": "status",
      "update_value": "Pending"
    },
    {
      "state": "Approved",
      "doc_status": "1",
      "update_field": "status",
      "update_value": "Approved"
    },
    {
      "state": "Rejected",
      "doc_status": "2",
      "update_field": "status",
      "update_value": "Rejected"
    }
  ],
  "transitions": [
    {
      "state": "Draft",
      "action": "Submit for Approval",
      "next_state": "Pending Approval",
      "allowed": "Sales User",
      "allow_self_approval": 0
    },
    {
      "state": "Pending Approval",
      "action": "Approve",
      "next_state": "Approved",
      "allowed": "Sales Manager"
    },
    {
      "state": "Pending Approval",
      "action": "Reject",
      "next_state": "Rejected",
      "allowed": "Sales Manager"
    },
    {
      "state": "Rejected",
      "action": "Revise",
      "next_state": "Draft",
      "allowed": "Sales User"
    }
  ]
}

2. Conditional Transitions

Workflow with Amount-Based Routing:

{
  "transitions": [
    {
      "state": "Draft",
      "action": "Submit",
      "next_state": "Pending L1 Approval",
      "allowed": "Sales User",
      "condition": "doc.grand_total <= 10000"
    },
    {
      "state": "Draft",
      "action": "Submit",
      "next_state": "Pending L2 Approval",
      "allowed": "Sales User",
      "condition": "doc.grand_total > 10000 && doc.grand_total <= 50000"
    },
    {
      "state": "Draft",
      "action": "Submit",
      "next_state": "Pending Director Approval",
      "allowed": "Sales User",
      "condition": "doc.grand_total > 50000"
    }
  ]
}

References

Frappe Workflow Core:

Official Documentation:

Install via CLI
npx skills add https://github.com/Venkateshvenki404224/frappe-apps-manager --skill frappe-workflow-generator
Repository Details
star Stars 19
call_split Forks 13
navigation Branch main
article Path SKILL.md
More from Creator
Venkateshvenki404224
Venkateshvenki404224 Explore all skills →