Work Schedule automation for C#
Work Schedule exposes a supported C# surface for trusted business logic in the
workspace Net Operation Project. Prefer
IWorkScheduleAutomationQueryService and
IWorkScheduleAutomationCommandService: they enter the host application
boundary, apply module readiness and resource checks, preserve audit
attribution, and return typed MoltaroRuntimeResult<T> results.
This release does not add a public Work Schedule REST API. It also does not cover shifts, crews, attendance, payroll, capacity planning, module lifecycle administration, security-role association, or Worker-to-user association.
Choose the supported surface
Section titled “Choose the supported surface”The installation-local developer-surface catalog marks the two automation
interfaces as ApplicationAutomation and Preferred: true. They are supported
from Action, TriggerHandler, Command, Job, and HttpEndpoint functions.
Validation and BeforeSaveMutation cannot call application automation.
The lower-level calendar, assignment, exception, and effective-schedule
services under Moltaro.Package.NET.WorkSchedule.Runtime are
TrustedDirectDb and Preferred: false. Use them only for advanced code that
deliberately owns its database transaction, authorization, audit provenance,
and application orchestration. A direct-DB call is not a substitute for the
preferred facade.
Query an effective schedule
Section titled “Query an effective schedule”Inject the query service and pass a bounded local-date range plus the exact Workers or Sites to resolve:
using Moltaro.Package.NET.WorkSchedule.Automation;using Moltaro.Package.NET.WorkSchedule.Runtime;
public sealed class ScheduleReader(IWorkScheduleAutomationQueryService schedules){ public async Task<WorkScheduleAutomationEffectiveSchedule> ReadAsync( string workerId, CancellationToken cancellationToken) { var result = await schedules.QueryEffectiveScheduleAsync( new WorkScheduleEffectiveScheduleRequest( new DateOnly(2026, 10, 26), new DateOnly(2026, 11, 1), [workerId], [], new TimeOnly(9, 0)), cancellationToken);
result.ThrowIfFailed(); return result.Data!; }}Use LookupEffectiveResourcesAsync before an interactive or agent-selected
query. It returns only field-safe resources available through the application
boundary. Do not invent Worker or Site identifiers from database knowledge.
The effective result combines immutable published calendar revisions, effective-dated Site and Worker assignments, inheritance, and active exceptions. Exception scope precedence is Worker, then Site, then Workspace; Remove wins over Add at equal scope, followed by the narrower interval and the newest evidence. Operational Location supplies civil time and is not an exception scope. Authority tier is server-derived provenance and does not participate in precedence.
Calendar lifecycle
Section titled “Calendar lifecycle”Calendar commands follow a draft/publish lifecycle:
- Create or read a calendar and retain its
RowVersion. - Start one Draft, optionally from an explicit published source.
- Replace the complete Draft pattern with local wall-clock intervals.
- Publish the Draft. The published revision is immutable.
- Start another Draft for a later correction, or cancel only a future published revision when the returned actions allow it.
Every command request carries an OperationId. Generate one stable
caller-owned value for a logical command and preserve it only for an exact
retry after an unknown outcome. Reusing it with changed payload conflicts.
Mutation results expose Replayed and the current RowVersion.
var created = await commands.CreateCalendarAsync( new CreateWorkScheduleAutomationCalendarRequest( "weekday-office", "Weekday office", "Standard office pattern", Guid.NewGuid().ToString("D")), cancellationToken);
created.ThrowIfFailed();Send the last returned RowVersion as ExpectedRowVersion for calendar metadata, draft, and
publish mutations. A stale version fails rather than overwriting concurrent
work.
Assignments and inheritance
Section titled “Assignments and inheritance”Site assignments select an enabled calendar. Worker assignments select a Site
and may either select a personal calendar or inherit the Site calendar. Each
subject has an append-only effective-dated chain. Read the chain first, retain
its ChainVersion, and send that value for change or end operations.
Use create only for the first row. Use change to append a new effective-dated
state or to record an explicit correction. Use end to create a deliberate gap;
do not delete history. LookupWorkerSitesAsync is the field-safe target lookup
for Worker assignment authoring.
Exceptions
Section titled “Exceptions”Exceptions add or remove bounded working time at Workspace, Site, or Worker scope. Creation records immutable evidence. Correction appends a complete replacement, and cancellation appends terminal evidence; neither rewrites the previous entries.
Requests accept the effect, scope, local boundaries, reason, and operation id.
They never accept ActorUserId or an authority tier. The host derives actor,
origin, and provenance. Read the chain and send its ExpectedChainVersion
before correction or cancellation.
Time zones and DST
Section titled “Time zones and DST”Author calendar and exception boundaries in local civil time. Site and Worker resolution obtains its IANA time-zone context through the effective Operational Location relationship. Results retain both local and UTC boundaries and report DST adjustment or ambiguity diagnostics. Do not pre-convert authored local boundaries to UTC or treat a numeric offset as the time-zone identity.
Authorization and trusted automation
Section titled “Authorization and trusted automation”Ordinary product users continue through scoped Work Schedule authorization;
the facade does not weaken those UI or application-service paths. Net Operation
Project application automation enters an explicit host-owned boundary as
moltaro-system-automation. The reserved actor string alone grants no access,
and public requests cannot select it.
Trusted automation bypasses end-user Work Schedule permission statements only inside that host boundary. It still fails closed when the module is disabled or not ready, a resource is absent, a business invariant fails, the operation is invalid, an idempotency key is reused incorrectly, or a row/chain version is stale. Audit and origin metadata retain the function, run, correlation, and original-user facts supplied by the host.
For exact symbols and return records, use the Work Schedule XML reference and the installation’s developer-surface catalog.