Skip to content

Commit

Permalink
Added Initial set of classes for Incidents Batch Resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
oskardudycz committed Feb 6, 2024
1 parent efef1df commit cc14f75
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 1 deletion.
1 change: 0 additions & 1 deletion Sample/Helpdesk.Wolverine/Helpdesk.Api/Helpdesk.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
</ItemGroup>

<ItemGroup>
<Folder Include="Incidents\ResolvingBatch\" />
<Folder Include="Internal\Generated\"/>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System.Collections.Immutable;

namespace Helpdesk.Api.Incidents.ResolutionBatch;

public record IncidentsBatchResolution(
Guid Id,
ImmutableDictionary<Guid, ResolutionStatus> Incidents,
ResolutionStatus Status
)
{
public static IncidentsBatchResolution Create(IncidentsBatchResolutionInitiated initiated) =>
new(
initiated.BatchId,
initiated.Incidents.ToImmutableDictionary(ks => ks, vs => ResolutionStatus.Pending),
ResolutionStatus.Pending
);

public IncidentsBatchResolution Apply(IncidentResolutionRecorded resolved) =>
this with { Incidents = Incidents.SetItem(resolved.IncidentId, ResolutionStatus.Resolved) };

public IncidentsBatchResolution Apply(IncidentResolutionFailureRecorded resolutionFailed) =>
this with { Incidents = Incidents.SetItem(resolutionFailed.IncidentId, ResolutionStatus.Failed) };

public IncidentsBatchResolution Apply(IncidentsBatchResolutionCompleted completed) =>
this with { Status = ResolutionStatus.Resolved };

public IncidentsBatchResolution Apply(IncidentsBatchResolutionFailed failed) =>
this with { Status = ResolutionStatus.Failed };

public IncidentsBatchResolution Apply(IncidentsBatchResolutionTimedOut timedOut) =>
this with { Status = ResolutionStatus.Failed };
}

public enum ResolutionStatus
{
Pending,
Resolved,
Failed
}

public record IncidentsBatchResolutionInitiated(
Guid BatchId,
List<Guid> Incidents,
Guid InitiatedBy,
DateTimeOffset InitiatedAt
);

public record IncidentResolutionRecorded(
Guid IncidentId,
Guid BatchId,
DateTimeOffset ResolvedAt
);

public record IncidentResolutionFailureRecorded(
Guid IncidentId,
Guid BatchId,
DateTimeOffset FailedAt
);

public record IncidentsBatchResolutionCompleted(
Guid BatchId,
List<Guid> Incidents,
DateTimeOffset CompletedAt
);

public record IncidentsBatchResolutionFailed(
Guid BatchId,
Dictionary<Guid, ResolutionStatus> Incidents,
DateTimeOffset FailedAt
);

public record IncidentsBatchResolutionTimedOut(
Guid BatchId,
Dictionary<Guid, ResolutionStatus> Incidents,
DateTimeOffset TimedOutAt
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using JasperFx.Core;
using Wolverine.Http;
using Wolverine.Marten;

namespace Helpdesk.Api.Incidents.ResolutionBatch;

public static class IncidentsBatchResolutionSaga
{
[WolverinePost("/api/agents/{agentId:guid}/incidents/resolve")]
public static (CreationResponse, IStartStream) InitiateResolutionBatch(
InitiateIncidentsBatchResolution command,
DateTimeOffset now
)
{
var (incidents, agentId) = command;
var batchId = CombGuidIdGeneration.NewGuid();

var @event = new IncidentsBatchResolutionInitiated(batchId, incidents, agentId, now);

return (
new CreationResponse($"/api/incidents/resolution/{batchId}"),
new StartStream<Incident>(batchId, @event)
);
}
}

public record InitiateIncidentsBatchResolution(
List<Guid> Incidents,
Guid AgentId
);


Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Wolverine;
using Wolverine.Http;
using Wolverine.Marten;
using static Microsoft.AspNetCore.Http.TypedResults;
Expand Down Expand Up @@ -28,6 +29,34 @@ DateTimeOffset now

return (Ok(), [new IncidentResolved(incident.Id, command.Resolution, command.AgentId, now)]);
}

[AggregateHandler]
public static (Events, OutgoingMessages) ResolveFromBatch
(
ResolveIncidentFromBatch command,
Incident incident,
DateTimeOffset now
)
{
if (incident.Status is IncidentStatus.Resolved
or IncidentStatus.ResolutionAcknowledgedByCustomer
or IncidentStatus.Closed
)
return ([],
[
new IncidentResolutionFailed(incident.Id, command.BatchId,
IncidentResolutionFailed.Reason.AlreadyResolved)
]);

if (incident.HasOutstandingResponseToCustomer)
return ([],
[
new IncidentResolutionFailed(incident.Id, command.BatchId,
IncidentResolutionFailed.Reason.HasOutstandingResponseToCustomer)
]);

return ([new IncidentResolved(incident.Id, command.Resolution, command.AgentId, now)], []);
}
}

public record ResolveIncident(
Expand All @@ -36,3 +65,23 @@ public record ResolveIncident(
ResolutionType Resolution,
int Version
);

public record ResolveIncidentFromBatch(
Guid IncidentId,
Guid AgentId,
ResolutionType Resolution,
Guid BatchId
);

public record IncidentResolutionFailed(
Guid IncidentId,
Guid BatchId,
IncidentResolutionFailed.Reason FailureReason
)
{
public enum Reason
{
AlreadyResolved,
HasOutstandingResponseToCustomer
}
}
2 changes: 2 additions & 0 deletions Sample/Helpdesk.Wolverine/Helpdesk.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Helpdesk.Api.Incidents.GettingCustomerIncidentsSummary;
using Helpdesk.Api.Incidents.GettingDetails;
using Helpdesk.Api.Incidents.GettingHistory;
using Helpdesk.Api.Incidents.ResolutionBatch;
using JasperFx.CodeGeneration;
using Marten;
using Marten.Events.Daemon.Resiliency;
Expand Down Expand Up @@ -52,6 +53,7 @@
);
options.Projections.LiveStreamAggregation<Incident>();
options.Projections.LiveStreamAggregation<IncidentsBatchResolution>();
options.Projections.Add<IncidentHistoryTransformation>(ProjectionLifecycle.Inline);
options.Projections.Add<IncidentDetailsProjection>(ProjectionLifecycle.Inline);
options.Projections.Add<IncidentShortInfoProjection>(ProjectionLifecycle.Inline);
Expand Down

0 comments on commit cc14f75

Please sign in to comment.