← Model behaviors

Active-window status synchronization

sync_active_window_statuses reconciles denormalized status fields for tenant entities based on their start_on/expires_on window. In the managed platform, run it through the allowlisted active-window-sync platform schedule so each active tenant receives an isolated datasource and table locator.

Current execution model

The seeded platform schedule is named active-window-sync and is due every 15 minutes. The unified platform worker claims due schedules; the schedule runner iterates active tenants in slug order, enters TenantConnectionManager scope, executes the command, records a platform job, then cleans up before the next tenant.

To invoke the managed fan-out intentionally:

bin/cake platform schedule run active-window-sync

Do not call the tenant command once against an arbitrary default datasource and assume the fleet was processed.

Workflow-first behavior

For a normal (non-dry-run) execution, the command first looks for an active active-window-sync workflow definition in the current tenant. If found, it dispatches ActiveWindow.SyncTriggered for each Kingdom branch in that tenant (or once with a null kingdom when none exists).

If no active definition exists or dispatch fails, it runs the legacy reconciliation logic. A dispatch failure is logged and reported before fallback. The legacy path remains a compatibility mechanism; new transition orchestration belongs in the workflow definition/provider.

Legacy transitions

The fallback discovers core and loaded-plugin tables whose entity extends ActiveWindowBaseEntity and whose schema has a status column. In a transaction per table it changes:

When a table has modified_by, the fallback assigns the system member ID 1. It saves without validation/build-rule checks, so eligibility must remain encoded in the discovery and transition contract.

This status reconciliation boundary is not identical to the ActiveWindowBehavior::find('current') filter at the exact expiration instant: the finder uses expires_on >= effective, while synchronization expires at expires_on <= now. Code that depends on that instant must supply and test an explicit effective time rather than mixing finder and status assumptions.

Dry run

bin/cake sync_active_window_statuses --dry-run

Dry-run bypasses workflow dispatch and previews the legacy changes without saving. Run this only when the CLI process is already connected to the intended single tenant (for example the local primary tenant). The command itself does not accept a tenant selector. Fleet-safe selection belongs to the platform schedule runner.

Monitoring and failure handling

Review:

One tenant failure is recorded centrally and must not contaminate the next scope. Do not “repair” statuses in the platform database; all affected records are tenant-owned.

Development and testing

When adding an ActiveWindowBaseEntity subclass:

  1. include compatible status, start_on, and nullable expires_on fields;
  2. use the established status constants;
  3. decide whether automatic discovery is intended;
  4. add exact-boundary and dry-run tests;
  5. test it through two sequential tenant scopes; and
  6. update the workflow provider if transitions require domain side effects.

Relevant sources: