< Summary - Heimdall API

Line coverage
96%
Covered lines: 1040
Uncovered lines: 33
Coverable lines: 1073
Total lines: 1181
Line coverage: 96.9%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
66%
Covered methods: 2
Fully covered methods: 2
Total methods: 3
Method coverage: 66.6%
Full method coverage: 66.6%

Metrics

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

File(s)

/home/runner/work/heimdall-api/heimdall-api/src/Infrastructure/ArturRios.Heimdall.Data/Migrations/20260909163322_AnonymiseDeletedIdentities.cs

#LineLine coverage
 1using System;
 2using Microsoft.EntityFrameworkCore.Migrations;
 3
 4#nullable disable
 5
 6namespace ArturRios.Heimdall.Data.Migrations
 7{
 8    /// <summary>
 9    ///     Adds the deletion metadata NFR-20's retention window is measured from: when a record was
 10    ///     logically deleted, why, and whether it has since been anonymised.
 11    /// </summary>
 12    public partial class AnonymiseDeletedIdentities : Migration
 13    {
 14        /// <inheritdoc />
 15        protected override void Up(MigrationBuilder migrationBuilder)
 16        {
 417            migrationBuilder.AddColumn<DateTime>(
 418                name: "anonymised_at",
 419                schema: "heimdall",
 420                table: "person",
 421                type: "timestamp with time zone",
 422                nullable: true);
 23
 424            migrationBuilder.AddColumn<DateTime>(
 425                name: "deleted_at",
 426                schema: "heimdall",
 427                table: "person",
 428                type: "timestamp with time zone",
 429                nullable: true);
 30
 431            migrationBuilder.AddColumn<int>(
 432                name: "deletion_kind",
 433                schema: "heimdall",
 434                table: "person",
 435                type: "integer",
 436                nullable: true);
 37
 438            migrationBuilder.AddColumn<DateTime>(
 439                name: "anonymised_at",
 440                schema: "heimdall",
 441                table: "google_user",
 442                type: "timestamp with time zone",
 443                nullable: true);
 44
 445            migrationBuilder.AddColumn<DateTime>(
 446                name: "deleted_at",
 447                schema: "heimdall",
 448                table: "google_user",
 449                type: "timestamp with time zone",
 450                nullable: true);
 51
 452            migrationBuilder.AddColumn<int>(
 453                name: "deletion_kind",
 454                schema: "heimdall",
 455                table: "google_user",
 456                type: "integer",
 457                nullable: true);
 58
 459            migrationBuilder.CreateIndex(
 460                name: "ix_person_deleted_at",
 461                schema: "heimdall",
 462                table: "person",
 463                column: "deleted_at",
 464                filter: "is_deleted = true AND anonymised_at IS NULL");
 65
 466            migrationBuilder.CreateIndex(
 467                name: "ix_google_user_deleted_at",
 468                schema: "heimdall",
 469                table: "google_user",
 470                column: "deleted_at",
 471                filter: "is_deleted = true AND anonymised_at IS NULL");
 72
 73            // Rows logically deleted before this migration carry no deletion date, and the
 74            // anonymisation pass deliberately skips a record whose window cannot be shown to have
 75            // elapsed. Without a backfill those rows would be the one set the schedule never
 76            // reaches — exactly the indefinitely retained data NFR-20 exists to end.
 77            //
 78            // updated_at is the only evidence available. It is a proxy, not the true deletion date:
 79            // the logical deletes stamp it, but any later write to the row moves it. That makes it
 80            // equal to or later than the real deletion, never earlier, so the backfilled window
 81            // closes on time or late and can never erase a record early. Erring late is the safe
 82            // direction here; erring early would destroy data before its window was up.
 83            //
 84            // The kind is Administrative because it is the only one that could have been recorded:
 85            // there was no way to request an erasure before this, so no row can be a subject
 86            // request, and assuming otherwise would apply the shorter statutory deadline to
 87            // deletions nobody asked for.
 488            migrationBuilder.Sql(
 489                """
 490                UPDATE heimdall.person
 491                SET deleted_at = updated_at, deletion_kind = 1
 492                WHERE is_deleted = true AND deleted_at IS NULL;
 493                """);
 94
 495            migrationBuilder.Sql(
 496                """
 497                UPDATE heimdall.google_user
 498                SET deleted_at = updated_at, deletion_kind = 1
 499                WHERE is_deleted = true AND deleted_at IS NULL;
 4100                """);
 4101        }
 102
 103        /// <inheritdoc />
 104        protected override void Down(MigrationBuilder migrationBuilder)
 105        {
 0106            migrationBuilder.DropIndex(
 0107                name: "ix_person_deleted_at",
 0108                schema: "heimdall",
 0109                table: "person");
 110
 0111            migrationBuilder.DropIndex(
 0112                name: "ix_google_user_deleted_at",
 0113                schema: "heimdall",
 0114                table: "google_user");
 115
 0116            migrationBuilder.DropColumn(
 0117                name: "anonymised_at",
 0118                schema: "heimdall",
 0119                table: "person");
 120
 0121            migrationBuilder.DropColumn(
 0122                name: "deleted_at",
 0123                schema: "heimdall",
 0124                table: "person");
 125
 0126            migrationBuilder.DropColumn(
 0127                name: "deletion_kind",
 0128                schema: "heimdall",
 0129                table: "person");
 130
 0131            migrationBuilder.DropColumn(
 0132                name: "anonymised_at",
 0133                schema: "heimdall",
 0134                table: "google_user");
 135
 0136            migrationBuilder.DropColumn(
 0137                name: "deleted_at",
 0138                schema: "heimdall",
 0139                table: "google_user");
 140
 0141            migrationBuilder.DropColumn(
 0142                name: "deletion_kind",
 0143                schema: "heimdall",
 0144                table: "google_user");
 0145        }
 146    }
 147}

/home/runner/work/heimdall-api/heimdall-api/src/Infrastructure/ArturRios.Heimdall.Data/Migrations/20260909163322_AnonymiseDeletedIdentities.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("20260909163322_AnonymiseDeletedIdentities")]
 16    partial class AnonymiseDeletedIdentities
 17    {
 18        /// <inheritdoc />
 19        protected override void BuildTargetModel(ModelBuilder modelBuilder)
 20        {
 21#pragma warning disable 612, 618
 222            modelBuilder
 223                .HasDefaultSchema("heimdall")
 224                .HasAnnotation("ProductVersion", "10.0.11")
 225                .HasAnnotation("Relational:MaxIdentifierLength", 63);
 26
 227            NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
 28
 229            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Application", b =>
 230                {
 231                    b.Property<long>("Id")
 232                        .ValueGeneratedOnAdd()
 233                        .HasColumnType("bigint")
 234                        .HasColumnName("id")
 235                        .HasColumnOrder(1);
 236
 237                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 238
 239                    b.Property<DateTime>("CreatedAt")
 240                        .ValueGeneratedOnAdd()
 241                        .HasColumnType("timestamp with time zone")
 242                        .HasColumnName("created_at")
 243                        .HasDefaultValueSql("now()");
 244
 245                    b.Property<bool>("IsDeleted")
 246                        .ValueGeneratedOnAdd()
 247                        .HasColumnType("boolean")
 248                        .HasDefaultValue(false)
 249                        .HasColumnName("is_deleted");
 250
 251                    b.Property<string>("Name")
 252                        .IsRequired()
 253                        .HasMaxLength(200)
 254                        .HasColumnType("character varying(200)")
 255                        .HasColumnName("name");
 256
 257                    b.Property<long>("OwnerId")
 258                        .HasColumnType("bigint")
 259                        .HasColumnName("owner_id");
 260
 261                    b.Property<Guid>("PublicId")
 262                        .HasColumnType("uuid")
 263                        .HasColumnName("public_id");
 264
 265                    b.Property<long>("ScopeId")
 266                        .HasColumnType("bigint")
 267                        .HasColumnName("scope_id");
 268
 269                    b.Property<DateTime>("UpdatedAt")
 270                        .ValueGeneratedOnAdd()
 271                        .HasColumnType("timestamp with time zone")
 272                        .HasColumnName("updated_at")
 273                        .HasDefaultValueSql("now()");
 274
 275                    b.HasKey("Id")
 276                        .HasName("pk_application");
 277
 278                    b.HasIndex("OwnerId")
 279                        .HasDatabaseName("ix_application_owner_id");
 280
 281                    b.HasIndex("PublicId")
 282                        .IsUnique()
 283                        .HasDatabaseName("ix_application_public_id");
 284
 285                    b.HasIndex("ScopeId")
 286                        .HasDatabaseName("ix_application_scope_id");
 287
 288                    b.ToTable("application", "heimdall");
 489                });
 90
 291            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.AuditLog", b =>
 292                {
 293                    b.Property<long>("Id")
 294                        .ValueGeneratedOnAdd()
 295                        .HasColumnType("bigint")
 296                        .HasColumnName("id")
 297                        .HasColumnOrder(1);
 298
 299                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2100
 2101                    b.Property<string>("Action")
 2102                        .IsRequired()
 2103                        .HasMaxLength(200)
 2104                        .HasColumnType("character varying(200)")
 2105                        .HasColumnName("action");
 2106
 2107                    b.Property<Guid?>("ActorPersonId")
 2108                        .HasColumnType("uuid")
 2109                        .HasColumnName("actor_person_id");
 2110
 2111                    b.Property<int?>("ActorRole")
 2112                        .HasColumnType("integer")
 2113                        .HasColumnName("actor_role");
 2114
 2115                    b.Property<DateTime>("CreatedAt")
 2116                        .ValueGeneratedOnAdd()
 2117                        .HasColumnType("timestamp with time zone")
 2118                        .HasColumnName("created_at")
 2119                        .HasDefaultValueSql("now()");
 2120
 2121                    b.Property<string>("FailureReason")
 2122                        .HasMaxLength(500)
 2123                        .HasColumnType("character varying(500)")
 2124                        .HasColumnName("failure_reason");
 2125
 2126                    b.Property<Guid>("PublicId")
 2127                        .HasColumnType("uuid")
 2128                        .HasColumnName("public_id");
 2129
 2130                    b.Property<bool>("Succeeded")
 2131                        .HasColumnType("boolean")
 2132                        .HasColumnName("succeeded");
 2133
 2134                    b.Property<Guid?>("TargetId")
 2135                        .HasColumnType("uuid")
 2136                        .HasColumnName("target_id");
 2137
 2138                    b.HasKey("Id")
 2139                        .HasName("pk_audit_log");
 2140
 2141                    b.HasIndex("ActorPersonId")
 2142                        .HasDatabaseName("ix_audit_log_actor_person_id");
 2143
 2144                    b.HasIndex("CreatedAt")
 2145                        .HasDatabaseName("ix_audit_log_created_at");
 2146
 2147                    b.HasIndex("PublicId")
 2148                        .IsUnique()
 2149                        .HasDatabaseName("ix_audit_log_public_id");
 2150
 2151                    b.ToTable("audit_log", "heimdall");
 4152                });
 153
 2154            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.EmailVerificationToken", b =>
 2155                {
 2156                    b.Property<long>("Id")
 2157                        .ValueGeneratedOnAdd()
 2158                        .HasColumnType("bigint")
 2159                        .HasColumnName("id")
 2160                        .HasColumnOrder(1);
 2161
 2162                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2163
 2164                    b.Property<DateTime>("ExpiresAt")
 2165                        .HasColumnType("timestamp with time zone")
 2166                        .HasColumnName("expires_at");
 2167
 2168                    b.Property<long>("PersonId")
 2169                        .HasColumnType("bigint")
 2170                        .HasColumnName("person_id");
 2171
 2172                    b.Property<string>("TokenHash")
 2173                        .IsRequired()
 2174                        .HasMaxLength(64)
 2175                        .HasColumnType("character varying(64)")
 2176                        .HasColumnName("token_hash");
 2177
 2178                    b.Property<bool>("Used")
 2179                        .ValueGeneratedOnAdd()
 2180                        .HasColumnType("boolean")
 2181                        .HasDefaultValue(false)
 2182                        .HasColumnName("used");
 2183
 2184                    b.HasKey("Id")
 2185                        .HasName("pk_email_verification_token");
 2186
 2187                    b.HasIndex("PersonId")
 2188                        .HasDatabaseName("ix_email_verification_token_person_id");
 2189
 2190                    b.HasIndex("TokenHash")
 2191                        .IsUnique()
 2192                        .HasDatabaseName("ix_email_verification_token_token_hash");
 2193
 2194                    b.ToTable("email_verification_token", "heimdall");
 4195                });
 196
 2197            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.GoogleUser", b =>
 2198                {
 2199                    b.Property<long>("Id")
 2200                        .ValueGeneratedOnAdd()
 2201                        .HasColumnType("bigint")
 2202                        .HasColumnName("id")
 2203                        .HasColumnOrder(1);
 2204
 2205                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2206
 2207                    b.Property<DateTime?>("AnonymisedAt")
 2208                        .HasColumnType("timestamp with time zone")
 2209                        .HasColumnName("anonymised_at");
 2210
 2211                    b.Property<DateTime>("CreatedAt")
 2212                        .ValueGeneratedOnAdd()
 2213                        .HasColumnType("timestamp with time zone")
 2214                        .HasColumnName("created_at")
 2215                        .HasDefaultValueSql("now()");
 2216
 2217                    b.Property<DateTime?>("DeletedAt")
 2218                        .HasColumnType("timestamp with time zone")
 2219                        .HasColumnName("deleted_at");
 2220
 2221                    b.Property<int?>("DeletionKind")
 2222                        .HasColumnType("integer")
 2223                        .HasColumnName("deletion_kind");
 2224
 2225                    b.Property<string>("Email")
 2226                        .IsRequired()
 2227                        .HasMaxLength(256)
 2228                        .HasColumnType("character varying(256)")
 2229                        .HasColumnName("email");
 2230
 2231                    b.Property<bool>("EmailVerified")
 2232                        .ValueGeneratedOnAdd()
 2233                        .HasColumnType("boolean")
 2234                        .HasDefaultValue(false)
 2235                        .HasColumnName("email_verified");
 2236
 2237                    b.Property<string>("GoogleId")
 2238                        .IsRequired()
 2239                        .HasMaxLength(255)
 2240                        .HasColumnType("character varying(255)")
 2241                        .HasColumnName("google_id");
 2242
 2243                    b.Property<bool>("IsDeleted")
 2244                        .ValueGeneratedOnAdd()
 2245                        .HasColumnType("boolean")
 2246                        .HasDefaultValue(false)
 2247                        .HasColumnName("is_deleted");
 2248
 2249                    b.Property<string>("Name")
 2250                        .IsRequired()
 2251                        .HasMaxLength(200)
 2252                        .HasColumnType("character varying(200)")
 2253                        .HasColumnName("name");
 2254
 2255                    b.Property<string>("ProfilePictureUrl")
 2256                        .HasMaxLength(2048)
 2257                        .HasColumnType("character varying(2048)")
 2258                        .HasColumnName("profile_picture_url");
 2259
 2260                    b.Property<Guid>("PublicId")
 2261                        .HasColumnType("uuid")
 2262                        .HasColumnName("public_id");
 2263
 2264                    b.Property<long>("ScopeId")
 2265                        .HasColumnType("bigint")
 2266                        .HasColumnName("scope_id");
 2267
 2268                    b.Property<DateTime>("UpdatedAt")
 2269                        .ValueGeneratedOnAdd()
 2270                        .HasColumnType("timestamp with time zone")
 2271                        .HasColumnName("updated_at")
 2272                        .HasDefaultValueSql("now()");
 2273
 2274                    b.HasKey("Id")
 2275                        .HasName("pk_google_user");
 2276
 2277                    b.HasIndex("DeletedAt")
 2278                        .HasDatabaseName("ix_google_user_deleted_at")
 2279                        .HasFilter("is_deleted = true AND anonymised_at IS NULL");
 2280
 2281                    b.HasIndex("PublicId")
 2282                        .IsUnique()
 2283                        .HasDatabaseName("ix_google_user_public_id");
 2284
 2285                    b.HasIndex("ScopeId", "Email")
 2286                        .IsUnique()
 2287                        .HasDatabaseName("ix_google_user_scope_id_email");
 2288
 2289                    b.HasIndex("ScopeId", "GoogleId")
 2290                        .IsUnique()
 2291                        .HasDatabaseName("ix_google_user_scope_id_google_id");
 2292
 2293                    b.ToTable("google_user", "heimdall");
 4294                });
 295
 2296            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PasswordResetToken", b =>
 2297                {
 2298                    b.Property<long>("Id")
 2299                        .ValueGeneratedOnAdd()
 2300                        .HasColumnType("bigint")
 2301                        .HasColumnName("id")
 2302                        .HasColumnOrder(1);
 2303
 2304                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2305
 2306                    b.Property<DateTime>("ExpiresAt")
 2307                        .HasColumnType("timestamp with time zone")
 2308                        .HasColumnName("expires_at");
 2309
 2310                    b.Property<long>("PersonId")
 2311                        .HasColumnType("bigint")
 2312                        .HasColumnName("person_id");
 2313
 2314                    b.Property<string>("TokenHash")
 2315                        .IsRequired()
 2316                        .HasMaxLength(64)
 2317                        .HasColumnType("character varying(64)")
 2318                        .HasColumnName("token_hash");
 2319
 2320                    b.Property<bool>("Used")
 2321                        .ValueGeneratedOnAdd()
 2322                        .HasColumnType("boolean")
 2323                        .HasDefaultValue(false)
 2324                        .HasColumnName("used");
 2325
 2326                    b.HasKey("Id")
 2327                        .HasName("pk_password_reset_token");
 2328
 2329                    b.HasIndex("PersonId")
 2330                        .HasDatabaseName("ix_password_reset_token_person_id");
 2331
 2332                    b.HasIndex("TokenHash")
 2333                        .IsUnique()
 2334                        .HasDatabaseName("ix_password_reset_token_token_hash");
 2335
 2336                    b.ToTable("password_reset_token", "heimdall");
 4337                });
 338
 2339            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 2340                {
 2341                    b.Property<long>("Id")
 2342                        .ValueGeneratedOnAdd()
 2343                        .HasColumnType("bigint")
 2344                        .HasColumnName("id")
 2345                        .HasColumnOrder(1);
 2346
 2347                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2348
 2349                    b.Property<DateTime?>("AnonymisedAt")
 2350                        .HasColumnType("timestamp with time zone")
 2351                        .HasColumnName("anonymised_at");
 2352
 2353                    b.Property<DateTime>("CreatedAt")
 2354                        .ValueGeneratedOnAdd()
 2355                        .HasColumnType("timestamp with time zone")
 2356                        .HasColumnName("created_at")
 2357                        .HasDefaultValueSql("now()");
 2358
 2359                    b.Property<DateTime?>("DeletedAt")
 2360                        .HasColumnType("timestamp with time zone")
 2361                        .HasColumnName("deleted_at");
 2362
 2363                    b.Property<int?>("DeletionKind")
 2364                        .HasColumnType("integer")
 2365                        .HasColumnName("deletion_kind");
 2366
 2367                    b.Property<string>("Email")
 2368                        .IsRequired()
 2369                        .HasMaxLength(256)
 2370                        .HasColumnType("character varying(256)")
 2371                        .HasColumnName("email");
 2372
 2373                    b.Property<bool>("EmailVerified")
 2374                        .ValueGeneratedOnAdd()
 2375                        .HasColumnType("boolean")
 2376                        .HasDefaultValue(false)
 2377                        .HasColumnName("email_verified");
 2378
 2379                    b.Property<int>("FailedLoginAttempts")
 2380                        .HasColumnType("integer")
 2381                        .HasColumnName("failed_login_attempts");
 2382
 2383                    b.Property<bool>("IsDeleted")
 2384                        .ValueGeneratedOnAdd()
 2385                        .HasColumnType("boolean")
 2386                        .HasDefaultValue(false)
 2387                        .HasColumnName("is_deleted");
 2388
 2389                    b.Property<DateTime?>("LockedOutUntil")
 2390                        .HasColumnType("timestamp with time zone")
 2391                        .HasColumnName("locked_out_until");
 2392
 2393                    b.Property<string>("Name")
 2394                        .IsRequired()
 2395                        .HasMaxLength(200)
 2396                        .HasColumnType("character varying(200)")
 2397                        .HasColumnName("name");
 2398
 2399                    b.Property<byte[]>("PasswordHash")
 2400                        .IsRequired()
 2401                        .HasColumnType("bytea")
 2402                        .HasColumnName("password_hash");
 2403
 2404                    b.Property<Guid>("PublicId")
 2405                        .HasColumnType("uuid")
 2406                        .HasColumnName("public_id");
 2407
 2408                    b.Property<long>("RoleId")
 2409                        .HasColumnType("bigint")
 2410                        .HasColumnName("role_id");
 2411
 2412                    b.Property<byte[]>("Salt")
 2413                        .IsRequired()
 2414                        .HasColumnType("bytea")
 2415                        .HasColumnName("salt");
 2416
 2417                    b.Property<long?>("ScopeId")
 2418                        .HasColumnType("bigint")
 2419                        .HasColumnName("scope_id");
 2420
 2421                    b.Property<DateTime>("UpdatedAt")
 2422                        .ValueGeneratedOnAdd()
 2423                        .HasColumnType("timestamp with time zone")
 2424                        .HasColumnName("updated_at")
 2425                        .HasDefaultValueSql("now()");
 2426
 2427                    b.HasKey("Id")
 2428                        .HasName("pk_person");
 2429
 2430                    b.HasIndex("DeletedAt")
 2431                        .HasDatabaseName("ix_person_deleted_at")
 2432                        .HasFilter("is_deleted = true AND anonymised_at IS NULL");
 2433
 2434                    b.HasIndex("Email")
 2435                        .HasDatabaseName("ix_person_email");
 2436
 2437                    b.HasIndex("PublicId")
 2438                        .IsUnique()
 2439                        .HasDatabaseName("ix_person_public_id");
 2440
 2441                    b.HasIndex("RoleId")
 2442                        .HasDatabaseName("ix_person_role_id");
 2443
 2444                    b.ToTable("person", "heimdall");
 4445                });
 446
 2447            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Role", b =>
 2448                {
 2449                    b.Property<long>("Id")
 2450                        .HasColumnType("bigint")
 2451                        .HasColumnName("id")
 2452                        .HasColumnOrder(1);
 2453
 2454                    b.Property<string>("Description")
 2455                        .HasMaxLength(500)
 2456                        .HasColumnType("character varying(500)")
 2457                        .HasColumnName("description");
 2458
 2459                    b.Property<string>("Name")
 2460                        .IsRequired()
 2461                        .HasMaxLength(200)
 2462                        .HasColumnType("character varying(200)")
 2463                        .HasColumnName("name");
 2464
 2465                    b.Property<Guid>("PublicId")
 2466                        .HasColumnType("uuid")
 2467                        .HasColumnName("public_id");
 2468
 2469                    b.HasKey("Id")
 2470                        .HasName("pk_role");
 2471
 2472                    b.HasIndex("Name")
 2473                        .IsUnique()
 2474                        .HasDatabaseName("ix_role_name");
 2475
 2476                    b.HasIndex("PublicId")
 2477                        .IsUnique()
 2478                        .HasDatabaseName("ix_role_public_id");
 2479
 2480                    b.ToTable("role", "heimdall");
 4481                });
 482
 2483            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Scope", b =>
 2484                {
 2485                    b.Property<long>("Id")
 2486                        .ValueGeneratedOnAdd()
 2487                        .HasColumnType("bigint")
 2488                        .HasColumnName("id")
 2489                        .HasColumnOrder(1);
 2490
 2491                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2492
 2493                    b.Property<DateTime>("CreatedAt")
 2494                        .ValueGeneratedOnAdd()
 2495                        .HasColumnType("timestamp with time zone")
 2496                        .HasColumnName("created_at")
 2497                        .HasDefaultValueSql("now()");
 2498
 2499                    b.Property<string>("Description")
 2500                        .HasMaxLength(500)
 2501                        .HasColumnType("character varying(500)")
 2502                        .HasColumnName("description");
 2503
 2504                    b.Property<bool>("GoogleSignInEnabled")
 2505                        .ValueGeneratedOnAdd()
 2506                        .HasColumnType("boolean")
 2507                        .HasDefaultValue(false)
 2508                        .HasColumnName("google_sign_in_enabled");
 2509
 2510                    b.Property<bool>("IsDeleted")
 2511                        .ValueGeneratedOnAdd()
 2512                        .HasColumnType("boolean")
 2513                        .HasDefaultValue(false)
 2514                        .HasColumnName("is_deleted");
 2515
 2516                    b.Property<string>("Name")
 2517                        .IsRequired()
 2518                        .HasMaxLength(200)
 2519                        .HasColumnType("character varying(200)")
 2520                        .HasColumnName("name");
 2521
 2522                    b.Property<Guid>("PublicId")
 2523                        .HasColumnType("uuid")
 2524                        .HasColumnName("public_id");
 2525
 2526                    b.Property<DateTime>("UpdatedAt")
 2527                        .ValueGeneratedOnAdd()
 2528                        .HasColumnType("timestamp with time zone")
 2529                        .HasColumnName("updated_at")
 2530                        .HasDefaultValueSql("now()");
 2531
 2532                    b.HasKey("Id")
 2533                        .HasName("pk_scope");
 2534
 2535                    b.HasIndex("Name")
 2536                        .IsUnique()
 2537                        .HasDatabaseName("ix_scope_name");
 2538
 2539                    b.HasIndex("PublicId")
 2540                        .IsUnique()
 2541                        .HasDatabaseName("ix_scope_public_id");
 2542
 2543                    b.ToTable("scope", "heimdall");
 4544                });
 545
 2546            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeOwner", b =>
 2547                {
 2548                    b.Property<long>("ScopeId")
 2549                        .HasColumnType("bigint")
 2550                        .HasColumnName("scope_id");
 2551
 2552                    b.Property<long>("PersonId")
 2553                        .HasColumnType("bigint")
 2554                        .HasColumnName("person_id");
 2555
 2556                    b.HasKey("ScopeId", "PersonId")
 2557                        .HasName("pk_scope_owner");
 2558
 2559                    b.HasIndex("PersonId")
 2560                        .HasDatabaseName("ix_scope_owner_person_id");
 2561
 2562                    b.ToTable("scope_owner", "heimdall");
 4563                });
 564
 2565            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopePermission", b =>
 2566                {
 2567                    b.Property<long>("Id")
 2568                        .ValueGeneratedOnAdd()
 2569                        .HasColumnType("bigint")
 2570                        .HasColumnName("id")
 2571                        .HasColumnOrder(1);
 2572
 2573                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2574
 2575                    b.Property<DateTime>("CreatedAt")
 2576                        .ValueGeneratedOnAdd()
 2577                        .HasColumnType("timestamp with time zone")
 2578                        .HasColumnName("created_at")
 2579                        .HasDefaultValueSql("now()");
 2580
 2581                    b.Property<string>("Description")
 2582                        .HasMaxLength(500)
 2583                        .HasColumnType("character varying(500)")
 2584                        .HasColumnName("description");
 2585
 2586                    b.Property<bool>("IncludeAsJwtClaim")
 2587                        .ValueGeneratedOnAdd()
 2588                        .HasColumnType("boolean")
 2589                        .HasDefaultValue(false)
 2590                        .HasColumnName("include_as_jwt_claim");
 2591
 2592                    b.Property<bool>("IsDeleted")
 2593                        .ValueGeneratedOnAdd()
 2594                        .HasColumnType("boolean")
 2595                        .HasDefaultValue(false)
 2596                        .HasColumnName("is_deleted");
 2597
 2598                    b.Property<string>("Name")
 2599                        .IsRequired()
 2600                        .HasMaxLength(200)
 2601                        .HasColumnType("character varying(200)")
 2602                        .HasColumnName("name");
 2603
 2604                    b.Property<Guid>("PublicId")
 2605                        .HasColumnType("uuid")
 2606                        .HasColumnName("public_id");
 2607
 2608                    b.Property<long>("ScopeId")
 2609                        .HasColumnType("bigint")
 2610                        .HasColumnName("scope_id");
 2611
 2612                    b.Property<DateTime>("UpdatedAt")
 2613                        .ValueGeneratedOnAdd()
 2614                        .HasColumnType("timestamp with time zone")
 2615                        .HasColumnName("updated_at")
 2616                        .HasDefaultValueSql("now()");
 2617
 2618                    b.HasKey("Id")
 2619                        .HasName("pk_scope_permission");
 2620
 2621                    b.HasIndex("PublicId")
 2622                        .IsUnique()
 2623                        .HasDatabaseName("ix_scope_permission_public_id");
 2624
 2625                    b.HasIndex("ScopeId")
 2626                        .HasDatabaseName("ix_scope_permission_scope_id");
 2627
 2628                    b.ToTable("scope_permission", "heimdall");
 4629                });
 630
 2631            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeUser", b =>
 2632                {
 2633                    b.Property<long>("ScopeId")
 2634                        .HasColumnType("bigint")
 2635                        .HasColumnName("scope_id");
 2636
 2637                    b.Property<long>("PersonId")
 2638                        .HasColumnType("bigint")
 2639                        .HasColumnName("person_id");
 2640
 2641                    b.HasKey("ScopeId", "PersonId")
 2642                        .HasName("pk_scope_user");
 2643
 2644                    b.HasIndex("PersonId")
 2645                        .IsUnique()
 2646                        .HasDatabaseName("ix_scope_user_person_id");
 2647
 2648                    b.ToTable("scope_user", "heimdall");
 4649                });
 650
 2651            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 2652                {
 2653                    b.Property<long>("Id")
 2654                        .ValueGeneratedOnAdd()
 2655                        .HasColumnType("bigint")
 2656                        .HasColumnName("id")
 2657                        .HasColumnOrder(1);
 2658
 2659                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2660
 2661                    b.Property<bool>("AppEnabled")
 2662                        .ValueGeneratedOnAdd()
 2663                        .HasColumnType("boolean")
 2664                        .HasDefaultValue(false)
 2665                        .HasColumnName("app_enabled");
 2666
 2667                    b.Property<DateTime>("CreatedAt")
 2668                        .ValueGeneratedOnAdd()
 2669                        .HasColumnType("timestamp with time zone")
 2670                        .HasColumnName("created_at")
 2671                        .HasDefaultValueSql("now()");
 2672
 2673                    b.Property<bool>("EmailEnabled")
 2674                        .ValueGeneratedOnAdd()
 2675                        .HasColumnType("boolean")
 2676                        .HasDefaultValue(false)
 2677                        .HasColumnName("email_enabled");
 2678
 2679                    b.Property<bool>("IsActive")
 2680                        .ValueGeneratedOnAdd()
 2681                        .HasColumnType("boolean")
 2682                        .HasDefaultValue(false)
 2683                        .HasColumnName("is_active");
 2684
 2685                    b.Property<long?>("LastTotpTimeStepUsed")
 2686                        .HasColumnType("bigint")
 2687                        .HasColumnName("last_totp_time_step_used");
 2688
 2689                    b.Property<long>("PersonId")
 2690                        .HasColumnType("bigint")
 2691                        .HasColumnName("person_id");
 2692
 2693                    b.Property<byte[]>("TotpSecretEncrypted")
 2694                        .HasColumnType("bytea")
 2695                        .HasColumnName("totp_secret_encrypted");
 2696
 2697                    b.Property<DateTime>("UpdatedAt")
 2698                        .ValueGeneratedOnAdd()
 2699                        .HasColumnType("timestamp with time zone")
 2700                        .HasColumnName("updated_at")
 2701                        .HasDefaultValueSql("now()");
 2702
 2703                    b.HasKey("Id")
 2704                        .HasName("pk_two_factor_auth");
 2705
 2706                    b.HasIndex("PersonId")
 2707                        .IsUnique()
 2708                        .HasDatabaseName("ix_two_factor_auth_person_id");
 2709
 2710                    b.ToTable("two_factor_auth", "heimdall");
 4711                });
 712
 2713            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode", b =>
 2714                {
 2715                    b.Property<long>("Id")
 2716                        .ValueGeneratedOnAdd()
 2717                        .HasColumnType("bigint")
 2718                        .HasColumnName("id")
 2719                        .HasColumnOrder(1);
 2720
 2721                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2722
 2723                    b.Property<byte[]>("CodeHash")
 2724                        .IsRequired()
 2725                        .HasColumnType("bytea")
 2726                        .HasColumnName("code_hash");
 2727
 2728                    b.Property<DateTime>("CreatedAt")
 2729                        .ValueGeneratedOnAdd()
 2730                        .HasColumnType("timestamp with time zone")
 2731                        .HasColumnName("created_at")
 2732                        .HasDefaultValueSql("now()");
 2733
 2734                    b.Property<DateTime>("ExpiresAt")
 2735                        .HasColumnType("timestamp with time zone")
 2736                        .HasColumnName("expires_at");
 2737
 2738                    b.Property<int>("FailedAttempts")
 2739                        .HasColumnType("integer")
 2740                        .HasColumnName("failed_attempts");
 2741
 2742                    b.Property<byte[]>("Salt")
 2743                        .IsRequired()
 2744                        .HasColumnType("bytea")
 2745                        .HasColumnName("salt");
 2746
 2747                    b.Property<long>("TwoFactorAuthId")
 2748                        .HasColumnType("bigint")
 2749                        .HasColumnName("two_factor_auth_id");
 2750
 2751                    b.Property<bool>("Used")
 2752                        .ValueGeneratedOnAdd()
 2753                        .HasColumnType("boolean")
 2754                        .HasDefaultValue(false)
 2755                        .HasColumnName("used");
 2756
 2757                    b.HasKey("Id")
 2758                        .HasName("pk_two_factor_email_code");
 2759
 2760                    b.HasIndex("TwoFactorAuthId")
 2761                        .HasDatabaseName("ix_two_factor_email_code_two_factor_auth_id");
 2762
 2763                    b.ToTable("two_factor_email_code", "heimdall");
 4764                });
 765
 2766            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorRecoveryCode", b =>
 2767                {
 2768                    b.Property<long>("Id")
 2769                        .ValueGeneratedOnAdd()
 2770                        .HasColumnType("bigint")
 2771                        .HasColumnName("id")
 2772                        .HasColumnOrder(1);
 2773
 2774                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 2775
 2776                    b.Property<byte[]>("CodeHash")
 2777                        .IsRequired()
 2778                        .HasColumnType("bytea")
 2779                        .HasColumnName("code_hash");
 2780
 2781                    b.Property<DateTime>("CreatedAt")
 2782                        .ValueGeneratedOnAdd()
 2783                        .HasColumnType("timestamp with time zone")
 2784                        .HasColumnName("created_at")
 2785                        .HasDefaultValueSql("now()");
 2786
 2787                    b.Property<long>("TwoFactorAuthId")
 2788                        .HasColumnType("bigint")
 2789                        .HasColumnName("two_factor_auth_id");
 2790
 2791                    b.Property<bool>("Used")
 2792                        .ValueGeneratedOnAdd()
 2793                        .HasColumnType("boolean")
 2794                        .HasDefaultValue(false)
 2795                        .HasColumnName("used");
 2796
 2797                    b.Property<DateTime?>("UsedAt")
 2798                        .HasColumnType("timestamp with time zone")
 2799                        .HasColumnName("used_at");
 2800
 2801                    b.HasKey("Id")
 2802                        .HasName("pk_two_factor_recovery_code");
 2803
 2804                    b.HasIndex("TwoFactorAuthId")
 2805                        .HasDatabaseName("ix_two_factor_recovery_code_two_factor_auth_id");
 2806
 2807                    b.ToTable("two_factor_recovery_code", "heimdall");
 4808                });
 809
 2810            modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
 2811                {
 2812                    b.Property<int>("Id")
 2813                        .ValueGeneratedOnAdd()
 2814                        .HasColumnType("integer")
 2815                        .HasColumnName("id");
 2816
 2817                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
 2818
 2819                    b.Property<string>("FriendlyName")
 2820                        .HasColumnType("text")
 2821                        .HasColumnName("friendly_name");
 2822
 2823                    b.Property<string>("Xml")
 2824                        .HasColumnType("text")
 2825                        .HasColumnName("xml");
 2826
 2827                    b.HasKey("Id")
 2828                        .HasName("pk_data_protection_keys");
 2829
 2830                    b.ToTable("data_protection_keys", "heimdall");
 4831                });
 832
 2833            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Application", b =>
 2834                {
 2835                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Owner")
 2836                        .WithMany("OwnedApplications")
 2837                        .HasForeignKey("OwnerId")
 2838                        .OnDelete(DeleteBehavior.Cascade)
 2839                        .IsRequired()
 2840                        .HasConstraintName("fk_application_person_owner_id");
 2841
 2842                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 2843                        .WithMany("Applications")
 2844                        .HasForeignKey("ScopeId")
 2845                        .OnDelete(DeleteBehavior.Cascade)
 2846                        .IsRequired()
 2847                        .HasConstraintName("fk_application_scope_scope_id");
 2848
 2849                    b.Navigation("Owner");
 2850
 2851                    b.Navigation("Scope");
 4852                });
 853
 2854            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.EmailVerificationToken", b =>
 2855                {
 2856                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 2857                        .WithMany("EmailVerificationTokens")
 2858                        .HasForeignKey("PersonId")
 2859                        .OnDelete(DeleteBehavior.Cascade)
 2860                        .IsRequired()
 2861                        .HasConstraintName("fk_email_verification_token_person_person_id");
 2862
 2863                    b.Navigation("Person");
 4864                });
 865
 2866            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.GoogleUser", b =>
 2867                {
 2868                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 2869                        .WithMany("GoogleUsers")
 2870                        .HasForeignKey("ScopeId")
 2871                        .OnDelete(DeleteBehavior.Cascade)
 2872                        .IsRequired()
 2873                        .HasConstraintName("fk_google_user_scope_scope_id");
 2874
 2875                    b.Navigation("Scope");
 4876                });
 877
 2878            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PasswordResetToken", b =>
 2879                {
 2880                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 2881                        .WithMany("PasswordResetTokens")
 2882                        .HasForeignKey("PersonId")
 2883                        .OnDelete(DeleteBehavior.Cascade)
 2884                        .IsRequired()
 2885                        .HasConstraintName("fk_password_reset_token_person_person_id");
 2886
 2887                    b.Navigation("Person");
 4888                });
 889
 2890            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 2891                {
 2892                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Role", "Role")
 2893                        .WithMany("Persons")
 2894                        .HasForeignKey("RoleId")
 2895                        .OnDelete(DeleteBehavior.Restrict)
 2896                        .IsRequired()
 2897                        .HasConstraintName("fk_person_roles_role_id");
 2898
 2899                    b.Navigation("Role");
 4900                });
 901
 2902            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeOwner", b =>
 2903                {
 2904                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 2905                        .WithMany("ScopeOwnerships")
 2906                        .HasForeignKey("PersonId")
 2907                        .OnDelete(DeleteBehavior.Cascade)
 2908                        .IsRequired()
 2909                        .HasConstraintName("fk_scope_owner_person_person_id");
 2910
 2911                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 2912                        .WithMany("Owners")
 2913                        .HasForeignKey("ScopeId")
 2914                        .OnDelete(DeleteBehavior.Cascade)
 2915                        .IsRequired()
 2916                        .HasConstraintName("fk_scope_owner_scope_scope_id");
 2917
 2918                    b.Navigation("Person");
 2919
 2920                    b.Navigation("Scope");
 4921                });
 922
 2923            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopePermission", b =>
 2924                {
 2925                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 2926                        .WithMany("ScopePermissions")
 2927                        .HasForeignKey("ScopeId")
 2928                        .OnDelete(DeleteBehavior.Cascade)
 2929                        .IsRequired()
 2930                        .HasConstraintName("fk_scope_permission_scope_scope_id");
 2931
 2932                    b.Navigation("Scope");
 4933                });
 934
 2935            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeUser", b =>
 2936                {
 2937                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 2938                        .WithOne("ScopeMembership")
 2939                        .HasForeignKey("ArturRios.Heimdall.Domain.Entities.ScopeUser", "PersonId")
 2940                        .OnDelete(DeleteBehavior.Cascade)
 2941                        .IsRequired()
 2942                        .HasConstraintName("fk_scope_user_person_person_id");
 2943
 2944                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 2945                        .WithMany("Users")
 2946                        .HasForeignKey("ScopeId")
 2947                        .OnDelete(DeleteBehavior.Cascade)
 2948                        .IsRequired()
 2949                        .HasConstraintName("fk_scope_user_scope_scope_id");
 2950
 2951                    b.Navigation("Person");
 2952
 2953                    b.Navigation("Scope");
 4954                });
 955
 2956            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 2957                {
 2958                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 2959                        .WithOne("TwoFactorAuth")
 2960                        .HasForeignKey("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "PersonId")
 2961                        .OnDelete(DeleteBehavior.Cascade)
 2962                        .IsRequired()
 2963                        .HasConstraintName("fk_two_factor_auth_person_person_id");
 2964
 2965                    b.Navigation("Person");
 4966                });
 967
 2968            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode", b =>
 2969                {
 2970                    b.HasOne("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "TwoFactorAuth")
 2971                        .WithMany("EmailCodes")
 2972                        .HasForeignKey("TwoFactorAuthId")
 2973                        .OnDelete(DeleteBehavior.Cascade)
 2974                        .IsRequired()
 2975                        .HasConstraintName("fk_two_factor_email_code_two_factor_auth_two_factor_auth_id");
 2976
 2977                    b.Navigation("TwoFactorAuth");
 4978                });
 979
 2980            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorRecoveryCode", b =>
 2981                {
 2982                    b.HasOne("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "TwoFactorAuth")
 2983                        .WithMany("RecoveryCodes")
 2984                        .HasForeignKey("TwoFactorAuthId")
 2985                        .OnDelete(DeleteBehavior.Cascade)
 2986                        .IsRequired()
 2987                        .HasConstraintName("fk_two_factor_recovery_code_two_factor_auth_two_factor_auth_id");
 2988
 2989                    b.Navigation("TwoFactorAuth");
 4990                });
 991
 2992            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 2993                {
 2994                    b.Navigation("EmailVerificationTokens");
 2995
 2996                    b.Navigation("OwnedApplications");
 2997
 2998                    b.Navigation("PasswordResetTokens");
 2999
 21000                    b.Navigation("ScopeMembership");
 21001
 21002                    b.Navigation("ScopeOwnerships");
 21003
 21004                    b.Navigation("TwoFactorAuth");
 41005                });
 1006
 21007            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Role", b =>
 21008                {
 21009                    b.Navigation("Persons");
 41010                });
 1011
 21012            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Scope", b =>
 21013                {
 21014                    b.Navigation("Applications");
 21015
 21016                    b.Navigation("GoogleUsers");
 21017
 21018                    b.Navigation("Owners");
 21019
 21020                    b.Navigation("ScopePermissions");
 21021
 21022                    b.Navigation("Users");
 41023                });
 1024
 21025            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 21026                {
 21027                    b.Navigation("EmailCodes");
 21028
 21029                    b.Navigation("RecoveryCodes");
 41030                });
 1031#pragma warning restore 612, 618
 21032        }
 1033    }
 1034}