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

Events & automation

record.created / updated, cron.tick, listeners and automation addon status.

In-process bus

sumeru/core/event is a synchronous publish/subscribe bus in the server process. Not an external broker.

Subscribe example
go
package my_module import (	"context" 	"sumeru/core/event") func init() {	event.Subscribe("record.created", onCreated)} func onCreated(ctx context.Context, ev event.Event) error {	// Payload typically includes model / id after a committed mutation.	_ = ev.Payload	return nil}

Important event names

NameWhen
record.createdAfter a committed create
record.updatedAfter a committed write
cron.tickScheduler fired a due sys.cron row

Automation addon. Kernel automation subscribes to record.created, record.updated, and cron.tick to run matching sys.server.action rows. Declarative code prefixes publish: and write: are executed; unknown prefixes are logged at debug.

Server actions (declarative)

Define actions in data XML — no Go required for simple event chains or field writes:

data/server_actions.xml
xml
<record id="action_followup" model="sys.server.action">    <field name="name">Follow-up event</field>    <field name="event_name">record.updated</field>    <field name="model">crm.lead</field>    <field name="code">publish:crm.lead.followup</field>    <field name="active" eval="True"/></record><record id="action_mark_done" model="sys.server.action">    <field name="name">Mark done</field>    <field name="event_name">crm.lead.followup</field>    <field name="code">write:{"active": false}</field>    <field name="active" eval="True"/></record>

Cron Go handlers

Register a handler keyed by the sys.cron row's code field in addon init.go:

init.go
go
import "sumeru/core/scheduler" func init() {	scheduler.RegisterCronHandler("my_module.nightly_digest", runNightlyDigest)}

The scheduler still publishes cron.tick and any custom event_name on the cron row. There is no Python/safe_eval — Go handlers only. CRM does not seed a sys.cron for lead assignment; use Assign Leads on the team form.

Outbox alignment

ORM mutations publish record.* for data that actually committed (outbox / mutation pipeline). A background drain worker (5s ticker) publishes pending sys.outbox.event rows asynchronously after commit. Do not emit business events for rolled-back work.

Compile and run

Listeners register in init via blank-imports. Restart the server after changing handler code:

Terminal
shell
make generatemake run

What not to do

  • Do not block the bus with long network calls. Keep handlers short or queue work yourself.
  • Do not assume multi-process fan-out; each process has its own bus.
  • Do not rely on event ordering guarantees beyond what the current engine documents.

Next step

Call models over HTTP in JSON-RPC API, or read Event bus.