using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nexus.Api.Models; namespace Nexus.Api.Data; /// /// Secret-free metadata for Nexus' one active OpenClaw connection. /// Device private keys, device tokens, bootstrap tokens and provider credentials /// are intentionally outside this entity. /// [Table("OpenClawConnectionProfiles")] public sealed class OpenClawConnectionProfile { public const string PrimaryProfileId = "primary"; [Key] [MaxLength(40)] public string ProfileId { get; set; } = PrimaryProfileId; [MaxLength(2048)] public required string Endpoint { get; set; } [MaxLength(80)] public required string DiscoverySource { get; set; } [MaxLength(120)] public string? RequiredVersion { get; set; } [MaxLength(128)] public string? TlsCertificateFingerprint { get; set; } [MaxLength(40)] public string AdoptionState { get; set; } = OpenClawAdoptionStates.None; public bool ManagementEnabled { get; set; } [MaxLength(128)] public string? CapabilityHash { get; set; } [MaxLength(240)] public string? DeviceId { get; set; } public int Revision { get; set; } public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow; public DateTimeOffset? LastProbedAt { get; set; } public DateTimeOffset? LastVerifiedAt { get; set; } public DateTimeOffset? AdoptedAt { get; set; } } /// /// Kept next to the entity so the root integration only has to apply this /// configuration from NexusDbContext.OnModelCreating. /// public sealed class OpenClawConnectionProfileConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder entity) { entity.ToTable( "OpenClawConnectionProfiles", table => table.HasCheckConstraint( "CK_OpenClawConnectionProfiles_Primary", "\"ProfileId\" = 'primary'")); entity.HasKey(profile => profile.ProfileId); entity.Property(profile => profile.Revision).IsConcurrencyToken(); } }