all the refactor
Build and Publish / BuildAndDeployAmd64 (push) Failing after 5s
Build and Publish / BuildAndDeployArm64 (push) Failing after 6s

This commit is contained in:
2026-06-28 17:51:52 +02:00
parent 7db0d236c7
commit aa8b2bdedc
84 changed files with 4328 additions and 2344 deletions
+16 -2
View File
@@ -99,6 +99,21 @@ type RegisteredMutation[V any, T proto.Message] struct {
msgType reflect.Type
}
// NewMutation registers a typed mutation handler for state V and message T.
//
// T MUST be a pointer to a generated proto message (e.g. *cart.AddLineRequest).
// Passing a non-pointer (e.g. cart.AddLineRequest) is a developer error caught
// at registration time — the type system on its own cannot tell a proto
// message from a struct, so we surface the violation here. The convention is
// the same as the broader Go MustX pattern (e.g. regexp.MustCompile): failures
// here mean the caller is misusing the API at startup, so we panic rather than
// silently storing an unusable handler.
//
// This is INTENTIONALLY not converted to a returned error: there is no
// composition-root decision to make — the program is wrong and must not boot.
// The composer-side registration code (see e.g. cart.NewCartMultationRegistry)
// runs in package init / function init contexts where returning an error is
// not possible.
func NewMutation[V any, T proto.Message](handler func(*V, T) error) *RegisteredMutation[V, T] {
// Derive the name and message type from a concrete instance produced by create().
// This avoids relying on reflect.TypeFor (which can yield unexpected results in some toolchains)
@@ -109,8 +124,7 @@ func NewMutation[V any, T proto.Message](handler func(*V, T) error) *RegisteredM
if rt != nil && rt.Kind() == reflect.Pointer {
return reflect.New(rt.Elem()).Interface().(proto.Message)
}
log.Fatalf("expected to create proto message got %+v", rt)
return nil
panic(fmt.Sprintf("NewMutation: T must be a pointer to a proto message, got %v", rt))
}
instance := create()
rt := reflect.TypeOf(instance)