feat: Implement Category, Item, UOM, Vendor, and Warehouse services with CRUD operations
- Added CategoryService for managing categories with listing, tree structure, and creation functionalities. - Introduced ItemService for item management, including listing, detail retrieval, creation, updating, and status management. - Created UomService for handling unit of measure operations, including listing and creation. - Developed VendorService for vendor management, supporting listing, detail retrieval, creation, updating, and status management. - Implemented WarehouseService for warehouse and bin management, including listing warehouses, creating warehouses, and managing bins within warehouses. - Added interfaces for each service to define the contract for service implementations. - Generated Entity Framework Core model snapshot for database migrations.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
namespace ERPCore.Common.Http;
|
||||
|
||||
/// <summary>
|
||||
/// Encodes the PostgreSQL xmin concurrency token (a <see cref="uint"/>) as an
|
||||
/// opaque, quoted HTTP ETag and parses <c>If-Match</c> values back. Round-trips
|
||||
/// via base64 so the value is stable and content-type agnostic
|
||||
/// (docs/11-BACKEND-PHASE1.md §1.6).
|
||||
/// </summary>
|
||||
public static class ETag
|
||||
{
|
||||
/// <summary>Quoted ETag string for a row-version token, e.g. <c>"0RsAAA=="</c>.</summary>
|
||||
public static string From(uint rowVersion)
|
||||
=> "\"" + Convert.ToBase64String(BitConverter.GetBytes(rowVersion)) + "\"";
|
||||
|
||||
/// <summary>Parse an <c>If-Match</c> header value (quoted, optionally weak) to a token.</summary>
|
||||
public static bool TryParse(string? ifMatch, out uint rowVersion)
|
||||
{
|
||||
rowVersion = 0;
|
||||
if (string.IsNullOrWhiteSpace(ifMatch)) return false;
|
||||
|
||||
var v = ifMatch.Trim();
|
||||
if (v.StartsWith("W/", StringComparison.OrdinalIgnoreCase)) v = v[2..].Trim();
|
||||
v = v.Trim('"');
|
||||
|
||||
try
|
||||
{
|
||||
var bytes = Convert.FromBase64String(v);
|
||||
if (bytes.Length != sizeof(uint)) return false;
|
||||
rowVersion = BitConverter.ToUInt32(bytes);
|
||||
return true;
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace ERPCore.Common.Http;
|
||||
|
||||
/// <summary>
|
||||
/// Pairs a response DTO with the aggregate's current row-version so the controller
|
||||
/// can emit an <c>ETag</c> header without the token leaking into the JSON body.
|
||||
/// </summary>
|
||||
public sealed record ETagged<T>(T Value, uint RowVersion);
|
||||
Reference in New Issue
Block a user