feat: add platform billing dunning and audit persistence
This commit is contained in:
@@ -6,6 +6,7 @@ using Tiku.Domain.Content;
|
||||
using Tiku.Domain.Growth;
|
||||
using Tiku.Domain.Learning;
|
||||
using Tiku.Domain.Operations;
|
||||
using Tiku.Domain.Platform;
|
||||
using Tiku.Domain.QuestionBanks;
|
||||
using Tiku.Domain.Tenancy;
|
||||
using Tiku.Infrastructure.Persistence;
|
||||
@@ -28,7 +29,7 @@ public sealed class PersistenceModelTests
|
||||
.Select(entity => entity.GetTableName())
|
||||
.ToHashSet(StringComparer.Ordinal);
|
||||
|
||||
Assert.Equal(111, tableNames.Count);
|
||||
Assert.Equal(121, tableNames.Count);
|
||||
Assert.Contains("tenants", tableNames);
|
||||
Assert.Contains("tenant_settings", tableNames);
|
||||
Assert.Contains("content_entries", tableNames);
|
||||
@@ -118,6 +119,16 @@ public sealed class PersistenceModelTests
|
||||
Assert.Contains("tenant_content_notifications", tableNames);
|
||||
Assert.Contains("tenant_theme_templates", tableNames);
|
||||
Assert.Contains("tenant_theme_configs", tableNames);
|
||||
Assert.Contains("platform_saas_plans", tableNames);
|
||||
Assert.Contains("tenant_billing_profiles", tableNames);
|
||||
Assert.Contains("tenant_invoices", tableNames);
|
||||
Assert.Contains("tenant_invoice_items", tableNames);
|
||||
Assert.Contains("tenant_invoice_payments", tableNames);
|
||||
Assert.Contains("tenant_invoice_reminders", tableNames);
|
||||
Assert.Contains("platform_audit_alert_rules", tableNames);
|
||||
Assert.Contains("platform_audit_alerts", tableNames);
|
||||
Assert.Contains("platform_dunning_notification_channels", tableNames);
|
||||
Assert.Contains("platform_dunning_notification_events", tableNames);
|
||||
Assert.Contains("questions", tableNames);
|
||||
Assert.Contains("question_versions", tableNames);
|
||||
Assert.Contains("answer_records", tableNames);
|
||||
@@ -714,4 +725,86 @@ public sealed class PersistenceModelTests
|
||||
.SequenceEqual(propertyNames));
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(typeof(PlatformSaasPlan), nameof(PlatformSaasPlan.IncludedQuotas), "'{}'::jsonb")]
|
||||
[InlineData(typeof(PlatformSaasPlan), nameof(PlatformSaasPlan.OveragePrices), "'{}'::jsonb")]
|
||||
[InlineData(typeof(PlatformSaasPlan), nameof(PlatformSaasPlan.FeatureFlags), "'{}'::jsonb")]
|
||||
[InlineData(typeof(TenantBillingProfile), nameof(TenantBillingProfile.Metadata), "'{}'::jsonb")]
|
||||
[InlineData(typeof(TenantInvoice), nameof(TenantInvoice.Metadata), "'{}'::jsonb")]
|
||||
[InlineData(typeof(TenantInvoiceItem), nameof(TenantInvoiceItem.Metadata), "'{}'::jsonb")]
|
||||
[InlineData(typeof(TenantInvoicePayment), nameof(TenantInvoicePayment.RawPayload), "'{}'::jsonb")]
|
||||
[InlineData(typeof(TenantInvoiceReminder), nameof(TenantInvoiceReminder.Metadata), "'{}'::jsonb")]
|
||||
[InlineData(typeof(PlatformAuditAlertRule), nameof(PlatformAuditAlertRule.Conditions), "'{}'::jsonb")]
|
||||
[InlineData(typeof(PlatformAuditAlertRule), nameof(PlatformAuditAlertRule.Metadata), "'{}'::jsonb")]
|
||||
[InlineData(typeof(PlatformAuditAlert), nameof(PlatformAuditAlert.Details), "'{}'::jsonb")]
|
||||
[InlineData(typeof(PlatformDunningNotificationChannel), nameof(PlatformDunningNotificationChannel.Metadata), "'{}'::jsonb")]
|
||||
[InlineData(typeof(PlatformDunningNotificationEvent), nameof(PlatformDunningNotificationEvent.RequestPayload), "'{}'::jsonb")]
|
||||
[InlineData(typeof(PlatformDunningNotificationEvent), nameof(PlatformDunningNotificationEvent.Metadata), "'{}'::jsonb")]
|
||||
public void Platform_operations_json_properties_are_mapped_to_jsonb(
|
||||
Type entityType,
|
||||
string propertyName,
|
||||
string expectedDefaultValueSql)
|
||||
{
|
||||
using var context = new TikuDbContext(Options);
|
||||
|
||||
var property = context.Model.FindEntityType(entityType)!
|
||||
.FindProperty(propertyName)!;
|
||||
|
||||
Assert.Equal("jsonb", property.GetColumnType());
|
||||
Assert.Equal(expectedDefaultValueSql, property.GetDefaultValueSql());
|
||||
Assert.Equal(typeof(System.Text.Json.JsonElement), property.ClrType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Platform_operations_have_expected_unique_indexes_arrays_and_money_fields()
|
||||
{
|
||||
using var context = new TikuDbContext(Options);
|
||||
|
||||
AssertHasUniqueIndex<PlatformSaasPlan>(nameof(PlatformSaasPlan.Code));
|
||||
AssertHasUniqueIndex<TenantInvoice>(nameof(TenantInvoice.InvoiceNo));
|
||||
AssertHasUniqueIndex<TenantInvoice>(
|
||||
nameof(TenantInvoice.TenantId),
|
||||
nameof(TenantInvoice.BillingPeriodStart),
|
||||
nameof(TenantInvoice.BillingPeriodEnd));
|
||||
AssertHasUniqueIndex<TenantInvoiceReminder>(
|
||||
nameof(TenantInvoiceReminder.TenantId),
|
||||
nameof(TenantInvoiceReminder.InvoiceId),
|
||||
nameof(TenantInvoiceReminder.ReminderType),
|
||||
nameof(TenantInvoiceReminder.Channel),
|
||||
nameof(TenantInvoiceReminder.ReminderDate));
|
||||
AssertHasUniqueIndex<PlatformAuditAlertRule>(nameof(PlatformAuditAlertRule.Code));
|
||||
AssertHasUniqueIndex<PlatformAuditAlert>(nameof(PlatformAuditAlert.RuleId), nameof(PlatformAuditAlert.AuditLogId));
|
||||
AssertHasUniqueIndex<PlatformDunningNotificationChannel>(nameof(PlatformDunningNotificationChannel.ChannelCode));
|
||||
AssertHasUniqueIndex<PlatformDunningNotificationEvent>(
|
||||
nameof(PlatformDunningNotificationEvent.ChannelId),
|
||||
nameof(PlatformDunningNotificationEvent.ReminderId));
|
||||
|
||||
Assert.Equal(
|
||||
"text[]",
|
||||
context.Model.FindEntityType(typeof(PlatformAuditAlertRule))!
|
||||
.FindProperty(nameof(PlatformAuditAlertRule.ActionPatterns))!
|
||||
.GetColumnType());
|
||||
Assert.Equal(
|
||||
"uuid[]",
|
||||
context.Model.FindEntityType(typeof(PlatformDunningNotificationChannel))!
|
||||
.FindProperty(nameof(PlatformDunningNotificationChannel.TenantIds))!
|
||||
.GetColumnType());
|
||||
|
||||
var total = context.Model.FindEntityType(typeof(TenantInvoice))!
|
||||
.FindProperty(nameof(TenantInvoice.TotalCents))!;
|
||||
Assert.Equal(typeof(int), total.ClrType);
|
||||
|
||||
void AssertHasUniqueIndex<TEntity>(params string[] propertyNames)
|
||||
{
|
||||
var indexes = context.Model.FindEntityType(typeof(TEntity))!.GetIndexes();
|
||||
|
||||
Assert.Contains(
|
||||
indexes,
|
||||
index => index.IsUnique
|
||||
&& index.Properties
|
||||
.Select(property => property.Name)
|
||||
.SequenceEqual(propertyNames));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user