# Module: Azaion.Services.DetectionClassService ## Purpose CRUD service for `DetectionClass` rows backing the admin Detection Classes table. Wraps `IDbFactory.RunAdmin` calls and translates request DTOs into entity writes. > **Cycle 1 (2026-05-13) origin** — added by AZ-513. ## Public Interface ### IDetectionClassService | Method | Signature | Description | |--------|-----------|-------------| | `Create` | `Task Create(CreateDetectionClassRequest request, CancellationToken ct)` | Inserts a new class; returns the entity with the DB-assigned `Id` | | `Update` | `Task Update(int id, UpdateDetectionClassRequest request, CancellationToken ct)` | Partial-merge update; returns `null` when the id doesn't exist | | `Delete` | `Task Delete(int id, CancellationToken ct)` | Returns `true` when at least one row was deleted; `false` when the id wasn't present | ## Internal Logic - **Create**: instantiates `DetectionClass`, sets `CreatedAt = DateTime.UtcNow`, calls `db.InsertWithInt32IdentityAsync`, assigns the returned id back to the entity, returns it. - **Update**: loads the row by id under the admin connection, returns `null` if missing. Otherwise applies a null-aware merge: each non-null property on the request overwrites the entity, then `db.UpdateAsync(existing)` persists the row. The route returns 404 when the service returns null. - **Delete**: `db.DetectionClasses.DeleteAsync(x => x.Id == id, ct)`; returns `deleted > 0`. The route returns 404 when the service returns false. All writes go through `IDbFactory.RunAdmin` (admin DB connection / role). ## Dependencies - `IDbFactory` (`Azaion.Common.Database.IDbFactory`) - `DetectionClass` entity - `CreateDetectionClassRequest`, `UpdateDetectionClassRequest` - `LinqToDB` extension methods (`FirstOrDefaultAsync`, `InsertWithInt32IdentityAsync`, `UpdateAsync`, `DeleteAsync`) ## Consumers - `Azaion.AdminApi.Program` — `POST /classes`, `PATCH /classes/{id:int}`, `DELETE /classes/{id:int}` handlers ## Data Models Operates on `DetectionClass` via `AzaionDb.DetectionClasses`. ## Configuration None. ## External Integrations PostgreSQL via `IDbFactory.RunAdmin`. ## Security - All endpoints that delegate to this service require `apiAdminPolicy` at the route level. - Validators run before the service (no extra defensive validation inside the service). ## Tests - `e2e/Azaion.E2E/Tests/DetectionClassesTests.cs` — covers AZ-513 ACs 1–9