# Resource lifecycle

Run focused behavior around resource changes.

Nimbly uses `.meta` event declarations for resource lifecycle side effects. A resource can declare what should happen after a record is created, updated, or deleted:

```json
{
  "events": {
    "create": ["job:application-email-created"],
    "update": ["application-updated"],
    "delete": ["application-deleted"]
  }
}
```

Event payloads are intentionally small:

```php
[
    'action' => 'create',
    'resource' => 'membership-applications',
    'uuid' => 'record-uuid',
    'data' => $record_data, // available for create/update/delete when already loaded
]
```

Plain event names are dispatched to module libraries by convention:

```text
ext/modules/member/lib/application-updated.php
function application_updated($event) {}
```

Entries prefixed with `job:` enqueue a `.jobs` record instead of running work inline:

```json
"events": {
  "create": ["job:application-email-created"]
}
```

Core setup creates the `.jobs` resource. `job_enqueue()` also creates it lazily if an older install does not have it yet.

Run queued jobs from CLI:

```bash
php core/cli/nimbly.php jobs:run
```

By default, `jobs:run` processes one eligible job. Pass an explicit limit only for catch-up runs:

```bash
php core/cli/nimbly.php jobs:run 25
```

Job handlers are module-discovered by convention:

```text
ext/modules/member/lib/application-email-created.php
function application_email_created_job($job) {}
```

The queue stores intent and payload, not shell commands. Handlers may send email, call APIs, or perform other side effects.
