Pre-alpha. No tagged release and no upgrade path between versions. Use for evaluation and development only, not production.
Addons DevPre-alpha

Events and hooks

Standard business addons automate cross-module behavior through the in-process event bus and ORM extension points.

Event subscription

Package: sumeru/core/event

event.Subscribe("record.updated", func(ctx context.Context, ev event.Event) error {
    if ev.Payload["model"] != "crm.lead" {
        return nil
    }
    // read ev.Payload["id"], ev.Payload["values"]
    return nil
})

Common events:

EventWhen
record.createdAfter insert commit
record.updatedAfter update commit
cron.tickScheduler tick (from sys.cron)
Custom namesFrom cron row event_name field

Register subscriptions in init.go or a services/ package imported from init.go.

Privileged writes

Use orm.ContextWithBypass(ctx) when the handler must write records the triggering user cannot access (e.g. auto-creating a quotation).

Object actions

UI buttons on forms call registered handlers:

orm.RegisterObjectAction("crm.lead", "action_set_won", handler)

Handler returns redirect URL or sets vals["next"]. See sumeru_addons/crm/services/hooks.go and account/services/actions.go.

Kanban expanders

Package: sumeru/core/engine/swcmeta

swcmeta.RegisterKanbanGroupExpander("crm.lead", "stage_id", expandFn)

Used for CRM pipeline and forecast kanbans in the SWC workspace.

Cron handlers

Register a Go handler keyed by a sys.cron row’s code field that you seed yourself:

scheduler.RegisterCronHandler("my_module.nightly_digest", func(ctx context.Context, payload map[string]interface{}) error {
    // run periodic work
    return nil
})

The scheduler still publishes cron.tick and any custom event_name on the cron row.

CRM subscribes to crm.cron_assign_leads in crm/services/hooks.go for round-robin assignment, but does not seed a sys.cron row. Shipped UX is the Assign Leads object button on the team form. Subscribe to that event (or add your own cron that publishes it) only if you want a schedule.

Alternatively, subscribe to cron.tick or a custom event name — the automation addon uses the same bus.

Declarative server actions

Define sys.server.action rows in data XML with declarative code (no Go required for simple flows):

  • publish: — chain a follow-up event
  • write: — write fields on the triggering record

See Events & automation for XML examples.

HTTP routes

router.Register(http.MethodGet, "/account/invoice/print", router.AuthSession, handler)

See Custom HTTP route.

Service layer

Keep heavy logic in services/ packages:

  • account/services/invoice.go — create/post moves
  • account/services/payment.go — payments
  • account/services/reconcile.go — reconciliation

Export functions like CreateCustomerInvoiceFromSale for custom addons to call.

See also