Skip to content

Commit b5416b5

Browse files
author
MPCoreDeveloper
committed
CQRS support 3 new packages new docs
1 parent d12c726 commit b5416b5

File tree

171 files changed

+8655
-488
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+8655
-488
lines changed

.github/CI_STATUS.md

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -75,42 +75,42 @@ After CI passes on master:
7575

7676
### 2. Publish to NuGet.org
7777
```bash
78-
# Use the correct order (see docs/RELEASE_CHECKLIST_v1.5.0.md)
78+
# Use the correct order (see docs/RELEASE_CHECKLIST_v1.6.0.md)
7979

8080
# Wave 1: Core
81-
dotnet nuget push "SharpCoreDB.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
81+
dotnet nuget push "SharpCoreDB.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
8282

8383
# Wave 2: Direct dependencies (wait 60 seconds after Wave 1)
84-
dotnet nuget push "SharpCoreDB.Analytics.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
85-
dotnet nuget push "SharpCoreDB.Data.Provider.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
86-
dotnet nuget push "SharpCoreDB.Extensions.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
87-
dotnet nuget push "SharpCoreDB.Graph.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
88-
dotnet nuget push "SharpCoreDB.Distributed.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
89-
dotnet nuget push "SharpCoreDB.VectorSearch.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
90-
dotnet nuget push "SharpCoreDB.Serilog.Sinks.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
84+
dotnet nuget push "SharpCoreDB.Analytics.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
85+
dotnet nuget push "SharpCoreDB.Data.Provider.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
86+
dotnet nuget push "SharpCoreDB.Extensions.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
87+
dotnet nuget push "SharpCoreDB.Graph.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
88+
dotnet nuget push "SharpCoreDB.Distributed.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
89+
dotnet nuget push "SharpCoreDB.VectorSearch.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
90+
dotnet nuget push "SharpCoreDB.Serilog.Sinks.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
9191

9292
# Wave 3: Multi-dependencies (wait 60 seconds after Wave 2)
93-
dotnet nuget push "SharpCoreDB.Provider.Sync.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
94-
dotnet nuget push "SharpCoreDB.Provider.YesSql.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
95-
dotnet nuget push "SharpCoreDB.EntityFrameworkCore.1.5.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
93+
dotnet nuget push "SharpCoreDB.Provider.Sync.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
94+
dotnet nuget push "SharpCoreDB.Provider.YesSql.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
95+
dotnet nuget push "SharpCoreDB.EntityFrameworkCore.1.6.0.nupkg" -k <api-key> -s https://api.nuget.org/v3/index.json
9696
```
9797

9898
### 3. Create GitHub Release
9999
```bash
100-
git tag v1.5.0
101-
git push origin v1.5.0
100+
git tag v1.6.0
101+
git push origin v1.6.0
102102
```
103103

104104
Then create release on GitHub with:
105-
- Tag: `v1.5.0`
106-
- Title: `SharpCoreDB v1.5.0 - Critical Bug Fixes & Metadata Compression`
107-
- Description: Link to `docs/PROGRESSION_V1.3.5_TO_v1.5.0.md`
105+
- Tag: `v1.6.0`
106+
- Title: `SharpCoreDB v1.6.0 - Critical Bug Fixes & Metadata Compression`
107+
- Description: Link to `docs/PROGRESSION_V1.3.5_TO_v1.6.0.md`
108108

109109
## 🔗 Related Documentation
110110

111-
- [Release Checklist](../docs/RELEASE_CHECKLIST_v1.5.0.md)
112-
- [Version Update Summary](../docs/VERSION_UPDATE_SUMMARY_v1.5.0.md)
113-
- [Progression Report](../docs/PROGRESSION_V1.3.5_TO_v1.5.0.md)
111+
- [Release Checklist](../docs/RELEASE_CHECKLIST_v1.6.0.md)
112+
- [Version Update Summary](../docs/VERSION_UPDATE_SUMMARY_v1.6.0.md)
113+
- [Progression Report](../docs/PROGRESSION_V1.3.5_TO_v1.6.0.md)
114114

115115
## 🐛 Troubleshooting
116116

@@ -123,11 +123,11 @@ Then create release on GitHub with:
123123
- Check test output in GitHub Actions artifacts
124124

125125
### Pack Failures
126-
- Ensure all dependencies are v1.5.0
126+
- Ensure all dependencies are v1.6.0
127127
- Check for missing NuGet.README.md files
128128

129129
---
130130

131131
**Last Updated:** 2026-02-28
132-
**Version:** 1.5.0
132+
**Version:** 1.6.0
133133
**Status:** ✅ Fully Operational with .NET 10 SDK

.github/copilot-instructions.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
- All project documentation must be written in English. This includes docs, README files, technical specs, implementation plans, and code comments.
66
- Provide periodic progress updates while work is ongoing to ensure the assistant is not stuck.
77
- When benchmarking competitor databases (like BLite), document the developer experience (DX) honestly. If a library's API is hard to use, poorly documented, or has mismatches between docs and actual API, note that as a real finding in the benchmark report. User-friendliness and ease of integration matter as much as raw performance numbers.
8-
- Standardize all documentation/version labels to v1.5.0 ("V 1.50").
8+
- Standardize all documentation/version labels to v1.6.0 ("V 1.60").
9+
- Continue implementation until the scoped roadmap work is finished without pausing for confirmation.
910

1011
## Testing Policy
1112
- All test projects in SharpCoreDB must use **xUnit v3** (`xunit.v3` NuGet package, currently 3.2.2+). **Never** use `xunit` v2 (package id `xunit`). The old v2 package is incompatible with .NET 10 / C# 14.
@@ -34,6 +35,7 @@
3435
- New SharpCoreDB features must remain optional; event sourcing must be delivered as a separate NuGet package, and issue-driven user features should be prioritized ahead of server mode work.
3536
- Event sourcing must support both persistent storage and the existing in-memory option; provide an additional demo example specifically for persistent storage.
3637
- Prioritize gRPC as the flagship protocol for SharpCoreDB.Server; binary/HTTP are secondary.
38+
- SharpCoreDB roadmap priority: make Event Sourcing first-class, add native snapshots, then projection engine; keep ES/CQRS optional packages, .NET 10-native, zero external deps in core, and gRPC-first networked server integration.
3739

3840
## Asynchronous Programming Guidelines
3941
- When fixing cancellation token handling in parallel async methods that use `Parallel.ForEachAsync`, always wrap the parallel operation in a try-catch block to properly propagate `OperationCanceledException`. The `CancellationToken` passed to `ParallelOptions` will cause an `OperationCanceledException` to be thrown from `Parallel.ForEachAsync`, and this must be caught and re-thrown to ensure proper cancellation propagation to calling code.

Examples/EventSourcing/OrderManagement.PersistentDemo/OrderManagement.PersistentDemo.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<LangVersion>14.0</LangVersion>
77
<ImplicitUsings>enable</ImplicitUsings>
88
<Nullable>enable</Nullable>
9-
<Version>1.5.0</Version>
9+
<Version>1.6.0</Version>
1010
<IsPackable>false</IsPackable>
1111
</PropertyGroup>
1212

Examples/EventSourcing/OrderManagement/OrderAggregate.cs

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
namespace OrderManagement;
77

8+
using System.Text.Json;
89
using SharpCoreDB.EventSourcing;
910

1011
/// <summary>
@@ -212,15 +213,72 @@ public void CancelOrder(string reason, string cancelledBy)
212213
public static OrderAggregate FromEventStream(IReadOnlyList<EventEnvelope> events)
213214
{
214215
var aggregate = new OrderAggregate();
215-
216+
aggregate.Replay(events);
217+
return aggregate;
218+
}
219+
220+
/// <summary>
221+
/// Rehydrates aggregate from snapshot payload.
222+
/// </summary>
223+
/// <param name="snapshotData">Serialized snapshot bytes.</param>
224+
/// <returns>Rehydrated aggregate.</returns>
225+
public static OrderAggregate FromSnapshot(ReadOnlyMemory<byte> snapshotData)
226+
{
227+
var snapshot = JsonSerializer.Deserialize<OrderSnapshotState>(snapshotData.Span)
228+
?? throw new InvalidOperationException("Failed to deserialize order snapshot.");
229+
230+
return new OrderAggregate
231+
{
232+
OrderId = snapshot.OrderId,
233+
CustomerId = snapshot.CustomerId,
234+
Status = snapshot.Status,
235+
Items = snapshot.Items,
236+
TotalAmount = snapshot.TotalAmount,
237+
TrackingNumber = snapshot.TrackingNumber,
238+
PaymentTransactionId = snapshot.PaymentTransactionId,
239+
DeliveredAt = snapshot.DeliveredAt,
240+
Version = snapshot.Version,
241+
};
242+
}
243+
244+
/// <summary>
245+
/// Serializes current aggregate state as snapshot payload.
246+
/// </summary>
247+
/// <param name="version">Version to persist in snapshot metadata.</param>
248+
/// <returns>Serialized snapshot bytes.</returns>
249+
public byte[] ToSnapshotData(long version)
250+
{
251+
var snapshot = new OrderSnapshotState
252+
{
253+
OrderId = OrderId,
254+
CustomerId = CustomerId,
255+
Status = Status,
256+
Items = [.. Items],
257+
TotalAmount = TotalAmount,
258+
TrackingNumber = TrackingNumber,
259+
PaymentTransactionId = PaymentTransactionId,
260+
DeliveredAt = DeliveredAt,
261+
Version = version,
262+
};
263+
264+
return JsonSerializer.SerializeToUtf8Bytes(snapshot);
265+
}
266+
267+
/// <summary>
268+
/// Replays additional envelopes into current aggregate state.
269+
/// </summary>
270+
/// <param name="events">Event envelopes to apply.</param>
271+
/// <returns>Current aggregate instance.</returns>
272+
public OrderAggregate Replay(IReadOnlyList<EventEnvelope> events)
273+
{
216274
foreach (var envelope in events)
217275
{
218276
var orderEvent = DeserializeEvent(envelope);
219-
aggregate.Apply(orderEvent);
220-
aggregate.Version = envelope.Sequence;
277+
Apply(orderEvent);
278+
Version = envelope.Sequence;
221279
}
222-
223-
return aggregate;
280+
281+
return this;
224282
}
225283

226284
/// <summary>
@@ -324,4 +382,25 @@ private static OrderEvent DeserializeEvent(EventEnvelope envelope)
324382
_ => throw new InvalidOperationException($"Unknown event type: {envelope.EventType}")
325383
};
326384
}
385+
386+
private sealed class OrderSnapshotState
387+
{
388+
public required string OrderId { get; init; }
389+
390+
public required string CustomerId { get; init; }
391+
392+
public required OrderStatus Status { get; init; }
393+
394+
public required List<OrderItem> Items { get; init; }
395+
396+
public required decimal TotalAmount { get; init; }
397+
398+
public required string? TrackingNumber { get; init; }
399+
400+
public required string? PaymentTransactionId { get; init; }
401+
402+
public required DateTimeOffset? DeliveredAt { get; init; }
403+
404+
public required long Version { get; init; }
405+
}
327406
}

Examples/EventSourcing/OrderManagement/OrderManagement.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<LangVersion>14.0</LangVersion>
77
<ImplicitUsings>enable</ImplicitUsings>
88
<Nullable>enable</Nullable>
9-
<Version>1.5.0</Version>
9+
<Version>1.6.0</Version>
1010
<IsPackable>false</IsPackable>
1111
</PropertyGroup>
1212

0 commit comments

Comments
 (0)