← Back to Activities Workflows

5.6.1 Activities Architecture

ActivitiesPlugin implements KMPPluginInterface and KMPApiPluginInterface. It owns /activities web routes and registers the member-authorizations API v1 route. app/config/plugins.php configures migration order 1; the plugin class fallback is 0.

Plugin initialization

bootstrap() registers:

routes() installs compatibility redirects to unified /approvals, the /activities web scope, and fallback plugin routes. registerApiRoutes() adds the member-authorizations API v1 route.

Service registration

services() registers:

Workflow metadata is supplied by ActivitiesWorkflowProvider, ActivitiesWorkflowActions, and ActivitiesWorkflowConditions. Current first-party providers are invoked by core WorkflowPluginLoader; keep provider registration and definition seeds aligned.

Code ownership

app/plugins/Activities/
├── config/Migrations/              # tenant schema
├── src/Controller/                 # web and API request coordination
├── src/Model/{Entity,Table}/       # activities/groups/authorizations
├── src/Policy/                     # entity, table, and reports policies
├── src/Services/                   # managers, workflows, UI providers
├── src/KMP/GridColumns/            # Dataverse definitions
├── src/View/Cell/                   # member/permission integrations
├── templates/                      # plugin views
└── tests/TestCase/                 # plugin tests

Boundary rules

Authorization identity and failures

Activation and denial resolve the workflow’s persisted entity_id first, then context.trigger.authorizationId, then the configured action parameter for older or custom definitions. Persisted workflow references must have the Activities.Authorizations entity type. Conflicting entity and trigger IDs fail before changing an authorization. Missing or invalid IDs never become ID zero.

Request creation returns the ID of the record it actually inserted. Creation, activation, and denial failures stop workflow execution before subsequent notifications or completion. A workflow approval decision and authorization activation remain distinct steps; completion must not hide a failed activation.

Legacy workflows that started at the approval gate may lack nodes.validate-request.result.authorizationId. The 1.5.10 resolver accepts their canonical references without requiring that synthetic node result. A separately reviewed SQL repair can populate that compatibility field for installations still running 1.5.9 and reconcile previously failed activations. See the operator repair runbook.

Multi-tenant behavior

Migrations, settings, records, cached permission lookups, workflow instances, and mail are tenant-local. A background expiration/notification job must enter a tenant context before resolving the Activities tables. There is no tenant_id column inside plugin tables.

Verification

Run vendor/bin/phpunit plugins/Activities/tests/TestCase, plus targeted workflow and API tests. Changed plugin PHP should pass PHPCS. UI/controller changes should cover keyboard/focus/status behavior and use npm run test:js; run npm run dev if imports change.