feat: ship agent-first mission control v0.2.57
This commit is contained in:
@@ -11,9 +11,20 @@ public sealed class NexusDbContext(DbContextOptions<NexusDbContext> options) : D
|
||||
public DbSet<NexusUser> Users => Set<NexusUser>();
|
||||
public DbSet<RefreshToken> RefreshTokens => Set<RefreshToken>();
|
||||
public DbSet<SeedAudit> SeedAudits => Set<SeedAudit>();
|
||||
public DbSet<OpenClawRun> OpenClawRuns => Set<OpenClawRun>();
|
||||
public DbSet<OpenClawRunHistory> OpenClawRunHistory => Set<OpenClawRunHistory>();
|
||||
public DbSet<OpenClawConnectionProfile> OpenClawConnectionProfiles =>
|
||||
Set<OpenClawConnectionProfile>();
|
||||
public DbSet<AgentProposal> AgentProposals => Set<AgentProposal>();
|
||||
public DbSet<AgentProvisionRequest> AgentProvisionRequests =>
|
||||
Set<AgentProvisionRequest>();
|
||||
public DbSet<OperationClaim> OperationClaims => Set<OperationClaim>();
|
||||
public DbSet<OutboxEvent> OutboxEvents => Set<OutboxEvent>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.ApplyConfiguration(new OpenClawConnectionProfileConfiguration());
|
||||
ConfigureAgentProvisioning(modelBuilder);
|
||||
modelBuilder.Entity<Project>().Property(x => x.Name).HasMaxLength(160);
|
||||
modelBuilder.Entity<WorkTask>(entity =>
|
||||
{
|
||||
@@ -26,6 +37,20 @@ public sealed class NexusDbContext(DbContextOptions<NexusDbContext> options) : D
|
||||
entity.HasIndex(x => x.AssignedTo);
|
||||
entity.HasIndex(x => x.IsAgentTask);
|
||||
entity.HasIndex(x => x.ExpectedFrom);
|
||||
entity.HasIndex(x => new { x.State, x.UpdatedAt, x.Id })
|
||||
.IsDescending(false, true, false)
|
||||
.HasDatabaseName("IX_Tasks_State_UpdatedAt_Id_Board");
|
||||
entity.HasIndex(x => new { x.UpdatedAt, x.Id })
|
||||
.IsDescending(true, true)
|
||||
.HasFilter("\"State\" = 'Done'")
|
||||
.HasDatabaseName("IX_Tasks_Done_UpdatedAt_Id");
|
||||
entity.HasIndex(x => new { x.ParentTaskId, x.State })
|
||||
.HasFilter("\"ParentTaskId\" IS NOT NULL")
|
||||
.HasDatabaseName("IX_Tasks_ParentTaskId_State");
|
||||
entity.HasIndex(x => new { x.ExpectedFrom, x.State, x.UpdatedAt, x.Id })
|
||||
.IsDescending(false, false, true, false)
|
||||
.HasFilter("\"IsAgentTask\" = TRUE")
|
||||
.HasDatabaseName("IX_Tasks_AgentWorkflow");
|
||||
entity.HasOne(x => x.ParentTask)
|
||||
.WithMany(x => x.ChildTasks)
|
||||
.HasForeignKey(x => x.ParentTaskId)
|
||||
@@ -44,6 +69,10 @@ public sealed class NexusDbContext(DbContextOptions<NexusDbContext> options) : D
|
||||
{
|
||||
entity.Property(x => x.Message).HasMaxLength(1000);
|
||||
entity.HasIndex(x => x.TaskId);
|
||||
entity.HasIndex(x => new { x.TaskId, x.CreatedAt, x.Id })
|
||||
.IsDescending(false, true, true)
|
||||
.HasFilter("\"TaskId\" IS NOT NULL")
|
||||
.HasDatabaseName("IX_Activity_TaskId_CreatedAt_Id");
|
||||
});
|
||||
modelBuilder.Entity<NexusUser>().HasIndex(u => u.NormalizedEmail).IsUnique();
|
||||
modelBuilder.Entity<RefreshToken>().HasIndex(r => r.TokenHash).IsUnique();
|
||||
@@ -56,5 +85,134 @@ public sealed class NexusDbContext(DbContextOptions<NexusDbContext> options) : D
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<ActivityEvent>().HasIndex(x => x.CreatedAt);
|
||||
|
||||
modelBuilder.Entity<OpenClawRun>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Title).HasMaxLength(160);
|
||||
entity.Property(x => x.Prompt).HasColumnType("text");
|
||||
entity.Property(x => x.AgentId).HasMaxLength(200);
|
||||
entity.Property(x => x.SessionKey).HasMaxLength(500);
|
||||
entity.Property(x => x.Status).HasMaxLength(40);
|
||||
entity.Property(x => x.OpenClawRunId).HasMaxLength(240);
|
||||
entity.Property(x => x.StartIdempotencyKey).HasMaxLength(200);
|
||||
entity.Property(x => x.CorrelationId).HasMaxLength(200);
|
||||
entity.Property(x => x.Actor).HasMaxLength(240);
|
||||
entity.Property(x => x.TraceParent).HasMaxLength(128);
|
||||
entity.Property(x => x.LastError).HasMaxLength(2000);
|
||||
entity.Property(x => x.Revision).IsConcurrencyToken();
|
||||
entity.HasIndex(x => x.StartIdempotencyKey).IsUnique();
|
||||
entity.HasIndex(x => x.OpenClawRunId).IsUnique();
|
||||
entity.HasIndex(x => new { x.Status, x.UpdatedAt });
|
||||
entity.HasIndex(x => x.TaskId);
|
||||
entity.HasIndex(x => x.ProjectId);
|
||||
entity.HasIndex(x => x.SessionKey);
|
||||
entity.HasIndex(x => x.RetriedFromRunId);
|
||||
entity.HasOne<WorkTask>()
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.TaskId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
entity.HasOne<Project>()
|
||||
.WithMany()
|
||||
.HasForeignKey(x => x.ProjectId)
|
||||
.OnDelete(DeleteBehavior.SetNull);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<OpenClawRunHistory>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Action).HasMaxLength(80);
|
||||
entity.Property(x => x.FromStatus).HasMaxLength(40);
|
||||
entity.Property(x => x.ToStatus).HasMaxLength(40);
|
||||
entity.Property(x => x.Message).HasMaxLength(2000);
|
||||
entity.Property(x => x.Actor).HasMaxLength(240);
|
||||
entity.Property(x => x.CorrelationId).HasMaxLength(200);
|
||||
entity.Property(x => x.IdempotencyKey).HasMaxLength(200);
|
||||
entity.Property(x => x.TraceParent).HasMaxLength(128);
|
||||
entity.Property(x => x.GatewayEventId).HasMaxLength(120);
|
||||
entity.HasIndex(x => new { x.RunId, x.OccurredAt });
|
||||
entity.HasIndex(x => new { x.RunId, x.Action, x.IdempotencyKey }).IsUnique();
|
||||
entity.HasIndex(x => x.GatewayEventId).IsUnique();
|
||||
entity.HasOne(x => x.Run)
|
||||
.WithMany(x => x.History)
|
||||
.HasForeignKey(x => x.RunId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
}
|
||||
|
||||
private static void ConfigureAgentProvisioning(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<AgentProposal>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Source).HasMaxLength(40);
|
||||
entity.Property(x => x.RequestedName).HasMaxLength(80);
|
||||
entity.Property(x => x.RequestedAgentId).HasMaxLength(64);
|
||||
entity.Property(x => x.Role).HasMaxLength(160);
|
||||
entity.Property(x => x.Description).HasMaxLength(4000);
|
||||
entity.Property(x => x.Model).HasMaxLength(240);
|
||||
entity.Property(x => x.Emoji).HasMaxLength(32);
|
||||
entity.Property(x => x.Avatar).HasMaxLength(2048);
|
||||
entity.Property(x => x.Workspace).HasMaxLength(2048);
|
||||
entity.Property(x => x.StandardFilesJson).HasColumnType("jsonb");
|
||||
entity.Property(x => x.StandardFilesHash).HasMaxLength(64);
|
||||
entity.Property(x => x.Status).HasMaxLength(40);
|
||||
entity.Property(x => x.RequestedBy).HasMaxLength(240);
|
||||
entity.Property(x => x.ApprovedBy).HasMaxLength(240);
|
||||
entity.Property(x => x.RejectedBy).HasMaxLength(240);
|
||||
entity.Property(x => x.RejectionReason).HasMaxLength(1000);
|
||||
entity.Property(x => x.OpenClawAgentId).HasMaxLength(128);
|
||||
entity.Property(x => x.OpenClawWorkspace).HasMaxLength(2048);
|
||||
entity.Property(x => x.LastErrorCode).HasMaxLength(120);
|
||||
entity.Property(x => x.LastErrorMessage).HasMaxLength(2000);
|
||||
entity.Property(x => x.Revision).IsConcurrencyToken();
|
||||
entity.HasIndex(x => new { x.Status, x.UpdatedAt });
|
||||
entity.HasIndex(x => x.RequestedAgentId);
|
||||
entity.HasIndex(x => x.OpenClawAgentId);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<AgentProvisionRequest>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Stage).HasMaxLength(40);
|
||||
entity.Property(x => x.Status).HasMaxLength(40);
|
||||
entity.Property(x => x.IdempotencyKeyHash).HasMaxLength(64);
|
||||
entity.Property(x => x.Actor).HasMaxLength(240);
|
||||
entity.Property(x => x.CorrelationId).HasMaxLength(200);
|
||||
entity.Property(x => x.TraceParent).HasMaxLength(128);
|
||||
entity.Property(x => x.OpenClawAgentId).HasMaxLength(128);
|
||||
entity.Property(x => x.LastErrorCode).HasMaxLength(120);
|
||||
entity.Property(x => x.LastErrorMessage).HasMaxLength(2000);
|
||||
entity.Property(x => x.LeaseOwner).HasMaxLength(160);
|
||||
entity.Property(x => x.Revision).IsConcurrencyToken();
|
||||
entity.HasIndex(x => new { x.ProposalId, x.Attempt }).IsUnique();
|
||||
entity.HasIndex(x => new { x.Status, x.CreatedAt });
|
||||
entity.HasIndex(x => x.LeaseUntil);
|
||||
entity.HasOne(x => x.Proposal)
|
||||
.WithMany(x => x.ProvisionRequests)
|
||||
.HasForeignKey(x => x.ProposalId)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<OperationClaim>(entity =>
|
||||
{
|
||||
entity.Property(x => x.Operation).HasMaxLength(100);
|
||||
entity.Property(x => x.IdempotencyKeyHash).HasMaxLength(64);
|
||||
entity.Property(x => x.RequestHash).HasMaxLength(64);
|
||||
entity.Property(x => x.State).HasMaxLength(40);
|
||||
entity.Property(x => x.ResultCode).HasMaxLength(120);
|
||||
entity.HasIndex(x => new { x.Operation, x.IdempotencyKeyHash }).IsUnique();
|
||||
entity.HasIndex(x => x.ExpiresAt);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<OutboxEvent>(entity =>
|
||||
{
|
||||
entity.HasKey(x => x.Sequence);
|
||||
entity.Property(x => x.Sequence).ValueGeneratedOnAdd();
|
||||
entity.Property(x => x.Type).HasMaxLength(120);
|
||||
entity.Property(x => x.AggregateType).HasMaxLength(80);
|
||||
entity.Property(x => x.AggregateId).HasMaxLength(128);
|
||||
entity.Property(x => x.PayloadJson).HasColumnType("jsonb");
|
||||
entity.Property(x => x.LastErrorCode).HasMaxLength(120);
|
||||
entity.HasIndex(x => x.EventId).IsUnique();
|
||||
entity.HasIndex(x => new { x.PublishedAt, x.Sequence });
|
||||
entity.HasIndex(x => x.OccurredAt);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user