Manifest and layout
Standard directory layout
<technical_name>/
manifest.json
init.go # blank-import subpackages; optional event hooks
models/ # struct + sdk.Model; zmodels.go generated
services/ # hooks, business logic (optional)
wizard/ # transient models (optional)
views/ # XML menus, actions, views
security/ # groups, rules, sys.access.csv
data/ # seed/demo XML (optional)
controllers/ # HTTP routes (optional)
test/ # integration tests (optional)
Folder name must match manifest name (^[a-z][a-z0-9_]*$).
manifest.json
{
"name": "crm",
"display_name": "CRM",
"version": "1.0.0",
"depends": ["base", "contacts", "mail", "utm"],
"application": true,
"data": [
"security/security.xml",
"security/crm_rules.xml",
"security/sys.access.csv",
"data/crm_stage_data.xml",
"views/crm_lead_views.xml",
"views/menus.xml"
]
}
| Field | Purpose |
|---|---|
name | Technical module name (directory name) |
depends | Modules that must install first |
application | true → shows as app tile on Home |
data | XML/CSV load order on install/update |
Bridge modules (e.g. sale_crm): "application": false, "data": [], logic in init.go only.
Wizard and other cross-package Many2One fields use sdk.Many2One[sdk.Any] with comodel= (typed T only works in the same Go package).
init.go
In sumeru_addons, keep a hand-written init.go that blank-imports subpackages so init() runs (models, services, wizard). Do not put log.Println in init().
package crm
import (
_ "sumeru_addons/crm/models"
_ "sumeru_addons/crm/services"
_ "sumeru_addons/crm/wizard"
)
In sumeru_custom_addons, workspace make generate overwrites each addon’s init.go with a models-only blank import (// Code generated by sumeru-import-gen; DO NOT EDIT.). Put hooks and object actions in models/ (see addons/my_module). Do not rely on a hand-written custom init.go surviving generate.
Security load order
Load groups and rules before views and menus that reference them:
security/security.xml— groupssecurity/*_rules.xml— record rulessecurity/sys.access.csv— model ACLsdata/— seed recordsviews/— actions and menus
Custom workspace
From sumeru_custom_addons:
make generate # refresh blank imports
make run
List ../sumeru_addons before ./addons on addons_path so custom modules can extend standard apps.