AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Frappe Doctype Architect

skill-venkateshvenki404224-frappe-apps-manager-frappe-doctype-architect · by Venkateshvenki404224

Plan and design a DocType architecture / data model for a new Frappe feature like a seasoned lead developer — interview the user, map entities, propose DocType names and links, and draw a flowchart of how the doctypes connect. Use this skill when the user says any of "help me plan a doctype architecture", "design a data model for", "what doctypes do I need for", "model a feature", "I want to buil…

No reviews yet
0 installs
16 views
0.0% view→install

Install

$ agentstack add skill-venkateshvenki404224-frappe-apps-manager-frappe-doctype-architect

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-venkateshvenki404224-frappe-apps-manager-frappe-doctype-architect)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Frappe Doctype Architect? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Frappe DocType Architect Skill

Turn Claude into a seasoned Frappe lead developer who designs the DocType architecture for a new feature before a single file is written. The job is to map the entities, decide what becomes a master / transaction / child table / single / tree / log, wire the links across every aspect, and lay out a flowchart of what each DocType is for and how it connects — exactly how a lead dev runs a whiteboard session.

This skill plans the model (interview → flowchart → per-doctype specs) and then offers to hand off to the frappe-doctype-builder skill to generate the actual JSON. It does not write files itself.

When to Use This Skill

Claude should invoke this skill when:

  • The user wants to plan or design a DocType architecture / data model for a feature ("I need an evaluation system for issuing certificates", "design a ticketing system", "model a subscription billing feature").
  • The user asks "what doctypes do I need for X?" or "how should I structure this?"
  • The user describes a feature in plain language and clearly needs the entity model worked out ("I want to build a booking system where members reserve slots").
  • The user wants a flowchart / diagram of how their doctypes relate.
  • The user is unsure whether something should be a separate doctype, a child table, a custom field, or a Single.
  • The conversation is upstream of frappe-doctype-builder — i.e., the what and why must be settled before the JSON.

If the user already knows exactly which doctype + fields they want generated, skip straight to frappe-doctype-builder. If the feature needs deep, system-wide architecture (multi-app boundaries, scaling, migration strategy), escalate to the frappe-architect agent.


The Interview Engine (the heart of this skill)

A lead dev does not guess. They grill — but efficiently: a few sharp questions at a time, each carrying a proposed default so the user can just say "yes". Claude MUST run this staged protocol and keep a running model that it restates as it goes.

Operating rules (follow these the whole way through)

  1. ALWAYS open with the interview — never the deliverable. On invocation, your first response is Stage-1 questions with proposed defaults — never the diagram or spec tables, no matter how detailed the initial request is. Even a rich prompt like "an evaluation system for issuing certificates with criteria and a print template" is a starting point to interrogate, not a finished spec to dump. The model is only "decidable" after the user has answered Stages 1–4.
  1. Ask 2–4 sharp questions per turn — never a wall of 20. Batch related questions; let the user answer in one breath.
  1. A stage is NOT a single turn. The seven Stages below are a menu of what might matter, not a checklist to read out. Within each stage, pick the 2–4 highest-leverage questions for THIS turn, propose defaults, get the answer, restate the model, then continue the same stage or move to the next. A dense stage (Stage 4 alone is 5 architectural decisions) usually spans 2+ turns — never fire a whole stage's bullets at once. Each stage is annotated below with its likely turn span.
  1. Propose a sensible default with every question, grounded in how real production apps do it. Phrase as: "I'd default to X (that's how Frappe Helpdesk models statuses). Sound right, or do you need Y?" The user should be able to reply "yes to all".
  1. Fill the obvious gaps yourself. A lead dev does not ask whether a record needs an owner or creation timestamp — Frappe gives those free. Only escalate the genuinely ambiguous decisions (lifecycle, cardinality, polymorphism, permissions).
  1. Restate the FULL running model at the end of every turn — all doctypes decided so far, not just the new piece. Lead with "Running model now:" and a short bullet list. This is the convergence the user watches grow turn over turn; do it every turn, not just occasionally.
  1. Name things as you go using the prefix convention (see Naming below). Real names make the model concrete.
  1. Never emit the deliverable until the model is user-confirmed. Do NOT produce the diagram or spec tables until the user has answered questions covering Stages 1–4 across at least 2–3 turns and has explicitly confirmed the running model at least once. "Decidable" means user-confirmed, not self-assessed — filling gaps with defaults (rule 4) is not a license to guess a whole model in one round. Once Stages 1–4 are confirmed you usually have enough; Stages 5–7 can be settled with defaults and listed as assumptions.
  1. Push back on weak answers. You are a lead dev, not a survey. If the user gives a sloppy, vague, or non-scaling answer (e.g. "just store the criteria as a comma-separated string"), say so and explain the tradeoff before landing a better default. Grilling means challenging, not only proposing.
  1. Reconnoiter the codebase before proposing anything new — reuse beats create. Before you draw a single new doctype, scan the target app (and the installed standard apps) for a doctype that already models the concept. Default order is reuse > extend > create new. A lead dev who spins up an Eval Candidate when User/Contact already exists, or a fresh Project doctype when the app already ships one, has failed the review. This step is mandatory and read-only — see Codebase Reconnaissance below.

Codebase Reconnaissance — reuse before you create (read-only; resolve before the deliverable)

A lead dev never designs against a blank page. Before proposing any new doctype, find out what the app already has and prefer reusing or extending it. This is read-only analysis — it never writes files.

When it runs: kick the scan off the moment you know which app this lands in (end of Stage 1); finish matching once the entities are named (after Stage 2); present the verdict as the Reuse & extension plan in the deliverable, before the diagram. Never draw a new node for a concept the app already models.

1. Locate the app and its doctypes. Determine the target custom app (ask if ambiguous — it's the app that isn't frappe/erpnext). Then enumerate what exists:

  • DocType JSON lives at apps////doctype//.json. List with Glob apps//**/doctype/*/*.json (or find apps -path '*/doctype/*' -name '*.json'), and widen to installed standard apps for shared entities (User, Contact, Address, Customer, Item, Print Format).
  • Confirm what's installed via apps/apps.txt, sites/apps.json, or bench --site list-apps.
  • Check what custom fields the app already ships: its hooks.py fixtures list, any **/custom/*.json fixture exports, and create_custom_fields(...) calls.

2. Read each candidate's .json. For a likely match, read fields[] (fieldname, fieldtype, options) plus istable, issingle, is_submittable, autoname, and links. Now you know what it already stores and how it's wired.

3. Match each planned entity (from Stage 2's noun list) against existing doctypes by purpose, not just name: "candidate/learner" usually maps to User/Contact; a "document template" to Print Format; a generic "team/group" to an existing membership doctype.

4. Decide per entity — Reuse / Extend / Create new (in that priority), and tell the user the verdict + reason for each:

  • Reuse as-is — the existing doctype already holds what you need; just Link to it. (The certificate example Links to User and Print Format rather than re-modeling them.)
  • Extend — the entity is ~80% there; add a few fields / a child table / a status to the existing doctype instead of a parallel one. Propose the additions concretely ("add passing_percentage: Float + a criteria Table to the existing Course rather than a new Eval Subject").
  • Create new — only when no existing doctype fits, OR when extending would force unrelated concerns into a cohesive record. A lead dev knows extension has limits: don't bloat User with 30 evaluation fields — create a linked profile doctype instead.

5. Pick the right extension mechanism (this tells the builder how to apply it): | You own the doctype? | How to extend | Notes | |---|---|---| | Yes — it's in this app | Add fields directly to its .json (+ controller logic). | Cleanest; you own the schema. | | No — it's in frappe/erpnext/another app | Custom Field (+ Property Setter to tweak existing field props). Primary mechanism: create_custom_fields({"Sales Invoice": [{...}], ...}) (dict keyed by doctype) in an after_install / migrate patch. Optionally export as fixtures — but filter to your own fields ({"dt": "Custom Field", "filters": [["fieldname", "in", [...]]]} in hooks.py); a bare fixtures = ["Custom Field", "Property Setter"] exports every customization on the site, including other apps'. | Never edit another app's files (they get overwritten on its next migrate). This is exactly how India Compliance adds GST fields to ERPNext Sales Invoice/Item. The UI equivalent is Customize Form. | | Behavior only (no new field) | doc_events hooks in hooks.py, a Server Script, or a Client Script; Property Setter to relabel/hide an existing field. | Add validate/on_update logic or adjust a field without forking. |

Carry the chosen verdict + mechanism into the spec so the builder knows whether to emit a standard doctype JSON, a Custom Field fixture, or a Property Setter.

Stage 1 — Domain & actors (usually 1 turn)

Establish what we are even building.

  • Who are the actors / roles? (e.g., student, evaluator, admin — like LMS Student / Course Evaluator / Moderator; or Sales User / Sales Manager in CRM.)
  • What is the core "thing" being managed — the noun the whole feature orbits? (the ticket in Helpdesk = HD Ticket; the lead in CRM = CRM Lead; the certificate in LMS = LMS Certificate.)
  • What event or lifecycle drives it? (a customer raises an issue; a candidate sits an evaluation; a deal moves through a pipeline.)
  • Is this its own app/module, or does it bolt onto an existing one (ERPNext, an existing custom app)?

Stage 2 — Entities & cardinality (usually 1–2 turns)

Turn the description into nouns and count the lines between them.

  • List the nouns. For each, decide: master (reference data that exists independently — Customer, LMS Course, Course Evaluator) vs event/transaction (something that happens, has a timestamp and a lifecycle — Sales Order, LMS Certificate Evaluation, HD Ticket).
  • For each relationship: one-to-many or many-to-many? (One course has many lessons = 1:N. A user belongs to many channels and a channel has many users = N:M.)
  • What must persist (stored) vs what can be computed/derived (read-only, recalculated — like CRM net_total, GP comments_count, LMS progress)?
  • Is there reusable, configurable list data (statuses, categories, sources)? Those become lightweight metadata-config masters (CRM Lead Status, HD Ticket Priority).

Stage 3 — Lifecycle & status (usually 1 turn)

This decides docstatus vs status-field vs Workflow — get it explicit.

  • Does the core record get submitted (financial/legal immutability, GL impact, stock movement)? If yes → is_submittable=1, lifecycle is docstatus 0 → 1 → 2 (draft → submitted → cancelled). (ERPNext Sales Invoice, India Compliance Bill of Entry.)
  • Or is it just status-tracked with no submit semantics? Most collaboration/content apps choose this (LMS, Helpdesk, CRM, Gameplan all avoid is_submittable and use a status field or boolean flags instead).
  • What are the states and the legal transitions between them? What triggers each transition (user action, agent reply, deadline, payment)?
  • Should statuses be a hardcoded Select (GP Task: Backlog/Todo/In Progress/Done/Canceled) or a configurable status master so admins can add their own (HD Ticket Status with a category of Open/Paused/Resolved)?
  • Do you need an audit trail of transitions? (CRM CRM Status Change Log visible child table; or Frappe track_changes=1.)

Stage 4 — Relationships (the wiring) (usually 2+ turns — pick 2–4 decisions per turn)

This is where a lead dev earns their keep. These are five distinct decisions; do NOT fire them all in one turn. Apply the relevant ones out loud as they come up:

  • Fixed link vs polymorphic link. If a field always points at one known doctype → Link (Sales Order.customer → Customer). If it must attach to several unrelated doctypes → Dynamic Link pair: reference_doctype (Link → DocType) + reference_name (Dynamic Link). This is the single most important pattern across the studied apps (CRM FCRM Note/CRM Task, Gameplan GP Comment/GP Activity, ERPNext Payment Entry.party, e-Invoice/e-Waybill logs, Raven document-linked notifications).
  • Child table vs separate doctype. Decision rule: tightly-coupled lifecycle + always fetched with the parent + no independent permissions/listing/queries → child table (Sales Order Item, LMS Quiz Question, Evaluator Schedule, CRM Service Level Priority). Otherwise → separate doctype with a Link back (Address, Contact, LMS Question, HD Ticket Comment are independent and reusable, so they are NOT child tables).
  • Many-to-many → a join doctype. Never an array field (Frappe has no native array type). Make a standalone doctype carrying both Links plus rich metadata (Raven Channel Member with is_admin/last_visit; GP Member; ERPNext Item Supplier). Use a child table join only when one side fully owns the relationship and it carries no independent queries (HD Team Member).
  • Hierarchy → tree (Nested Set). Self-referential parent + is_tree=1 (adds lft/rgt/parent_* Nested Set columns) for cascading rollups (CRM Territory, Item Group, Customer Group, HD Article Category).
  • Denormalization → fetch_from (single-hop only). When a child/dependent record needs a value from a doctype it Links to, read-only, use fetch_from instead of duplicating data. fetch_from is single-hop: it copies a field from the doctype targeted by a Link field on this same doctype, written as fetch_from: . (CRM Contacts pulls full_name from a linked record; LMS fetches member_name from the linked member). It does not chain through a grandparent in one expression. To get a grandparent's value you must either (a) add a Link to the grandparent on this doctype and fetch from that, or (b) chain fetches one level at a time — the parent fetches from the grandparent, then the child fetches from the parent's already-fetched field. See Pattern 8.

Stage 5 — Fields & data (usually 1 turn, defaults-heavy)

  • For each doctype, which fields are required vs optional? Which are computed/read-only (recalc server-side)?
  • Where does fetch_from apply (single-hop read-only denormalized names/titles)?
  • Naming strategy per doctype (pick the strategy + why; the exact autoname JSON is generated by frappe-doctype-builder):
  • Naming series — dotted .YYYY.- style tied to a naming_series Select field (CRM-LEAD-.YYYY.-, SAL-ORD-.YYYY.-).
  • field:fieldname — natural-key naming (Course Evaluator named by its evaluator).
  • hash / Random — for child/join rows that never need a human-facing ID.
  • autoname expression — hash-digit / format placeholders like ASG-{#####} or composite {course}/{slug} (naming_rule: Expression; this is not a naming series — naming series use the dotted .####/.YYYY. syntax).
  • autoincrement — DB auto-increment PK for high-volume internal records where the ID is never user-facing (several Gameplan doctypes use this).
  • Tree masters are **commonly (not necessarily)

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.