docs: native alarm ingestion across component docs + CLAUDE.md

This commit is contained in:
Joseph Doherty
2026-05-31 02:55:00 -04:00
parent 2b7c765a58
commit 003e54c1fb
9 changed files with 265 additions and 6 deletions
@@ -32,10 +32,12 @@ The configuration database stores all central system data, organized by domain a
- **TemplateFolders**: Hierarchical organizational folders for templates (`Id`, `Name`, nullable `ParentFolderId` self-reference, `SortOrder`). Unique index on `(ParentFolderId, Name)` enforces case-insensitive sibling uniqueness. Folders are UI-only — they have no effect on template resolution or flattening.
- **Template Attributes**: Attribute definitions per template (name, value, data type, lock flag, description, data source reference).
- **Template Alarms**: Alarm definitions per template (name, description, priority, lock flag, trigger type, trigger configuration, on-trigger script reference).
- **Native Alarm Sources** (`NativeAlarmSources`): Native alarm source bindings per template — alarms produced by the underlying data source rather than evaluated by the Site Runtime. Columns: `Name`, `Description`, `ConnectionName` (the data connection that surfaces the native alarms), `SourceReference` (the source-side address/path the native alarms are read from), and `ConditionFilter` (optional filter narrowing which native alarm conditions are subscribed). FK `TemplateId``Templates` with cascade delete; unique index on `(TemplateId, Name)`.
- **Template Scripts**: Script definitions per template (name, lock flag, C# source code, trigger type, trigger configuration, minimum time between runs, parameter definitions, return value definitions).
- **Template Compositions**: Feature module composition relationships (composing template, composed template, module instance name).
- **Instances**: Instance definitions (template reference, site reference, area reference, enabled/disabled state).
- **Instance Attribute Overrides**: Per-instance attribute value overrides.
- **Instance Native Alarm Source Overrides** (`InstanceNativeAlarmSourceOverrides`): Per-instance overrides for native alarm sources, keyed by the source's path-qualified canonical name. Columns: `SourceCanonicalName` (required, sized to fit composed `[ModuleInstanceName].[SourceName]` paths) and the nullable override fields `ConnectionNameOverride`, `SourceReferenceOverride`, and `ConditionFilterOverride` (a null override leaves the template value in effect). FK `InstanceId``Instances` with cascade delete; unique index on `(InstanceId, SourceCanonicalName)`.
- **Instance Connection Bindings**: Per-attribute data connection binding for each instance.
- **Areas**: Hierarchical area definitions per site (name, parent area reference, site reference).
@@ -90,13 +92,24 @@ A single `ScadaBridgeDbContext` (or a small number of bounded DbContexts if warr
- Configures relationships, indexes, constraints, and value conversions.
- Provides `SaveChangesAsync()` as the unit-of-work commit mechanism.
Each entity's Fluent mapping lives in its own `IEntityTypeConfiguration<T>` class under `Configurations/`, and `OnModelCreating` registers them all with `modelBuilder.ApplyConfigurationsFromAssembly(...)` — so a new mapping is picked up simply by adding its configuration class to the assembly.
#### Native Alarm Source Mappings
The native alarm source feature adds two EF-mapped entities (POCOs in Commons, Fluent mappings here), each exposed as a `DbSet` on `ScadaBridgeDbContext`:
- **`TemplateNativeAlarmSource`** → table `NativeAlarmSources` (`DbSet<TemplateNativeAlarmSource> TemplateNativeAlarmSources`). `Name` required (≤200), `Description` (≤2000), `ConnectionName` required (≤200), `SourceReference` required (≤1000), `ConditionFilter` (≤1000). Unique index `(TemplateId, Name)`. Owned by `Template` via `TemplateConfiguration` (`HasMany(t => t.NativeAlarmSources)` on FK `TemplateId`, `OnDelete: Cascade`) — deleting a template removes its native alarm sources.
- **`InstanceNativeAlarmSourceOverride`** → table `InstanceNativeAlarmSourceOverrides` (`DbSet<InstanceNativeAlarmSourceOverride> InstanceNativeAlarmSourceOverrides`). `SourceCanonicalName` required (≤400, wider than plain names so it can hold composed paths), `ConnectionNameOverride` (≤200), `SourceReferenceOverride` (≤1000), `ConditionFilterOverride` (≤1000). Unique index `(InstanceId, SourceCanonicalName)`. Owned by `Instance` via `InstanceConfiguration` (`HasMany(i => i.NativeAlarmSourceOverrides)` on FK `InstanceId`, `OnDelete: Cascade`).
Both mappings follow the same shape as the existing alarm definitions and alarm overrides: dedicated configuration classes that auto-register through `ApplyConfigurationsFromAssembly`, cascade-delete from their owning aggregate root, and a composite unique index that enforces name uniqueness within the owner.
### Per-Component Repository Implementations
Repository interfaces are defined in **Commons** alongside the POCO entity classes (see Component-Commons.md, REQ-COM-4). This component provides the **EF Core implementations** of those interfaces.
| Repository Interface (in Commons) | Consuming Component | Scope |
|---|---|---|
| `ITemplateEngineRepository` | Template Engine | Templates, attributes, alarms, scripts, compositions, instances, overrides, connection bindings, areas |
| `ITemplateEngineRepository` | Template Engine | Templates, attributes, alarms, native alarm sources, scripts, compositions, instances, overrides (including native alarm source overrides), connection bindings, areas |
| `IDeploymentManagerRepository` | Deployment Manager | Current deployment status per instance, deployed configuration snapshots, system-wide artifact deployment status per site (no deployment history — audit log provides historical traceability) |
| `ISecurityRepository` | Security & Auth | LDAP group mappings, site scoping rules |
| `IInboundApiRepository` | Inbound API | API keys, API method definitions |
@@ -109,6 +122,15 @@ Repository interfaces are defined in **Commons** alongside the POCO entity class
Each implementation class uses the DbContext internally and works with the POCO entity classes from Commons. Consuming components depend only on Commons (for interfaces and entities) — they never reference this component or EF Core directly. The DI container in the Host wires the implementations to the interfaces.
#### Native Alarm Source Repository Methods
`ITemplateEngineRepository` (implemented by `TemplateEngineRepository`) gains CRUD for both native alarm source entities, mirroring the existing alarm-override methods one-for-one:
- **Template side**: `GetTemplateNativeAlarmSourceByIdAsync`, `GetNativeAlarmSourcesByTemplateIdAsync`, `AddTemplateNativeAlarmSourceAsync`, `UpdateTemplateNativeAlarmSourceAsync`, `DeleteTemplateNativeAlarmSourceAsync`.
- **Instance side**: `GetNativeAlarmSourceOverridesByInstanceIdAsync`, `GetNativeAlarmSourceOverrideAsync(instanceId, sourceCanonicalName)`, `AddInstanceNativeAlarmSourceOverrideAsync`, `UpdateInstanceNativeAlarmSourceOverrideAsync`, `DeleteInstanceNativeAlarmSourceOverrideAsync`.
The aggregate loaders are extended to eager-load the new children so a template or instance is returned fully populated: `GetTemplateWithChildrenAsync` (and the other template loaders) `.Include(t => t.NativeAlarmSources)`, and the instance-with-children loader `.Include(i => i.NativeAlarmSourceOverrides)` alongside its existing attribute, alarm, and connection-binding includes. Consistent with every other repository method here, the `Add`/`Update`/`Delete` operations only **stage** changes on the DbContext — the caller commits them by invoking `SaveChangesAsync()` (typically together with the matching `IAuditService.LogAsync()` call in one transaction).
### Unit of Work
EF Core's DbContext naturally provides unit-of-work semantics:
@@ -248,6 +270,7 @@ A CI grep guard fails the build on any occurrence of `UPDATE … AuditLog` or `D
- Schema changes are managed via EF Core Migrations (`dotnet ef migrations add`, `dotnet ef migrations script`).
- Each migration is a versioned, incremental schema change.
- New tables are introduced as their own migration — for example, the `Notifications` table for the Notification Outbox ships as a dedicated EF Core migration that creates the table, its `Type`/`Status` value conversions, and its dispatcher and KPI indexes.
- The native alarm source tables ship in a dedicated `AddNativeAlarmSources` migration, parallel in shape to the existing `AddInstanceAlarmOverrides` migration: it creates `NativeAlarmSources` and `InstanceNativeAlarmSourceOverrides` with their columns, the `TemplateId``Templates` and `InstanceId``Instances` cascade-delete foreign keys, and the `(TemplateId, Name)` / `(InstanceId, SourceCanonicalName)` unique indexes.
- The initial `AuditLog` migration creates the monthly partition function `pf_AuditLog_Month` and partition scheme `ps_AuditLog_Month`, then creates the `AuditLog` table aligned to that scheme on `OccurredAtUtc`, along with the indexes listed under Database Schema. The migration also creates the `scadabridge_audit_writer` and `scadabridge_audit_purger` DB roles with the grants described in Database Roles. The ongoing **partition-maintenance job** that rolls the scheme forward each month (creating the next month's partition ahead of time) and switches out expired partitions is owned by the **Audit Log component** (`AuditLogPurgeActor` and its monthly roll-forward step), not by the Configuration Database component — this component is responsible only for the initial schema, roles, and any EF migrations against the table going forward.
### Development Environment