doctype-development
Skill68 starsChanged 9 days agoMITView on GitHub
Create and modify Frappe DocTypes including schema design, controllers, child tables, and customization. Use when building data models, adding fields, or implementing document lifecycle logic.
In this repository13 other files it gives its agents.
- api-developmentSkill
- app-developmentSkill
- desk-customizationSkill
- enterprise-patternsSkill
- frappe-managerSkill
- frontend-developmentSkill
- printing-templatesSkill
- project-triageSkill
- reportsSkill
- routerSkill
- testingSkill
- ui-patternsSkill
- web-formsSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 7 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 78
Create <doctype_name>.py alongside the JSON:
- Distinctive: line 124
Create Workflow DocType linking to your DocType with states and transitions.
- Distinctive: line 137
DocType not found: Check module path and app installation
- Distinctive: line 138
Controller not loading: Verify class name matches DocType name (PascalCase)
- Distinctive: line 139
Fields not saving: Check fieldtype and options compatibility
- Distinctive: line 140
Permission denied: Verify role permissions and User Permissions
- Distinctive: line 158
Verify naming series uniqueness: Ensure naming series prefixes don't conflict with existing DocTypes
- Distinctive: line 161
Validate fieldname conventions: Use snake_case, max 140 chars, no reserved SQL keywords
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Frappe DocType Development
Build and modify DocTypes—the core data model abstraction in Frappe Framework.
When to use
- Creating new DocTypes (standard, single, child table, submittable, tree)
- Adding or modifying fields on existing DocTypes
- Implementing controller logic (validate, before_save, on_submit, etc.)
- Setting up naming series and auto-naming
- Configuring permissions and workflows
- Building child tables and parent-child relationships
Inputs required
- Target app and module path
- DocType name and type (standard/single/child/submittable/tree)
- Field definitions (name, type, options)
- Permission requirements by role
- Whether workflow is needed
Procedure
0) Verify environment
# Ensure developer mode is enabled
bench --site <site> console
>>> frappe.conf.developer_mode # Must be True1) Choose DocType type
| Type | Use Case | Key Setting |
| Standard | Multiple records | Default |
| Single | Config/settings (one record) | issingle: 1 |
| Child Table | Rows in parent table | istable: 1 |
| Submittable | Draft→Submit→Cancel workflow | is_submittable: 1 |
| Tree | Hierarchical data | is_tree: 1 |
| Virtual | External data source | is_virtual: 1 |
2) Create DocType
Option A: Via UI (recommended for new DocTypes)
- Navigate to DocType List → New
- Define fields, permissions, settings
- Save (exports to app in developer mode)
Option B: Via code
# Create DocType JSON in:
# <app>/<module>/doctype/<doctype_name>/<doctype_name>.json3) Define fields
Common field patterns:
{
"fieldname": "customer",
"fieldtype": "Link",
"label": "Customer",
"options": "Customer",
"reqd": 1
}See references/field-types.md for all field types.
4) Implement controller
Create <doctype_name>.py alongside the JSON:
import frappe
from frappe.model.document import Document
class MyDocType(Document):
def validate(self):
# Lightweight validation
if not self.customer:
frappe.throw("Customer is required")
def before_save(self):
# Pre-save normalization
self.full_name = f"{self.first_name} {self.last_name}"
def after_insert(self):
# Post-create side effects
frappe.publish_realtime("new_doc", {"name": self.name})5) Set up naming
{
"autoname": "naming_series:",
"fields": [
{
"fieldname": "naming_series",
"fieldtype": "Select",
"options": "PRJ-.YYYY.-\nPRJ-.YYYY.-.###"
}
]
}Options: field:fieldname, naming_series:, hash, format:PREFIX-{####}
6) Configure permissions
Set in DocType → Permissions tab:
- Role + Read/Write/Create/Delete/Submit/Cancel
- User permissions for row-level filtering
7) Add workflow (if needed)
Create Workflow DocType linking to your DocType with states and transitions.
Verification
- DocType appears in list and can create new records
- All fields save correctly
- Controller hooks fire (check logs)
- Permissions enforced for each role
- Naming series generates correctly
- Run:
bench --site <site> migratesucceeds
Failure modes / debugging
- DocType not found: Check module path and app installation
- Controller not loading: Verify class name matches DocType name (PascalCase)
- Fields not saving: Check fieldtype and options compatibility
- Permission denied: Verify role permissions and User Permissions
Escalation
- For complex permission logic, see references/permissions.md
- For child table patterns, see references/child-tables.md
- For Virtual DocTypes, see references/virtual-doctypes.md
References
- references/field-types.md - All field types and options
- references/controllers.md - Controller lifecycle hooks
- references/child-tables.md - Parent-child patterns
- references/naming.md - Naming patterns
Guardrails
- Check developer_mode before schema changes: DocType modifications only export to files when
developer_mode = 1in site config - Verify naming series uniqueness: Ensure naming series prefixes don't conflict with existing DocTypes
- Test child tables separately: Child tables have their own lifecycle; test them in isolation before parent integration
- Always run migrate after changes: Schema changes require
bench --site <site> migrateto apply - Validate fieldname conventions: Use snake_case, max 140 chars, no reserved SQL keywords
Common Mistakes
| Mistake | Why It Fails | Fix |
Missing reqd on mandatory fields | Users can save incomplete data | Set reqd: 1 on fields that must have values |
| Wrong fieldtype for data | Data truncation or validation errors | Match fieldtype to data (e.g., Currency for money, not Float) |
Not running bench migrate | Schema changes not applied to database | Always run bench --site <site> migrate after DocType changes |
| Circular Link dependencies | DocType creation fails | Use Dynamic Link or restructure relationships |
| Controller class name mismatch | Controller methods not called | Class name must be PascalCase of DocType name (e.g., SalesOrder for "Sales Order") |
Missing in_list_view on key fields | Fields not visible in list | Set in_list_view: 1 on important fields |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

