The .NET client gained an ergonomic wrapper over the low-level pattern query, and the other clients should offer the same capability in their own idiom.
What it is
Behavior patterns are queried with a facet set — a partial context of Day, TimeBucket, CommandType, AggregateType and so on. That is the right primitive, but it is not the question an application actually has. The question is what does this person normally do at this point in the week?
So on top of it:
// Right now
var patterns = await eventStore.Patterns.GetPatternsAt(userId);
// A given moment
var patterns = await eventStore.Patterns.GetPatternsAt(userId, tomorrowMorning);
// Narrower than a moment
var patterns = await eventStore.Patterns.GetPatternsAt(
userId,
alsoConstraining: FacetSet.Empty.With(FacetName.AggregateType, "Invoice"));
The contract, which every client should keep:
- Scope is required — normally the user.
- The moment is optional and defaults to now. That default is the whole point; the common call is one argument.
Day and TimeBucket are derived from the moment, and the caller never passes them.
- Further facets can be added, so asking about a moment and asking about a command are the same call rather than two competing ones.
- The low-level facet-set query stays — this is a wrapper, not a replacement.
The part that actually matters
The time bucket must be derived with the same rule the engine mined with. In .NET that rule now lives on the concept (DateTimeOffset.ToTimeBucket()) rather than inside the kernel, precisely so the client and the engine share one copy of it, and the client exposes it so applications never write their own.
Get this wrong and nothing fails loudly. The query asks about a slot the mining never used and comes back empty, which is indistinguishable from "this person has no established behavior" — the one answer the API is supposed to be trustworthy about.
The buckets, from the event's own offset rather than UTC (somebody who works at nine does so at nine in their morning):
| Hours |
Bucket |
| 05:00–08:00 |
EarlyMorning |
| 08:00–11:00 |
Morning |
| 11:00–14:00 |
Midday |
| 14:00–17:00 |
Afternoon |
| 17:00–22:00 |
Evening |
| 22:00–05:00 |
Night |
Day is the day of week of the moment, again read from its own offset.
References
- Reference documentation:
Documentation/patterns/index.md in Cratis/Chronicle, section "Asking about a moment" — the client-neutral contract, with a table each client adds a row to.
- .NET implementation:
Source/Clients/DotNET/Patterns/Patterns.cs and IPatterns.cs.
- Shared rule:
Source/Kernel/Concepts/Patterns/TimeBucketExtensions.cs.
- No gRPC contract change is involved — this builds the facet set client-side and calls the existing
GetPatterns.
The .NET client gained an ergonomic wrapper over the low-level pattern query, and the other clients should offer the same capability in their own idiom.
What it is
Behavior patterns are queried with a facet set — a partial context of
Day,TimeBucket,CommandType,AggregateTypeand so on. That is the right primitive, but it is not the question an application actually has. The question is what does this person normally do at this point in the week?So on top of it:
The contract, which every client should keep:
DayandTimeBucketare derived from the moment, and the caller never passes them.The part that actually matters
The time bucket must be derived with the same rule the engine mined with. In .NET that rule now lives on the concept (
DateTimeOffset.ToTimeBucket()) rather than inside the kernel, precisely so the client and the engine share one copy of it, and the client exposes it so applications never write their own.Get this wrong and nothing fails loudly. The query asks about a slot the mining never used and comes back empty, which is indistinguishable from "this person has no established behavior" — the one answer the API is supposed to be trustworthy about.
The buckets, from the event's own offset rather than UTC (somebody who works at nine does so at nine in their morning):
EarlyMorningMorningMiddayAfternoonEveningNightDayis the day of week of the moment, again read from its own offset.References
Documentation/patterns/index.mdin Cratis/Chronicle, section "Asking about a moment" — the client-neutral contract, with a table each client adds a row to.Source/Clients/DotNET/Patterns/Patterns.csandIPatterns.cs.Source/Kernel/Concepts/Patterns/TimeBucketExtensions.cs.GetPatterns.