-
-
Notifications
You must be signed in to change notification settings - Fork 10
feat(Decider): add deterministic UUID generation (UUID v5) to Decision monad #596
Description
Summary
The Decision monad currently supports random UUID generation via generateUuid (which uses UUID v4 internally). There are use cases where a deterministic UUID derived from a known input (e.g., a text identifier from an external system) is needed within the decide function.
Use Case
When a command needs to derive an entity ID from an external identifier (e.g., a string-based user ID from an OAuth provider), there's currently no way to produce a stable, deterministic UUID from that input within the Decision monad. The only option is generateUuid, which produces a random UUID each time.
Proposed API
Add a generateDeterministicUuid (or uuidFromText) function to the Decider module:
-- | Generate a deterministic UUID (v5) from a namespace and a name.
-- Same inputs always produce the same UUID.
generateDeterministicUuid :: Uuid -> Text -> Decision UuidOr a simpler variant with a default namespace:
-- | Generate a deterministic UUID from a text value.
-- Same input always produces the same UUID.
uuidFromText :: Text -> Decision UuidThis could be implemented using UUID v5 (SHA-1 based, RFC 4122) from the uuid package, which already provides Data.UUID.V5.generateNamed.
Alternatives Considered
- Hashing outside the Decision monad: Not possible since
decideis pure andgetEntityIdonly has access to command fields. - Requiring the caller to pre-compute the UUID: Pushes the problem to the caller, who may also lack UUID v5 support in the framework.
- Adding the function to the
Uuidmodule instead: AUuid.fromNamespace :: Uuid -> Text -> Uuidpure function would also solve this, and wouldn't need to be in the Decision monad at all since UUID v5 is deterministic and pure.
Notes
The uuid package (already a dependency via Data.UUID and Data.UUID.V4) includes Data.UUID.V5 which provides the necessary generateNamed function, so no new dependencies would be needed.