Skip to content

fix(types): strengthen dispatch struct contracts for Dialyzer - #76

Merged
yordis merged 1 commit into
mainfrom
yordis/fix-dispatch-typed-structs
Apr 15, 2026
Merged

yordis merged 1 commit into
mainfrom
yordis/fix-dispatch-typed-structs

Conversation

@yordis

@yordis yordis commented Apr 15, 2026

Copy link
Copy Markdown
Member
  • Makes more of the dispatch pipeline visible to static analysis so contract drift is caught earlier without adding more runtime checks
  • Aligns the typed dispatch surface with real usage, including named application atoms and the middleware pipeline struct shape

@cursor

cursor Bot commented Apr 15, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Primarily type/spec changes with no intended behavior changes; small risk that @enforce_keys or widened application types expose previously hidden mismatches in downstream code at compile/runtime.

Overview
Improves static typing for command dispatch by introducing Commanded.Application.app_ref() (module or named atom) and using it across router dispatch options and middleware/pipeline structs.

Strengthens the dispatch surface for Dialyzer by fully specifying Commanded.Commands.Dispatcher.Payload.t(), adding @enforce_keys for required dispatch fields, and formalizing Commanded.Middleware.Pipeline.t()/Commanded.Middleware callback types.

Reviewed by Cursor Bugbot for commit 08ee8a9. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Apr 15, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bae75290-431f-4307-8486-aafbce8d79d0

📥 Commits

Reviewing files that changed from the base of the PR and between c8a381c and 08ee8a9.

📒 Files selected for processing (5)
  • lib/application.ex
  • lib/commanded/commands/dispatcher.ex
  • lib/commanded/commands/router.ex
  • lib/commanded/middleware/middleware.ex
  • lib/commanded/middleware/pipeline.ex
✅ Files skipped from review due to trivial changes (4)
  • lib/application.ex
  • lib/commanded/middleware/middleware.ex
  • lib/commanded/commands/router.ex
  • lib/commanded/middleware/pipeline.ex

Walkthrough

This PR tightens and expands type specifications: Payload.t and Pipeline.t are now explicit struct types with concrete field types; Commanded.Application gained an app_ref alias; dispatch_option for :application now uses app_ref() and middleware pipeline type refs were normalized.

Changes

Cohort / File(s) Summary
Command Dispatch Types
lib/commanded/commands/dispatcher.ex, lib/commanded/commands/router.ex
Converted Payload.t from opaque %Payload{} to an explicit %Commanded.Commands.Dispatcher.Payload{...} with enforced keys and concrete field types; changed dispatch_option :application type from Commanded.Application.t() to Commanded.Application.app_ref().
Middleware Pipeline Types
lib/commanded/middleware/middleware.ex, lib/commanded/middleware/pipeline.ex
Replaced pipeline type alias from concrete %Pipeline{} to Pipeline.t() and added a public @type t :: %Commanded.Middleware.Pipeline{...} describing pipeline struct fields and their types.
Application Type Alias
lib/application.ex
Added `@type app_ref :: t

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐇 I hopped through types with joy and glee,

Fields uncovered for all to see.
From opaque burrows to structured light,
Payloads and Pipelines feel just right.
Tiny changes — clearer sight! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: improving type safety for dispatch structs by making contracts visible to Dialyzer, which matches the substantial type annotation updates across multiple files.
Description check ✅ Passed The description is directly related to the changeset, explaining the intent to improve static analysis visibility and align typed dispatch surface with real usage, which aligns with the type specification enhancements made.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yordis/fix-dispatch-typed-structs

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.

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/commanded/commands/dispatcher.ex`:
- Around line 14-33: The Payload type declares many fields as required (non-nil)
but defstruct allows them to be nil; add an `@enforce_keys` attribute for the
non-nil fields so the struct cannot be created without them. Update the module
that defines %__MODULE__{} (the Payload struct) to include something like
`@enforce_keys` [:application, :command, :command_uuid, :consistency,
:handler_module, :handler_function, :aggregate_module, :identity, :timeout,
:lifespan, :metadata, :returning, :middleware] (omitting fields intentionally
allowed to be nil such as :causation_id, :correlation_id,
:handler_before_execute, :identity_prefix, :retry_attempts), and keep the
existing defstruct unchanged so construction matches the `@type` t/0 guarantees.

In `@lib/commanded/middleware/pipeline.ex`:
- Around line 43-56: The declared type t for module Pipeline lists fields
(application, command, command_uuid, consistency, identity, metadata, etc.) as
non-nil but defstruct provides no defaults so those become nil when not
supplied; either add `@enforce_keys` [:application, :command, :command_uuid,
:consistency, :identity, :metadata] above defstruct to require those fields at
construction (ensuring callers pass them) or update the `@type` t to allow nil for
those specific fields; modify the Pipeline module’s defstruct/@type accordingly
and keep symbols application, command, command_uuid, consistency, identity,
metadata, `@type` t, and defstruct consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4bf7723f-8bd9-4601-ad93-9fa07fe25e77

📥 Commits

Reviewing files that changed from the base of the PR and between 195a12b and c8a381c.

📒 Files selected for processing (4)
  • lib/commanded/commands/dispatcher.ex
  • lib/commanded/commands/router.ex
  • lib/commanded/middleware/middleware.ex
  • lib/commanded/middleware/pipeline.ex

Comment thread lib/commanded/commands/dispatcher.ex Resolved
Comment thread lib/commanded/middleware/pipeline.ex Resolved
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis
yordis force-pushed the yordis/fix-dispatch-typed-structs branch from 0f8c570 to 08ee8a9 Compare April 15, 2026 01:26
@yordis
yordis merged commit c677d4c into main Apr 15, 2026
5 checks passed
@yordis
yordis deleted the yordis/fix-dispatch-typed-structs branch April 15, 2026 01:31
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