Skip to content

feat: migrate mail watch to event consume#1650

Open
chumbleyneria wants to merge 7 commits into
larksuite:mainfrom
chumbleyneria:feat/65e307d
Open

feat: migrate mail watch to event consume#1650
chumbleyneria wants to merge 7 commits into
larksuite:mainfrom
chumbleyneria:feat/65e307d

Conversation

@chumbleyneria

@chumbleyneria chumbleyneria commented Jun 29, 2026

Copy link
Copy Markdown

Summary

  • add a Mail EventKey for message received events
  • route mail +watch through the shared event consume runner
  • keep legacy mail +watch output compatibility while enabling event consume usage

Tests

  • go test ./events/mail ./events ./internal/event/consume ./internal/event/consumecli ./cmd/event ./shortcuts/mail

Summary by CodeRabbit

  • New Features
    • Added subscription-aware event identity: new SUB column in consumer status and SUB-KEY in schema output.
    • Added mail.user_mailbox.event.message_received_v1 support and unified mail +watch via the shared event consume flow, including --max-events / --timeout and optional legacy JSON envelope output.
    • Added “did you mean” suggestions for unknown event keys.
  • Bug Fixes
    • Improved cleanup/unsubscribe error handling and ensured event match filtering runs before processing/output.
  • Documentation
    • Updated mail watch docs to recommend the unified event consume workflow and clarify output formatting.
  • Tests
    • Expanded tests for subscription-id wiring, protocol encoding/decoding, envelope output, and mail message processing (including minimal formatting).

@CLAassistant

CLAassistant commented Jun 29, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added domain/mail PR touches the mail domain size/XL Architecture-level or global-impact change labels Jun 29, 2026
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds subscription-scoped identity across the event protocol, bus, and consume flow, extracts the event consume CLI runtime into consumecli, registers the mail message_received event, and refactors mail watch to delegate to the shared runner.

Changes

Subscription-scoped event consume and mail event handler

Layer / File(s) Summary
Core contracts
internal/event/types.go, internal/event/protocol/messages.go, internal/event/protocol/messages_test.go, internal/event/protocol/codec_test.go
ParamDef gains SubscriptionKey; KeyDefinition gains NormalizeParams; PreConsume cleanup returns error; protocol Hello, PreShutdownCheck, and ConsumerInfo carry SubscriptionID.
Subscription ID fingerprinting
internal/event/consume/fingerprint.go, internal/event/consume/fingerprint_test.go
ComputeSubscriptionID hashes only SubscriptionKey params into a deterministic subscription suffix, with tests for stability, format, unicode, and empty values.
Bus and connection subscription scoping
internal/event/bus/hub.go, internal/event/bus/conn.go, internal/event/bus/bus.go, internal/event/bus/conn_test.go, internal/event/bus/hub_test.go, internal/event/bus/handle_hello_test.go, internal/event/bus/hub_observability_test.go, internal/event/bus/hub_publish_race_test.go, internal/event/bus/bus_shutdown_test.go
Conn stores subID; Hub counts and cleans up by SubscriptionID; handleHello derives subID from Hello.SubscriptionID; tests cover the updated registration and consumer metadata behavior.
Consume runtime and output flow
internal/event/consume/consume.go, internal/event/consume/handshake.go, internal/event/consume/loop.go, internal/event/consume/shutdown.go, internal/event/consume/sink.go, internal/event/consume/consume_test.go, internal/event/consume/loop_test.go, internal/event/consume/shutdown_test.go, internal/event/consume/sink_test.go, internal/event/consume/handshake_test.go
Run normalizes params, computes subscriptionID, passes it through hello and shutdown handling, runs Match before Process, and can wrap output in EnvelopeSink; tests cover handshake, shutdown, matching, validation, and envelope output.
Consume CLI runner and helpers
internal/event/consumecli/runner.go, internal/event/consumecli/suggestions.go, internal/event/consumecli/console_url.go, internal/event/consumecli/appmeta_err.go, internal/event/consumecli/sigpipe_unix.go, internal/event/consumecli/sigpipe_windows.go
New package with Options and Run, plus preflight checks, identity resolution, param parsing, output-dir validation, EOF watching, console URL helpers, suggestions, SIGPIPE handling, and app-meta error formatting.
Cleanup error propagation
events/minutes/preconsume.go, events/vc/preconsume.go, events/whiteboard/preconsume.go
Pre-consume cleanup callbacks now return unsubscribe errors instead of discarding them.
Mail message_received event
events/mail/register.go, events/mail/message_received.go, events/mail/message_received_test.go, events/register.go
Registers the mail message_received key and implements mailbox normalization, subscription setup, event matching, message fetch/filter logic, and supporting tests.
Mail watch delegation and display updates
shortcuts/mail/mail_watch.go, shortcuts/mail/mail_watch_test.go, cmd/event/consume.go, cmd/event/status.go, cmd/event/schema.go, cmd/event/schema_test.go, cmd/event/format_helpers_test.go, skills/lark-mail/references/lark-mail-watch.md
Mail watch now delegates to consumecli; status and schema outputs show subscription columns; docs and tests reflect the new runner path and output modes.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as cmd/event consume or mail +watch
  participant Runner as consumecli.Run
  participant Consume as consume.Run
  participant Bus as event bus

  CLI->>Runner: Run(opts)
  Runner->>Runner: NormalizeParams, ComputeSubscriptionID
  Runner->>Runner: Preflight checks
  Runner->>Consume: Run(..., subscriptionID)
  Consume->>Bus: Hello{EventKey, SubscriptionID}
  Bus-->>Consume: HelloAck
  loop events
    Bus-->>Consume: RawEvent
    Consume->>Consume: Match → Process → Sink
  end
  Consume->>Bus: PreShutdownCheck{EventKey, SubscriptionID}
  Bus-->>Consume: PreShutdownAck
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • larksuite/cli#198: Overlaps with the mail watch path in shortcuts/mail/mail_watch.go, which this PR rewires to delegate to consumecli.Run.
  • larksuite/cli#350: Touches the same mail +watch execution path that this PR removes from the shortcut implementation.
  • larksuite/cli#654: Introduces the event consume/bus infrastructure that this PR extends with subscription-scoped identity and runner delegation.

Suggested labels

domain/mail, size/XL

Suggested reviewers

  • haidaodashushu
  • liuxinyanglxy

Poem

🐇 A rabbit taps the keys so light,
SUB and SUB-KEY bloom in sight.
Mail hops through consume, clean and neat,
With tidy scopes and echoed beat.
The bus now knows each hopping name —
Hooray for logs and rabbit fame!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.37% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title concisely and accurately summarizes the main change: routing mail watch through event consume.
Description check ✅ Passed The description covers the change summary and testing, and is mostly complete despite a looser section structure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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

🧹 Nitpick comments (1)
internal/event/protocol/messages_test.go (1)

20-29: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Pin the new SubscriptionID constructor behavior.

Line 20 and Line 29 pass "", so this constructor test won’t catch a future regression where the new parameter is ignored.

Suggested test update
-	if got := NewHello(1, "k", []string{"t"}, "v1", ""); got.Type != MsgTypeHello {
+	if got := NewHello(1, "k", []string{"t"}, "v1", "k:sub"); got.Type != MsgTypeHello || got.SubscriptionID != "k:sub" {
 		t.Errorf("NewHello.Type = %q, want %q", got.Type, MsgTypeHello)
 	}
@@
-	if got := NewPreShutdownCheck("k", ""); got.Type != MsgTypePreShutdownCheck || got.EventKey != "k" {
+	if got := NewPreShutdownCheck("k", "k:sub"); got.Type != MsgTypePreShutdownCheck || got.EventKey != "k" || got.SubscriptionID != "k:sub" {
 		t.Errorf("NewPreShutdownCheck mismatch: %+v", got)
 	}

As per coding guidelines, “Every behavior change needs a test alongside the change.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/event/protocol/messages_test.go` around lines 20 - 29, The
constructor tests for NewHello and NewPreShutdownCheck still pass an empty
SubscriptionID, so they won’t detect regressions where the new parameter is
ignored. Update the assertions in messages_test.go to use a non-empty
SubscriptionID and verify it is preserved on the returned message structs,
alongside the existing checks for Type, FirstForKey, Seq, and EventKey.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@events/mail/message_received_test.go`:
- Around line 125-146: The test name claims to cover the event-format branch,
but `TestProcessOutputDirForcesFullFetchEvenForEventFormat` currently uses
`processMessageReceived` with `msg_format` set to `minimal`, so it does not
exercise the `event` path. Update the test data to use `msg_format: "event"` (or
split this into a separate case) so the assertions verify the special
`watch_output_dir_full` behavior in the actual event-format flow and protect the
`processMessageReceived` branch from regressions.

In `@events/mail/message_received.go`:
- Around line 163-171: Wrap every bare JSON decode failure in
message_received.go with a typed errs problem instead of returning the raw
json.Unmarshal error; update the decode paths in the profile, mailbox/message,
and related response handling code so they use
errs.NewInternalError(errs.SubtypeInvalidResponse, ...).WithCause(err) while
leaving existing typed CallAPI errors unchanged. Use the existing decode points
in message_received.go (for example the response parsing around the profile
fetch and the other listed unmarshal sites) to locate and replace the direct
returns, preserving the underlying cause with .WithCause(err).

In `@events/mail/register.go`:
- Around line 55-70: The mail event registration currently uses a single static
mailScopes list in register.go, which causes consumecli preflight to demand
fetch-only permissions even when processMessageReceived runs in no-fetch mode
for msg_format=event. Update the scope definition around the KeyDefinition in
register.go so preflight can distinguish baseline subscribe scopes from
fetch-only scopes, or make the scope check aware of the requested params by
using normalizeParams/processMessageReceived mode to avoid rejecting
least-privilege runs like mailbox=alice@example.com,msg_format=event.

In `@events/whiteboard/preconsume.go`:
- Around line 42-48: The new cleanup contract in the preconsume unsubscribe path
needs an error-path test. Update the existing test coverage around cleanup() in
preconsume_test to add a case where rt.CallAPI fails for the unsubscribePath and
verify the returned error is preserved unchanged. Assert the typed problem
metadata with errs.ProblemOf, including category, subtype, and param, and also
check the cause is preserved rather than relying on message matching.

In `@internal/event/bus/handle_hello_test.go`:
- Around line 100-105: The HelloAck read in the handleHello tests can block
indefinitely, so add a timeout around the blocking ReadString('\n') call before
waiting on the later select. Update the test logic in the handleHello test
helpers/blocks to set a read deadline on client or perform the read in a
goroutine with timeout protection, so a missing ack fails quickly instead of
hanging. Use the same approach in both test cases that currently read the
HelloAck directly.

In `@internal/event/consume/consume.go`:
- Around line 106-109: The handshake error path in doHello handling currently
wraps everything with fmt.Errorf, which downgrades typed command errors. Update
the error handling in consume/run flow so any already-typed handshake error is
returned unchanged, and only untyped failures are converted using the
appropriate errs.* constructor with .WithCause(err). Keep the change localized
around doHello and the Run boundary so error classification and unwrapping
remain intact.

In `@internal/event/consume/loop.go`:
- Around line 202-205: Populate the full event.RawEvent before hook invocation
in the consume loop so Match and Process can see EventID and SourceTime, not
just EventType and Payload. Update the RawEvent construction in the event
handling path in loop.go to copy the metadata from protocol.Event into
event.RawEvent, and make sure the same change is applied wherever the same
initializer is duplicated. Add a small regression test around the consume
loop/hook path that verifies EventID and SourceTime are preserved and available
to a hook implementation.

In `@internal/event/consume/sink.go`:
- Around line 30-33: The MkdirAll failure path in the output-directory setup is
returning an untyped fmt.Errorf, so callers lose the expected file-I/O error
metadata. Update the opts.OutputDir handling in sink.go to validate the path
first if needed, then wrap vfs.MkdirAll errors with
errs.NewInternalError(errs.SubtypeFileIO, ...) and attach the underlying cause
with .WithCause(err) so the existing error category and unwrap/is behavior are
preserved.

In `@internal/event/consumecli/runner.go`:
- Around line 306-312: The output-dir validation in validate.SafeOutputPath
handling is losing the real path-validation failure by attaching
ErrOutputDirUnsafe as the cause instead of the returned err. Update the error
construction in runner.go so the errs.NewValidationError chain keeps the
sentinel in the message if needed, but calls WithCause(err) to preserve the
concrete rejection reason for errors.Is/errors.Unwrap. Use the existing
validate.SafeOutputPath and WithCause chain as the location to fix.

In `@shortcuts/mail/mail_watch.go`:
- Around line 182-202: The compatibility envelope identity is derived from
runtime.As() while runMailWatchConsume is forced to use core.AsUser, so the two
can diverge. Update the mail_watch flow in the runMailWatchConsume call site to
build consume.OutputEnvelope with the same forced identity used by
IdentityOverride, ensuring Envelope.Identity and the delegated consume identity
stay in sync.
- Around line 24-25: The new `vfs.MkdirAll` usage in `mail_watch.go` violates
the `shortcuts-no-vfs` depguard rule because `shortcuts/` code must not import
`internal/vfs` directly. Remove the `vfs` dependency from `mailWatch`-related
code and route directory creation through the shortcut/runtime file abstraction
used elsewhere in `shortcuts/`, updating any related calls in the referenced
block so the logic stays the same without importing `vfs`.

---

Nitpick comments:
In `@internal/event/protocol/messages_test.go`:
- Around line 20-29: The constructor tests for NewHello and NewPreShutdownCheck
still pass an empty SubscriptionID, so they won’t detect regressions where the
new parameter is ignored. Update the assertions in messages_test.go to use a
non-empty SubscriptionID and verify it is preserved on the returned message
structs, alongside the existing checks for Type, FirstForKey, Seq, and EventKey.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: dddc3ada-1274-4820-90c0-7feab6838087

📥 Commits

Reviewing files that changed from the base of the PR and between 602c788 and 703d7ea.

📒 Files selected for processing (46)
  • cmd/event/consume.go
  • cmd/event/format_helpers_test.go
  • cmd/event/schema.go
  • cmd/event/schema_test.go
  • cmd/event/status.go
  • events/mail/message_received.go
  • events/mail/message_received_test.go
  • events/mail/register.go
  • events/minutes/preconsume.go
  • events/register.go
  • events/vc/preconsume.go
  • events/whiteboard/preconsume.go
  • internal/event/bus/bus.go
  • internal/event/bus/bus_shutdown_test.go
  • internal/event/bus/conn.go
  • internal/event/bus/conn_test.go
  • internal/event/bus/handle_hello_test.go
  • internal/event/bus/hub.go
  • internal/event/bus/hub_observability_test.go
  • internal/event/bus/hub_publish_race_test.go
  • internal/event/bus/hub_test.go
  • internal/event/consume/consume.go
  • internal/event/consume/consume_test.go
  • internal/event/consume/fingerprint.go
  • internal/event/consume/fingerprint_test.go
  • internal/event/consume/handshake.go
  • internal/event/consume/handshake_test.go
  • internal/event/consume/loop.go
  • internal/event/consume/loop_test.go
  • internal/event/consume/shutdown.go
  • internal/event/consume/shutdown_test.go
  • internal/event/consume/sink.go
  • internal/event/consume/sink_test.go
  • internal/event/consumecli/appmeta_err.go
  • internal/event/consumecli/console_url.go
  • internal/event/consumecli/runner.go
  • internal/event/consumecli/sigpipe_unix.go
  • internal/event/consumecli/sigpipe_windows.go
  • internal/event/consumecli/suggestions.go
  • internal/event/protocol/codec_test.go
  • internal/event/protocol/messages.go
  • internal/event/protocol/messages_test.go
  • internal/event/types.go
  • shortcuts/mail/mail_watch.go
  • shortcuts/mail/mail_watch_test.go
  • skills/lark-mail/references/lark-mail-watch.md

Comment thread events/mail/message_received_test.go
Comment thread events/mail/message_received.go Outdated
Comment thread events/mail/register.go
Comment on lines +42 to +48
return func() error {
cleanupCtx, cancel := context.WithTimeout(context.Background(), cleanupTimeout)
defer cancel()
_, _ = rt.CallAPI(cleanupCtx, "POST", unsubscribePath, body)
if _, err := rt.CallAPI(cleanupCtx, "POST", unsubscribePath, body); err != nil {
return err
}
return nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add an unsubscribe failure test for the new cleanup contract.

This change makes cleanup() observable, but the provided downstream test at events/whiteboard/preconsume_test.go:99-144 still only verifies that unsubscribe is called and ignores the returned error. Please add a case where rt.CallAPI fails on the unsubscribe path and assert that cleanup() preserves the typed problem metadata/cause unchanged. As per coding guidelines, "Every behavior change needs a test alongside the change" and "**/*_test.go: Error-path tests must assert typed metadata via errs.ProblemOf (category / subtype / param) and cause preservation, not message substrings alone."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@events/whiteboard/preconsume.go` around lines 42 - 48, The new cleanup
contract in the preconsume unsubscribe path needs an error-path test. Update the
existing test coverage around cleanup() in preconsume_test to add a case where
rt.CallAPI fails for the unsubscribePath and verify the returned error is
preserved unchanged. Assert the typed problem metadata with errs.ProblemOf,
including category, subtype, and param, and also check the cause is preserved
rather than relying on message matching.

Source: Coding guidelines

Comment on lines +100 to +105
// Read the HelloAck from client side to let handleHello complete.
clientReader := bufio.NewReader(client)
ackLine, err := clientReader.ReadString('\n')
if err != nil {
t.Fatalf("failed to read HelloAck: %v", err)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Put a deadline around the HelloAck read.

Both tests call ReadString('\n') before the timeout select, so a regression that stops handleHello from writing the ack will hang the test until the package timeout instead of failing in 3 seconds. Set a read deadline on client (or read in a goroutine with a timeout) before the blocking read.

Suggested fix
+	client.SetReadDeadline(time.Now().Add(3 * time.Second))
 	ackLine, err := clientReader.ReadString('\n')
 	if err != nil {
 		t.Fatalf("failed to read HelloAck: %v", err)
 	}
+	_ = client.SetReadDeadline(time.Time{})

Also applies to: 166-171

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/event/bus/handle_hello_test.go` around lines 100 - 105, The HelloAck
read in the handleHello tests can block indefinitely, so add a timeout around
the blocking ReadString('\n') call before waiting on the later select. Update
the test logic in the handleHello test helpers/blocks to set a read deadline on
client or perform the read in a goroutine with timeout protection, so a missing
ack fails quickly instead of hanging. Use the same approach in both test cases
that currently read the HelloAck directly.

Comment on lines +202 to +205
raw := &event.RawEvent{
EventType: evt.EventType,
Payload: evt.Payload,
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Populate the full RawEvent before invoking hooks.

protocol.Event already has EventID and SourceTime, and event.RawEvent exposes those fields, but this initializer drops them. Any Match or Process implementation that relies on event metadata will see zero values even though the wire message has the data.

🩹 Proposed fix
  raw := &event.RawEvent{
+ 	EventID:    evt.EventID,
  	EventType: evt.EventType,
+ 	SourceTime: evt.SourceTime,
  	Payload:   evt.Payload,
  }

Please add a small regression test for metadata propagation alongside the fix. As per coding guidelines, “Every behavior change needs a test alongside the change.”

Also applies to: 207-210

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/event/consume/loop.go` around lines 202 - 205, Populate the full
event.RawEvent before hook invocation in the consume loop so Match and Process
can see EventID and SourceTime, not just EventType and Payload. Update the
RawEvent construction in the event handling path in loop.go to copy the metadata
from protocol.Event into event.RawEvent, and make sure the same change is
applied wherever the same initializer is duplicated. Add a small regression test
around the consume loop/hook path that verifies EventID and SourceTime are
preserved and available to a hook implementation.

Source: Coding guidelines

Comment thread internal/event/consume/sink.go
Comment thread internal/event/consumecli/runner.go
Comment thread shortcuts/mail/mail_watch.go
Comment thread shortcuts/mail/mail_watch.go

@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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/event/consume/consume_test.go`:
- Around line 125-133: Update the error-path assertions in the consume test to
check typed metadata instead of relying on multiple substrings from err.Error().
Use errs.ProblemOf(err) to assert the expected category and subtype, and use
errors.As with *errs.ValidationError to verify the failed param value. Keep only
one message-based assertion for the CLI guidance text, and reference the
existing consume test/error handling path so the checks stay tied to the right
validation failure.

In `@internal/event/consume/consume.go`:
- Around line 238-239: The invalid enum value path in consume validation is
returning a plain formatted error instead of a typed validation error. Update
the error handling around the EventKey parameter check in the consume flow to
use errs.NewValidationError(errs.SubtypeInvalidArgument, ...) with the same
message, chain .WithParam(p.Name), and move the schema guidance text into
.WithHint(...) so it matches the other command-facing validation paths.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: c2616cdc-bb45-4018-b010-f5edc107b100

📥 Commits

Reviewing files that changed from the base of the PR and between 75d5be7 and 66a3bc1.

📒 Files selected for processing (2)
  • internal/event/consume/consume.go
  • internal/event/consume/consume_test.go

Comment thread internal/event/consume/consume_test.go
Comment thread internal/event/consume/consume.go Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain/mail PR touches the mail domain size/XL Architecture-level or global-impact change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants