Files
DodoSSH/src/DodoSSH.Infrastructure/Migrations/DodoDbContextModelSnapshot.cs
T
laurensandClaude Opus 5.5 ef365f462e Spelunk: sign each device in through the browser instead of keeping Spelunk API keys in the vault
A Spelunk API key reaches one organisation, so a server elsewhere - oc-linux in Orange Climate - was
refused before it reached the agent. Each device now signs in to a Spelunk once, under Settings ->
Security -> Spelunk or from a Spelunk host's editor: the OAuth authorization code flow with PKCE for a
native app (RFC 8252), with Spelunk as the authorization server. The browser opens Spelunk's
/api/app-sign-in/authorize with a loopback redirect (the app's own scheme on Android), the person signs
in there however they normally do and allows "DodoSSH on <device>", and the code is redeemed at
/api/app-sign-in/token for an app session token. That token opens terminals in every organisation its
person is in, with the role they have on each server at the time; tunnel tickets send no organisation.

The sign-in stays on the device: sealed in the local cache under the LocalCacheKey (AAD resource type
18, bound to its row), never synced, wiped with the cache, and only ever sent to the Spelunk it came
from. A 401 from Spelunk forgets it; SIGN OUT ends it there and here, and so does signing out of
DodoSSH. Before every Spelunk connection DodoSSH asks its own identity provider whether its sign-in
still stands (a forced refresh, at most once a minute), and an account it refuses is signed out of
DodoSSH and of every Spelunk on the device.

A route names no key any more: Spelunk hosts are written at host schema 11, which an older build shows
read-only and asks to be updated for, and a payload that still names a key credential decodes with the
id skipped. The SpelunkKey item type is gone: SyncEntityType 14, ChangeEntityType 14 and AAD type 17
are retired, the server drops spelunk_key and its change-log rows, and the client cache drops its
cached items, outbox entries and conflicts of that type. A link still never starts a sign-in: from a
Spelunk this device is not signed in to it opens the editor, which offers to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 16:26:25 +02:00

1909 lines
76 KiB
C#

// <auto-generated />
using System;
using DodoSSH.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace DodoSSH.Infrastructure.Migrations
{
[DbContext(typeof(DodoDbContext))]
partial class DodoDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasDefaultSchema("dodo")
.HasAnnotation("ProductVersion", "10.0.10")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "citext");
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("DodoSSH.Domain.Device", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<DateTimeOffset>("EnrolledAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("enrolled_at_utc");
b.Property<DateTimeOffset?>("LastSeenAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("last_seen_at_utc");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)")
.HasColumnName("name");
b.Property<int>("Platform")
.HasColumnType("integer")
.HasColumnName("platform");
b.Property<byte[]>("PublicKey")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("public_key");
b.Property<DateTimeOffset?>("RevokedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("revoked_at_utc");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("pk_device");
b.HasIndex("UserId")
.HasDatabaseName("ix_device_user_id");
b.ToTable("device", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.KeyLogEntry", b =>
{
b.Property<long>("Sequence")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("sequence");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Sequence"));
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<byte[]>("EncryptionPublicKey")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("encryption_public_key");
b.Property<int>("Generation")
.HasColumnType("integer")
.HasColumnName("generation");
b.Property<byte[]>("Hash")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("hash");
b.Property<byte[]>("PreviousHash")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("previous_hash");
b.Property<byte[]>("SigningPublicKey")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("signing_public_key");
b.Property<byte[]>("StatementSignature")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("bytea")
.HasColumnName("statement_signature");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Sequence")
.HasName("pk_key_log");
b.HasIndex("Hash")
.IsUnique()
.HasDatabaseName("ix_key_log_hash");
b.HasIndex("UserId")
.HasDatabaseName("ix_key_log_user_id");
b.ToTable("key_log", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.RelaySession", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("BytesClientToTarget")
.HasColumnType("bigint")
.HasColumnName("bytes_client_to_target");
b.Property<long>("BytesTargetToClient")
.HasColumnType("bigint")
.HasColumnName("bytes_target_to_client");
b.Property<string>("ClientAddress")
.HasMaxLength(45)
.HasColumnType("character varying(45)")
.HasColumnName("client_address");
b.Property<int>("CloseReason")
.HasColumnType("integer")
.HasColumnName("close_reason");
b.Property<DateTimeOffset?>("EndedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("ended_at_utc");
b.Property<Guid>("HostId")
.HasColumnType("uuid")
.HasColumnName("host_id");
b.Property<DateTimeOffset>("StartedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("started_at_utc");
b.Property<string>("TargetAddress")
.HasMaxLength(45)
.HasColumnType("character varying(45)")
.HasColumnName("target_address");
b.Property<string>("TargetHost")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("target_host");
b.Property<int>("TargetPort")
.HasColumnType("integer")
.HasColumnName("target_port");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.HasKey("Id")
.HasName("pk_relay_session");
b.HasIndex("HostId", "StartedAtUtc")
.HasDatabaseName("ix_relay_session_host_id_started_at_utc");
b.HasIndex("UserId", "StartedAtUtc")
.HasDatabaseName("ix_relay_session_user_id_started_at_utc");
b.ToTable("relay_session", "dodo", t =>
{
t.HasCheckConstraint("ck_relay_session_bytes", "bytes_client_to_target >= 0 AND bytes_target_to_client >= 0");
t.HasCheckConstraint("ck_relay_session_port_range", "target_port BETWEEN 1 AND 65535");
});
});
modelBuilder.Entity("DodoSSH.Domain.RelayTicketUse", b =>
{
b.Property<Guid>("TicketId")
.HasColumnType("uuid")
.HasColumnName("ticket_id");
b.Property<DateTimeOffset>("ExpiresAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("expires_at_utc");
b.Property<DateTimeOffset>("UsedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("used_at_utc");
b.HasKey("TicketId")
.HasName("pk_relay_ticket_use");
b.HasIndex("ExpiresAtUtc")
.HasDatabaseName("ix_relay_ticket_use_expires_at_utc");
b.ToTable("relay_ticket_use", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.SshHost", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<string>("Hostname")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("hostname");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<int?>("Port")
.HasColumnType("integer")
.HasColumnName("port");
b.Property<bool>("RelayEnabled")
.HasColumnType("boolean")
.HasColumnName("relay_enabled");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_host");
b.HasIndex("VaultId")
.HasDatabaseName("ix_host_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_host_vault_id_change_sequence");
b.ToTable("host", "dodo", t =>
{
t.HasCheckConstraint("ck_host_port_range", "port IS NULL OR (port BETWEEN 1 AND 65535)");
t.HasCheckConstraint("ck_host_relay_target", "(relay_enabled AND hostname IS NOT NULL AND port IS NOT NULL)\nOR (NOT relay_enabled AND hostname IS NULL AND port IS NULL)");
t.HasCheckConstraint("ck_host_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.SyncOperationReceipt", b =>
{
b.Property<Guid>("OperationId")
.HasColumnType("uuid")
.HasColumnName("operation_id");
b.Property<long?>("AppliedChangeSequence")
.HasColumnType("bigint")
.HasColumnName("applied_change_sequence");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<int?>("ResultVersion")
.HasColumnType("integer")
.HasColumnName("result_version");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.HasKey("OperationId")
.HasName("pk_sync_operation_receipt");
b.HasIndex("VaultId", "CreatedAtUtc")
.HasDatabaseName("ix_sync_operation_receipt_vault_id_created_at_utc");
b.ToTable("sync_operation_receipt", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.Team", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<string>("Description")
.HasMaxLength(2048)
.HasColumnType("character varying(2048)")
.HasColumnName("description");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)")
.HasColumnName("name");
b.Property<string>("Slug")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("citext")
.HasColumnName("slug");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_team");
b.HasIndex("Slug")
.IsUnique()
.HasDatabaseName("ix_team_slug")
.HasFilter("deleted_at_utc IS NULL");
b.ToTable("team", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.TeamMembership", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<Guid?>("InvitedByUserId")
.HasColumnType("uuid")
.HasColumnName("invited_by_user_id");
b.Property<DateTimeOffset?>("JoinedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("joined_at_utc");
b.Property<int>("Role")
.HasColumnType("integer")
.HasColumnName("role");
b.Property<int>("Status")
.HasColumnType("integer")
.HasColumnName("status");
b.Property<Guid>("TeamId")
.HasColumnType("uuid")
.HasColumnName("team_id");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_team_membership");
b.HasIndex("UserId")
.HasDatabaseName("ix_team_membership_user_id");
b.HasIndex("TeamId", "UserId")
.IsUnique()
.HasDatabaseName("ix_team_membership_team_id_user_id")
.HasFilter("deleted_at_utc IS NULL");
b.ToTable("team_membership", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.UserAccount", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<string>("DisplayName")
.HasMaxLength(256)
.HasColumnType("character varying(256)")
.HasColumnName("display_name");
b.Property<string>("Email")
.HasMaxLength(320)
.HasColumnType("citext")
.HasColumnName("email");
b.Property<DateTimeOffset?>("EnrolledAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("enrolled_at_utc");
b.Property<string>("Issuer")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("character varying(512)")
.HasColumnName("issuer");
b.Property<DateTimeOffset?>("LastSeenAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("last_seen_at_utc");
b.Property<int>("Status")
.HasColumnType("integer")
.HasColumnName("status");
b.Property<string>("Subject")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)")
.HasColumnName("subject");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_user_account");
b.HasIndex("Email")
.IsUnique()
.HasDatabaseName("ix_user_account_email")
.HasFilter("email IS NOT NULL AND deleted_at_utc IS NULL");
b.HasIndex("Issuer", "Subject")
.IsUnique()
.HasDatabaseName("ix_user_account_issuer_subject");
b.ToTable("user_account", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.UserKey", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<byte[]>("EncryptionPublicKey")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("encryption_public_key");
b.Property<byte[]>("FingerprintSha256")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("fingerprint_sha256");
b.Property<int>("Generation")
.HasColumnType("integer")
.HasColumnName("generation");
b.Property<string>("IdentityProviderBinding")
.HasColumnType("jsonb")
.HasColumnName("identity_provider_binding");
b.Property<bool>("IsCurrent")
.HasColumnType("boolean")
.HasColumnName("is_current");
b.Property<DateTimeOffset?>("RevokedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("revoked_at_utc");
b.Property<byte[]>("SigningPublicKey")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("signing_public_key");
b.Property<string>("Statement")
.IsRequired()
.HasColumnType("jsonb")
.HasColumnName("statement");
b.Property<byte[]>("StatementSignature")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("bytea")
.HasColumnName("statement_signature");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("pk_user_key");
b.HasIndex("FingerprintSha256")
.IsUnique()
.HasDatabaseName("ix_user_key_fingerprint_sha256");
b.HasIndex("UserId")
.IsUnique()
.HasDatabaseName("ix_user_key_current")
.HasFilter("is_current");
b.HasIndex("UserId", "Generation")
.IsUnique()
.HasDatabaseName("ix_user_key_user_id_generation");
b.ToTable("user_key", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.UserKeyWrap", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid?>("DeviceId")
.HasColumnType("uuid")
.HasColumnName("device_id");
b.Property<string>("KdfAlgorithm")
.HasMaxLength(64)
.HasColumnType("character varying(64)")
.HasColumnName("kdf_algorithm");
b.Property<int?>("KdfMemoryKibibytes")
.HasColumnType("integer")
.HasColumnName("kdf_memory_kibibytes");
b.Property<int?>("KdfParallelism")
.HasColumnType("integer")
.HasColumnName("kdf_parallelism");
b.Property<int?>("KdfPasses")
.HasColumnType("integer")
.HasColumnName("kdf_passes");
b.Property<byte[]>("KdfSalt")
.HasMaxLength(64)
.HasColumnType("bytea")
.HasColumnName("kdf_salt");
b.Property<int>("Kind")
.HasColumnType("integer")
.HasColumnName("kind");
b.Property<DateTimeOffset?>("LastUsedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("last_used_at_utc");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id");
b.Property<byte[]>("Wrap")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("wrap");
b.Property<int>("WrapVersion")
.HasColumnType("integer")
.HasColumnName("wrap_version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_user_key_wrap");
b.HasIndex("DeviceId")
.HasDatabaseName("ix_user_key_wrap_device_id");
b.HasIndex("UserId", "DeviceId")
.IsUnique()
.HasDatabaseName("ix_user_key_wrap_user_device")
.HasFilter("device_id IS NOT NULL");
b.HasIndex("UserId", "Kind")
.IsUnique()
.HasDatabaseName("ix_user_key_wrap_user_kind")
.HasFilter("device_id IS NULL");
b.ToTable("user_key_wrap", "dodo", t =>
{
t.HasCheckConstraint("ck_user_key_wrap_device", "(kind = 2 AND device_id IS NOT NULL) OR (kind <> 2 AND device_id IS NULL)");
t.HasCheckConstraint("ck_user_key_wrap_kdf", "(kind IN (1, 3) AND kdf_algorithm IS NOT NULL AND kdf_salt IS NOT NULL\n AND kdf_memory_kibibytes IS NOT NULL AND kdf_passes IS NOT NULL\n AND kdf_parallelism IS NOT NULL)\nOR (kind IN (2, 4) AND kdf_algorithm IS NULL AND kdf_salt IS NULL)");
});
});
modelBuilder.Entity("DodoSSH.Domain.Vault", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("character varying(256)")
.HasColumnName("name");
b.Property<int>("OwnerKind")
.HasColumnType("integer")
.HasColumnName("owner_kind");
b.Property<Guid?>("OwnerUserId")
.HasColumnType("uuid")
.HasColumnName("owner_user_id");
b.Property<int>("RekeyReason")
.HasColumnType("integer")
.HasColumnName("rekey_reason");
b.Property<bool>("RekeyRequired")
.HasColumnType("boolean")
.HasColumnName("rekey_required");
b.Property<long>("SyncHorizon")
.HasColumnType("bigint")
.HasColumnName("sync_horizon");
b.Property<Guid?>("TeamId")
.HasColumnType("uuid")
.HasColumnName("team_id");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_vault");
b.HasIndex("OwnerUserId")
.HasDatabaseName("ix_vault_owner_user_id");
b.HasIndex("TeamId")
.HasDatabaseName("ix_vault_team_id");
b.ToTable("vault", "dodo", t =>
{
t.HasCheckConstraint("ck_vault_key_generation", "key_generation >= 1");
t.HasCheckConstraint("ck_vault_owner", "(owner_kind = 1 AND owner_user_id IS NOT NULL AND team_id IS NULL)\nOR (owner_kind = 2 AND team_id IS NOT NULL AND owner_user_id IS NULL)");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultActivityLogEntry", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_activity_log_entry");
b.HasIndex("VaultId")
.HasDatabaseName("ix_activity_log_entry_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_activity_log_entry_vault_id_change_sequence");
b.ToTable("activity_log_entry", "dodo", t =>
{
t.HasCheckConstraint("ck_activity_log_entry_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultChange", b =>
{
b.Property<long>("Sequence")
.ValueGeneratedOnAdd()
.HasColumnType("bigint")
.HasColumnName("sequence");
NpgsqlPropertyBuilderExtensions.UseIdentityAlwaysColumn(b.Property<long>("Sequence"));
b.Property<Guid>("ActorUserId")
.HasColumnType("uuid")
.HasColumnName("actor_user_id");
b.Property<Guid>("EntityId")
.HasColumnType("uuid")
.HasColumnName("entity_id");
b.Property<int>("EntityType")
.HasColumnType("integer")
.HasColumnName("entity_type");
b.Property<DateTimeOffset>("OccurredAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("occurred_at_utc");
b.Property<int>("Operation")
.HasColumnType("integer")
.HasColumnName("operation");
b.Property<int>("Revision")
.HasColumnType("integer")
.HasColumnName("revision");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.HasKey("Sequence")
.HasName("pk_sync_change");
b.HasIndex("VaultId", "Sequence")
.HasDatabaseName("ix_sync_change_vault_id_sequence");
b.HasIndex("VaultId", "EntityId", "Sequence")
.IsDescending(false, false, true)
.HasDatabaseName("ix_sync_change_vault_id_entity_id_sequence");
b.ToTable("sync_change", "dodo");
});
modelBuilder.Entity("DodoSSH.Domain.VaultConnectionLogEntry", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_connection_log_entry");
b.HasIndex("VaultId")
.HasDatabaseName("ix_connection_log_entry_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_connection_log_entry_vault_id_change_sequence");
b.ToTable("connection_log_entry", "dodo", t =>
{
t.HasCheckConstraint("ck_connection_log_entry_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultCredential", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_credential");
b.HasIndex("VaultId")
.HasDatabaseName("ix_credential_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_credential_vault_id_change_sequence");
b.ToTable("credential", "dodo", t =>
{
t.HasCheckConstraint("ck_credential_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultHostGroup", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_host_group");
b.HasIndex("VaultId")
.HasDatabaseName("ix_host_group_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_host_group_vault_id_change_sequence");
b.ToTable("host_group", "dodo", t =>
{
t.HasCheckConstraint("ck_host_group_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultKeyGrant", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<byte[]>("GranterKeyFingerprint")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("granter_key_fingerprint");
b.Property<Guid>("GranterUserId")
.HasColumnType("uuid")
.HasColumnName("granter_user_id");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("KeyLogHead")
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("key_log_head");
b.Property<int>("Kind")
.HasColumnType("integer")
.HasColumnName("kind");
b.Property<byte[]>("RecipientKeyFingerprint")
.IsRequired()
.HasMaxLength(32)
.HasColumnType("bytea")
.HasColumnName("recipient_key_fingerprint");
b.Property<Guid?>("RecipientUserId")
.HasColumnType("uuid")
.HasColumnName("recipient_user_id");
b.Property<DateTimeOffset?>("RevokedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("revoked_at_utc");
b.Property<byte[]>("Signature")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("bytea")
.HasColumnName("signature");
b.Property<int>("State")
.HasColumnType("integer")
.HasColumnName("state");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<byte[]>("WrappedKey")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("wrapped_key");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_vault_key_grant");
b.HasIndex("RecipientUserId")
.HasDatabaseName("ix_vault_key_grant_recipient_user_id");
b.HasIndex("VaultId", "KeyGeneration", "RecipientUserId")
.IsUnique()
.HasDatabaseName("ix_vault_key_grant_vault_id_key_generation_recipient_user_id")
.HasFilter("revoked_at_utc IS NULL AND recipient_user_id IS NOT NULL");
b.ToTable("vault_key_grant", "dodo", t =>
{
t.HasCheckConstraint("ck_vault_key_grant_recipient", "(kind = 1 AND recipient_user_id IS NOT NULL) OR (kind <> 1 AND recipient_user_id IS NULL)");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultKnownHostKey", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_known_host_key");
b.HasIndex("VaultId")
.HasDatabaseName("ix_known_host_key_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_known_host_key_vault_id_change_sequence");
b.ToTable("known_host_key", "dodo", t =>
{
t.HasCheckConstraint("ck_known_host_key_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultObjectStore", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_object_store");
b.HasIndex("VaultId")
.HasDatabaseName("ix_object_store_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_object_store_vault_id_change_sequence");
b.ToTable("object_store", "dodo", t =>
{
t.HasCheckConstraint("ck_object_store_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultSnippet", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_snippet");
b.HasIndex("VaultId")
.HasDatabaseName("ix_snippet_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_snippet_vault_id_change_sequence");
b.ToTable("snippet", "dodo", t =>
{
t.HasCheckConstraint("ck_snippet_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultSshKey", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<string>("PublicKeyFingerprint")
.HasMaxLength(128)
.HasColumnType("character varying(128)")
.HasColumnName("public_key_fingerprint");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_ssh_key");
b.HasIndex("VaultId")
.HasDatabaseName("ix_ssh_key_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_ssh_key_vault_id_change_sequence");
b.ToTable("ssh_key", "dodo", t =>
{
t.HasCheckConstraint("ck_ssh_key_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.VaultTag", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<long>("ChangeSequence")
.HasColumnType("bigint")
.HasColumnName("change_sequence");
b.Property<Guid?>("ContentKeyId")
.HasColumnType("uuid")
.HasColumnName("content_key_id");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("created_at_utc");
b.Property<Guid>("CreatedByUserId")
.HasColumnType("uuid")
.HasColumnName("created_by_user_id");
b.Property<byte[]>("DataKeyWrap")
.HasColumnType("bytea")
.HasColumnName("data_key_wrap");
b.Property<DateTimeOffset?>("DeletedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("deleted_at_utc");
b.Property<int>("KeyGeneration")
.HasColumnType("integer")
.HasColumnName("key_generation");
b.Property<byte[]>("Payload")
.IsRequired()
.HasColumnType("bytea")
.HasColumnName("payload");
b.Property<short>("PayloadAadVersion")
.HasColumnType("smallint")
.HasColumnName("payload_aad_version");
b.Property<DateTimeOffset>("UpdatedAtUtc")
.HasColumnType("timestamp with time zone")
.HasColumnName("updated_at_utc");
b.Property<Guid>("UpdatedByUserId")
.HasColumnType("uuid")
.HasColumnName("updated_by_user_id");
b.Property<Guid>("VaultId")
.HasColumnType("uuid")
.HasColumnName("vault_id");
b.Property<int>("Version")
.HasColumnType("integer")
.HasColumnName("version");
b.Property<uint>("xmin")
.IsConcurrencyToken()
.ValueGeneratedOnAddOrUpdate()
.HasColumnType("xid")
.HasColumnName("xmin");
b.HasKey("Id")
.HasName("pk_tag");
b.HasIndex("VaultId")
.HasDatabaseName("ix_tag_vault_live")
.HasFilter("deleted_at_utc IS NULL");
b.HasIndex("VaultId", "ChangeSequence")
.HasDatabaseName("ix_tag_vault_id_change_sequence");
b.ToTable("tag", "dodo", t =>
{
t.HasCheckConstraint("ck_tag_version", "version >= 1");
});
});
modelBuilder.Entity("DodoSSH.Domain.Device", b =>
{
b.HasOne("DodoSSH.Domain.UserAccount", "User")
.WithMany("Devices")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_device_users_user_id");
b.Navigation("User");
});
modelBuilder.Entity("DodoSSH.Domain.SshHost", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany("Hosts")
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_host_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.TeamMembership", b =>
{
b.HasOne("DodoSSH.Domain.Team", "Team")
.WithMany("Memberships")
.HasForeignKey("TeamId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_team_membership_team_team_id");
b.HasOne("DodoSSH.Domain.UserAccount", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_team_membership_users_user_id");
b.Navigation("Team");
b.Navigation("User");
});
modelBuilder.Entity("DodoSSH.Domain.UserKey", b =>
{
b.HasOne("DodoSSH.Domain.UserAccount", "User")
.WithMany("Keys")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_user_key_user_account_user_id");
b.Navigation("User");
});
modelBuilder.Entity("DodoSSH.Domain.UserKeyWrap", b =>
{
b.HasOne("DodoSSH.Domain.Device", "Device")
.WithMany()
.HasForeignKey("DeviceId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_user_key_wrap_device_device_id");
b.HasOne("DodoSSH.Domain.UserAccount", "User")
.WithMany("KeyWraps")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_user_key_wrap_user_account_user_id");
b.Navigation("Device");
b.Navigation("User");
});
modelBuilder.Entity("DodoSSH.Domain.Vault", b =>
{
b.HasOne("DodoSSH.Domain.UserAccount", "OwnerUser")
.WithMany()
.HasForeignKey("OwnerUserId")
.OnDelete(DeleteBehavior.Restrict)
.HasConstraintName("fk_vault_user_account_owner_user_id");
b.HasOne("DodoSSH.Domain.Team", "Team")
.WithMany()
.HasForeignKey("TeamId")
.OnDelete(DeleteBehavior.Restrict)
.HasConstraintName("fk_vault_team_team_id");
b.Navigation("OwnerUser");
b.Navigation("Team");
});
modelBuilder.Entity("DodoSSH.Domain.VaultActivityLogEntry", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_activity_log_entry_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultConnectionLogEntry", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_connection_log_entry_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultCredential", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_credential_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultHostGroup", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_host_group_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultKeyGrant", b =>
{
b.HasOne("DodoSSH.Domain.UserAccount", "RecipientUser")
.WithMany()
.HasForeignKey("RecipientUserId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_vault_key_grant_user_account_recipient_user_id");
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany("KeyGrants")
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_vault_key_grant_vault_vault_id");
b.Navigation("RecipientUser");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultKnownHostKey", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_known_host_key_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultObjectStore", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_object_store_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultSnippet", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_snippet_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultSshKey", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_ssh_key_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.VaultTag", b =>
{
b.HasOne("DodoSSH.Domain.Vault", "Vault")
.WithMany()
.HasForeignKey("VaultId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired()
.HasConstraintName("fk_tag_vaults_vault_id");
b.Navigation("Vault");
});
modelBuilder.Entity("DodoSSH.Domain.Team", b =>
{
b.Navigation("Memberships");
});
modelBuilder.Entity("DodoSSH.Domain.UserAccount", b =>
{
b.Navigation("Devices");
b.Navigation("KeyWraps");
b.Navigation("Keys");
});
modelBuilder.Entity("DodoSSH.Domain.Vault", b =>
{
b.Navigation("Hosts");
b.Navigation("KeyGrants");
});
#pragma warning restore 612, 618
}
}
}