Files
admin/Azaion.Common/Database/DbFactory.cs
T
Oleksandr Bezdieniezhnykh 5ca9ccab2c [AZ-513] [AZ-196] [AZ-183] Add /classes CRUD, /devices, fleet OTA
AZ-513: POST/PATCH/DELETE /classes for detection-class CRUD; new
DetectionClass entity, schema, DTOs, IDetectionClassService. Unblocks
ui/AZ-512.

AZ-196: POST /devices auto-assigns sequential azj-NNNN serial+email
+password and inserts a CompanionPC user. Returns plaintext credentials
for the provisioning script.

AZ-183: Resources table + POST /get-update + POST /resources/publish
for fleet OTA. Per-resource encryption_key column AES-256-CBC encrypted
at rest with ResourcesConfig.EncryptionMasterKey; ICache wraps the
per-(arch,stage) latest-versions lookup and is invalidated on publish.

Adds IDbFactory.RunAdmin<T> overload for write-and-return.

Backfills _docs/02_document/module-layout.md to satisfy the implement
skill's File Ownership prerequisite (the _docs/ artifact set predates
the Step 1.5 module-layout addition).

Code review: PASS_WITH_WARNINGS — see
_docs/03_implementation/reviews/batch_05_review.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 04:34:42 +03:00

65 lines
1.8 KiB
C#

using System.Diagnostics;
using Azaion.Common.Configs;
using LinqToDB;
using Microsoft.Extensions.Options;
namespace Azaion.Common.Database;
public interface IDbFactory
{
Task<T> Run<T>(Func<AzaionDb, Task<T>> func);
Task Run(Func<AzaionDb, Task> func);
Task RunAdmin(Func<AzaionDb, Task> func);
Task<T> RunAdmin<T>(Func<AzaionDb, Task<T>> func);
}
public class DbFactory : IDbFactory
{
private readonly DataOptions _dataOptions;
private readonly DataOptions _dataOptionsAdmin;
public DbFactory(IOptions<ConnectionStrings> connectionString)
{
_dataOptions = LoadOptions(connectionString.Value.AzaionDb);
_dataOptionsAdmin = LoadOptions(connectionString.Value.AzaionDbAdmin);
}
private DataOptions LoadOptions(string connStr)
{
if (string.IsNullOrEmpty(connStr))
throw new ArgumentException($"Empty connection string in config!");
var dataOptions = new DataOptions()
.UsePostgreSQL(connStr)
.UseMappingSchema(AzaionDbSchemaHolder.MappingSchema);
_ = dataOptions.UseTracing(TraceLevel.Info, t => Console.WriteLine(t.SqlText));
return dataOptions;
}
public async Task<T> Run<T>(Func<AzaionDb, Task<T>> func)
{
await using var db = new AzaionDb(_dataOptions);
return await func(db);
}
public async Task Run(Func<AzaionDb, Task> func)
{
await using var db = new AzaionDb(_dataOptions);
await func(db);
}
public async Task RunAdmin(Func<AzaionDb, Task> func)
{
await using var db = new AzaionDb(_dataOptionsAdmin);
await func(db);
}
public async Task<T> RunAdmin<T>(Func<AzaionDb, Task<T>> func)
{
await using var db = new AzaionDb(_dataOptionsAdmin);
return await func(db);
}
}