88 lines
2.9 KiB
C#
88 lines
2.9 KiB
C#
using ControlCenter.Api.Entities;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||
|
||
namespace ControlCenter.Api.Configurations;
|
||
|
||
/// <summary>
|
||
/// EF Core entity type configuration for the agents table.
|
||
/// Enforces snake_case naming, required fields, and index design.
|
||
/// </summary>
|
||
public class AgentConfiguration : IEntityTypeConfiguration<Agent>
|
||
{
|
||
public void Configure(EntityTypeBuilder<Agent> builder)
|
||
{
|
||
// Table name — snake_case
|
||
builder.ToTable("agents");
|
||
|
||
// Primary key
|
||
builder.HasKey(a => a.Id);
|
||
builder.Property(a => a.Id)
|
||
.HasColumnName("id")
|
||
.ValueGeneratedOnAdd();
|
||
|
||
// Status — stored as PostgreSQL enum via Npgsql
|
||
builder.Property(a => a.Status)
|
||
.HasColumnName("status")
|
||
.HasColumnType("agent_status")
|
||
.IsRequired();
|
||
|
||
// Task — nullable text
|
||
builder.Property(a => a.Task)
|
||
.HasColumnName("task")
|
||
.HasColumnType("text");
|
||
|
||
// Progress — nullable integer (0–100)
|
||
builder.Property(a => a.Progress)
|
||
.HasColumnName("progress");
|
||
|
||
// Session key — required, not null
|
||
builder.Property(a => a.SessionKey)
|
||
.HasColumnName("session_key")
|
||
.HasColumnType("text")
|
||
.IsRequired();
|
||
|
||
// Channel — required, not null
|
||
builder.Property(a => a.Channel)
|
||
.HasColumnName("channel")
|
||
.HasColumnType("text")
|
||
.IsRequired();
|
||
|
||
// Last activity — required, defaults to now()
|
||
builder.Property(a => a.LastActivity)
|
||
.HasColumnName("last_activity")
|
||
.HasColumnType("timestamptz")
|
||
.IsRequired();
|
||
|
||
// Created at — auto-set on insert
|
||
builder.Property(a => a.CreatedAt)
|
||
.HasColumnName("created_at")
|
||
.HasColumnType("timestamptz")
|
||
.IsRequired()
|
||
.HasDefaultValueSql("now()");
|
||
|
||
// Updated at — auto-set on insert and update
|
||
builder.Property(a => a.UpdatedAt)
|
||
.HasColumnName("updated_at")
|
||
.HasColumnType("timestamptz")
|
||
.IsRequired()
|
||
.HasDefaultValueSql("now()");
|
||
|
||
// Indexes
|
||
// Sessions are looked up by session_key frequently
|
||
builder.HasIndex(a => a.SessionKey)
|
||
.HasDatabaseName("ix_agents_session_key")
|
||
.IsUnique();
|
||
|
||
// Agents are filtered by channel for channel-specific queries
|
||
builder.HasIndex(a => a.Channel)
|
||
.HasDatabaseName("ix_agents_channel");
|
||
|
||
// Agents are filtered by status for fleet health monitoring
|
||
builder.HasIndex(a => a.Status)
|
||
.HasDatabaseName("ix_agents_status");
|
||
|
||
// Check constraint: progress must be 0–100 if present
|
||
builder.ToTable(t => t.HasCheckConstraint("ck_agents_progress_range", "progress IS NULL OR (progress >= 0 AND progress <= 100)"));
|
||
}
|
||
} |