Enterprise Patterns logo

Enterprise Patterns

Organization
lubusIN
enterprise-patterns

Production-grade architectural patterns for building enterprise Frappe apps like CRM, Helpdesk, and HRMS. Use when designing complex multi-entity systems with workflows, SLAs, and integrations.

Overview

PublisherlubusIN
Repositoryfrappe-skills
Skill nameenterprise-patterns
Stars
62
Forks
23
Bundled files
6
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 6 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by lubusIN on GitHub. Read the source before you install it.

Installation

Install the Enterprise Patterns AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/lubusIN/frappe-skills.git /tmp/frappe-skills
mkdir -p .claude/skills
cp -r /tmp/frappe-skills/enterprise-patterns .claude/skills/enterprise-patterns
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Enterprise Patterns in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Enterprise Patterns on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Enterprise Patterns is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Frappe Enterprise Patterns

Architectural patterns for building production-grade enterprise applications.

When to use

  • Building CRM, Helpdesk, HRMS, or similar multi-entity systems
  • Designing SLA-driven workflows
  • Implementing assignment and queue management
  • Building audit trails and activity logs
  • Integrating with external systems (email, telephony, CRM)

Inputs required

  • System type (CRM/Helpdesk/custom)
  • Core entities and relationships
  • SLA requirements
  • Workflow states and transitions
  • Integration points

Procedure

0) Design data model

Start with clear, normalized DocTypes:

Ticket (parent)
├── customer (Link: Customer)
├── assigned_to (Link: User)
├── status (Select: Open, In Progress, Resolved, Closed)
├── priority (Link: Priority)
├── sla (Link: SLA)
├── activities (Table: Ticket Activity)
└── response_by, resolution_by (Datetime)

Key patterns:

  • Use Link fields for relationships
  • Use child tables for activities, timelines, line items
  • Use Dynamic Link when target DocType varies

1) Implement state machine

Option A: Workflow DocType

  • Create Workflow with states and role-based transitions
  • Link to your DocType

Option B: docstatus for submission flow

docstatusMeaning
0Draft
1Submitted
2Cancelled

Option C: Custom status field with validation

python
def validate(self):
    allowed = self.get_allowed_transitions()
    if self.status not in allowed:
        frappe.throw(f"Cannot transition to {self.status}")

2) Set up permissions

Row-level filtering:

  • Use User Permissions to restrict by entity
  • Combine with Role Permissions

Always re-check in RPC methods:

python
@frappe.whitelist()
def update_ticket(name, status):
    doc = frappe.get_doc("Ticket", name)
    if not frappe.has_permission("Ticket", "write", doc):
        frappe.throw("Not permitted", frappe.PermissionError)
    doc.status = status
    doc.save()

3) Build activity trail

Track changes using Activity Log or custom child table:

python
def on_update(self):
    if self.has_value_changed("status"):
        self.append("activities", {
            "action": "Status Change",
            "old_value": self._doc_before_save.status,
            "new_value": self.status,
            "timestamp": frappe.utils.now()
        })

4) Implement SLA

SLA DocType:

SLA
├── entity_type (Link: DocType)
├── response_time (Duration)
├── resolution_time (Duration)
└── escalation_rules (Table: Escalation Rule)

Apply SLA on creation:

python
def after_insert(self):
    sla = get_applicable_sla(self)
    if sla:
        self.response_by = add_to_date(self.creation, hours=sla.response_time)
        self.resolution_by = add_to_date(self.creation, hours=sla.resolution_time)
        self.db_update()

Monitor breaches (scheduled job):

python
def check_sla_breaches():
    tickets = frappe.get_all("Ticket", 
        filters={"status": ["not in", ["Resolved", "Closed"]]},
        fields=["name", "resolution_by"]
    )
    for t in tickets:
        if frappe.utils.now_datetime() > t.resolution_by:
            mark_sla_breached(t.name)

5) Assignment and queues

Round-robin assignment:

python
def assign_next_agent(queue):
    agents = frappe.get_all("Queue Member",
        filters={"queue": queue, "available": 1},
        fields=["user", "current_load"],
        order_by="current_load asc"
    )
    if agents:
        return agents[0].user
    return None

Assignment Rules DocType for automatic assignment.

6) Notifications and escalations

Configure Notification DocType for:

  • SLA approaching breach
  • Assignment changes
  • Status transitions
  • Customer replies

Escalation chain:

Level 1 (0h): Notify assigned agent
Level 2 (4h): Notify team lead
Level 3 (8h): Notify manager
Level 4 (24h): Notify department head

7) External integrations

Centralize in integrations/ module:

python
# my_app/integrations/email_connector.py
def sync_emails():
    # Fetch from Email Account
    # Create Communications
    # Link to Tickets

Use background jobs for sync:

python
frappe.enqueue(
    "my_app.integrations.email_connector.sync_emails",
    queue="long",
    timeout=600
)

Verification

  • Workflow transitions work for all roles
  • Permissions enforced at API level
  • Activity log captures all changes
  • SLA calculation correct
  • Notifications fire appropriately
  • Integration sync runs without errors

Failure modes / debugging

  • Permission bypass: Check RPC methods have explicit permission checks
  • SLA not applying: Verify scheduled job is running
  • Activities not logging: Check has_value_changed usage
  • Notifications not sending: Check Notification rules and email queue

Escalation

References

Guardrails

  • Follow CRM/Helpdesk UI patterns: For CRUD apps, follow ui-patterns skill which documents app shell, navigation, list views, and form patterns from official Frappe apps. This includes sidebar layouts, quick filters, Kanban views, and detail panels.
  • Use Frappe UI for frontends: All custom enterprise frontends must use Frappe UI (Vue 3 + TailwindCSS) — never vanilla JS or jQuery
  • Design workflows carefully: Map all states and transitions before implementation; consider rollback paths
  • Handle edge cases: Plan for cancelled, on-hold, and exception states in workflows
  • Test performance early: Run load tests for high-volume DocTypes and complex queries
  • Use background jobs for heavy operations: Never block web requests with long-running tasks
  • Log critical operations: Use frappe.log_error() and activity logs for auditability

Common Mistakes

MistakeWhy It FailsFix
Over-complex workflowsHard to maintain, user confusionKeep workflows linear when possible; split complex flows
Missing error handling in integrationsSilent failures, data inconsistencyWrap external calls in try/except; log errors; retry logic
Race conditions in document updatesData corruptionUse frappe.db.get_value(..., for_update=True) for locks
SLA without timezone handlingWrong calculations for global usersStore and compare in UTC; use frappe.utils.convert_utc_to_timezone
Not using queues for bulk operationsTimeouts, memory issuesUse frappe.enqueue() for operations on many records
Hardcoded role namesBreaks on role changesUse constants or settings for role names
Custom UI patternsInconsistent UX, user confusionStudy and follow CRM/Helpdesk app shells
Using vanilla JS/jQuery for frontendMaintenance burden, ecosystem mismatchAlways use Frappe UI with Vue 3

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Enterprise Patterns AI skill do?

Production-grade architectural patterns for building enterprise Frappe apps like CRM, Helpdesk, and HRMS. Use when designing complex multi-entity systems with workflows, SLAs, and integrations.

Why use Enterprise Patterns on TypingMind?

Because you install it once and use it with any model. Enterprise Patterns is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Enterprise Patterns in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/lubusIN/frappe-skills/tree/main/enterprise-patterns. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Enterprise Patterns?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Enterprise Patterns?

As many as you like. As long as a model supports skills, you can use Enterprise Patterns with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Enterprise Patterns AI skill free?

Yes. It is published on GitHub by lubusIN under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇