-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDbPluginSettingsStore.cs
More file actions
55 lines (46 loc) · 2.31 KB
/
Copy pathDbPluginSettingsStore.cs
File metadata and controls
55 lines (46 loc) · 2.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System.Text.Json;
using AdaptiveApi.Infrastructure.Persistence;
using AdaptiveApi.Plugins.SDK;
using Microsoft.EntityFrameworkCore;
namespace AdaptiveApi.Infrastructure.Plugins;
/// EF-backed plugin settings store. Persists opaque settings JSON keyed by
/// <c>(TenantId, PluginId)</c>; <c>tenantId = null</c> maps to the "*" sentinel
/// for global settings (v1 has no per-tenant scoping yet).
public sealed class DbPluginSettingsStore : IPluginSettingsStore
{
private const string GlobalTenantId = "*";
private static readonly JsonSerializerOptions Json = new(JsonSerializerDefaults.Web);
private readonly AdaptiveApiDbContext _db;
public DbPluginSettingsStore(AdaptiveApiDbContext db) => _db = db;
public async Task<string?> GetRawAsync(string pluginId, string? tenantId, CancellationToken ct)
{
var key = tenantId ?? GlobalTenantId;
var row = await _db.PluginSettings.AsNoTracking()
.FirstOrDefaultAsync(x => x.TenantId == key && x.PluginId == pluginId, ct);
return row?.SettingsJson;
}
public async Task SetRawAsync(string pluginId, string? tenantId, string json, CancellationToken ct)
{
// Callers are expected to validate JSON syntax at the input boundary
// (e.g. the admin endpoint). The store trusts what it's given to keep
// a single validation layer — see PluginEndpoints.UpdateSettings.
var key = tenantId ?? GlobalTenantId;
var row = await _db.PluginSettings
.FirstOrDefaultAsync(x => x.TenantId == key && x.PluginId == pluginId, ct);
if (row is null)
{
row = new PluginSettingsEntity { TenantId = key, PluginId = pluginId };
_db.PluginSettings.Add(row);
}
row.SettingsJson = json;
row.UpdatedAt = DateTimeOffset.UtcNow;
await _db.SaveChangesAsync(ct);
}
public async Task<T?> GetAsync<T>(string pluginId, string? tenantId, CancellationToken ct) where T : class
{
var raw = await GetRawAsync(pluginId, tenantId, ct);
return string.IsNullOrEmpty(raw) ? null : JsonSerializer.Deserialize<T>(raw, Json);
}
public Task SetAsync<T>(string pluginId, string? tenantId, T value, CancellationToken ct) where T : class =>
SetRawAsync(pluginId, tenantId, JsonSerializer.Serialize(value, Json), ct);
}