DirectivSys.Sdk
1.1.7
See the version list below for details.
dotnet add package DirectivSys.Sdk --version 1.1.7
NuGet\Install-Package DirectivSys.Sdk -Version 1.1.7
<PackageReference Include="DirectivSys.Sdk" Version="1.1.7" />
<PackageVersion Include="DirectivSys.Sdk" Version="1.1.7" />
<PackageReference Include="DirectivSys.Sdk" />
paket add DirectivSys.Sdk --version 1.1.7
#r "nuget: DirectivSys.Sdk, 1.1.7"
#:package DirectivSys.Sdk@1.1.7
#addin nuget:?package=DirectivSys.Sdk&version=1.1.7
#tool nuget:?package=DirectivSys.Sdk&version=1.1.7
DirectivSys.Sdk
Official .NET SDK for DirectivSys Analytics Platform. Enables seamless integration with DirectivSys to receive AI-powered business intelligence directives and submit analytics payloads.
Features
✨ Zero Boilerplate - Automatic webhook endpoint creation
🔒 Secure by Default - Built-in authentication and validation
📦 Strongly Typed - Complete DTOs for all analytics types
🚀 Easy Submission - Fluent API for submitting analytics payloads
📊 Inventory Ingestion - Real-time and batch data synchronization
⚡ Async/Await - Modern async patterns throughout
🎯 Enum Support - Type-safe analytics type selection
Installation
dotnet add package DirectivSys.Sdk
Or via Package Manager Console:
Install-Package DirectivSys.Sdk
Quick Start
1. Configure Services (Program.cs or Startup.cs)
using DirectivSys.Sdk.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add DirectivSys SDK
builder.Services.AddDirectivSys(options =>
{
options.ApiKey = "your-directivsys-api-key";
// ClientId is automatically extracted from the API Key
});
var app = builder.Build();
// Map the webhook endpoint
app.MapDirectivWebhook();
// Set up your callback to handle incoming directives
var directivSys = app.GetDirectivSys();
directivSys.OnDirectiveReceived = HandleDirective;
app.Run();
void HandleDirective(GlobalRecord record)
{
Console.WriteLine($"Received {record.Directives.Count} directives for {record.AnalyticsType}");
foreach (var directive in record.Directives.OrderBy(d => d.Priority))
{
Console.WriteLine($"[Priority {directive.Priority}] {directive.Action}");
Console.WriteLine($" Rationale: {directive.Rationale}");
// Execute your business logic based on the directive
switch (directive.Action)
{
case "reorderSupplier":
var sku = directive.Parameters["sku"].ToString();
var quantity = Convert.ToInt32(directive.Parameters["quantity"]);
// Your reorder logic here
break;
case "launchPromotion":
var targets = directive.Targets;
// Your promotion logic here
break;
}
}
}
2. Submit Analytics Data
using DirectivSys.Sdk.Models.Payloads;
using DirectivSys.Sdk.Services;
public class InventoryService
{
private readonly DirectivSysClient _client;
public InventoryService(DirectivSysClient client)
{
_client = client;
}
public async Task AnalyzeInventoryAsync()
{
var payload = new InventoryHealthPayload
{
Sku = "SKU123",
StockLevel = 20,
ReorderPoint = 50,
SafetyStock = 30,
ForecastedDemandNext30Days = 200,
AverageLeadTimeDays = 5
};
// Submit the payload for async processing
// Instructions are pre-configured in AnalyticsConfig on the backend
var response = await _client.SubmitInventoryHealthAsync(payload);
Console.WriteLine($"Payload submitted: {response.PayloadId}, Status: {response.Status}");
// Option 1: Poll for results
var result = await PollForResultAsync(response.PayloadId);
// Option 2: Process immediately (synchronous)
// var result = await _client.ProcessLatestAsync("InventoryHealth");
}
private async Task<AnalyticsResult?> PollForResultAsync(Guid payloadId, int maxAttempts = 30)
{
for (int i = 0; i < maxAttempts; i++)
{
var response = await _client.GetResultByPayloadIdAsync(payloadId);
if (response.IsComplete && response.Result != null)
{
return response.Result;
}
if (response.Status == "failed")
{
throw new Exception($"Processing failed: {response.Error}");
}
await Task.Delay(1000); // Wait 1 second before next poll
}
throw new TimeoutException("Polling timed out");
}
}
Supported Analytics Types
The SDK includes strongly-typed payload classes for all DirectivSys analytics types:
Important: Instructions for each analytics type are configured once in the AnalyticsConfig on the backend, not sent with each payload submission. Payloads contain only data - this reduces payload size and allows updating instructions without changing client code.
Supply Chain Analytics
- InventoryHealth - Stock level monitoring and reorder recommendations
- SupplierReliability - Supplier performance evaluation
- DemandForecast - Future demand prediction
- CostOptimization - Order quantity and cost optimization
E-Commerce Analytics
- CustomerSegmentation - Customer grouping by behavior and value
- CartAbandonment - Abandoned cart detection and recovery
- SalesFunnelConversion - Conversion rate tracking and optimization
- ProductPerformance - Bestseller and slow-mover identification
- CustomerLifetimeValue - Long-term customer value estimation
- MarketingROI - Campaign effectiveness measurement
Inventory Data Ingestion
The SDK provides powerful methods for synchronizing inventory data into DirectivSys for real-time analytics. This enables you to keep your inventory data up-to-date with both single-item updates and efficient batch synchronization.
Features
- ✅ Single Item Updates - Real-time updates for individual inventory items
- ✅ Batch Synchronization - Efficient bulk data sync with progress tracking
- ✅ Automatic Validation - Client-side validation before sending
- ✅ Sync Status Monitoring - Track progress of batch operations
- ✅ Error Handling - Detailed error reporting for failed items
- ✅ Idempotent Operations - Safe to retry on network failures
Single Item Update
Update or insert individual inventory items in real-time (e.g., after a sale or restock):
using DirectivSys.Sdk.Models;
public class InventoryService
{
private readonly DirectivSysClient _client;
public InventoryService(DirectivSysClient client)
{
_client = client;
}
public async Task UpdateInventoryAsync(string sku, decimal newStockLevel)
{
var item = new InventoryItem
{
Sku = sku,
ProductName = "Widget A",
ProductCategory = "Tools",
PriorityLevel = "high",
StockLevel = newStockLevel,
ReorderPoint = 50,
SafetyStock = 20,
ForecastedDemandNext30Days = 200,
UnitCost = 5.5m,
HoldingCostPerUnit = 0.2m,
OrderCost = 15m,
SupplierId = "SUP456",
SupplierName = "Acme Supplies",
AvgLeadTimeDays = 7,
LateDeliveriesPercent = 0.05m,
QualityDefectRate = 0.02m,
SupplierReliabilityScore = 92m,
MinOrderQty = 10,
BudgetCap = 5000m
};
// Using enum (recommended)
var response = await _client.UpdateInventoryItemAsync(
AnalyticsType.InventoryHealth,
item);
Console.WriteLine($"Item {response.Sku} {response.Status}");
}
}
Required Fields:
Sku- Stock Keeping Unit (unique identifier)StockLevel- Current stock level (must be >= 0)ReorderPoint- Reorder threshold (must be >= 0)
All other fields are optional but recommended for comprehensive analytics.
Batch Synchronization
For syncing large datasets (e.g., nightly full inventory sync), use batch ingestion with automatic progress tracking:
public class InventorySyncService
{
private readonly DirectivSysClient _client;
private readonly ILogger<InventorySyncService> _logger;
public InventorySyncService(
DirectivSysClient client,
ILogger<InventorySyncService> logger)
{
_client = client;
_logger = logger;
}
public async Task SyncFullInventoryAsync(List<InventoryItem> allItems)
{
// Generate unique sync ID
var syncId = $"sync-{DateTime.UtcNow:yyyyMMdd-HHmmss}";
// Split into batches of 100-500 items
var batchSize = 250;
var batches = allItems
.Select((item, index) => new { item, index })
.GroupBy(x => x.index / batchSize)
.Select(g => g.Select(x => x.item).ToList())
.ToList();
_logger.LogInformation(
"Starting sync {SyncId} with {TotalBatches} batches ({TotalItems} items)",
syncId, batches.Count, allItems.Count);
// Process each batch
for (int i = 0; i < batches.Count; i++)
{
var request = new BatchIngestionRequest
{
SyncId = syncId,
TotalBatches = batches.Count,
CurrentBatchIndex = i,
Items = batches[i]
};
try
{
var response = await _client.SyncInventoryBatchAsync(
AnalyticsType.InventoryHealth,
request);
_logger.LogInformation(
"Batch {Current}/{Total}: {Success} succeeded, {Failed} failed",
i + 1,
batches.Count,
response.SuccessfulCount,
response.FailedCount);
// Log any failures
foreach (var failure in response.FailedItems)
{
_logger.LogWarning(
"Failed to sync {Sku}: {Error} ({ErrorType})",
failure.Sku,
failure.ErrorMessage,
failure.ErrorType);
}
// Check if sync is complete
if (response.SyncStatus.IsComplete)
{
_logger.LogInformation(
"Sync {SyncId} completed! Total: {Success} succeeded, {Failed} failed",
syncId,
response.SyncStatus.TotalSuccessfulItems,
response.SyncStatus.TotalFailedItems);
}
}
catch (DirectivSysException ex)
{
_logger.LogError(ex, "Failed to sync batch {Index}", i);
throw;
}
}
// Verify completion
var finalStatus = await _client.GetSyncStatusAsync(syncId);
if (!finalStatus.IsComplete)
{
throw new Exception(
$"Sync incomplete: {finalStatus.ReceivedBatches}/{finalStatus.TotalBatches} batches received");
}
return finalStatus;
}
}
Sync Status Monitoring
Check the progress of a batch synchronization job:
public async Task<SyncStatus> CheckSyncProgressAsync(string syncId)
{
var status = await _client.GetSyncStatusAsync(syncId);
Console.WriteLine($"Status: {status.Status}");
Console.WriteLine($"Progress: {status.ReceivedBatches}/{status.TotalBatches} batches");
Console.WriteLine($"Items: {status.TotalSuccessfulItems} succeeded, {status.TotalFailedItems} failed");
Console.WriteLine($"Complete: {status.IsComplete}");
if (status.IsComplete)
{
Console.WriteLine($"Completed at: {status.CompletedAt}");
}
return status;
}
Resilient Batch Sync with Recovery
Handle network interruptions gracefully:
public async Task SyncWithRecoveryAsync(
List<InventoryItem> allItems,
string? resumeSyncId = null)
{
string syncId;
int startBatchIndex = 0;
// Check if resuming an existing sync
if (!string.IsNullOrEmpty(resumeSyncId))
{
var status = await _client.GetSyncStatusAsync(resumeSyncId);
syncId = resumeSyncId;
startBatchIndex = status.ReceivedBatches; // Resume from where we left off
_logger.LogInformation(
"Resuming sync {SyncId} from batch {StartIndex}",
syncId, startBatchIndex);
}
else
{
syncId = $"sync-{DateTime.UtcNow:yyyyMMdd-HHmmss}";
_logger.LogInformation("Starting new sync {SyncId}", syncId);
}
var batchSize = 250;
var batches = allItems
.Select((item, index) => new { item, index })
.GroupBy(x => x.index / batchSize)
.Select(g => g.Select(x => x.item).ToList())
.ToList();
// Process from startBatchIndex onwards
for (int i = startBatchIndex; i < batches.Count; i++)
{
var request = new BatchIngestionRequest
{
SyncId = syncId,
TotalBatches = batches.Count,
CurrentBatchIndex = i,
Items = batches[i]
};
try
{
await _client.SyncInventoryBatchAsync(
AnalyticsType.InventoryHealth,
request);
}
catch (Exception ex)
{
_logger.LogError(ex,
"Network failure at batch {Index}. Resume with syncId: {SyncId}",
i, syncId);
throw;
}
}
}
Inventory Item Schema
public class InventoryItem
{
// Required fields
public string Sku { get; set; } // Stock Keeping Unit
public decimal StockLevel { get; set; } // Current stock level
public decimal ReorderPoint { get; set; } // Reorder threshold
// Product information
public string? ProductName { get; set; }
public string? ProductCategory { get; set; }
public string? PriorityLevel { get; set; } // "high", "medium", "low"
// Inventory metrics
public decimal? SafetyStock { get; set; }
public decimal? ForecastedDemandNext30Days { get; set; }
public decimal? UnitCost { get; set; }
public decimal? HoldingCostPerUnit { get; set; }
public decimal? OrderCost { get; set; }
public int? MinOrderQty { get; set; }
public decimal? BudgetCap { get; set; }
// Supplier information
public string? SupplierId { get; set; }
public string? SupplierName { get; set; }
public int? AvgLeadTimeDays { get; set; }
public decimal? LateDeliveriesPercent { get; set; } // 0-1
public decimal? QualityDefectRate { get; set; } // 0-1
public decimal? SupplierReliabilityScore { get; set; } // 0-100
}
Best Practices
Batch Sizing
- 50-100 items: Better error isolation, more API calls
- 100-500 items: Balanced approach (recommended)
- 500-1000 items: Fewer API calls, harder to debug failures
Sync ID Naming
Use descriptive, unique identifiers:
✅ Good: "sync-20260118-nightly-001"
✅ Good: "sync-inventory-full-20260118143045"
❌ Bad: "sync1" or "test"
Error Handling
try
{
var response = await client.UpdateInventoryItemAsync(
AnalyticsType.InventoryHealth,
item);
}
catch (ArgumentException ex)
{
// Validation error (e.g., missing SKU, negative stock)
logger.LogError(ex, "Invalid inventory item");
}
catch (DirectivSysException ex)
{
// API error (e.g., authentication, server error)
logger.LogError(ex, "Failed to update inventory");
}
Real-Time vs Batch Sync
Use Single Item Updates for:
- Real-time inventory changes (sales, restocking)
- Event-driven updates
- Individual corrections
Use Batch Sync for:
- Full inventory synchronization
- Large dataset ingestion
- Scheduled periodic syncs (e.g., nightly)
Rate Limits
- Single Item Updates: 100 requests/minute
- Batch Ingestion: 10 batches/minute
- Sync Status: 60 requests/minute
Exceeding rate limits returns 429 Too Many Requests.
API Reference
Configuration
DirectivSysOptions
public class DirectivSysOptions
{
public string ApiKey { get; set; } // Required: Your DirectivSys API Key (X-API-Key header)
public string BaseUrl { get; set; } // Default: "https://api.directivsys.com"
public Guid? ClientId { get; set; } // Optional: Extracted from API Key if not provided
public int TimeoutSeconds { get; set; } // Default: 30
}
Core Models
GlobalRecord
The main container for analytics results received via webhook:
public class GlobalRecord
{
public Guid RecordId { get; set; }
public string AnalyticsType { get; set; }
public List<Directive> Directives { get; set; }
public List<Metric> Metrics { get; set; }
public List<Observation> Observations { get; set; }
public string Provenance { get; set; }
public DateTime CreatedAt { get; set; }
}
Directive
Actionable recommendations from the AI agent:
public class Directive
{
public Guid DirectiveId { get; set; }
public int Priority { get; set; } // 1 = highest priority
public string Action { get; set; } // e.g., "reorderSupplier"
public Dictionary<string, object> Parameters { get; set; }
public List<string> Targets { get; set; }
public string Rationale { get; set; }
public string Status { get; set; }
}
Metric
Calculated business metrics:
public class Metric
{
public string Name { get; set; }
public double Value { get; set; }
public string Unit { get; set; }
public string Status { get; set; } // "healthy", "warning", "critical"
public string Explanation { get; set; }
}
Observation
Human-readable explanations and context:
public class Observation
{
public string Text { get; set; }
public string Severity { get; set; } // "info", "warning", "critical"
public string Scope { get; set; } // "global", "product", "supplier"
}
DirectivSysClient Methods
Submit Analytics Payloads
// Specific analytics types - Submit for async processing
Task<IngestResponse> SubmitInventoryHealthAsync(InventoryHealthPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitCustomerSegmentationAsync(CustomerSegmentationPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitCartAbandonmentAsync(CartAbandonmentPayload payload, CancellationToken cancellationToken = default)
Task<IngestResponse> SubmitProductPerformanceAsync(ProductPerformancePayload payload, CancellationToken cancellationToken = default)
// Generic submission for any analytics type (with enum)
Task<IngestResponse> SubmitAnalyticsAsync<T>(AnalyticsType analyticsType, T payload, CancellationToken cancellationToken = default)
where T : AnalyticsPayloadBase
// Generic submission for any analytics type (with string)
Task<IngestResponse> SubmitAnalyticsAsync<T>(string analyticsType, T payload, CancellationToken cancellationToken = default)
where T : AnalyticsPayloadBase
Inventory Data Ingestion
// Update or insert a single inventory item (with enum)
Task<ItemUpdateResponse> UpdateInventoryItemAsync(
AnalyticsType analyticsType,
InventoryItem item,
CancellationToken cancellationToken = default)
// Update or insert a single inventory item (with string)
Task<ItemUpdateResponse> UpdateInventoryItemAsync(
string analyticsType,
InventoryItem item,
CancellationToken cancellationToken = default)
// Ingest a batch of inventory items (with enum)
Task<BatchIngestionResponse> SyncInventoryBatchAsync(
AnalyticsType analyticsType,
BatchIngestionRequest request,
CancellationToken cancellationToken = default)
// Ingest a batch of inventory items (with string)
Task<BatchIngestionResponse> SyncInventoryBatchAsync(
string analyticsType,
BatchIngestionRequest request,
CancellationToken cancellationToken = default)
// Get sync status and progress
Task<SyncStatus> GetSyncStatusAsync(
string syncId,
CancellationToken cancellationToken = default)
Process and Retrieve Results
// Process the latest pending payload synchronously (with enum)
Task<AnalyticsResult> ProcessLatestAsync(AnalyticsType analyticsType, CancellationToken cancellationToken = default)
// Process the latest pending payload synchronously (with string)
Task<AnalyticsResult> ProcessLatestAsync(string analyticsType, CancellationToken cancellationToken = default)
// Get result for a specific payload (for polling after async submission)
Task<PayloadResultResponse> GetResultByPayloadIdAsync(Guid payloadId, CancellationToken cancellationToken = default)
Response Models
// Response from ingestion
public class IngestResponse
{
public Guid PayloadId { get; set; }
public string Status { get; set; } // "pending"
}
// Response from single item update
public class ItemUpdateResponse
{
public string Sku { get; set; }
public string Status { get; set; } // "upserted"
}
// Response from batch ingestion
public class BatchIngestionResponse
{
public string SyncId { get; set; }
public int BatchIndex { get; set; }
public int TotalItemsInBatch { get; set; }
public int SuccessfulCount { get; set; }
public int FailedCount { get; set; }
public List<FailedItem> FailedItems { get; set; }
public SyncStatus SyncStatus { get; set; }
}
// Sync status information
public class SyncStatus
{
public string Status { get; set; } // "in-progress", "completed", "failed"
public int TotalBatches { get; set; }
public int ReceivedBatches { get; set; }
public int TotalSuccessfulItems { get; set; }
public int TotalFailedItems { get; set; }
public bool IsComplete { get; set; }
public DateTime? CompletedAt { get; set; }
}
// Failed item details
public class FailedItem
{
public string Sku { get; set; }
public string ErrorMessage { get; set; }
public string ErrorType { get; set; } // "validation", "processing", "conflict"
}
// Complete analytics result
public class AnalyticsResult
{
public Guid ResultId { get; set; }
public Guid PayloadId { get; set; }
public string AnalyticsType { get; set; }
public DateTime CreatedAt { get; set; }
public string InputsSummary { get; set; }
public string InstructionSet { get; set; }
public string Provenance { get; set; }
public List<MetricResult> Metrics { get; set; }
public List<DirectiveResult> Directives { get; set; }
public List<ObservationResult> Observations { get; set; }
}
// Polling response (can be complete or status)
public class PayloadResultResponse
{
public bool IsComplete { get; set; }
public AnalyticsResult? Result { get; set; } // Available when IsComplete = true
public string? Status { get; set; } // "pending", "processing", "failed"
public string? Error { get; set; } // Available when Status = "failed"
}
Advanced Usage
Processing Patterns
The SDK supports three different processing patterns:
Pattern 1: Fire-and-Forget Ingestion
Submit payloads for async processing without waiting for results:
var response = await client.SubmitInventoryHealthAsync(payload);
// Store response.PayloadId for later retrieval if needed
Console.WriteLine($"Submitted: {response.PayloadId}");
Pattern 2: Synchronous Processing
Process immediately and get results:
// First ingest the payload
var ingestResponse = await client.SubmitInventoryHealthAsync(payload);
// Then immediately process the latest one
var result = await client.ProcessLatestAsync("InventoryHealth");
// Work with the result
foreach (var directive in result.Directives)
{
Console.WriteLine($"{directive.Action}: {directive.Rationale}");
}
Pattern 3: Async with Polling
Submit for async processing and poll until complete:
var ingestResponse = await client.SubmitInventoryHealthAsync(payload);
// Poll for results
AnalyticsResult? result = null;
int attempts = 0;
while (result == null && attempts < 30)
{
await Task.Delay(1000); // Wait 1 second
var response = await client.GetResultByPayloadIdAsync(ingestResponse.PayloadId);
if (response.IsComplete)
{
result = response.Result;
}
else if (response.Status == "failed")
{
throw new Exception($"Processing failed: {response.Error}");
}
attempts++;
}
Custom Analytics Types
For analytics types not included in the SDK, use the generic submission method:
public class CustomAnalyticsPayload : AnalyticsPayloadBase
{
public string CustomField1 { get; set; }
public int CustomField2 { get; set; }
}
var payload = new CustomAnalyticsPayload
{
CustomField1 = "value",
CustomField2 = 42
};
await client.SubmitAnalyticsAsync("CustomAnalyticsType", payload);
Accessing Services Directly
// In a controller or service
public class MyController : ControllerBase
{
private readonly DirectivSysClient _client;
private readonly IDirectivSysService _service;
public MyController(DirectivSysClient client, IDirectivSysService service)
{
_client = client;
_service = service;
// Set callback dynamically
_service.OnDirectiveReceived = HandleDirective;
}
}
Error Handling
try
{
var response = await client.SubmitInventoryHealthAsync(payload);
}
catch (DirectivSysException ex)
{
// Handle DirectivSys-specific errors
Console.WriteLine($"DirectivSys error: {ex.Message}");
}
catch (HttpRequestException ex)
{
// Handle network errors
Console.WriteLine($"Network error: {ex.Message}");
}
Configuration Best Practices
Using Configuration Files
appsettings.json:
{
"DirectivSys": {
"ApiKey": "your-api-key",
"BaseUrl": "https://api.directivsys.com",
"TimeoutSeconds": 30
}
}
Program.cs:
builder.Services.AddDirectivSys(options =>
{
builder.Configuration.GetSection("DirectivSys").Bind(options);
});
Using Environment Variables
builder.Services.AddDirectivSys(options =>
{
options.ApiKey = Environment.GetEnvironmentVariable("DIRECTIVSYS_API_KEY")
?? throw new InvalidOperationException("DIRECTIVSYS_API_KEY not set");
});
Webhook Security
The webhook endpoint (/directivsys/webhook) validates incoming requests using the API key. DirectivSys includes the X-API-Key header automatically when sending webhook notifications.
The validation ensures:
- Request includes
X-API-Key: {your-api-key}header - The provided key matches your configured API key
- Payload can be deserialized to
GlobalRecord
Example: Complete Integration
using DirectivSys.Sdk.Extensions;
using DirectivSys.Sdk.Models;
using DirectivSys.Sdk.Models.Payloads;
using DirectivSys.Sdk.Services;
var builder = WebApplication.CreateBuilder(args);
// Configure DirectivSys
builder.Services.AddDirectivSys(options =>
{
options.ApiKey = builder.Configuration["DirectivSys:ApiKey"]!;
});
// Add your services
builder.Services.AddControllers();
builder.Services.AddHostedService<InventoryAnalysisWorker>();
var app = builder.Build();
app.UseRouting();
app.MapControllers();
app.MapDirectivWebhook();
// Configure directive callback
var directivSys = app.GetDirectivSys();
directivSys.OnDirectiveReceived = record =>
{
var logger = app.Services.GetRequiredService<ILogger<Program>>();
logger.LogInformation("Received analytics: {Type} with {Count} directives",
record.AnalyticsType, record.Directives.Count);
foreach (var directive in record.Directives)
{
// Process each directive
ProcessDirective(directive, app.Services);
}
};
app.Run();
void ProcessDirective(Directive directive, IServiceProvider services)
{
var scope = services.CreateScope();
switch (directive.Action)
{
case "reorderSupplier":
var inventoryService = scope.ServiceProvider.GetRequiredService<IInventoryService>();
inventoryService.Reorder(directive.Parameters["sku"].ToString()!);
break;
case "launchPromotion":
var marketingService = scope.ServiceProvider.GetRequiredService<IMarketingService>();
marketingService.LaunchCampaign(directive.Targets);
break;
}
}
// Background worker to periodically submit analytics
public class InventoryAnalysisWorker : BackgroundService
{
private readonly DirectivSysClient _client;
private readonly ILogger<InventoryAnalysisWorker> _logger;
public InventoryAnalysisWorker(DirectivSysClient client, ILogger<InventoryAnalysisWorker> logger)
{
_client = client;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
// Aggregate your data
var inventoryData = await GetCurrentInventoryAsync();
// Submit to DirectivSys
await _client.SubmitInventoryHealthAsync(inventoryData, stoppingToken);
_logger.LogInformation("Inventory analysis submitted successfully");
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to submit inventory analysis");
}
// Run daily
await Task.Delay(TimeSpan.FromHours(24), stoppingToken);
}
}
private async Task<InventoryHealthPayload> GetCurrentInventoryAsync()
{
// Your logic to aggregate inventory data
return new InventoryHealthPayload
{
Sku = "SKU123",
StockLevel = 45,
ReorderPoint = 50,
SafetyStock = 30,
ForecastedDemandNext30Days = 200
};
}
}
Requirements
- .NET 6.0 or higher
- ASP.NET Core application (for webhook endpoint)
Support
For issues, questions, or feature requests, please visit:
- GitHub Issues: https://github.com/directivsys/directivsys-sdk-dotnet/issues
- Documentation: https://docs.directivsys.com
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Made with ❤️ by DirectivSys Inc
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.9 | 144 | 4/21/2026 |
| 1.2.8 | 147 | 4/10/2026 |
| 1.2.7 | 129 | 3/14/2026 |
| 1.2.6 | 131 | 3/9/2026 |
| 1.2.5 | 118 | 3/9/2026 |
| 1.2.4 | 108 | 3/8/2026 |
| 1.2.3 | 116 | 3/7/2026 |
| 1.2.1 | 318 | 2/4/2026 |
| 1.2.0 | 161 | 2/2/2026 |
| 1.1.9 | 136 | 2/1/2026 |
| 1.1.8 | 134 | 2/1/2026 |
| 1.1.7 | 137 | 2/1/2026 |
| 1.1.6 | 142 | 1/31/2026 |
| 1.1.5 | 151 | 1/20/2026 |
| 1.1.4 | 130 | 1/20/2026 |
| 1.1.3 | 127 | 1/19/2026 |
| 1.1.2 | 138 | 1/19/2026 |
| 1.1.1 | 136 | 1/18/2026 |
| 1.1.0 | 135 | 1/10/2026 |
| 1.0.1 | 139 | 1/9/2026 |