using DodoSSH.Domain; using Microsoft.EntityFrameworkCore; namespace DodoSSH.Infrastructure; /// /// The application database context. /// /// /// /// Everything lives in the dodo schema with snake_case names. Timestamps are /// timestamptz and always UTC, so there is no tzdata dependency and no conflict with /// InvariantGlobalization. /// /// /// Two concurrency mechanisms coexist deliberately. Version on item rows is the /// client-visible, monotonic value used for expectedVersion conflict detection. /// xmin is the server-side optimistic guard and is never exposed, because it is not stable /// across VACUUM FREEZE and must never become a client cursor. /// /// public class DodoDbContext(DbContextOptions options) : DbContext(options) { /// The database schema every table lives in. public const string SchemaName = "dodo"; /// User accounts. public DbSet Users => Set(); /// Identity key generations. public DbSet UserKeys => Set(); /// Wraps of users' secret bundles. public DbSet UserKeyWraps => Set(); /// Enrolled devices. public DbSet Devices => Set(); /// The append-only key transparency log. public DbSet KeyLog => Set(); /// Teams. public DbSet Teams => Set(); /// Team memberships. public DbSet TeamMemberships => Set(); /// Vaults. public DbSet Vaults => Set(); /// Wrapped vault keys. public DbSet VaultKeyGrants => Set(); /// SSH hosts. public DbSet Hosts => Set(); /// The per-vault change log that delta sync reads. public DbSet VaultChanges => Set(); /// Applied-operation receipts, for exactly-once retries. public DbSet SyncOperationReceipts => Set(); /// protected override void OnModelCreating(ModelBuilder modelBuilder) { ArgumentNullException.ThrowIfNull(modelBuilder); modelBuilder.HasDefaultSchema(SchemaName); modelBuilder.HasPostgresExtension("citext"); modelBuilder.ApplyConfigurationsFromAssembly(typeof(DodoDbContext).Assembly); base.OnModelCreating(modelBuilder); } }