Spensara Spensara Knowledge Base & Documentation Repository

Repository Docs & Knowledge Base

Consolidated Spensara documentation repository (722 Markdown & architecture documents in ../repository)
Built Word Documents (.docx): Spensara Overview (.docx) Capability Assessment (.docx) Brink POS Ingestion Analysis (.docx) The Borg Ingestion Architecture (.docx)

Implementation Specs (157)

Detailed engineering and feature implementation specifications.
implementation-specs/specs/AnomalyDetection/TASK1.1.md 4,659 bytes · Updated Oct 23, 2026 10:44 AM EDT
Raw File

TASK 1.1: Create MonitorSpec Entity and EF Configuration

Summary

Create the MonitorSpec entity that represents a versioned, executable monitor definition stored in the database. This is the core configuration object that defines what the anomaly detector should monitor.

Dependencies

  • None (first task)

Files to Create

1. backend/Kds.Ai.Data/Entities/MonitorSpec.cs

csharp
using Kds.Ai.Data.Enums;

namespace Kds.Ai.Data.Entities;

public sealed class MonitorSpec
{
    public Guid Id { get; set; }
    
    /// <summary>
    /// Human-readable name for the monitor (e.g., "Prep Time Anomaly Monitor")
    /// </summary>
    public required string Name { get; set; }
    
    /// <summary>
    /// LLM system prompt that defines the agent's behavior
    /// </summary>
    public required string SystemPrompt { get; set; }
    
    /// <summary>
    /// JSON configuration for thresholds, lookback periods, etc.
    /// </summary>
    public string? Configuration { get; set; }
    
    /// <summary>
    /// Current state of the monitor (Draft, Active, Paused, Archived)
    /// </summary>
    public MonitorState State { get; set; }
    
    /// <summary>
    /// When this monitor spec was created
    /// </summary>
    public DateTimeOffset CreatedAt { get; set; }
    
    /// <summary>
    /// When this monitor was last updated
    /// </summary>
    public DateTimeOffset? UpdatedAt { get; set; }
    
    /// <summary>
    /// Timestamp of the last successful run
    /// </summary>
    public DateTimeOffset? LastRunAt { get; set; }
    
    /// <summary>
    /// Navigation property to execution history
    /// </summary>
    public ICollection<MonitorRun> Runs { get; set; } = [];
}

2. backend/Kds.Ai.Data/Enums/MonitorState.cs

csharp
namespace Kds.Ai.Data.Enums;

/// <summary>
/// Represents the lifecycle state of a monitor specification
/// </summary>
public enum MonitorState
{
    /// <summary>
    /// Monitor is being configured and is not yet ready to run
    /// </summary>
    Draft,
    
    /// <summary>
    /// Monitor is active and will be executed on schedule
    /// </summary>
    Active,
    
    /// <summary>
    /// Monitor is temporarily paused and will not run
    /// </summary>
    Paused,
    
    /// <summary>
    /// Monitor is archived and no longer in use
    /// </summary>
    Archived
}

3. backend/Kds.Ai.Data/Configurations/MonitorSpecConfiguration.cs

csharp
using Kds.Ai.Data.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Kds.Ai.Data.Configurations;

public sealed class MonitorSpecConfiguration : IEntityTypeConfiguration<MonitorSpec>
{
    public void Configure(EntityTypeBuilder<MonitorSpec> builder)
    {
        builder.ToTable("MonitorSpecs");
        
        builder.HasKey(x => x.Id);
        
        builder.Property(x => x.Name)
            .IsRequired()
            .HasMaxLength(200);
        
        builder.Property(x => x.SystemPrompt)
            .IsRequired()
            .HasColumnType("longtext");
        
        builder.Property(x => x.Configuration)
            .HasColumnType("longtext");
        
        builder.Property(x => x.State)
            .IsRequired()
            .HasMaxLength(50);
        
        builder.Property(x => x.CreatedAt)
            .IsRequired();
        
        // Indexes for common queries
        builder.HasIndex(x => x.Name);
        builder.HasIndex(x => x.State);
    }
}

Files to Modify

4. backend/Kds.Ai.Data/KdsAiDbContext.cs

Add DbSet property:

csharp
public DbSet<MonitorSpec> MonitorSpecs => Set<MonitorSpec>();

Note: Configuration is automatically applied via ApplyConfigurationsFromAssembly - no manual registration needed.

Acceptance Criteria

  • [ ] MonitorSpec entity created with all specified properties
  • [ ] MonitorState enum created with Draft, Active, Paused, Archived values
  • [ ] Fluent API configuration follows project conventions (no data annotations on entity)
  • [ ] Enum properties converted to strings (per project convention via ConfigureConventions)
  • [ ] Proper indexes defined for Name and State
  • [ ] DbSet registered in KdsAiDbContext
  • [ ] Solution builds without errors

Notes

  • Follow existing patterns from AlertEvent entity and AlertEventConfiguration
  • The Configuration field stores JSON; parsing will be handled at the service layer
  • MonitorRun navigation property will be populated in TASK 1.2
  • Use sealed class modifier per project convention
  • Configurations are auto-discovered via ApplyConfigurationsFromAssembly