User Story
As a developer using Pulse in production, I want failed commands persisted in a dead-letter store so that I can inspect failures, replay corrected commands, and track error patterns without losing command payloads.
Background
Commands that throw unhandled exceptions are currently lost. A persistent dead-letter store enables post-mortem analysis and replay. This issue defines the schema constants and the two interfaces that provider-specific implementations must satisfy.
Requirements
- Create src/NetEvolve.Pulse.Extensibility/DeadLetter/CommandDeadLetterSchema.cs:
- DefaultSchema = "pulse", DefaultTableName = "CommandDeadLetter".
- Columns: Id (UNIQUEIDENTIFIER PK), CommandType (NVARCHAR 500), Payload (NVARCHAR MAX), ExceptionType (NVARCHAR 500), ExceptionMessage (NVARCHAR MAX), OccurredAt (DATETIMEOFFSET), AttemptCount (INT), Status (TINYINT).
- CommandDeadLetterStatus enum: New = 0, Replaying = 1, Resolved = 2, Dismissed = 3.
- Create src/NetEvolve.Pulse.Extensibility/DeadLetter/ICommandDeadLetterStore.cs:
csharp public interface ICommandDeadLetterStore { Task StoreAsync(string commandType, string payload, Exception exception, CancellationToken cancellationToken = default); }
- Create src/NetEvolve.Pulse.Extensibility/DeadLetter/ICommandDeadLetterManagement.cs:
csharp public interface ICommandDeadLetterManagement { Task<IReadOnlyList<CommandDeadLetterEntry>> GetPendingAsync(int count = 50, CancellationToken cancellationToken = default); Task ReplayAsync(Guid id, CancellationToken cancellationToken = default); Task DismissAsync(Guid id, CancellationToken cancellationToken = default); Task<CommandDeadLetterStatistics> GetStatisticsAsync(CancellationToken cancellationToken = default); }
ReplayAsync deserializes the stored payload and dispatches it via IMediator.
Acceptance Criteria
Dependencies
- Requires feat: Define IPayloadSerializer interface (NetEvolve.Pulse.Extensibility)
User Story
As a developer using Pulse in production, I want failed commands persisted in a dead-letter store so that I can inspect failures, replay corrected commands, and track error patterns without losing command payloads.
Background
Commands that throw unhandled exceptions are currently lost. A persistent dead-letter store enables post-mortem analysis and replay. This issue defines the schema constants and the two interfaces that provider-specific implementations must satisfy.
Requirements
csharp public interface ICommandDeadLetterStore { Task StoreAsync(string commandType, string payload, Exception exception, CancellationToken cancellationToken = default); }csharp public interface ICommandDeadLetterManagement { Task<IReadOnlyList<CommandDeadLetterEntry>> GetPendingAsync(int count = 50, CancellationToken cancellationToken = default); Task ReplayAsync(Guid id, CancellationToken cancellationToken = default); Task DismissAsync(Guid id, CancellationToken cancellationToken = default); Task<CommandDeadLetterStatistics> GetStatisticsAsync(CancellationToken cancellationToken = default); }ReplayAsync deserializes the stored payload and dispatches it via IMediator.
Acceptance Criteria
Dependencies