< Summary - Heimdall API

Line coverage
100%
Covered lines: 942
Uncovered lines: 0
Coverable lines: 942
Total lines: 1042
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
100%
Covered methods: 3
Fully covered methods: 3
Total methods: 3
Method coverage: 100%
Full method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: Up(...)100%11100%
File 1: Down(...)100%11100%
File 2: BuildTargetModel(...)100%11100%

File(s)

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Infrastructure/ArturRios.Heimdall.Data/Migrations/20260814203528_AddPersonScopeId.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore.Migrations;
 2
 3#nullable disable
 4
 5namespace ArturRios.Heimdall.Data.Migrations
 6{
 7    /// <summary>
 8    ///     Adds PERSON.scope_id — a copy of the owning SCOPE_USER row's scope — and the partial
 9    ///     unique index it exists to make possible, closing the last email-uniqueness rule that
 10    ///     nothing but a check-then-insert enforced (FR-PE-09).
 11    /// </summary>
 12    /// <remarks>
 13    ///     The scope of a User lives in SCOPE_USER and the address in PERSON, and a PostgreSQL unique
 14    ///     index covers one table — so the per-scope rule could only ever be a read followed by a
 15    ///     write, which two concurrent creates both pass. The loser of that race became a person who
 16    ///     could never authenticate, because UC-11's lookup resolves one row and stops.
 17    ///
 18    ///     A trigger would not have helped: under READ COMMITTED both inserts see the same pre-write
 19    ///     snapshot, so both would find the address free. Only a unique index serialises them, and an
 20    ///     index needs the columns on one table.
 21    /// </remarks>
 22    public partial class AddPersonScopeId : Migration
 23    {
 24        /// <inheritdoc />
 25        protected override void Up(MigrationBuilder migrationBuilder)
 26        {
 1927            migrationBuilder.AddColumn<long>(
 1928                name: "scope_id",
 1929                schema: "heimdall",
 1930                table: "person",
 1931                type: "bigint",
 1932                nullable: true);
 33
 34            // Backfill from the relationship this column copies, so the index below can be created
 35            // over existing data rather than only over rows written from here on.
 1936            migrationBuilder.Sql(
 1937                """
 1938                UPDATE heimdall.person AS p
 1939                SET scope_id = su.scope_id
 1940                FROM heimdall.scope_user AS su
 1941                WHERE su.person_id = p.id;
 1942                """);
 43
 44            // FR-PE-09, User half. The condition matches CreateUserCommandHandler's check term for
 45            // term — the scope, a case-insensitive address, role User (3), and not logically deleted
 46            // — so the rule does not change; it simply becomes one the database can hold under
 47            // concurrency. A logically deleted User drops out of the index exactly as they drop out
 48            // of the handler's check, which is what keeps their address reusable.
 49            //
 50            // As with ux_person_admin_email, this fails on a database that already violates the
 51            // rule. That is the point: the duplicates have to be resolved before the invariant can
 52            // be enforced, and creating the index conditionally would leave it unenforced silently.
 1953            migrationBuilder.Sql(
 1954                """
 1955                CREATE UNIQUE INDEX ux_person_scope_user_email
 1956                    ON heimdall.person (scope_id, LOWER(email))
 1957                    WHERE role_id = 3 AND is_deleted = false;
 1958                """);
 1959        }
 60
 61        /// <inheritdoc />
 62        protected override void Down(MigrationBuilder migrationBuilder)
 63        {
 164            migrationBuilder.Sql("DROP INDEX heimdall.ux_person_scope_user_email;");
 65
 166            migrationBuilder.DropColumn(
 167                name: "scope_id",
 168                schema: "heimdall",
 169                table: "person");
 170        }
 71    }
 72}

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Infrastructure/ArturRios.Heimdall.Data/Migrations/20260814203528_AddPersonScopeId.Designer.cs

#LineLine coverage
 1// <auto-generated />
 2using System;
 3using ArturRios.Heimdall.Data.Configuration;
 4using Microsoft.EntityFrameworkCore;
 5using Microsoft.EntityFrameworkCore.Infrastructure;
 6using Microsoft.EntityFrameworkCore.Migrations;
 7using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
 8using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
 9
 10#nullable disable
 11
 12namespace ArturRios.Heimdall.Data.Migrations
 13{
 14    [DbContext(typeof(AppDbContext))]
 15    [Migration("20260814203528_AddPersonScopeId")]
 16    partial class AddPersonScopeId
 17    {
 18        /// <inheritdoc />
 19        protected override void BuildTargetModel(ModelBuilder modelBuilder)
 20        {
 21#pragma warning disable 612, 618
 1022            modelBuilder
 1023                .HasDefaultSchema("heimdall")
 1024                .HasAnnotation("ProductVersion", "10.0.11")
 1025                .HasAnnotation("Relational:MaxIdentifierLength", 63);
 26
 1027            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
 28
 1029            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Application", b =>
 1030                {
 1031                    b.Property<long>("Id")
 1032                        .ValueGeneratedOnAdd()
 1033                        .HasColumnType("bigint")
 1034                        .HasColumnName("id")
 1035                        .HasColumnOrder(1);
 1036
 1037                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 1038
 1039                    b.Property<DateTime>("CreatedAt")
 1040                        .ValueGeneratedOnAdd()
 1041                        .HasColumnType("timestamp with time zone")
 1042                        .HasColumnName("created_at")
 1043                        .HasDefaultValueSql("now()");
 1044
 1045                    b.Property<bool>("IsDeleted")
 1046                        .ValueGeneratedOnAdd()
 1047                        .HasColumnType("boolean")
 1048                        .HasDefaultValue(false)
 1049                        .HasColumnName("is_deleted");
 1050
 1051                    b.Property<string>("Name")
 1052                        .IsRequired()
 1053                        .HasMaxLength(200)
 1054                        .HasColumnType("character varying(200)")
 1055                        .HasColumnName("name");
 1056
 1057                    b.Property<long>("OwnerId")
 1058                        .HasColumnType("bigint")
 1059                        .HasColumnName("owner_id");
 1060
 1061                    b.Property<Guid>("PublicId")
 1062                        .HasColumnType("uuid")
 1063                        .HasColumnName("public_id");
 1064
 1065                    b.Property<long>("ScopeId")
 1066                        .HasColumnType("bigint")
 1067                        .HasColumnName("scope_id");
 1068
 1069                    b.Property<DateTime>("UpdatedAt")
 1070                        .ValueGeneratedOnAdd()
 1071                        .HasColumnType("timestamp with time zone")
 1072                        .HasColumnName("updated_at")
 1073                        .HasDefaultValueSql("now()");
 1074
 1075                    b.HasKey("Id")
 1076                        .HasName("pk_application");
 1077
 1078                    b.HasIndex("OwnerId")
 1079                        .HasDatabaseName("ix_application_owner_id");
 1080
 1081                    b.HasIndex("PublicId")
 1082                        .IsUnique()
 1083                        .HasDatabaseName("ix_application_public_id");
 1084
 1085                    b.HasIndex("ScopeId")
 1086                        .HasDatabaseName("ix_application_scope_id");
 1087
 1088                    b.ToTable("application", "heimdall");
 2089                });
 90
 1091            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.AuditLog", b =>
 1092                {
 1093                    b.Property<long>("Id")
 1094                        .ValueGeneratedOnAdd()
 1095                        .HasColumnType("bigint")
 1096                        .HasColumnName("id")
 1097                        .HasColumnOrder(1);
 1098
 1099                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10100
 10101                    b.Property<string>("Action")
 10102                        .IsRequired()
 10103                        .HasMaxLength(200)
 10104                        .HasColumnType("character varying(200)")
 10105                        .HasColumnName("action");
 10106
 10107                    b.Property<Guid?>("ActorPersonId")
 10108                        .HasColumnType("uuid")
 10109                        .HasColumnName("actor_person_id");
 10110
 10111                    b.Property<int?>("ActorRole")
 10112                        .HasColumnType("integer")
 10113                        .HasColumnName("actor_role");
 10114
 10115                    b.Property<DateTime>("CreatedAt")
 10116                        .ValueGeneratedOnAdd()
 10117                        .HasColumnType("timestamp with time zone")
 10118                        .HasColumnName("created_at")
 10119                        .HasDefaultValueSql("now()");
 10120
 10121                    b.Property<Guid>("PublicId")
 10122                        .HasColumnType("uuid")
 10123                        .HasColumnName("public_id");
 10124
 10125                    b.Property<Guid?>("TargetId")
 10126                        .HasColumnType("uuid")
 10127                        .HasColumnName("target_id");
 10128
 10129                    b.HasKey("Id")
 10130                        .HasName("pk_audit_log");
 10131
 10132                    b.HasIndex("ActorPersonId")
 10133                        .HasDatabaseName("ix_audit_log_actor_person_id");
 10134
 10135                    b.HasIndex("CreatedAt")
 10136                        .HasDatabaseName("ix_audit_log_created_at");
 10137
 10138                    b.HasIndex("PublicId")
 10139                        .IsUnique()
 10140                        .HasDatabaseName("ix_audit_log_public_id");
 10141
 10142                    b.ToTable("audit_log", "heimdall");
 20143                });
 144
 10145            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.EmailVerificationToken", b =>
 10146                {
 10147                    b.Property<long>("Id")
 10148                        .ValueGeneratedOnAdd()
 10149                        .HasColumnType("bigint")
 10150                        .HasColumnName("id")
 10151                        .HasColumnOrder(1);
 10152
 10153                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10154
 10155                    b.Property<DateTime>("ExpiresAt")
 10156                        .HasColumnType("timestamp with time zone")
 10157                        .HasColumnName("expires_at");
 10158
 10159                    b.Property<long>("PersonId")
 10160                        .HasColumnType("bigint")
 10161                        .HasColumnName("person_id");
 10162
 10163                    b.Property<string>("Token")
 10164                        .IsRequired()
 10165                        .HasMaxLength(256)
 10166                        .HasColumnType("character varying(256)")
 10167                        .HasColumnName("token");
 10168
 10169                    b.Property<bool>("Used")
 10170                        .ValueGeneratedOnAdd()
 10171                        .HasColumnType("boolean")
 10172                        .HasDefaultValue(false)
 10173                        .HasColumnName("used");
 10174
 10175                    b.HasKey("Id")
 10176                        .HasName("pk_email_verification_token");
 10177
 10178                    b.HasIndex("PersonId")
 10179                        .HasDatabaseName("ix_email_verification_token_person_id");
 10180
 10181                    b.HasIndex("Token")
 10182                        .IsUnique()
 10183                        .HasDatabaseName("ix_email_verification_token_token");
 10184
 10185                    b.ToTable("email_verification_token", "heimdall");
 20186                });
 187
 10188            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.GoogleUser", b =>
 10189                {
 10190                    b.Property<long>("Id")
 10191                        .ValueGeneratedOnAdd()
 10192                        .HasColumnType("bigint")
 10193                        .HasColumnName("id")
 10194                        .HasColumnOrder(1);
 10195
 10196                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10197
 10198                    b.Property<DateTime>("CreatedAt")
 10199                        .ValueGeneratedOnAdd()
 10200                        .HasColumnType("timestamp with time zone")
 10201                        .HasColumnName("created_at")
 10202                        .HasDefaultValueSql("now()");
 10203
 10204                    b.Property<string>("Email")
 10205                        .IsRequired()
 10206                        .HasMaxLength(256)
 10207                        .HasColumnType("character varying(256)")
 10208                        .HasColumnName("email");
 10209
 10210                    b.Property<bool>("EmailVerified")
 10211                        .ValueGeneratedOnAdd()
 10212                        .HasColumnType("boolean")
 10213                        .HasDefaultValue(false)
 10214                        .HasColumnName("email_verified");
 10215
 10216                    b.Property<string>("GoogleId")
 10217                        .IsRequired()
 10218                        .HasMaxLength(255)
 10219                        .HasColumnType("character varying(255)")
 10220                        .HasColumnName("google_id");
 10221
 10222                    b.Property<bool>("IsDeleted")
 10223                        .ValueGeneratedOnAdd()
 10224                        .HasColumnType("boolean")
 10225                        .HasDefaultValue(false)
 10226                        .HasColumnName("is_deleted");
 10227
 10228                    b.Property<string>("Name")
 10229                        .IsRequired()
 10230                        .HasMaxLength(200)
 10231                        .HasColumnType("character varying(200)")
 10232                        .HasColumnName("name");
 10233
 10234                    b.Property<string>("ProfilePictureUrl")
 10235                        .HasMaxLength(2048)
 10236                        .HasColumnType("character varying(2048)")
 10237                        .HasColumnName("profile_picture_url");
 10238
 10239                    b.Property<Guid>("PublicId")
 10240                        .HasColumnType("uuid")
 10241                        .HasColumnName("public_id");
 10242
 10243                    b.Property<long>("ScopeId")
 10244                        .HasColumnType("bigint")
 10245                        .HasColumnName("scope_id");
 10246
 10247                    b.Property<DateTime>("UpdatedAt")
 10248                        .ValueGeneratedOnAdd()
 10249                        .HasColumnType("timestamp with time zone")
 10250                        .HasColumnName("updated_at")
 10251                        .HasDefaultValueSql("now()");
 10252
 10253                    b.HasKey("Id")
 10254                        .HasName("pk_google_user");
 10255
 10256                    b.HasIndex("PublicId")
 10257                        .IsUnique()
 10258                        .HasDatabaseName("ix_google_user_public_id");
 10259
 10260                    b.HasIndex("ScopeId", "Email")
 10261                        .IsUnique()
 10262                        .HasDatabaseName("ix_google_user_scope_id_email");
 10263
 10264                    b.HasIndex("ScopeId", "GoogleId")
 10265                        .IsUnique()
 10266                        .HasDatabaseName("ix_google_user_scope_id_google_id");
 10267
 10268                    b.ToTable("google_user", "heimdall");
 20269                });
 270
 10271            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PasswordResetToken", b =>
 10272                {
 10273                    b.Property<long>("Id")
 10274                        .ValueGeneratedOnAdd()
 10275                        .HasColumnType("bigint")
 10276                        .HasColumnName("id")
 10277                        .HasColumnOrder(1);
 10278
 10279                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10280
 10281                    b.Property<DateTime>("ExpiresAt")
 10282                        .HasColumnType("timestamp with time zone")
 10283                        .HasColumnName("expires_at");
 10284
 10285                    b.Property<long>("PersonId")
 10286                        .HasColumnType("bigint")
 10287                        .HasColumnName("person_id");
 10288
 10289                    b.Property<string>("Token")
 10290                        .IsRequired()
 10291                        .HasMaxLength(256)
 10292                        .HasColumnType("character varying(256)")
 10293                        .HasColumnName("token");
 10294
 10295                    b.Property<bool>("Used")
 10296                        .ValueGeneratedOnAdd()
 10297                        .HasColumnType("boolean")
 10298                        .HasDefaultValue(false)
 10299                        .HasColumnName("used");
 10300
 10301                    b.HasKey("Id")
 10302                        .HasName("pk_password_reset_token");
 10303
 10304                    b.HasIndex("PersonId")
 10305                        .HasDatabaseName("ix_password_reset_token_person_id");
 10306
 10307                    b.HasIndex("Token")
 10308                        .IsUnique()
 10309                        .HasDatabaseName("ix_password_reset_token_token");
 10310
 10311                    b.ToTable("password_reset_token", "heimdall");
 20312                });
 313
 10314            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 10315                {
 10316                    b.Property<long>("Id")
 10317                        .ValueGeneratedOnAdd()
 10318                        .HasColumnType("bigint")
 10319                        .HasColumnName("id")
 10320                        .HasColumnOrder(1);
 10321
 10322                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10323
 10324                    b.Property<DateTime>("CreatedAt")
 10325                        .ValueGeneratedOnAdd()
 10326                        .HasColumnType("timestamp with time zone")
 10327                        .HasColumnName("created_at")
 10328                        .HasDefaultValueSql("now()");
 10329
 10330                    b.Property<string>("Email")
 10331                        .IsRequired()
 10332                        .HasMaxLength(256)
 10333                        .HasColumnType("character varying(256)")
 10334                        .HasColumnName("email");
 10335
 10336                    b.Property<bool>("EmailVerified")
 10337                        .ValueGeneratedOnAdd()
 10338                        .HasColumnType("boolean")
 10339                        .HasDefaultValue(false)
 10340                        .HasColumnName("email_verified");
 10341
 10342                    b.Property<int>("FailedLoginAttempts")
 10343                        .HasColumnType("integer")
 10344                        .HasColumnName("failed_login_attempts");
 10345
 10346                    b.Property<bool>("IsDeleted")
 10347                        .ValueGeneratedOnAdd()
 10348                        .HasColumnType("boolean")
 10349                        .HasDefaultValue(false)
 10350                        .HasColumnName("is_deleted");
 10351
 10352                    b.Property<DateTime?>("LockedOutUntil")
 10353                        .HasColumnType("timestamp with time zone")
 10354                        .HasColumnName("locked_out_until");
 10355
 10356                    b.Property<string>("Name")
 10357                        .IsRequired()
 10358                        .HasMaxLength(200)
 10359                        .HasColumnType("character varying(200)")
 10360                        .HasColumnName("name");
 10361
 10362                    b.Property<byte[]>("PasswordHash")
 10363                        .IsRequired()
 10364                        .HasColumnType("bytea")
 10365                        .HasColumnName("password_hash");
 10366
 10367                    b.Property<Guid>("PublicId")
 10368                        .HasColumnType("uuid")
 10369                        .HasColumnName("public_id");
 10370
 10371                    b.Property<long>("RoleId")
 10372                        .HasColumnType("bigint")
 10373                        .HasColumnName("role_id");
 10374
 10375                    b.Property<byte[]>("Salt")
 10376                        .IsRequired()
 10377                        .HasColumnType("bytea")
 10378                        .HasColumnName("salt");
 10379
 10380                    b.Property<long?>("ScopeId")
 10381                        .HasColumnType("bigint")
 10382                        .HasColumnName("scope_id");
 10383
 10384                    b.Property<DateTime>("UpdatedAt")
 10385                        .ValueGeneratedOnAdd()
 10386                        .HasColumnType("timestamp with time zone")
 10387                        .HasColumnName("updated_at")
 10388                        .HasDefaultValueSql("now()");
 10389
 10390                    b.HasKey("Id")
 10391                        .HasName("pk_person");
 10392
 10393                    b.HasIndex("Email")
 10394                        .HasDatabaseName("ix_person_email");
 10395
 10396                    b.HasIndex("PublicId")
 10397                        .IsUnique()
 10398                        .HasDatabaseName("ix_person_public_id");
 10399
 10400                    b.HasIndex("RoleId")
 10401                        .HasDatabaseName("ix_person_role_id");
 10402
 10403                    b.ToTable("person", "heimdall");
 20404                });
 405
 10406            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Role", b =>
 10407                {
 10408                    b.Property<long>("Id")
 10409                        .HasColumnType("bigint")
 10410                        .HasColumnName("id")
 10411                        .HasColumnOrder(1);
 10412
 10413                    b.Property<string>("Description")
 10414                        .HasMaxLength(500)
 10415                        .HasColumnType("character varying(500)")
 10416                        .HasColumnName("description");
 10417
 10418                    b.Property<string>("Name")
 10419                        .IsRequired()
 10420                        .HasMaxLength(200)
 10421                        .HasColumnType("character varying(200)")
 10422                        .HasColumnName("name");
 10423
 10424                    b.Property<Guid>("PublicId")
 10425                        .HasColumnType("uuid")
 10426                        .HasColumnName("public_id");
 10427
 10428                    b.HasKey("Id")
 10429                        .HasName("pk_role");
 10430
 10431                    b.HasIndex("Name")
 10432                        .IsUnique()
 10433                        .HasDatabaseName("ix_role_name");
 10434
 10435                    b.HasIndex("PublicId")
 10436                        .IsUnique()
 10437                        .HasDatabaseName("ix_role_public_id");
 10438
 10439                    b.ToTable("role", "heimdall");
 20440                });
 441
 10442            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Scope", b =>
 10443                {
 10444                    b.Property<long>("Id")
 10445                        .ValueGeneratedOnAdd()
 10446                        .HasColumnType("bigint")
 10447                        .HasColumnName("id")
 10448                        .HasColumnOrder(1);
 10449
 10450                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10451
 10452                    b.Property<DateTime>("CreatedAt")
 10453                        .ValueGeneratedOnAdd()
 10454                        .HasColumnType("timestamp with time zone")
 10455                        .HasColumnName("created_at")
 10456                        .HasDefaultValueSql("now()");
 10457
 10458                    b.Property<string>("Description")
 10459                        .HasMaxLength(500)
 10460                        .HasColumnType("character varying(500)")
 10461                        .HasColumnName("description");
 10462
 10463                    b.Property<bool>("GoogleSignInEnabled")
 10464                        .ValueGeneratedOnAdd()
 10465                        .HasColumnType("boolean")
 10466                        .HasDefaultValue(false)
 10467                        .HasColumnName("google_sign_in_enabled");
 10468
 10469                    b.Property<bool>("IsDeleted")
 10470                        .ValueGeneratedOnAdd()
 10471                        .HasColumnType("boolean")
 10472                        .HasDefaultValue(false)
 10473                        .HasColumnName("is_deleted");
 10474
 10475                    b.Property<string>("Name")
 10476                        .IsRequired()
 10477                        .HasMaxLength(200)
 10478                        .HasColumnType("character varying(200)")
 10479                        .HasColumnName("name");
 10480
 10481                    b.Property<Guid>("PublicId")
 10482                        .HasColumnType("uuid")
 10483                        .HasColumnName("public_id");
 10484
 10485                    b.Property<DateTime>("UpdatedAt")
 10486                        .ValueGeneratedOnAdd()
 10487                        .HasColumnType("timestamp with time zone")
 10488                        .HasColumnName("updated_at")
 10489                        .HasDefaultValueSql("now()");
 10490
 10491                    b.HasKey("Id")
 10492                        .HasName("pk_scope");
 10493
 10494                    b.HasIndex("Name")
 10495                        .IsUnique()
 10496                        .HasDatabaseName("ix_scope_name");
 10497
 10498                    b.HasIndex("PublicId")
 10499                        .IsUnique()
 10500                        .HasDatabaseName("ix_scope_public_id");
 10501
 10502                    b.ToTable("scope", "heimdall");
 20503                });
 504
 10505            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeOwner", b =>
 10506                {
 10507                    b.Property<long>("ScopeId")
 10508                        .HasColumnType("bigint")
 10509                        .HasColumnName("scope_id");
 10510
 10511                    b.Property<long>("PersonId")
 10512                        .HasColumnType("bigint")
 10513                        .HasColumnName("person_id");
 10514
 10515                    b.HasKey("ScopeId", "PersonId")
 10516                        .HasName("pk_scope_owner");
 10517
 10518                    b.HasIndex("PersonId")
 10519                        .HasDatabaseName("ix_scope_owner_person_id");
 10520
 10521                    b.ToTable("scope_owner", "heimdall");
 20522                });
 523
 10524            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopePermission", b =>
 10525                {
 10526                    b.Property<long>("Id")
 10527                        .ValueGeneratedOnAdd()
 10528                        .HasColumnType("bigint")
 10529                        .HasColumnName("id")
 10530                        .HasColumnOrder(1);
 10531
 10532                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10533
 10534                    b.Property<DateTime>("CreatedAt")
 10535                        .ValueGeneratedOnAdd()
 10536                        .HasColumnType("timestamp with time zone")
 10537                        .HasColumnName("created_at")
 10538                        .HasDefaultValueSql("now()");
 10539
 10540                    b.Property<string>("Description")
 10541                        .HasMaxLength(500)
 10542                        .HasColumnType("character varying(500)")
 10543                        .HasColumnName("description");
 10544
 10545                    b.Property<bool>("IncludeAsJwtClaim")
 10546                        .ValueGeneratedOnAdd()
 10547                        .HasColumnType("boolean")
 10548                        .HasDefaultValue(false)
 10549                        .HasColumnName("include_as_jwt_claim");
 10550
 10551                    b.Property<bool>("IsDeleted")
 10552                        .ValueGeneratedOnAdd()
 10553                        .HasColumnType("boolean")
 10554                        .HasDefaultValue(false)
 10555                        .HasColumnName("is_deleted");
 10556
 10557                    b.Property<string>("Name")
 10558                        .IsRequired()
 10559                        .HasMaxLength(200)
 10560                        .HasColumnType("character varying(200)")
 10561                        .HasColumnName("name");
 10562
 10563                    b.Property<Guid>("PublicId")
 10564                        .HasColumnType("uuid")
 10565                        .HasColumnName("public_id");
 10566
 10567                    b.Property<long>("ScopeId")
 10568                        .HasColumnType("bigint")
 10569                        .HasColumnName("scope_id");
 10570
 10571                    b.Property<DateTime>("UpdatedAt")
 10572                        .ValueGeneratedOnAdd()
 10573                        .HasColumnType("timestamp with time zone")
 10574                        .HasColumnName("updated_at")
 10575                        .HasDefaultValueSql("now()");
 10576
 10577                    b.HasKey("Id")
 10578                        .HasName("pk_scope_permission");
 10579
 10580                    b.HasIndex("PublicId")
 10581                        .IsUnique()
 10582                        .HasDatabaseName("ix_scope_permission_public_id");
 10583
 10584                    b.HasIndex("ScopeId")
 10585                        .HasDatabaseName("ix_scope_permission_scope_id");
 10586
 10587                    b.ToTable("scope_permission", "heimdall");
 20588                });
 589
 10590            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeUser", b =>
 10591                {
 10592                    b.Property<long>("ScopeId")
 10593                        .HasColumnType("bigint")
 10594                        .HasColumnName("scope_id");
 10595
 10596                    b.Property<long>("PersonId")
 10597                        .HasColumnType("bigint")
 10598                        .HasColumnName("person_id");
 10599
 10600                    b.HasKey("ScopeId", "PersonId")
 10601                        .HasName("pk_scope_user");
 10602
 10603                    b.HasIndex("PersonId")
 10604                        .IsUnique()
 10605                        .HasDatabaseName("ix_scope_user_person_id");
 10606
 10607                    b.ToTable("scope_user", "heimdall");
 20608                });
 609
 10610            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 10611                {
 10612                    b.Property<long>("Id")
 10613                        .ValueGeneratedOnAdd()
 10614                        .HasColumnType("bigint")
 10615                        .HasColumnName("id")
 10616                        .HasColumnOrder(1);
 10617
 10618                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10619
 10620                    b.Property<bool>("AppEnabled")
 10621                        .ValueGeneratedOnAdd()
 10622                        .HasColumnType("boolean")
 10623                        .HasDefaultValue(false)
 10624                        .HasColumnName("app_enabled");
 10625
 10626                    b.Property<DateTime>("CreatedAt")
 10627                        .ValueGeneratedOnAdd()
 10628                        .HasColumnType("timestamp with time zone")
 10629                        .HasColumnName("created_at")
 10630                        .HasDefaultValueSql("now()");
 10631
 10632                    b.Property<bool>("EmailEnabled")
 10633                        .ValueGeneratedOnAdd()
 10634                        .HasColumnType("boolean")
 10635                        .HasDefaultValue(false)
 10636                        .HasColumnName("email_enabled");
 10637
 10638                    b.Property<bool>("IsActive")
 10639                        .ValueGeneratedOnAdd()
 10640                        .HasColumnType("boolean")
 10641                        .HasDefaultValue(false)
 10642                        .HasColumnName("is_active");
 10643
 10644                    b.Property<long?>("LastTotpTimeStepUsed")
 10645                        .HasColumnType("bigint")
 10646                        .HasColumnName("last_totp_time_step_used");
 10647
 10648                    b.Property<long>("PersonId")
 10649                        .HasColumnType("bigint")
 10650                        .HasColumnName("person_id");
 10651
 10652                    b.Property<byte[]>("TotpSecretEncrypted")
 10653                        .HasColumnType("bytea")
 10654                        .HasColumnName("totp_secret_encrypted");
 10655
 10656                    b.Property<DateTime>("UpdatedAt")
 10657                        .ValueGeneratedOnAdd()
 10658                        .HasColumnType("timestamp with time zone")
 10659                        .HasColumnName("updated_at")
 10660                        .HasDefaultValueSql("now()");
 10661
 10662                    b.HasKey("Id")
 10663                        .HasName("pk_two_factor_auth");
 10664
 10665                    b.HasIndex("PersonId")
 10666                        .IsUnique()
 10667                        .HasDatabaseName("ix_two_factor_auth_person_id");
 10668
 10669                    b.ToTable("two_factor_auth", "heimdall");
 20670                });
 671
 10672            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode", b =>
 10673                {
 10674                    b.Property<long>("Id")
 10675                        .ValueGeneratedOnAdd()
 10676                        .HasColumnType("bigint")
 10677                        .HasColumnName("id")
 10678                        .HasColumnOrder(1);
 10679
 10680                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10681
 10682                    b.Property<byte[]>("CodeHash")
 10683                        .IsRequired()
 10684                        .HasColumnType("bytea")
 10685                        .HasColumnName("code_hash");
 10686
 10687                    b.Property<DateTime>("CreatedAt")
 10688                        .ValueGeneratedOnAdd()
 10689                        .HasColumnType("timestamp with time zone")
 10690                        .HasColumnName("created_at")
 10691                        .HasDefaultValueSql("now()");
 10692
 10693                    b.Property<DateTime>("ExpiresAt")
 10694                        .HasColumnType("timestamp with time zone")
 10695                        .HasColumnName("expires_at");
 10696
 10697                    b.Property<int>("FailedAttempts")
 10698                        .HasColumnType("integer")
 10699                        .HasColumnName("failed_attempts");
 10700
 10701                    b.Property<byte[]>("Salt")
 10702                        .IsRequired()
 10703                        .HasColumnType("bytea")
 10704                        .HasColumnName("salt");
 10705
 10706                    b.Property<long>("TwoFactorAuthId")
 10707                        .HasColumnType("bigint")
 10708                        .HasColumnName("two_factor_auth_id");
 10709
 10710                    b.Property<bool>("Used")
 10711                        .ValueGeneratedOnAdd()
 10712                        .HasColumnType("boolean")
 10713                        .HasDefaultValue(false)
 10714                        .HasColumnName("used");
 10715
 10716                    b.HasKey("Id")
 10717                        .HasName("pk_two_factor_email_code");
 10718
 10719                    b.HasIndex("TwoFactorAuthId")
 10720                        .HasDatabaseName("ix_two_factor_email_code_two_factor_auth_id");
 10721
 10722                    b.ToTable("two_factor_email_code", "heimdall");
 20723                });
 724
 10725            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorRecoveryCode", b =>
 10726                {
 10727                    b.Property<long>("Id")
 10728                        .ValueGeneratedOnAdd()
 10729                        .HasColumnType("bigint")
 10730                        .HasColumnName("id")
 10731                        .HasColumnOrder(1);
 10732
 10733                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10734
 10735                    b.Property<byte[]>("CodeHash")
 10736                        .IsRequired()
 10737                        .HasColumnType("bytea")
 10738                        .HasColumnName("code_hash");
 10739
 10740                    b.Property<DateTime>("CreatedAt")
 10741                        .ValueGeneratedOnAdd()
 10742                        .HasColumnType("timestamp with time zone")
 10743                        .HasColumnName("created_at")
 10744                        .HasDefaultValueSql("now()");
 10745
 10746                    b.Property<long>("TwoFactorAuthId")
 10747                        .HasColumnType("bigint")
 10748                        .HasColumnName("two_factor_auth_id");
 10749
 10750                    b.Property<bool>("Used")
 10751                        .ValueGeneratedOnAdd()
 10752                        .HasColumnType("boolean")
 10753                        .HasDefaultValue(false)
 10754                        .HasColumnName("used");
 10755
 10756                    b.Property<DateTime?>("UsedAt")
 10757                        .HasColumnType("timestamp with time zone")
 10758                        .HasColumnName("used_at");
 10759
 10760                    b.HasKey("Id")
 10761                        .HasName("pk_two_factor_recovery_code");
 10762
 10763                    b.HasIndex("TwoFactorAuthId")
 10764                        .HasDatabaseName("ix_two_factor_recovery_code_two_factor_auth_id");
 10765
 10766                    b.ToTable("two_factor_recovery_code", "heimdall");
 20767                });
 768
 10769            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Application", b =>
 10770                {
 10771                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Owner")
 10772                        .WithMany("OwnedApplications")
 10773                        .HasForeignKey("OwnerId")
 10774                        .OnDelete(DeleteBehavior.Cascade)
 10775                        .IsRequired()
 10776                        .HasConstraintName("fk_application_person_owner_id");
 10777
 10778                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10779                        .WithMany("Applications")
 10780                        .HasForeignKey("ScopeId")
 10781                        .OnDelete(DeleteBehavior.Cascade)
 10782                        .IsRequired()
 10783                        .HasConstraintName("fk_application_scope_scope_id");
 10784
 10785                    b.Navigation("Owner");
 10786
 10787                    b.Navigation("Scope");
 20788                });
 789
 10790            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.EmailVerificationToken", b =>
 10791                {
 10792                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10793                        .WithMany("EmailVerificationTokens")
 10794                        .HasForeignKey("PersonId")
 10795                        .OnDelete(DeleteBehavior.Cascade)
 10796                        .IsRequired()
 10797                        .HasConstraintName("fk_email_verification_token_person_person_id");
 10798
 10799                    b.Navigation("Person");
 20800                });
 801
 10802            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.GoogleUser", b =>
 10803                {
 10804                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10805                        .WithMany("GoogleUsers")
 10806                        .HasForeignKey("ScopeId")
 10807                        .OnDelete(DeleteBehavior.Cascade)
 10808                        .IsRequired()
 10809                        .HasConstraintName("fk_google_user_scope_scope_id");
 10810
 10811                    b.Navigation("Scope");
 20812                });
 813
 10814            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PasswordResetToken", b =>
 10815                {
 10816                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10817                        .WithMany("PasswordResetTokens")
 10818                        .HasForeignKey("PersonId")
 10819                        .OnDelete(DeleteBehavior.Cascade)
 10820                        .IsRequired()
 10821                        .HasConstraintName("fk_password_reset_token_person_person_id");
 10822
 10823                    b.Navigation("Person");
 20824                });
 825
 10826            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 10827                {
 10828                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Role", "Role")
 10829                        .WithMany("Persons")
 10830                        .HasForeignKey("RoleId")
 10831                        .OnDelete(DeleteBehavior.Restrict)
 10832                        .IsRequired()
 10833                        .HasConstraintName("fk_person_roles_role_id");
 10834
 10835                    b.Navigation("Role");
 20836                });
 837
 10838            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeOwner", b =>
 10839                {
 10840                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10841                        .WithMany("ScopeOwnerships")
 10842                        .HasForeignKey("PersonId")
 10843                        .OnDelete(DeleteBehavior.Cascade)
 10844                        .IsRequired()
 10845                        .HasConstraintName("fk_scope_owner_person_person_id");
 10846
 10847                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10848                        .WithMany("Owners")
 10849                        .HasForeignKey("ScopeId")
 10850                        .OnDelete(DeleteBehavior.Cascade)
 10851                        .IsRequired()
 10852                        .HasConstraintName("fk_scope_owner_scope_scope_id");
 10853
 10854                    b.Navigation("Person");
 10855
 10856                    b.Navigation("Scope");
 20857                });
 858
 10859            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopePermission", b =>
 10860                {
 10861                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10862                        .WithMany("ScopePermissions")
 10863                        .HasForeignKey("ScopeId")
 10864                        .OnDelete(DeleteBehavior.Cascade)
 10865                        .IsRequired()
 10866                        .HasConstraintName("fk_scope_permission_scope_scope_id");
 10867
 10868                    b.Navigation("Scope");
 20869                });
 870
 10871            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeUser", b =>
 10872                {
 10873                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10874                        .WithOne("ScopeMembership")
 10875                        .HasForeignKey("ArturRios.Heimdall.Domain.Entities.ScopeUser", "PersonId")
 10876                        .OnDelete(DeleteBehavior.Cascade)
 10877                        .IsRequired()
 10878                        .HasConstraintName("fk_scope_user_person_person_id");
 10879
 10880                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 10881                        .WithMany("Users")
 10882                        .HasForeignKey("ScopeId")
 10883                        .OnDelete(DeleteBehavior.Cascade)
 10884                        .IsRequired()
 10885                        .HasConstraintName("fk_scope_user_scope_scope_id");
 10886
 10887                    b.Navigation("Person");
 10888
 10889                    b.Navigation("Scope");
 20890                });
 891
 10892            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 10893                {
 10894                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 10895                        .WithOne("TwoFactorAuth")
 10896                        .HasForeignKey("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "PersonId")
 10897                        .OnDelete(DeleteBehavior.Cascade)
 10898                        .IsRequired()
 10899                        .HasConstraintName("fk_two_factor_auth_person_person_id");
 10900
 10901                    b.Navigation("Person");
 20902                });
 903
 10904            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode", b =>
 10905                {
 10906                    b.HasOne("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "TwoFactorAuth")
 10907                        .WithMany("EmailCodes")
 10908                        .HasForeignKey("TwoFactorAuthId")
 10909                        .OnDelete(DeleteBehavior.Cascade)
 10910                        .IsRequired()
 10911                        .HasConstraintName("fk_two_factor_email_code_two_factor_auth_two_factor_auth_id");
 10912
 10913                    b.Navigation("TwoFactorAuth");
 20914                });
 915
 10916            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorRecoveryCode", b =>
 10917                {
 10918                    b.HasOne("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "TwoFactorAuth")
 10919                        .WithMany("RecoveryCodes")
 10920                        .HasForeignKey("TwoFactorAuthId")
 10921                        .OnDelete(DeleteBehavior.Cascade)
 10922                        .IsRequired()
 10923                        .HasConstraintName("fk_two_factor_recovery_code_two_factor_auth_two_factor_auth_id");
 10924
 10925                    b.Navigation("TwoFactorAuth");
 20926                });
 927
 10928            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 10929                {
 10930                    b.Navigation("EmailVerificationTokens");
 10931
 10932                    b.Navigation("OwnedApplications");
 10933
 10934                    b.Navigation("PasswordResetTokens");
 10935
 10936                    b.Navigation("ScopeMembership");
 10937
 10938                    b.Navigation("ScopeOwnerships");
 10939
 10940                    b.Navigation("TwoFactorAuth");
 20941                });
 942
 10943            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Role", b =>
 10944                {
 10945                    b.Navigation("Persons");
 20946                });
 947
 10948            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Scope", b =>
 10949                {
 10950                    b.Navigation("Applications");
 10951
 10952                    b.Navigation("GoogleUsers");
 10953
 10954                    b.Navigation("Owners");
 10955
 10956                    b.Navigation("ScopePermissions");
 10957
 10958                    b.Navigation("Users");
 20959                });
 960
 10961            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 10962                {
 10963                    b.Navigation("EmailCodes");
 10964
 10965                    b.Navigation("RecoveryCodes");
 20966                });
 967#pragma warning restore 612, 618
 10968        }
 969    }
 970}