Skip to content

Add an ergonomic 'patterns at a moment' query over the facet-set API #21

Description

@einari

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 nowvarpatterns=awaiteventStore.Patterns.GetPatternsAt(userId);// A given momentvarpatterns=awaiteventStore.Patterns.GetPatternsAt(userId,tomorrowMorning);// Narrower than a momentvarpatterns=awaiteventStore.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):

HoursBucket
05:00–08:00EarlyMorning
08:00–11:00Morning
11:00–14:00Midday
14:00–17:00Afternoon
17:00–22:00Evening
22:00–05:00Night

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions