Skip to content

feat: add support for UUIDv7 generation and update command options to use UUIDv7 - #22

Merged
yordis merged 1 commit into
mainfrom
feat/use-uuidv7
Sep 13, 2025
Merged

yordis merged 1 commit into
mainfrom
feat/use-uuidv7

Conversation

@yordis

@yordis yordis commented Sep 13, 2025

Copy link
Copy Markdown
Member

No description provided.

@coderabbitai

coderabbitai Bot commented Sep 13, 2025 •

Copy link
Copy Markdown

Walkthrough

Replaces default UUID generation from uuid4 to uuid7 across command dispatch and in-memory event storage. Adds Commanded.UUID.uuid7/0 delegating to the configured UUID provider. Updates documentation examples to reference uuid7. No public signatures changed; behavior updates are default-value substitutions.

Changes

Cohort / File(s) Summary
Router dispatch defaults
lib/commanded/commands/router.ex
Switched default generators for command_uuid and correlation_id from UUID.uuid4/0 to UUID.uuid7/0 in runtime and macro-generated dispatch paths.
Event mapper docs
lib/commanded/event/mapper.ex
Updated doc example to use Commanded.UUID.uuid7() for causation_id and correlation_id; no code changes.
In-memory event store defaults
lib/commanded/event_store/adapters/in_memory.ex
Changed fallback event_id generator to UUID.uuid7/0 when not provided; logic unchanged otherwise.
UUID API extension
lib/commanded/uuid.ex
Added public uuid7/0 delegating to configured UUID module; existing uuid4/0 unchanged.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor C as Client
  participant R as Router
  participant U as Commanded.UUID
  participant P as UUID Provider
  participant H as Handler/Aggregate
  participant ES as Event Store (InMemory)

  C->>R: dispatch(command)
  R->>U: uuid7() for command_uuid
  U->>P: uuid7()
  P-->>U: time-ordered UUID
  U-->>R: uuid7
  R->>U: uuid7() for correlation_id
  U->>P: uuid7()
  P-->>U: time-ordered UUID
  U-->>R: uuid7
  R->>H: execute(command, ids)
  H-->>ES: append(event[, event_id?])
  alt event_id not provided
    ES->>U: uuid7() fallback
    U->>P: uuid7()
    P-->>U: time-ordered UUID
    U-->>ES: uuid7
  end
  ES-->>C: ack
Loading
sequenceDiagram
  autonumber
  participant App as Application Code
  participant U as Commanded.UUID
  participant P as UUID Provider (config)

  App->>U: uuid7()
  U->>P: delegate uuid7()
  P-->>U: uuid7 value
  U-->>App: uuid7 value
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I thump the ground—tick, tock, seven!
Time-sorted snowflakes from UUID heaven.
Commands hop swift, events align,
A tidy burrow in ordered time.
With whiskers twitch and ears held high,
I stamp “uuid7” and bound on by. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description Check ❓ Inconclusive I cannot assess the PR description because no pull request description was provided in the input, so its relevance to the changeset cannot be determined. Please add a short PR description that states the intent (introduce uuid7/0, switch defaults to UUIDv7), lists affected areas (router, in-memory event store, Commanded.UUID), and notes any migration or compatibility considerations so the description clearly matches the changeset.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title accurately summarizes the primary change: adding UUIDv7 support and switching defaults to UUIDv7 for command-related IDs, which matches the added Commanded.UUID.uuid7/0 and the replaced uuid4 usages in the router, docs, and in-memory event store described in the change summary.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/use-uuidv7

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yordis
yordis marked this pull request as ready for review September 13, 2025 05:36
… use UUIDv7

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis
yordis merged commit bb29716 into main Sep 13, 2025
3 of 4 checks passed
@yordis
yordis deleted the feat/use-uuidv7 branch September 13, 2025 05:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eab7e73 and 1297471.

📒 Files selected for processing (4)
  • lib/commanded/commands/router.ex (1 hunks)
  • lib/commanded/event/mapper.ex (1 hunks)
  • lib/commanded/event_store/adapters/in_memory.ex (1 hunks)
  • lib/commanded/uuid.ex (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Quality Assurance (1.18.x, 27)
🔇 Additional comments (3)
lib/commanded/event/mapper.ex (1)

40-41: Docs: switch to UUIDv7 in examples looks good.

Keeps examples aligned with the new defaults.

lib/commanded/event_store/adapters/in_memory.ex (1)

455-455: Default event_id uses UUIDv7 — ensure custom providers implement uuid7/0 or add fallback

event_id: event_id || UUID.uuid7() — lib/commanded/event_store/adapters/in_memory.ex:455.

The provided rg search returned no matches; absence of matches is not conclusive.

Confirm whether any apps configure a custom Commanded.UUID provider. Custom providers must implement uuid7/0; otherwise add a safe fallback in lib/commanded/uuid.ex.

lib/commanded/commands/router.ex (1)

528-530: Switching defaults to UUIDv7 for command_uuid and correlation_id — LGTM.

The Keyword.get_lazy/3 usage with &UUID.uuid7/0 is correct and aligns with the new API.

Comment thread lib/commanded/uuid.ex
Comment on lines +20 to 24
@doc """
Generates a UUIDv7 using the configured provider (defaults to `Uniq.UUID`).
"""
defdelegate uuid7, to: @uuid_mod
end

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Prevent runtime breakages with custom providers: add uuid7/0 fallback (or update docs and enforce).

Today uuid7/0 is a direct delegate; if a custom provider lacks uuid7/0, calls from the router/in-memory adapter will crash. Suggest a backward-compatible fallback to uuid4/0 when uuid7/0 isn’t exported.

Apply this change:

-  @doc """
-  Generates a UUIDv7 using the configured provider (defaults to `Uniq.UUID`).
-  """
-  defdelegate uuid7, to: @uuid_mod
+  @doc """
+  Generates a UUIDv7 using the configured provider (defaults to `Uniq.UUID`).
+  Falls back to `uuid4/0` if the configured provider does not implement `uuid7/0`.
+  """
+  def uuid7 do
+    if function_exported?(@uuid_mod, :uuid7, 0) do
+      @uuid_mod.uuid7()
+    else
+      @uuid_mod.uuid4()
+    end
+  end

Additionally, the moduledoc still states “Your custom module must provide a uuid4/0 function.” Please update it to reflect uuid7/0 usage or the fallback, e.g.:

@moduledoc """
Configurable UUID generation...

By default uses `Uniq.UUID` (supports uuid1/3/4/5, v6, and v7).

config :commanded, Commanded.UUID, module: MyApp.CustomUUID

Your custom module must provide `uuid4/0`. If it also provides `uuid7/0`,
Commanded will use it; otherwise `uuid7/0` falls back to `uuid4/0`.
"""

Note: The default provider Uniq.UUID already supports uuid7/0. (github.com)

If you prefer strictness over fallback, we can instead keep the delegate and raise early with a clear error if uuid7/0 is missing. Want a patch for that path instead?


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- file: lib/commanded/uuid.ex (if present) ----"
if [ -f lib/commanded/uuid.ex ]; then
  sed -n '1,240p' lib/commanded/uuid.ex
else
  echo "lib/commanded/uuid.ex not found"
fi

echo
echo "---- search: occurrences of 'uuid7' ----"
rg -n --hidden --no-ignore -S '\buuid7\b' || true

echo
echo "---- search: defdelegate uuid7 ----"
rg -n --hidden --no-ignore -S 'defdelegate\s+uuid7' || true

echo
echo "---- search: '@moduledoc' and look for 'uuid4' text ----"
rg -n --hidden --no-ignore -S '@moduledoc' lib/commanded/uuid.ex || true
rg -n --hidden --no-ignore -S 'Your custom module must provide' || true
rg -n --hidden --no-ignore -S 'uuid4/0' || true

Length of output: 1887


Prevent runtime breakages with custom providers: add uuid7/0 fallback (or update docs and enforce).

defdelegate uuid7/0 currently delegates directly; if a configured provider doesn't export uuid7/0, callers will crash at runtime (seen in lib/commanded/event/mapper.ex, lib/commanded/commands/router.ex, lib/commanded/event_store/adapters/in_memory.ex). Replace the delegate with a safe fallback and update docs.

Apply this change to lib/commanded/uuid.ex:

-  @doc """
-  Generates a UUIDv7 using the configured provider (defaults to `Uniq.UUID`).
-  """
-  defdelegate uuid7, to: @uuid_mod
+  @doc """
+  Generates a UUIDv7 using the configured provider (defaults to `Uniq.UUID`).
+  Falls back to `uuid4/0` if the configured provider does not implement `uuid7/0`.
+  """
+  def uuid7 do
+    if function_exported?(@uuid_mod, :uuid7, 0) do
+      @uuid_mod.uuid7()
+    else
+      @uuid_mod.uuid4()
+    end
+  end

Also update the moduledoc and guides (lib/commanded/uuid.ex @moduledoc and guides/explanations/commands.md) to reflect the fallback, e.g.:

@moduledoc """
Configurable UUID generation...

By default uses `Uniq.UUID` (supports uuid1/3/4/5, v6, and v7).

config :commanded, Commanded.UUID, module: MyApp.CustomUUID

Your custom module must provide `uuid4/0`. If it also provides `uuid7/0`,
Commanded will use it; otherwise `uuid7/0` falls back to `uuid4/0`.
"""

If you prefer strictness instead of a fallback, keep the delegate and raise early with a clear error — I can provide that patch.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant