codymaster 4.5.4 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -1
- package/README.md +86 -31
- package/dist/backends/viking-backend.js +235 -0
- package/dist/backends/viking-http-client.js +176 -0
- package/dist/browse-server.js +251 -0
- package/dist/cli/command-registry.js +26 -0
- package/dist/cli/commands/agent.js +120 -0
- package/dist/cli/commands/dashboard.js +93 -0
- package/dist/cli/commands/design-studio.js +111 -0
- package/dist/cli/commands/distro.js +25 -0
- package/dist/cli/commands/engineering.js +488 -0
- package/dist/cli/commands/project.js +324 -0
- package/dist/cli/commands/skill-chain.js +269 -0
- package/dist/cli/commands/system.js +89 -0
- package/dist/cli/commands/task.js +254 -0
- package/dist/cli/update-check.js +83 -0
- package/dist/cm-config.js +110 -0
- package/dist/cm-suggest.js +77 -0
- package/dist/continuity.js +8 -0
- package/dist/distro-validate.js +54 -0
- package/dist/guardian-core.js +74 -0
- package/dist/index.js +36 -2759
- package/dist/mcp-context-server.js +60 -1
- package/dist/mcp-skills-tools.js +81 -0
- package/dist/retro-summary.js +70 -0
- package/dist/second-opinion-providers.js +79 -0
- package/dist/sprint-pipeline.js +228 -0
- package/dist/storage-backend.js +63 -0
- package/dist/utils/cli-utils.js +76 -0
- package/dist/utils/skill-utils.js +32 -0
- package/install.sh +286 -58
- package/package.json +16 -5
- package/scripts/build-skills.mjs +51 -0
- package/scripts/gate-0-repo-hygiene.js +75 -0
- package/scripts/postinstall.js +56 -1
- package/scripts/security-scan.js +1 -1
- package/scripts/validate-skills.mjs +42 -0
- package/scripts/viking-demo.ts +105 -0
- package/skills/CLAUDE.md +2 -2
- package/skills/_shared/helpers.md +10 -0
- package/skills/cm-ads-tracker/SKILL.md +3 -6
- package/skills/cm-browse/SKILL.md +28 -0
- package/skills/cm-conductor-worktrees/SKILL.md +24 -0
- package/skills/cm-content-factory/SKILL.md +1 -1
- package/skills/cm-content-factory/landing/docs/content/changelog.md +36 -0
- package/skills/cm-content-factory/landing/docs/content/deployment.md +46 -0
- package/skills/cm-content-factory/landing/docs/content/execution-flow.md +67 -0
- package/skills/cm-content-factory/landing/docs/content/openspace.md +27 -0
- package/skills/cm-content-factory/landing/docs/content/openviking.md +33 -0
- package/skills/cm-content-factory/landing/docs/content/use-cases.md +26 -0
- package/skills/cm-content-factory/landing/docs/content/v5-intro.md +28 -0
- package/skills/cm-content-factory/landing/docs/index.html +240 -0
- package/skills/cm-content-factory/landing/index.html +99 -99
- package/skills/cm-content-factory/landing/script.js +42 -0
- package/skills/cm-content-factory/landing/translations.js +400 -400
- package/skills/cm-continuity/SKILL.md +33 -6
- package/skills/cm-design-studio/SKILL.md +30 -0
- package/skills/cm-ecosystem-roadmap/SKILL.md +11 -0
- package/skills/cm-engineering-meta/SKILL.md +69 -0
- package/skills/cm-growth-hacking/SKILL.md +1 -12
- package/skills/cm-guardian-runtime/SKILL.md +22 -0
- package/skills/cm-mcp-engineering/SKILL.md +18 -0
- package/skills/cm-notebooklm/SKILL.md +1 -17
- package/skills/cm-post-deploy-canary/SKILL.md +18 -0
- package/skills/cm-qa-visual-cli/SKILL.md +18 -0
- package/skills/cm-retro-cli/SKILL.md +19 -0
- package/skills/cm-second-opinion-cli/SKILL.md +19 -0
- package/skills/cm-secret-shield/SKILL.md +2 -2
- package/skills/cm-sprint-bus/SKILL.md +29 -0
- package/skills/cm-start/SKILL.md +11 -2
- package/skills/cm-tdd/SKILL.md +61 -74
- package/skills/profiles/README.md +21 -0
- package/skills/profiles/core.txt +23 -0
- package/skills/profiles/design.txt +6 -0
- package/skills/profiles/full.txt +58 -0
- package/skills/profiles/growth.txt +10 -0
- package/skills/profiles/knowledge.txt +7 -0
- package/scripts/test-gemini.js +0 -13
- package/skills/cm-frappe-agent/SKILL.md +0 -134
- package/skills/cm-frappe-agent/agents/doctype-architect.md +0 -596
- package/skills/cm-frappe-agent/agents/erpnext-customizer.md +0 -643
- package/skills/cm-frappe-agent/agents/frappe-backend.md +0 -814
- package/skills/cm-frappe-agent/agents/frappe-custom-frontend.md +0 -557
- package/skills/cm-frappe-agent/agents/frappe-debugger.md +0 -625
- package/skills/cm-frappe-agent/agents/frappe-fixer.md +0 -275
- package/skills/cm-frappe-agent/agents/frappe-frontend.md +0 -660
- package/skills/cm-frappe-agent/agents/frappe-installer.md +0 -158
- package/skills/cm-frappe-agent/agents/frappe-performance.md +0 -307
- package/skills/cm-frappe-agent/agents/frappe-planner.md +0 -419
- package/skills/cm-frappe-agent/agents/frappe-remote-ops.md +0 -153
- package/skills/cm-frappe-agent/agents/github-workflow.md +0 -286
- package/skills/cm-frappe-agent/commands/frappe-app.md +0 -351
- package/skills/cm-frappe-agent/commands/frappe-backend.md +0 -162
- package/skills/cm-frappe-agent/commands/frappe-bench.md +0 -254
- package/skills/cm-frappe-agent/commands/frappe-debug.md +0 -263
- package/skills/cm-frappe-agent/commands/frappe-doctype-create.md +0 -272
- package/skills/cm-frappe-agent/commands/frappe-doctype-field.md +0 -310
- package/skills/cm-frappe-agent/commands/frappe-erpnext.md +0 -210
- package/skills/cm-frappe-agent/commands/frappe-fix.md +0 -59
- package/skills/cm-frappe-agent/commands/frappe-frontend.md +0 -210
- package/skills/cm-frappe-agent/commands/frappe-fullstack.md +0 -243
- package/skills/cm-frappe-agent/commands/frappe-github.md +0 -57
- package/skills/cm-frappe-agent/commands/frappe-install.md +0 -52
- package/skills/cm-frappe-agent/commands/frappe-plan.md +0 -442
- package/skills/cm-frappe-agent/commands/frappe-remote.md +0 -58
- package/skills/cm-frappe-agent/commands/frappe-test.md +0 -356
- package/skills/cm-frappe-agent/docs/README.md +0 -51
- package/skills/cm-frappe-agent/docs/agents-catalog.md +0 -113
- package/skills/cm-frappe-agent/docs/architecture.md +0 -149
- package/skills/cm-frappe-agent/docs/commands-catalog.md +0 -82
- package/skills/cm-frappe-agent/docs/resources-catalog.md +0 -66
- package/skills/cm-frappe-agent/docs/sitemap-urls.txt +0 -52
- package/skills/cm-frappe-agent/docs/sitemap.md +0 -81
- package/skills/cm-frappe-agent/docs/sop/user-guide.md +0 -178
- package/skills/cm-frappe-agent/docs/sop/vibe-coding-guide.md +0 -122
- package/skills/cm-frappe-agent/resources/7-layer-architecture.md +0 -985
- package/skills/cm-frappe-agent/resources/bench_commands.md +0 -73
- package/skills/cm-frappe-agent/resources/code-patterns-guide.md +0 -948
- package/skills/cm-frappe-agent/resources/common_pitfalls.md +0 -266
- package/skills/cm-frappe-agent/resources/doctype-registry.md +0 -158
- package/skills/cm-frappe-agent/resources/installation-guide.md +0 -289
- package/skills/cm-frappe-agent/resources/rest-api-patterns.md +0 -182
- package/skills/cm-frappe-agent/resources/scaffold_checklist.md +0 -82
- package/skills/cm-frappe-agent/resources/upgrade_patterns.md +0 -113
- package/skills/cm-frappe-agent/resources/web-form-patterns.md +0 -252
- package/skills/cm-frappe-agent/skills/bench-commands/SKILL.md +0 -621
- package/skills/cm-frappe-agent/skills/client-scripts/SKILL.md +0 -642
- package/skills/cm-frappe-agent/skills/doctype-patterns/SKILL.md +0 -576
- package/skills/cm-frappe-agent/skills/frappe-api/SKILL.md +0 -740
- package/skills/cm-frappe-agent/skills/remote-operations/SKILL.md +0 -47
- package/skills/cm-frappe-agent/skills/server-scripts/SKILL.md +0 -608
- package/skills/cm-frappe-agent/skills/web-forms/SKILL.md +0 -46
- package/skills/frappe-app-builder.zip +0 -0
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
# Common Frappe Pitfalls & Solutions
|
|
2
|
-
|
|
3
|
-
Hard-won lessons from production Frappe apps.
|
|
4
|
-
|
|
5
|
-
## 1. Forgetting `frappe.db.commit()` After Bulk Operations
|
|
6
|
-
|
|
7
|
-
**Problem:** Batch task creates 100 records but none appear in DB.
|
|
8
|
-
**Cause:** Frappe's auto-commit only works for single-request lifecycle.
|
|
9
|
-
**Fix:** Always add `frappe.db.commit()` at the end of scheduler tasks and bulk API calls.
|
|
10
|
-
|
|
11
|
-
```python
|
|
12
|
-
# ✅ Correct
|
|
13
|
-
def run_monthly():
|
|
14
|
-
for emp in employees:
|
|
15
|
-
frappe.get_doc({...}).insert(ignore_permissions=True)
|
|
16
|
-
frappe.db.commit() # Don't forget!
|
|
17
|
-
|
|
18
|
-
# ❌ Wrong — records may never be committed
|
|
19
|
-
def run_monthly():
|
|
20
|
-
for emp in employees:
|
|
21
|
-
frappe.get_doc({...}).insert(ignore_permissions=True)
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## 2. Querying Non-Submitted Documents
|
|
25
|
-
|
|
26
|
-
**Problem:** Aggregation includes draft and cancelled records.
|
|
27
|
-
**Fix:** Always filter by `docstatus = 1` for submitted records.
|
|
28
|
-
|
|
29
|
-
```python
|
|
30
|
-
# ✅ Correct
|
|
31
|
-
frappe.db.sql("""
|
|
32
|
-
SELECT SUM(points) FROM `tabViolation`
|
|
33
|
-
WHERE employee = %s AND docstatus = 1
|
|
34
|
-
""", employee)
|
|
35
|
-
|
|
36
|
-
# ❌ Wrong — includes drafts and cancelled
|
|
37
|
-
frappe.db.sql("""
|
|
38
|
-
SELECT SUM(points) FROM `tabViolation`
|
|
39
|
-
WHERE employee = %s
|
|
40
|
-
""", employee)
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## 3. NULL SUM Results
|
|
44
|
-
|
|
45
|
-
**Problem:** `SUM()` returns NULL when no rows match, causing TypeError.
|
|
46
|
-
**Fix:** Use `COALESCE(SUM(...), 0)`.
|
|
47
|
-
|
|
48
|
-
```python
|
|
49
|
-
# ✅ Correct
|
|
50
|
-
result = frappe.db.sql("""
|
|
51
|
-
SELECT COALESCE(SUM(points), 0) AS total FROM `tabBonus`
|
|
52
|
-
WHERE employee = %(emp)s AND docstatus = 1
|
|
53
|
-
""", {"emp": employee}, as_dict=True)
|
|
54
|
-
total = result[0].total # Always a number
|
|
55
|
-
|
|
56
|
-
# ❌ Wrong — total could be None
|
|
57
|
-
result = frappe.db.sql("""SELECT SUM(points) AS total ...""")
|
|
58
|
-
total = result[0].total # Could be None!
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## 4. Non-Idempotent Install/Migrate Hooks
|
|
62
|
-
|
|
63
|
-
**Problem:** `bench migrate` crashes because role/field already exists.
|
|
64
|
-
**Fix:** Always check existence before creating.
|
|
65
|
-
|
|
66
|
-
```python
|
|
67
|
-
# ✅ Correct
|
|
68
|
-
if not frappe.db.exists("Role", "My Role"):
|
|
69
|
-
frappe.get_doc({"doctype": "Role", "role_name": "My Role"}).insert()
|
|
70
|
-
|
|
71
|
-
# ❌ Wrong — crashes on second migrate
|
|
72
|
-
frappe.get_doc({"doctype": "Role", "role_name": "My Role"}).insert()
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## 5. Modifying Fields in on_submit Without db_update
|
|
76
|
-
|
|
77
|
-
**Problem:** Setting fields in `on_submit()` but changes don't persist.
|
|
78
|
-
**Cause:** By on_submit time, the doc is already saved.
|
|
79
|
-
**Fix:** Call `self.db_update()` after modifying fields.
|
|
80
|
-
|
|
81
|
-
```python
|
|
82
|
-
# ✅ Correct
|
|
83
|
-
def on_submit(self):
|
|
84
|
-
self.confirmed_by = frappe.session.user
|
|
85
|
-
self.confirmed_at = now()
|
|
86
|
-
self.db_update() # Persist the changes!
|
|
87
|
-
|
|
88
|
-
# ❌ Wrong — changes are lost
|
|
89
|
-
def on_submit(self):
|
|
90
|
-
self.confirmed_by = frappe.session.user
|
|
91
|
-
# Forgot db_update!
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## 6. Business Logic in DocType Controllers
|
|
95
|
-
|
|
96
|
-
**Problem:** Complex calculations in `.py` controller = untestable.
|
|
97
|
-
**Fix:** Put logic in `engines/`, call from controller.
|
|
98
|
-
|
|
99
|
-
```python
|
|
100
|
-
# ✅ Correct — controller delegates to engine
|
|
101
|
-
class MyDoc(Document):
|
|
102
|
-
def on_submit(self):
|
|
103
|
-
from my_app.engines.engine import process_submission
|
|
104
|
-
process_submission(self)
|
|
105
|
-
|
|
106
|
-
# ❌ Wrong — 200 lines of business logic in controller
|
|
107
|
-
class MyDoc(Document):
|
|
108
|
-
def on_submit(self):
|
|
109
|
-
# 200 lines of complex calculations here...
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## 7. Hardcoded Company/Branch References
|
|
113
|
-
|
|
114
|
-
**Problem:** App only works for one company.
|
|
115
|
-
**Fix:** Always use Link fields and dynamic lookups.
|
|
116
|
-
|
|
117
|
-
```python
|
|
118
|
-
# ✅ Correct
|
|
119
|
-
company = frappe.db.get_value("Employee", employee, "company")
|
|
120
|
-
config = get_config(company=company)
|
|
121
|
-
|
|
122
|
-
# ❌ Wrong
|
|
123
|
-
config = get_config(company="Boxme Vietnam")
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## 8. Missing Permission Checks in APIs
|
|
127
|
-
|
|
128
|
-
**Problem:** Any logged-in user can call your API.
|
|
129
|
-
**Fix:** Always check permissions first.
|
|
130
|
-
|
|
131
|
-
```python
|
|
132
|
-
# ✅ Correct
|
|
133
|
-
@frappe.whitelist()
|
|
134
|
-
def my_api(employee):
|
|
135
|
-
if not frappe.has_permission("My DocType", "write"):
|
|
136
|
-
frappe.throw(_("Permission denied"), frappe.PermissionError)
|
|
137
|
-
# ... proceed
|
|
138
|
-
|
|
139
|
-
# ❌ Wrong — no permission check
|
|
140
|
-
@frappe.whitelist()
|
|
141
|
-
def my_api(employee):
|
|
142
|
-
# Anyone can call this!
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## 9. Forgetting to Build After JS Changes
|
|
146
|
-
|
|
147
|
-
**Problem:** JS changes don't appear in browser.
|
|
148
|
-
**Fix:** Run `bench build --app my_app` after any JS/CSS change.
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
# After changing any .js or .css file:
|
|
152
|
-
bench build --app my_app
|
|
153
|
-
|
|
154
|
-
# Or for development with auto-rebuild:
|
|
155
|
-
bench --site mysite clear-cache
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## 10. SQL Injection via String Formatting
|
|
159
|
-
|
|
160
|
-
**Problem:** User input injected directly into SQL.
|
|
161
|
-
**Fix:** Always use parameterized queries.
|
|
162
|
-
|
|
163
|
-
```python
|
|
164
|
-
# ✅ Correct — parameterized
|
|
165
|
-
frappe.db.sql("""
|
|
166
|
-
SELECT * FROM `tabEmployee` WHERE name = %(emp)s
|
|
167
|
-
""", {"emp": employee}, as_dict=True)
|
|
168
|
-
|
|
169
|
-
# ❌ Wrong — SQL injection risk
|
|
170
|
-
frappe.db.sql(f"SELECT * FROM `tabEmployee` WHERE name = '{employee}'")
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## 11. Workflow State Records Not Created
|
|
174
|
-
|
|
175
|
-
**Problem:** Workflow fails because Workflow State records don't exist.
|
|
176
|
-
**Fix:** Create all workflow states in `after_install` / `after_migrate`.
|
|
177
|
-
|
|
178
|
-
## 12. Custom Fields Missing Module Property
|
|
179
|
-
|
|
180
|
-
**Problem:** `bench export-fixtures` doesn't pick up custom fields.
|
|
181
|
-
**Fix:** Always set `"module": "My App"` in custom field definitions.
|
|
182
|
-
|
|
183
|
-
## 12b. Non-ASCII/Accented Characters in Schema (Names/Fieldnames)
|
|
184
|
-
|
|
185
|
-
**Problem:** Creating DocTypes or fields with non-ASCII characters (e.g., Vietnamese `custom_tên_vi_phạm`) causes cryptic Frappe Builder and MariaDB SQL parsing errors, specifically breaking Frappe Insights and complex `apply_user_permissions` queries.
|
|
186
|
-
**Fix:** **ALWAYS** use strict English for DocType `name` (Title Case) and `fieldname` (snake_case). Use the `label` property or Frappe Translation system for localized display in the UI. **NEVER** use non-ASCII characters in schema definitions.
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
## Remote API & Operations Pitfalls
|
|
191
|
-
|
|
192
|
-
## 13. Using `set_value()` in Web Form Client Scripts
|
|
193
|
-
|
|
194
|
-
**Problem:** WebForm shows error or silently fails.
|
|
195
|
-
**Cause:** WebForm extends `FieldGroup`, NOT `Form`. It uses `set_values()` (plural).
|
|
196
|
-
**Fix:** Always use `frappe.web_form.set_values({...})`.
|
|
197
|
-
|
|
198
|
-
```javascript
|
|
199
|
-
// ✅ Correct
|
|
200
|
-
frappe.ready(function() {
|
|
201
|
-
frappe.web_form.set_values({ date: frappe.datetime.get_today() });
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
// ❌ Wrong — set_value doesn't exist on WebForm
|
|
205
|
-
frappe.web_form.set_value('date', frappe.datetime.get_today());
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## 14. Web Form Code Outside `frappe.ready()`
|
|
209
|
-
|
|
210
|
-
**Problem:** Code runs before form is loaded, fields are undefined.
|
|
211
|
-
**Fix:** Always wrap Web Form client script code in `frappe.ready()`.
|
|
212
|
-
|
|
213
|
-
```javascript
|
|
214
|
-
// ❌ Wrong — form may not be loaded yet
|
|
215
|
-
frappe.web_form.set_values({ field: 'value' });
|
|
216
|
-
|
|
217
|
-
// ✅ Correct
|
|
218
|
-
frappe.ready(function() {
|
|
219
|
-
frappe.web_form.set_values({ field: 'value' });
|
|
220
|
-
});
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
## 15. Exposing API Keys in Output or Logs
|
|
224
|
-
|
|
225
|
-
**Problem:** API keys leaked in console output, error logs, or AI responses.
|
|
226
|
-
**Fix:** Always use environment variables, never hardcode credentials.
|
|
227
|
-
|
|
228
|
-
```bash
|
|
229
|
-
# ✅ Correct — use .env file
|
|
230
|
-
source .env
|
|
231
|
-
curl -sS "$FRAPPE_SITE/api/resource/Employee" \
|
|
232
|
-
-H "Authorization: token $FRAPPE_API_KEY:$FRAPPE_API_SECRET"
|
|
233
|
-
|
|
234
|
-
# ❌ Wrong — hardcoded credentials
|
|
235
|
-
curl -sS "https://mysite.com/api/resource/Employee" \
|
|
236
|
-
-H "Authorization: token abc123:xyz789"
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
## 16. Using `frappe.logger` Instead of `frappe.log_error`
|
|
240
|
-
|
|
241
|
-
**Problem:** Log entries disappear, not visible in Error Log DocType.
|
|
242
|
-
**Fix:** ALWAYS use `frappe.log_error()` for persistent logging.
|
|
243
|
-
|
|
244
|
-
```python
|
|
245
|
-
# ✅ Correct — visible in Error Log
|
|
246
|
-
frappe.log_error(title="Debug", message=f"Value: {value}")
|
|
247
|
-
|
|
248
|
-
# ❌ Wrong — logs to file only, easy to miss
|
|
249
|
-
logger = frappe.logger("myapp")
|
|
250
|
-
logger.info(f"Value: {value}")
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
## 17. Using `ignore_permissions=True` as a Bug Fix
|
|
254
|
-
|
|
255
|
-
**Problem:** Permission error → developer bypasses permissions instead of fixing them.
|
|
256
|
-
**Fix:** Fix the actual permission (add role, DocPerm, User Permission). Only use `ignore_permissions=True` for system operations (scheduler tasks, install hooks).
|
|
257
|
-
|
|
258
|
-
```python
|
|
259
|
-
# ✅ Correct — fix the permission
|
|
260
|
-
# Add "My Role" to DocPerm for "My DocType" with read/write
|
|
261
|
-
# Then users with "My Role" can access naturally
|
|
262
|
-
|
|
263
|
-
# ❌ Wrong — bypassing permissions hides real issues
|
|
264
|
-
doc = frappe.get_doc("My DocType", name)
|
|
265
|
-
doc.save(ignore_permissions=True) # DON'T do this to "fix" permission errors
|
|
266
|
-
```
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
# DocType Registry
|
|
2
|
-
|
|
3
|
-
> Reference for discovering and exploring DocTypes on Frappe/ERPNext sites.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## How to Generate a Site-Specific Registry
|
|
8
|
-
|
|
9
|
-
### Via bench console
|
|
10
|
-
```python
|
|
11
|
-
bench --site <sitename> console
|
|
12
|
-
|
|
13
|
-
# List all DocTypes grouped by module
|
|
14
|
-
import json
|
|
15
|
-
from collections import defaultdict
|
|
16
|
-
|
|
17
|
-
doctypes = frappe.get_all("DocType", fields=["name", "module"], limit_page_length=0)
|
|
18
|
-
by_module = defaultdict(list)
|
|
19
|
-
for dt in doctypes:
|
|
20
|
-
by_module[dt.module].append(dt.name)
|
|
21
|
-
|
|
22
|
-
for module in sorted(by_module.keys()):
|
|
23
|
-
names = sorted(by_module[module])
|
|
24
|
-
print(f"\n## {module} ({len(names)})")
|
|
25
|
-
print(", ".join(names))
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Via REST API (remote sites)
|
|
29
|
-
```bash
|
|
30
|
-
curl -sS "https://{site}/api/method/frappe.client.get_list" \
|
|
31
|
-
-H "Authorization: token {key}:{secret}" \
|
|
32
|
-
-H "Content-Type: application/json" \
|
|
33
|
-
-d '{"doctype":"DocType","fields":["name","module"],"limit_page_length":0}' \
|
|
34
|
-
| jq '[.message[] | {name, module}] | group_by(.module) | map({module: .[0].module, count: length, doctypes: [.[].name]})'
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Core Frappe Modules (Standard)
|
|
40
|
-
|
|
41
|
-
These modules exist on every Frappe site:
|
|
42
|
-
|
|
43
|
-
| Module | Typical DocTypes | Purpose |
|
|
44
|
-
|--------|-----------------|---------|
|
|
45
|
-
| **Core** | DocType, User, Role, File, Report, Page | Framework foundation |
|
|
46
|
-
| **Custom** | Custom Field, Client Script, Property Setter | Customization layer |
|
|
47
|
-
| **Desk** | ToDo, Dashboard, Kanban Board, Workspace | User interface |
|
|
48
|
-
| **Email** | Email Account, Notification, Email Template | Email system |
|
|
49
|
-
| **Integrations** | Webhook, OAuth Client, Connected App | Third-party integrations |
|
|
50
|
-
| **Printing** | Print Format, Letter Head | Print templates |
|
|
51
|
-
| **Website** | Web Page, Web Form, Blog Post | Website/portal |
|
|
52
|
-
| **Workflow** | Workflow, Workflow State, Workflow Action | Document workflows |
|
|
53
|
-
| **Automation** | Assignment Rule, Auto Repeat | Automation rules |
|
|
54
|
-
| **Contacts** | Address, Contact | Contact management |
|
|
55
|
-
| **Geo** | Country, Currency | Geographic data |
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## ERPNext Modules (if installed)
|
|
60
|
-
|
|
61
|
-
| Module | Key DocTypes | Purpose |
|
|
62
|
-
|--------|-------------|---------|
|
|
63
|
-
| **Accounts** | Sales Invoice, Purchase Invoice, Journal Entry, Payment Entry | Accounting |
|
|
64
|
-
| **Selling** | Customer, Sales Order, Quotation | Sales management |
|
|
65
|
-
| **Buying** | Supplier, Purchase Order, Request for Quotation | Procurement |
|
|
66
|
-
| **Stock** | Item, Warehouse, Stock Entry, Delivery Note | Inventory |
|
|
67
|
-
| **HR** | Employee, Leave Application, Attendance, Expense Claim | Human resources |
|
|
68
|
-
| **Payroll** | Salary Slip, Salary Structure, Payroll Entry | Payroll processing |
|
|
69
|
-
| **Manufacturing** | BOM, Work Order, Job Card | Manufacturing |
|
|
70
|
-
| **Projects** | Project, Task, Timesheet | Project management |
|
|
71
|
-
| **Assets** | Asset, Asset Movement, Depreciation Schedule | Fixed assets |
|
|
72
|
-
| **CRM** | Lead, Opportunity, Campaign | Customer relationship |
|
|
73
|
-
| **Support** | Issue, Service Level Agreement | Customer support |
|
|
74
|
-
| **Setup** | Company, Department, Designation, Employee | Organization setup |
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Quick DocType Discovery Commands
|
|
79
|
-
|
|
80
|
-
### Find DocTypes by keyword
|
|
81
|
-
```python
|
|
82
|
-
# In bench console
|
|
83
|
-
frappe.get_all("DocType",
|
|
84
|
-
filters={"name": ["like", "%Invoice%"]},
|
|
85
|
-
fields=["name", "module", "issingle"],
|
|
86
|
-
limit_page_length=0
|
|
87
|
-
)
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Find custom app DocTypes
|
|
91
|
-
```python
|
|
92
|
-
frappe.get_all("DocType",
|
|
93
|
-
filters={"module": "My Custom Module"},
|
|
94
|
-
fields=["name", "issingle", "istable"],
|
|
95
|
-
limit_page_length=0
|
|
96
|
-
)
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Check DocType metadata
|
|
100
|
-
```python
|
|
101
|
-
meta = frappe.get_meta("Sales Invoice")
|
|
102
|
-
print(f"Fields: {len(meta.fields)}")
|
|
103
|
-
print(f"Is Submittable: {meta.is_submittable}")
|
|
104
|
-
print(f"Is Child Table: {meta.istable}")
|
|
105
|
-
for df in meta.fields:
|
|
106
|
-
print(f" {df.fieldname} ({df.fieldtype})" + (" *" if df.reqd else ""))
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Find child tables of a DocType
|
|
110
|
-
```python
|
|
111
|
-
meta = frappe.get_meta("Sales Invoice")
|
|
112
|
-
for df in meta.fields:
|
|
113
|
-
if df.fieldtype == "Table":
|
|
114
|
-
print(f" {df.fieldname} → {df.options}")
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Common Patterns
|
|
120
|
-
|
|
121
|
-
### Get all Link fields pointing to a DocType
|
|
122
|
-
```python
|
|
123
|
-
# Find all DocTypes that link to "Customer"
|
|
124
|
-
links = frappe.get_all("DocField",
|
|
125
|
-
filters={"fieldtype": "Link", "options": "Customer"},
|
|
126
|
-
fields=["parent", "fieldname"],
|
|
127
|
-
limit_page_length=0
|
|
128
|
-
)
|
|
129
|
-
for l in links:
|
|
130
|
-
print(f" {l.parent}.{l.fieldname}")
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Export DocType Registry to File
|
|
134
|
-
```python
|
|
135
|
-
import json
|
|
136
|
-
from collections import defaultdict
|
|
137
|
-
|
|
138
|
-
doctypes = frappe.get_all("DocType",
|
|
139
|
-
fields=["name", "module", "issingle", "istable", "is_submittable"],
|
|
140
|
-
limit_page_length=0
|
|
141
|
-
)
|
|
142
|
-
by_module = defaultdict(list)
|
|
143
|
-
for dt in doctypes:
|
|
144
|
-
by_module[dt.module].append(dt)
|
|
145
|
-
|
|
146
|
-
output = {}
|
|
147
|
-
for module in sorted(by_module.keys()):
|
|
148
|
-
output[module] = [{
|
|
149
|
-
"name": dt.name,
|
|
150
|
-
"single": bool(dt.issingle),
|
|
151
|
-
"child": bool(dt.istable),
|
|
152
|
-
"submittable": bool(dt.is_submittable)
|
|
153
|
-
} for dt in sorted(by_module[module], key=lambda x: x.name)]
|
|
154
|
-
|
|
155
|
-
with open("doctype-registry.json", "w") as f:
|
|
156
|
-
json.dump(output, f, indent=2)
|
|
157
|
-
print(f"Exported {len(doctypes)} DocTypes across {len(output)} modules")
|
|
158
|
-
```
|
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
# Frappe Installation & Setup Guide
|
|
2
|
-
|
|
3
|
-
> Complete reference for installing bench, creating sites, and production deployment.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Prerequisites
|
|
8
|
-
|
|
9
|
-
### System Requirements
|
|
10
|
-
|
|
11
|
-
| Component | Minimum | Recommended |
|
|
12
|
-
|-----------|---------|-------------|
|
|
13
|
-
| OS | Ubuntu 22.04 / macOS 13+ | Ubuntu 22.04 LTS |
|
|
14
|
-
| Python | 3.10+ | 3.11 |
|
|
15
|
-
| Node.js | 18+ | 20 LTS |
|
|
16
|
-
| MariaDB | 10.6+ | 10.11 |
|
|
17
|
-
| Redis | 6+ | 7+ |
|
|
18
|
-
| RAM | 2 GB | 4 GB+ |
|
|
19
|
-
| Disk | 20 GB | 40 GB+ |
|
|
20
|
-
|
|
21
|
-
### Install Prerequisites (Ubuntu)
|
|
22
|
-
```bash
|
|
23
|
-
# System packages
|
|
24
|
-
sudo apt update && sudo apt upgrade -y
|
|
25
|
-
sudo apt install -y git python3-dev python3-pip python3-venv \
|
|
26
|
-
redis-server mariadb-server mariadb-client \
|
|
27
|
-
libmysqlclient-dev libffi-dev libssl-dev \
|
|
28
|
-
wkhtmltopdf xvfb nginx supervisor
|
|
29
|
-
|
|
30
|
-
# Node.js via nvm
|
|
31
|
-
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
|
32
|
-
source ~/.bashrc
|
|
33
|
-
nvm install 20
|
|
34
|
-
npm install -g yarn
|
|
35
|
-
|
|
36
|
-
# MariaDB configuration
|
|
37
|
-
sudo mysql_secure_installation
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### Install Prerequisites (macOS)
|
|
41
|
-
```bash
|
|
42
|
-
# Via Homebrew
|
|
43
|
-
brew install python@3.11 node@20 mariadb redis
|
|
44
|
-
brew services start mariadb
|
|
45
|
-
brew services start redis
|
|
46
|
-
|
|
47
|
-
npm install -g yarn
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### MariaDB Configuration
|
|
51
|
-
```ini
|
|
52
|
-
# /etc/mysql/mariadb.conf.d/50-server.cnf (Ubuntu)
|
|
53
|
-
# /opt/homebrew/etc/my.cnf (macOS)
|
|
54
|
-
|
|
55
|
-
[mysqld]
|
|
56
|
-
character-set-server = utf8mb4
|
|
57
|
-
collation-server = utf8mb4_unicode_ci
|
|
58
|
-
innodb_file_per_table = 1
|
|
59
|
-
innodb_large_prefix = 1
|
|
60
|
-
|
|
61
|
-
[client]
|
|
62
|
-
default-character-set = utf8mb4
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
# Restart MariaDB after config change
|
|
67
|
-
sudo systemctl restart mariadb # Ubuntu
|
|
68
|
-
brew services restart mariadb # macOS
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## Bench Installation
|
|
74
|
-
|
|
75
|
-
### Install via pip
|
|
76
|
-
```bash
|
|
77
|
-
pip3 install frappe-bench
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Initialize Bench
|
|
81
|
-
```bash
|
|
82
|
-
# Latest version
|
|
83
|
-
bench init frappe-bench --frappe-branch version-15
|
|
84
|
-
cd frappe-bench
|
|
85
|
-
|
|
86
|
-
# Specific version
|
|
87
|
-
bench init frappe-bench --frappe-branch version-14
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Verify Installation
|
|
91
|
-
```bash
|
|
92
|
-
bench --version
|
|
93
|
-
bench find . # Should find the bench directory
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## Site Management
|
|
99
|
-
|
|
100
|
-
### Create New Site
|
|
101
|
-
```bash
|
|
102
|
-
bench new-site mysite.localhost \
|
|
103
|
-
--mariadb-root-password <root_password> \
|
|
104
|
-
--admin-password <admin_password>
|
|
105
|
-
|
|
106
|
-
# With PostgreSQL
|
|
107
|
-
bench new-site mysite.localhost \
|
|
108
|
-
--db-type postgres \
|
|
109
|
-
--db-host localhost \
|
|
110
|
-
--db-port 5432
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### Set Default Site
|
|
114
|
-
```bash
|
|
115
|
-
bench use mysite.localhost
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Install Apps on Site
|
|
119
|
-
```bash
|
|
120
|
-
# Get app from git
|
|
121
|
-
bench get-app erpnext --branch version-15
|
|
122
|
-
bench get-app https://github.com/user/my-custom-app.git
|
|
123
|
-
|
|
124
|
-
# Install on site
|
|
125
|
-
bench --site mysite.localhost install-app erpnext
|
|
126
|
-
bench --site mysite.localhost install-app my_custom_app
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### Start Development Server
|
|
130
|
-
```bash
|
|
131
|
-
bench start
|
|
132
|
-
# Access at http://mysite.localhost:8000
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
## Custom App Development Setup
|
|
138
|
-
|
|
139
|
-
### Create New App
|
|
140
|
-
```bash
|
|
141
|
-
bench new-app my_custom_app
|
|
142
|
-
# Follow interactive prompts for title, description, etc.
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Install on Site
|
|
146
|
-
```bash
|
|
147
|
-
bench --site mysite.localhost install-app my_custom_app
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### Development Workflow
|
|
151
|
-
```bash
|
|
152
|
-
# Watch for changes (auto-rebuild JS/CSS)
|
|
153
|
-
bench watch
|
|
154
|
-
|
|
155
|
-
# Manual build
|
|
156
|
-
bench build --app my_custom_app
|
|
157
|
-
|
|
158
|
-
# Run migrations after schema changes
|
|
159
|
-
bench --site mysite.localhost migrate
|
|
160
|
-
|
|
161
|
-
# Clear cache
|
|
162
|
-
bench --site mysite.localhost clear-cache
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
## Production Setup
|
|
168
|
-
|
|
169
|
-
### Setup Production (Ubuntu)
|
|
170
|
-
```bash
|
|
171
|
-
# Run as root or with sudo
|
|
172
|
-
sudo bench setup production <user>
|
|
173
|
-
|
|
174
|
-
# This configures:
|
|
175
|
-
# - Nginx (reverse proxy)
|
|
176
|
-
# - Supervisor (process manager)
|
|
177
|
-
# - Redis (cache & queue)
|
|
178
|
-
# - Fail2ban (security)
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Manual Production Setup
|
|
182
|
-
|
|
183
|
-
#### Nginx Config
|
|
184
|
-
```bash
|
|
185
|
-
bench setup nginx
|
|
186
|
-
sudo ln -s `pwd`/config/nginx.conf /etc/nginx/conf.d/frappe-bench.conf
|
|
187
|
-
sudo nginx -t && sudo systemctl reload nginx
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
#### Supervisor Config
|
|
191
|
-
```bash
|
|
192
|
-
bench setup supervisor
|
|
193
|
-
sudo ln -s `pwd`/config/supervisor.conf /etc/supervisor/conf.d/frappe-bench.conf
|
|
194
|
-
sudo supervisorctl reread && sudo supervisorctl update
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
#### SSL with Certbot
|
|
198
|
-
```bash
|
|
199
|
-
sudo apt install certbot python3-certbot-nginx
|
|
200
|
-
sudo certbot --nginx -d mysite.example.com
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### Enable Scheduler (Production)
|
|
204
|
-
```bash
|
|
205
|
-
bench --site mysite.localhost enable-scheduler
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
---
|
|
209
|
-
|
|
210
|
-
## Docker Setup (Development)
|
|
211
|
-
|
|
212
|
-
### Using frappe_docker
|
|
213
|
-
```bash
|
|
214
|
-
git clone https://github.com/frappe/frappe_docker.git
|
|
215
|
-
cd frappe_docker
|
|
216
|
-
|
|
217
|
-
# Development setup
|
|
218
|
-
cp example.env .env
|
|
219
|
-
docker compose -f compose.yaml \
|
|
220
|
-
-f overrides/compose.noproxy.yaml \
|
|
221
|
-
-f overrides/compose.mariadb.yaml \
|
|
222
|
-
up -d
|
|
223
|
-
|
|
224
|
-
# Create site
|
|
225
|
-
docker compose exec backend \
|
|
226
|
-
bench new-site mysite.localhost --mariadb-root-password 123
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
---
|
|
230
|
-
|
|
231
|
-
## Common Installation Errors
|
|
232
|
-
|
|
233
|
-
| Error | Cause | Fix |
|
|
234
|
-
|-------|-------|-----|
|
|
235
|
-
| `ERROR 1698: Access denied for user 'root'` | MariaDB auth method | `sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';"` |
|
|
236
|
-
| `ModuleNotFoundError: No module named 'frappe'` | Virtualenv not activated | Run from bench directory, or `source env/bin/activate` |
|
|
237
|
-
| `error: externally-managed-environment` | PEP 668 on Ubuntu 23+ | Use `pip install --break-system-packages` or use `pipx` |
|
|
238
|
-
| `node: command not found` | Node.js not installed | Install via nvm: `nvm install 20` |
|
|
239
|
-
| `Redis connection refused` | Redis not running | `sudo systemctl start redis` or `brew services start redis` |
|
|
240
|
-
| `wkhtmltopdf not found` | PDF generation dependency | `sudo apt install wkhtmltopdf xvfb` |
|
|
241
|
-
| `yarn: command not found` | Yarn not installed | `npm install -g yarn` |
|
|
242
|
-
| `bench start` hangs | Port conflict | Check `lsof -i :8000` and kill conflicting process |
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
## Multi-Site Setup
|
|
247
|
-
|
|
248
|
-
```bash
|
|
249
|
-
# Enable DNS-based multi-tenancy
|
|
250
|
-
bench config dns_multitenant on
|
|
251
|
-
|
|
252
|
-
# Create additional sites
|
|
253
|
-
bench new-site site2.localhost
|
|
254
|
-
bench --site site2.localhost install-app erpnext
|
|
255
|
-
|
|
256
|
-
# Add to hosts file
|
|
257
|
-
echo "127.0.0.1 site2.localhost" | sudo tee -a /etc/hosts
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
---
|
|
261
|
-
|
|
262
|
-
## Backup & Restore
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
# Backup
|
|
266
|
-
bench --site mysite.localhost backup --with-files
|
|
267
|
-
|
|
268
|
-
# List backups
|
|
269
|
-
ls sites/mysite.localhost/private/backups/
|
|
270
|
-
|
|
271
|
-
# Restore
|
|
272
|
-
bench --site mysite.localhost restore \
|
|
273
|
-
sites/mysite.localhost/private/backups/<backup>.sql.gz \
|
|
274
|
-
--with-private-files <private.tar> \
|
|
275
|
-
--with-public-files <public.tar>
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
## Version Upgrade
|
|
281
|
-
|
|
282
|
-
```bash
|
|
283
|
-
# Update to latest patch
|
|
284
|
-
bench update
|
|
285
|
-
|
|
286
|
-
# Switch major version
|
|
287
|
-
bench switch-to-branch version-15 frappe erpnext
|
|
288
|
-
bench update --patch
|
|
289
|
-
```
|