Add LittleShop.Client SDK library with complete API wrapper

Features:
- Complete .NET client SDK for LittleShop API
- JWT authentication with automatic token management
- Catalog service for products and categories
- Order service with payment creation
- Retry policies using Polly for resilience
- Error handling middleware
- Dependency injection support
- Comprehensive documentation and examples

SDK Components:
- Authentication service with token refresh
- Strongly-typed models for all API responses
- HTTP handlers for retry and error handling
- Extension methods for easy DI registration
- Example console application demonstrating usage

Test Updates:
- Fixed test compilation errors
- Updated test data builders for new models
- Corrected service constructor dependencies
- Fixed enum value changes (PaymentStatus, OrderStatus)

Documentation:
- Complete project README with features and usage
- Client SDK README with detailed examples
- API endpoint documentation
- Security considerations
- Deployment guidelines

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
sysadmin
2025-08-20 18:15:35 +01:00
parent a281bb2896
commit 1f7c0af497
28 changed files with 1810 additions and 33 deletions

View File

@@ -0,0 +1,40 @@
using System.Net;
namespace LittleShop.Client.Models;
public class ApiResponse<T>
{
public bool IsSuccess { get; set; }
public T? Data { get; set; }
public string? ErrorMessage { get; set; }
public HttpStatusCode StatusCode { get; set; }
public static ApiResponse<T> Success(T data, HttpStatusCode statusCode = HttpStatusCode.OK)
{
return new ApiResponse<T>
{
IsSuccess = true,
Data = data,
StatusCode = statusCode
};
}
public static ApiResponse<T> Failure(string errorMessage, HttpStatusCode statusCode)
{
return new ApiResponse<T>
{
IsSuccess = false,
ErrorMessage = errorMessage,
StatusCode = statusCode
};
}
}
public class PagedResult<T>
{
public List<T> Items { get; set; } = new();
public int TotalCount { get; set; }
public int PageNumber { get; set; }
public int PageSize { get; set; }
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
}

View File

@@ -0,0 +1,11 @@
namespace LittleShop.Client.Models;
public class Category
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public bool IsActive { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}

View File

@@ -0,0 +1,14 @@
namespace LittleShop.Client.Models;
public class LoginRequest
{
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
public class LoginResponse
{
public string Token { get; set; } = string.Empty;
public string Username { get; set; } = string.Empty;
public DateTime ExpiresAt { get; set; }
}

View File

@@ -0,0 +1,51 @@
namespace LittleShop.Client.Models;
public class Order
{
public Guid Id { get; set; }
public string IdentityReference { get; set; } = string.Empty;
public string Status { get; set; } = string.Empty;
public decimal TotalAmount { get; set; }
public string Currency { get; set; } = string.Empty;
public string ShippingName { get; set; } = string.Empty;
public string ShippingAddress { get; set; } = string.Empty;
public string ShippingCity { get; set; } = string.Empty;
public string ShippingPostCode { get; set; } = string.Empty;
public string ShippingCountry { get; set; } = string.Empty;
public string? Notes { get; set; }
public string? TrackingNumber { get; set; }
public List<OrderItem> Items { get; set; } = new();
public List<CryptoPayment> Payments { get; set; } = new();
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public DateTime? PaidAt { get; set; }
public DateTime? ShippedAt { get; set; }
}
public class OrderItem
{
public Guid Id { get; set; }
public Guid ProductId { get; set; }
public string? ProductName { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal TotalPrice { get; set; }
}
public class CreateOrderRequest
{
public string IdentityReference { get; set; } = string.Empty;
public string ShippingName { get; set; } = string.Empty;
public string ShippingAddress { get; set; } = string.Empty;
public string ShippingCity { get; set; } = string.Empty;
public string ShippingPostCode { get; set; } = string.Empty;
public string ShippingCountry { get; set; } = "United Kingdom";
public string? Notes { get; set; }
public List<CreateOrderItem> Items { get; set; } = new();
}
public class CreateOrderItem
{
public Guid ProductId { get; set; }
public int Quantity { get; set; }
}

View File

@@ -0,0 +1,23 @@
namespace LittleShop.Client.Models;
public class CryptoPayment
{
public Guid Id { get; set; }
public Guid OrderId { get; set; }
public string Currency { get; set; } = string.Empty;
public string WalletAddress { get; set; } = string.Empty;
public decimal RequiredAmount { get; set; }
public decimal? PaidAmount { get; set; }
public string Status { get; set; } = string.Empty;
public string? TransactionHash { get; set; }
public string? BTCPayInvoiceId { get; set; }
public string? BTCPayCheckoutUrl { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? PaidAt { get; set; }
public DateTime ExpiresAt { get; set; }
}
public class CreatePaymentRequest
{
public string Currency { get; set; } = "BTC";
}

View File

@@ -0,0 +1,25 @@
namespace LittleShop.Client.Models;
public class Product
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string? Description { get; set; }
public decimal Price { get; set; }
public decimal Weight { get; set; }
public string WeightUnit { get; set; } = string.Empty;
public Guid CategoryId { get; set; }
public string? CategoryName { get; set; }
public bool IsActive { get; set; }
public List<ProductPhoto> Photos { get; set; } = new();
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
public class ProductPhoto
{
public Guid Id { get; set; }
public string Url { get; set; } = string.Empty;
public string? AltText { get; set; }
public int SortOrder { get; set; }
}