frappe-agent-architect
Use when designing multi-app Frappe architectures, deciding whether to split functionality into separate apps, or implementing cross-app communication…
Use when implementing document lifecycle hooks via doc_events in hooks.py, understanding event execution order, or extending/overriding document behavior from another app. Prevents silent hook failures from wrong event names, incorrect execution order assumptions, and broken
$ npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-syntax-hooks-events --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/frappe-syntax-hooks-eventsContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when implementing document lifecycle hooks via doc_events in hooks.py, understanding event execution order, or extending/overriding document behavior from another app. Prevents silent hook failures from wrong event names, incorrect execution order assumptions, and broken
name: frappe-syntax-hooks-events description: > Use when implementing document lifecycle hooks via doc_events in hooks.py, understanding event execution order, or extending/overriding document behavior from another app. Prevents silent hook failures from wrong event names, incorrect execution order assumptions, and broken override chains. Covers doc_events hook syntax, all document events (before_insert, validate, on_submit, etc.), event execution order, extend vs override behavior, cross-app doc_events. Keywords: doc_events, hooks.py, before_insert, validate, on_submit, on_cancel, lifecycle, document events, override, extend, event order, which event fires when, before_save vs validate, document event list.. license: MIT compatibility: "Claude Code, Claude.ai Projects, Claude API. Frappe v14-v16." metadata: author: OpenAEC-Foundation version: "2.0"
| Order | Event | Purpose | Can Raise? | |-------|---------------------|--------------------------------------|------------| | 1 | `before_insert` | Set defaults before naming | YES | | 2 | `before_naming` | Modify naming logic | YES | | 3 | `autoname` | Set the `name` property | YES | | 4 | `before_validate` | Auto-set missing values | YES | | 5 | `validate` | Validation logic — throw to abort | YES | | 6 | `before_save` | Final mutations before DB write | YES | | 7 | `db_insert` | *Internal* — writes row to DB | — | | 8 | `after_insert` | Post-insert logic (runs once ever) | YES | | 9 | `on_update` | Post-save logic (runs on every save) | YES | | 10 | `on_change` | Fires if any field value changed | YES |
| Order | Event | Purpose | |-------|-------------------|-----------------------------------| | 1 | `before_validate` | Auto-set missing values | | 2 | `validate` | Validation logic — throw to abort | | 3 | `before_save` | Final mutations before DB write | | 4 | `db_update` | *Internal* — updates row in DB | | 5 | `on_update` | Post-save logic | | 6 | `on_change` | Fires if any field value changed |
| Order | Event | Purpose | |-------|-------------------|------------------------------------| | 1 | `before_validate` | Auto-set missing values | | 2 | `validate` | Validation logic | | 3 | `before_save` | Final mutations before DB write | | 4 | `before_submit` | Pre-submit logic — throw to abort | | 5 | `db_update` | *Internal* — updates row in DB | | 6 | `on_submit` | Post-submit logic (GL entries etc) | | 7 | `on_update` | Post-save logic | | 8 | `on_change` | Fires if any field value changed |
| Order | Event | Purpose | |-------|-------------------|-------------------------------------| | 1 | `before_cancel` | Pre-cancel validation | | 2 | `db_update` | *Internal* — updates row in DB | | 3 | `on_cancel` | Post-cancel logic (reverse GL etc) | | 4 | `on_change` | Fires if any field value changed |
| Order | Event | Purpose | |-------|----------------|--------------------------------| | 1 | `on_trash` | Pre-delete cleanup | | 2 | `after_delete` | Post-delete logic |
| Operation | Events (in order) | |------------------------|----------------------------------------------------------| | Rename | `before_rename` → `after_rename` | | Amend | `before_insert` chain runs on the new amended doc | | Update After Submit | `before_update_after_submit` → `db_update` → `on_update_after_submit` → `on_change` |
---
# hooks.py
doc_events = {
"Sales Invoice": {
"on_submit": "myapp.events.sales_invoice.on_submit",
"on_cancel": "myapp.events.sales_invoice.on_cancel",
},
"Purchase Order": {
"validate": "myapp.events.purchase_order.validate",
}
}doc_events = {
"*": {
"after_insert": "myapp.events.global_handler.after_insert_all",
"on_update": "myapp.events.global_handler.track_changes",
}
}ALWAYS use `"*"` (string with asterisk) as the key. This fires the handler for every DocType.
doc_events = {
"Sales Invoice": {
"on_submit": [
"myapp.events.accounting.create_gl_entries",
"myapp.events.notifications.send_invoice_email",
]
}
}# myapp/events/sales_invoice.py
def on_submit(doc, method=None):
"""
doc — the Document instance (e.g., Sales Invoice)
method — string name of the event (e.g., "on_submit"), or None
"""
if doc.grand_total > 10000:
frappe.sendmail(...)ALWAYS accept `method` as the second parameter (with default `None`). Frappe passes it automatically.
---
→ Use `validate`. ALWAYS raise `frappe.throw()` here to block invalid saves.
→ Use `before_validate`. This runs before `validate`, so your
60 deterministic Claude AI skills for Frappe Framework & ERPNext v14-v16 development and operations
Repo: Impertio-Studio/Frappe_Claude_Skill_Package
Use when designing multi-app Frappe architectures, deciding whether to split functionality into separate apps, or implementing cross-app communication…
Use when debugging Frappe errors, using bench console for live inspection, analyzing tracebacks, or reading Frappe log files. Prevents wasted debugging time…
Use when receiving vague or unclear ERPNext/Frappe development requests that need interpretation. Transforms requirements like 'make invoice auto-calculate' or…
Use when migrating a Frappe app between major versions, detecting breaking API changes, or resolving post-migration errors. Prevents failed migrations from…
Use when reviewing or validating Frappe/ERPNext code against best practices and common pitfalls. Checks generated code before deployment, validates against all…
Use when building ERPNext/Frappe API integrations (v14/v15/v16) including REST API, RPC API, authentication, webhooks, and rate limiting. Covers external API…