< Summary - Heimdall API

Line coverage
100%
Covered lines: 1441
Uncovered lines: 0
Coverable lines: 1441
Total lines: 1556
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/20261014170441_AllowClearingAuditTarget.cs

#LineLine coverage
 1using Microsoft.EntityFrameworkCore.Migrations;
 2
 3#nullable disable
 4
 5namespace ArturRios.Heimdall.Data.Migrations
 6{
 7    /// <summary>
 8    ///     Widens the audit log's append-only rule by exactly one more permitted change: a target
 9    ///     naming a person or Google User may be cleared once it is due (NFR-21, #184).
 10    /// </summary>
 11    /// <remarks>
 12    ///     <para>
 13    ///         `AllowClearingAuditActor` let the actor attribution be forgotten and left `target_id`
 14    ///         immutable. That was not enough to make an entry anonymous. For a command somebody runs
 15    ///         on their own account the target is their own `PublicId`, and for an administrator's
 16    ///         action on a person it is that person, so the entry kept naming somebody for as long as
 17    ///         their `person` or `google_user` row stayed identifiable — whatever happened to the
 18    ///         actor. UC-48's filter by `targetId` made that a one-query lookup.
 19    ///     </para>
 20    ///     <para>
 21    ///         This replaces `heimdall.audit_log_actor_clear_only()` with
 22    ///         `heimdall.audit_log_attribution_clear_only()`, still a row-level BEFORE UPDATE
 23    ///         trigger. The actor rule is unchanged. The one addition: `target_id` may go from a
 24    ///         value to NULL — never to another value — and only when the old value is the `public_id`
 25    ///         of a `person` or `google_user` row and the clearing is due on the actor's own two
 26    ///         grounds: that row has been anonymised, or the entry is past the thirty-day floor.
 27    ///         A target naming anything else (a scope, an application, a credential, a permission)
 28    ///         is not personal data and stays immutable, as does one that resolves to nobody.
 29    ///     </para>
 30    ///     <para>
 31    ///         Each of the two clearable parts may now also be written back unchanged, so the pass
 32    ///         can clear a due target while leaving an undue actor in place, and the reverse. The
 33    ///         row's `id`, unguarded before, joins the immutable columns: once an unchanged actor is
 34    ///         an accepted write, leaving `id` out would have let any row be renumbered, a change
 35    ///         the old rule refused on every attributed row. DELETE and TRUNCATE stay refused
 36    ///         outright and their triggers are not touched.
 37    ///     </para>
 38    /// </remarks>
 39    public partial class AllowClearingAuditTarget : Migration
 40    {
 41        /// <inheritdoc />
 42        protected override void Up(MigrationBuilder migrationBuilder)
 43        {
 1944            migrationBuilder.Sql(
 1945                "DROP TRIGGER IF EXISTS audit_log_actor_clear_only ON heimdall.audit_log;");
 1946            migrationBuilder.Sql(
 1947                "DROP FUNCTION IF EXISTS heimdall.audit_log_actor_clear_only();");
 48
 1949            migrationBuilder.Sql(
 1950                """
 1951                CREATE OR REPLACE FUNCTION heimdall.audit_log_attribution_clear_only()
 1952                RETURNS TRIGGER AS $$
 1953                DECLARE
 1954                    actor_erased boolean;
 1955                    target_is_person boolean;
 1956                    target_erased boolean;
 1957                BEGIN
 1958                    -- What happened is immutable. Checked first, so an attempt to rewrite it is
 1959                    -- refused with that reason rather than a later one, and so created_at cannot be
 1960                    -- moved to make a clearing look due.
 1961                    IF NEW.id IS DISTINCT FROM OLD.id
 1962                       OR NEW.public_id IS DISTINCT FROM OLD.public_id
 1963                       OR NEW.action IS DISTINCT FROM OLD.action
 1964                       OR NEW.succeeded IS DISTINCT FROM OLD.succeeded
 1965                       OR NEW.failure_reason IS DISTINCT FROM OLD.failure_reason
 1966                       OR NEW.created_at IS DISTINCT FROM OLD.created_at
 1967                    THEN
 1968                        RAISE EXCEPTION
 1969                            'heimdall.audit_log is append-only: only the actor attribution and a person target may be cl
 1970                            USING ERRCODE = 'restrict_violation';
 1971                    END IF;
 1972
 1973                    -- The actor: unchanged, or cleared once due. Never reassigned, because a trail
 1974                    -- that says somebody else acted is worse than one that does not say who did.
 1975                    IF NEW.actor_person_id IS DISTINCT FROM OLD.actor_person_id
 1976                       OR NEW.actor_role IS DISTINCT FROM OLD.actor_role
 1977                    THEN
 1978                        IF NEW.actor_person_id IS NOT NULL OR NEW.actor_role IS NOT NULL THEN
 1979                            RAISE EXCEPTION
 1980                                'heimdall.audit_log actor attribution may be cleared but not reassigned'
 1981                                USING ERRCODE = 'restrict_violation';
 1982                        END IF;
 1983
 1984                        SELECT EXISTS (
 1985                            SELECT 1 FROM heimdall.person p
 1986                            WHERE p.public_id = OLD.actor_person_id AND p.anonymised_at IS NOT NULL
 1987                            UNION ALL
 1988                            SELECT 1 FROM heimdall.google_user g
 1989                            WHERE g.public_id = OLD.actor_person_id AND g.anonymised_at IS NOT NULL
 1990                        ) INTO actor_erased;
 1991
 1992                        IF NOT (actor_erased OR OLD.created_at <= now() - interval '30 days') THEN
 1993                            RAISE EXCEPTION
 1994                                'heimdall.audit_log actor attribution is not yet due to be cleared'
 1995                                USING ERRCODE = 'restrict_violation';
 1996                        END IF;
 1997                    END IF;
 1998
 1999                    -- The target: unchanged, or cleared once due, and only when it names a person.
 19100                    -- Anything else it can name is not personal data and stays as recorded.
 19101                    IF NEW.target_id IS DISTINCT FROM OLD.target_id THEN
 19102                        IF NEW.target_id IS NOT NULL AND OLD.target_id IS NULL THEN
 19103                            RAISE EXCEPTION
 19104                                'heimdall.audit_log target may be cleared but not set'
 19105                                USING ERRCODE = 'restrict_violation';
 19106                        END IF;
 19107
 19108                        IF NEW.target_id IS NOT NULL THEN
 19109                            RAISE EXCEPTION
 19110                                'heimdall.audit_log target may be cleared but not reassigned'
 19111                                USING ERRCODE = 'restrict_violation';
 19112                        END IF;
 19113
 19114                        SELECT EXISTS (
 19115                            SELECT 1 FROM heimdall.person p WHERE p.public_id = OLD.target_id
 19116                            UNION ALL
 19117                            SELECT 1 FROM heimdall.google_user g WHERE g.public_id = OLD.target_id
 19118                        ) INTO target_is_person;
 19119
 19120                        IF NOT target_is_person THEN
 19121                            RAISE EXCEPTION
 19122                                'heimdall.audit_log target names no person and may not be cleared'
 19123                                USING ERRCODE = 'restrict_violation';
 19124                        END IF;
 19125
 19126                        SELECT EXISTS (
 19127                            SELECT 1 FROM heimdall.person p
 19128                            WHERE p.public_id = OLD.target_id AND p.anonymised_at IS NOT NULL
 19129                            UNION ALL
 19130                            SELECT 1 FROM heimdall.google_user g
 19131                            WHERE g.public_id = OLD.target_id AND g.anonymised_at IS NOT NULL
 19132                        ) INTO target_erased;
 19133
 19134                        IF NOT (target_erased OR OLD.created_at <= now() - interval '30 days') THEN
 19135                            RAISE EXCEPTION
 19136                                'heimdall.audit_log target is not yet due to be cleared'
 19137                                USING ERRCODE = 'restrict_violation';
 19138                        END IF;
 19139                    END IF;
 19140
 19141                    RETURN NEW;
 19142                END;
 19143                $$ LANGUAGE plpgsql;
 19144                """);
 145
 19146            migrationBuilder.Sql(
 19147                """
 19148                CREATE TRIGGER audit_log_attribution_clear_only
 19149                BEFORE UPDATE ON heimdall.audit_log
 19150                FOR EACH ROW EXECUTE FUNCTION heimdall.audit_log_attribution_clear_only();
 19151                """);
 19152        }
 153
 154        /// <inheritdoc />
 155        protected override void Down(MigrationBuilder migrationBuilder)
 156        {
 1157            migrationBuilder.Sql(
 1158                "DROP TRIGGER IF EXISTS audit_log_attribution_clear_only ON heimdall.audit_log;");
 1159            migrationBuilder.Sql(
 1160                "DROP FUNCTION IF EXISTS heimdall.audit_log_attribution_clear_only();");
 161
 162            // Back to AllowClearingAuditActor's rule, copied verbatim: the actor alone, target_id
 163            // immutable.
 1164            migrationBuilder.Sql(
 1165                """
 1166                CREATE OR REPLACE FUNCTION heimdall.audit_log_actor_clear_only()
 1167                RETURNS TRIGGER AS $$
 1168                DECLARE
 1169                    actor_erased boolean;
 1170                BEGIN
 1171                    -- Everything but the attribution is immutable. Checked first, so an attempt to
 1172                    -- rewrite what happened is refused with that reason rather than a later one.
 1173                    IF NEW.public_id IS DISTINCT FROM OLD.public_id
 1174                       OR NEW.action IS DISTINCT FROM OLD.action
 1175                       OR NEW.target_id IS DISTINCT FROM OLD.target_id
 1176                       OR NEW.succeeded IS DISTINCT FROM OLD.succeeded
 1177                       OR NEW.failure_reason IS DISTINCT FROM OLD.failure_reason
 1178                       OR NEW.created_at IS DISTINCT FROM OLD.created_at
 1179                    THEN
 1180                        RAISE EXCEPTION
 1181                            'heimdall.audit_log is append-only: only the actor attribution may be cleared'
 1182                            USING ERRCODE = 'restrict_violation';
 1183                    END IF;
 1184
 1185                    -- Cleared, never reassigned. Without this the trail could be made to say that
 1186                    -- somebody else took the action, which is worse than it not saying who did.
 1187                    IF NEW.actor_person_id IS NOT NULL OR NEW.actor_role IS NOT NULL THEN
 1188                        RAISE EXCEPTION
 1189                            'heimdall.audit_log actor attribution may be cleared but not reassigned'
 1190                            USING ERRCODE = 'restrict_violation';
 1191                    END IF;
 1192
 1193                    -- Already clear: a no-op write, permitted so a re-run is not an error.
 1194                    IF OLD.actor_person_id IS NULL AND OLD.actor_role IS NULL THEN
 1195                        RETURN NEW;
 1196                    END IF;
 1197
 1198                    SELECT EXISTS (
 1199                        SELECT 1 FROM heimdall.person p
 1200                        WHERE p.public_id = OLD.actor_person_id AND p.anonymised_at IS NOT NULL
 1201                        UNION ALL
 1202                        SELECT 1 FROM heimdall.google_user g
 1203                        WHERE g.public_id = OLD.actor_person_id AND g.anonymised_at IS NOT NULL
 1204                    ) INTO actor_erased;
 1205
 1206                    IF actor_erased OR OLD.created_at <= now() - interval '30 days' THEN
 1207                        RETURN NEW;
 1208                    END IF;
 1209
 1210                    RAISE EXCEPTION
 1211                        'heimdall.audit_log actor attribution is not yet due to be cleared'
 1212                        USING ERRCODE = 'restrict_violation';
 1213                END;
 1214                $$ LANGUAGE plpgsql;
 1215                """);
 216
 1217            migrationBuilder.Sql(
 1218                """
 1219                CREATE TRIGGER audit_log_actor_clear_only
 1220                BEFORE UPDATE ON heimdall.audit_log
 1221                FOR EACH ROW EXECUTE FUNCTION heimdall.audit_log_actor_clear_only();
 1222                """);
 1223        }
 224    }
 225}

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Infrastructure/ArturRios.Heimdall.Data/Migrations/20261014170441_AllowClearingAuditTarget.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("20261014170441_AllowClearingAuditTarget")]
 16    partial class AllowClearingAuditTarget
 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.13")
 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.ApplicationCredential", 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<long>("ApplicationId")
 10102                        .HasColumnType("bigint")
 10103                        .HasColumnName("application_id");
 10104
 10105                    b.Property<DateTime>("CreatedAt")
 10106                        .HasColumnType("timestamp with time zone")
 10107                        .HasColumnName("created_at");
 10108
 10109                    b.Property<DateTime?>("ExpiresAt")
 10110                        .HasColumnType("timestamp with time zone")
 10111                        .HasColumnName("expires_at");
 10112
 10113                    b.Property<DateTime?>("LastUsedAt")
 10114                        .HasColumnType("timestamp with time zone")
 10115                        .HasColumnName("last_used_at");
 10116
 10117                    b.Property<Guid>("PublicId")
 10118                        .HasColumnType("uuid")
 10119                        .HasColumnName("public_id");
 10120
 10121                    b.Property<DateTime?>("RevokedAt")
 10122                        .HasColumnType("timestamp with time zone")
 10123                        .HasColumnName("revoked_at");
 10124
 10125                    b.Property<string>("SecretHash")
 10126                        .IsRequired()
 10127                        .HasMaxLength(64)
 10128                        .HasColumnType("character varying(64)")
 10129                        .HasColumnName("secret_hash");
 10130
 10131                    b.HasKey("Id")
 10132                        .HasName("pk_application_credential");
 10133
 10134                    b.HasIndex("ApplicationId")
 10135                        .HasDatabaseName("ix_application_credential_application_id");
 10136
 10137                    b.HasIndex("PublicId")
 10138                        .IsUnique()
 10139                        .HasDatabaseName("ix_application_credential_public_id");
 10140
 10141                    b.HasIndex("SecretHash")
 10142                        .IsUnique()
 10143                        .HasDatabaseName("ix_application_credential_secret_hash");
 10144
 10145                    b.ToTable("application_credential", "heimdall");
 20146                });
 147
 10148            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.AuditLog", b =>
 10149                {
 10150                    b.Property<long>("Id")
 10151                        .ValueGeneratedOnAdd()
 10152                        .HasColumnType("bigint")
 10153                        .HasColumnName("id")
 10154                        .HasColumnOrder(1);
 10155
 10156                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10157
 10158                    b.Property<string>("Action")
 10159                        .IsRequired()
 10160                        .HasMaxLength(200)
 10161                        .HasColumnType("character varying(200)")
 10162                        .HasColumnName("action");
 10163
 10164                    b.Property<Guid?>("ActorPersonId")
 10165                        .HasColumnType("uuid")
 10166                        .HasColumnName("actor_person_id");
 10167
 10168                    b.Property<int?>("ActorRole")
 10169                        .HasColumnType("integer")
 10170                        .HasColumnName("actor_role");
 10171
 10172                    b.Property<DateTime>("CreatedAt")
 10173                        .ValueGeneratedOnAdd()
 10174                        .HasColumnType("timestamp with time zone")
 10175                        .HasColumnName("created_at")
 10176                        .HasDefaultValueSql("now()");
 10177
 10178                    b.Property<string>("FailureReason")
 10179                        .HasMaxLength(500)
 10180                        .HasColumnType("character varying(500)")
 10181                        .HasColumnName("failure_reason");
 10182
 10183                    b.Property<Guid>("PublicId")
 10184                        .HasColumnType("uuid")
 10185                        .HasColumnName("public_id");
 10186
 10187                    b.Property<bool>("Succeeded")
 10188                        .HasColumnType("boolean")
 10189                        .HasColumnName("succeeded");
 10190
 10191                    b.Property<Guid?>("TargetId")
 10192                        .HasColumnType("uuid")
 10193                        .HasColumnName("target_id");
 10194
 10195                    b.HasKey("Id")
 10196                        .HasName("pk_audit_log");
 10197
 10198                    b.HasIndex("ActorPersonId")
 10199                        .HasDatabaseName("ix_audit_log_actor_person_id");
 10200
 10201                    b.HasIndex("CreatedAt")
 10202                        .HasDatabaseName("ix_audit_log_created_at");
 10203
 10204                    b.HasIndex("PublicId")
 10205                        .IsUnique()
 10206                        .HasDatabaseName("ix_audit_log_public_id");
 10207
 10208                    b.HasIndex("TargetId")
 10209                        .HasDatabaseName("ix_audit_log_target_id");
 10210
 10211                    b.ToTable("audit_log", "heimdall");
 20212                });
 213
 10214            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.EmailVerificationToken", b =>
 10215                {
 10216                    b.Property<long>("Id")
 10217                        .ValueGeneratedOnAdd()
 10218                        .HasColumnType("bigint")
 10219                        .HasColumnName("id")
 10220                        .HasColumnOrder(1);
 10221
 10222                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10223
 10224                    b.Property<DateTime>("ExpiresAt")
 10225                        .HasColumnType("timestamp with time zone")
 10226                        .HasColumnName("expires_at");
 10227
 10228                    b.Property<long>("PersonId")
 10229                        .HasColumnType("bigint")
 10230                        .HasColumnName("person_id");
 10231
 10232                    b.Property<string>("TokenHash")
 10233                        .IsRequired()
 10234                        .HasMaxLength(64)
 10235                        .HasColumnType("character varying(64)")
 10236                        .HasColumnName("token_hash");
 10237
 10238                    b.Property<bool>("Used")
 10239                        .ValueGeneratedOnAdd()
 10240                        .HasColumnType("boolean")
 10241                        .HasDefaultValue(false)
 10242                        .HasColumnName("used");
 10243
 10244                    b.HasKey("Id")
 10245                        .HasName("pk_email_verification_token");
 10246
 10247                    b.HasIndex("PersonId")
 10248                        .HasDatabaseName("ix_email_verification_token_person_id");
 10249
 10250                    b.HasIndex("TokenHash")
 10251                        .IsUnique()
 10252                        .HasDatabaseName("ix_email_verification_token_token_hash");
 10253
 10254                    b.ToTable("email_verification_token", "heimdall");
 20255                });
 256
 10257            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.GoogleUser", b =>
 10258                {
 10259                    b.Property<long>("Id")
 10260                        .ValueGeneratedOnAdd()
 10261                        .HasColumnType("bigint")
 10262                        .HasColumnName("id")
 10263                        .HasColumnOrder(1);
 10264
 10265                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10266
 10267                    b.Property<DateTime?>("AnonymisedAt")
 10268                        .HasColumnType("timestamp with time zone")
 10269                        .HasColumnName("anonymised_at");
 10270
 10271                    b.Property<DateTime?>("BasisRecordedAt")
 10272                        .HasColumnType("timestamp with time zone")
 10273                        .HasColumnName("basis_recorded_at");
 10274
 10275                    b.Property<DateTime>("CreatedAt")
 10276                        .ValueGeneratedOnAdd()
 10277                        .HasColumnType("timestamp with time zone")
 10278                        .HasColumnName("created_at")
 10279                        .HasDefaultValueSql("now()");
 10280
 10281                    b.Property<DateTime?>("DeletedAt")
 10282                        .HasColumnType("timestamp with time zone")
 10283                        .HasColumnName("deleted_at");
 10284
 10285                    b.Property<int?>("DeletionKind")
 10286                        .HasColumnType("integer")
 10287                        .HasColumnName("deletion_kind");
 10288
 10289                    b.Property<string>("Email")
 10290                        .IsRequired()
 10291                        .HasMaxLength(256)
 10292                        .HasColumnType("character varying(256)")
 10293                        .HasColumnName("email");
 10294
 10295                    b.Property<bool>("EmailVerified")
 10296                        .ValueGeneratedOnAdd()
 10297                        .HasColumnType("boolean")
 10298                        .HasDefaultValue(false)
 10299                        .HasColumnName("email_verified");
 10300
 10301                    b.Property<string>("ErasureBlockedReason")
 10302                        .HasMaxLength(500)
 10303                        .HasColumnType("character varying(500)")
 10304                        .HasColumnName("erasure_blocked_reason");
 10305
 10306                    b.Property<DateTime?>("ErasureDueAt")
 10307                        .HasColumnType("timestamp with time zone")
 10308                        .HasColumnName("erasure_due_at");
 10309
 10310                    b.Property<DateTime?>("ErasureRequestedAt")
 10311                        .HasColumnType("timestamp with time zone")
 10312                        .HasColumnName("erasure_requested_at");
 10313
 10314                    b.Property<string>("GoogleId")
 10315                        .IsRequired()
 10316                        .HasMaxLength(255)
 10317                        .HasColumnType("character varying(255)")
 10318                        .HasColumnName("google_id");
 10319
 10320                    b.Property<bool>("IsDeleted")
 10321                        .ValueGeneratedOnAdd()
 10322                        .HasColumnType("boolean")
 10323                        .HasDefaultValue(false)
 10324                        .HasColumnName("is_deleted");
 10325
 10326                    b.Property<int>("LegalBasis")
 10327                        .ValueGeneratedOnAdd()
 10328                        .HasColumnType("integer")
 10329                        .HasDefaultValue(0)
 10330                        .HasColumnName("legal_basis");
 10331
 10332                    b.Property<string>("Name")
 10333                        .IsRequired()
 10334                        .HasMaxLength(200)
 10335                        .HasColumnType("character varying(200)")
 10336                        .HasColumnName("name");
 10337
 10338                    b.Property<string>("PrivacyNoticeVersion")
 10339                        .HasMaxLength(50)
 10340                        .HasColumnType("character varying(50)")
 10341                        .HasColumnName("privacy_notice_version");
 10342
 10343                    b.Property<DateTime?>("ProcessingRestrictedAt")
 10344                        .HasColumnType("timestamp with time zone")
 10345                        .HasColumnName("processing_restricted_at");
 10346
 10347                    b.Property<string>("ProfilePictureUrl")
 10348                        .HasMaxLength(2048)
 10349                        .HasColumnType("character varying(2048)")
 10350                        .HasColumnName("profile_picture_url");
 10351
 10352                    b.Property<Guid>("PublicId")
 10353                        .HasColumnType("uuid")
 10354                        .HasColumnName("public_id");
 10355
 10356                    b.Property<int?>("RestrictionGround")
 10357                        .HasColumnType("integer")
 10358                        .HasColumnName("restriction_ground");
 10359
 10360                    b.Property<DateTime?>("RestrictionLiftNotifiedAt")
 10361                        .HasColumnType("timestamp with time zone")
 10362                        .HasColumnName("restriction_lift_notified_at");
 10363
 10364                    b.Property<long>("ScopeId")
 10365                        .HasColumnType("bigint")
 10366                        .HasColumnName("scope_id");
 10367
 10368                    b.Property<DateTime>("UpdatedAt")
 10369                        .ValueGeneratedOnAdd()
 10370                        .HasColumnType("timestamp with time zone")
 10371                        .HasColumnName("updated_at")
 10372                        .HasDefaultValueSql("now()");
 10373
 10374                    b.HasKey("Id")
 10375                        .HasName("pk_google_user");
 10376
 10377                    b.HasIndex("DeletedAt")
 10378                        .HasDatabaseName("ix_google_user_deleted_at")
 10379                        .HasFilter("is_deleted = true AND anonymised_at IS NULL");
 10380
 10381                    b.HasIndex("ProcessingRestrictedAt")
 10382                        .HasDatabaseName("ix_google_user_processing_restricted_at")
 10383                        .HasFilter("processing_restricted_at IS NOT NULL");
 10384
 10385                    b.HasIndex("PublicId")
 10386                        .IsUnique()
 10387                        .HasDatabaseName("ix_google_user_public_id");
 10388
 10389                    b.HasIndex("ScopeId", "Email")
 10390                        .IsUnique()
 10391                        .HasDatabaseName("ix_google_user_scope_id_email");
 10392
 10393                    b.HasIndex("ScopeId", "GoogleId")
 10394                        .IsUnique()
 10395                        .HasDatabaseName("ix_google_user_scope_id_google_id");
 10396
 10397                    b.ToTable("google_user", "heimdall");
 20398                });
 399
 10400            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PasswordResetToken", b =>
 10401                {
 10402                    b.Property<long>("Id")
 10403                        .ValueGeneratedOnAdd()
 10404                        .HasColumnType("bigint")
 10405                        .HasColumnName("id")
 10406                        .HasColumnOrder(1);
 10407
 10408                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10409
 10410                    b.Property<DateTime>("ExpiresAt")
 10411                        .HasColumnType("timestamp with time zone")
 10412                        .HasColumnName("expires_at");
 10413
 10414                    b.Property<long>("PersonId")
 10415                        .HasColumnType("bigint")
 10416                        .HasColumnName("person_id");
 10417
 10418                    b.Property<string>("TokenHash")
 10419                        .IsRequired()
 10420                        .HasMaxLength(64)
 10421                        .HasColumnType("character varying(64)")
 10422                        .HasColumnName("token_hash");
 10423
 10424                    b.Property<bool>("Used")
 10425                        .ValueGeneratedOnAdd()
 10426                        .HasColumnType("boolean")
 10427                        .HasDefaultValue(false)
 10428                        .HasColumnName("used");
 10429
 10430                    b.HasKey("Id")
 10431                        .HasName("pk_password_reset_token");
 10432
 10433                    b.HasIndex("PersonId")
 10434                        .HasDatabaseName("ix_password_reset_token_person_id");
 10435
 10436                    b.HasIndex("TokenHash")
 10437                        .IsUnique()
 10438                        .HasDatabaseName("ix_password_reset_token_token_hash");
 10439
 10440                    b.ToTable("password_reset_token", "heimdall");
 20441                });
 442
 10443            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PendingRegistration", b =>
 10444                {
 10445                    b.Property<long>("Id")
 10446                        .ValueGeneratedOnAdd()
 10447                        .HasColumnType("bigint")
 10448                        .HasColumnName("id")
 10449                        .HasColumnOrder(1);
 10450
 10451                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10452
 10453                    b.Property<DateTime>("CreatedAt")
 10454                        .ValueGeneratedOnAdd()
 10455                        .HasColumnType("timestamp with time zone")
 10456                        .HasColumnName("created_at")
 10457                        .HasDefaultValueSql("now()");
 10458
 10459                    b.Property<string>("Email")
 10460                        .IsRequired()
 10461                        .HasMaxLength(256)
 10462                        .HasColumnType("character varying(256)")
 10463                        .HasColumnName("email");
 10464
 10465                    b.Property<DateTime>("ExpiresAt")
 10466                        .HasColumnType("timestamp with time zone")
 10467                        .HasColumnName("expires_at");
 10468
 10469                    b.Property<int>("FailedAttempts")
 10470                        .ValueGeneratedOnAdd()
 10471                        .HasColumnType("integer")
 10472                        .HasDefaultValue(0)
 10473                        .HasColumnName("failed_attempts");
 10474
 10475                    b.Property<string>("Name")
 10476                        .IsRequired()
 10477                        .HasMaxLength(200)
 10478                        .HasColumnType("character varying(200)")
 10479                        .HasColumnName("name");
 10480
 10481                    b.Property<byte[]>("PasswordHash")
 10482                        .IsRequired()
 10483                        .HasColumnType("bytea")
 10484                        .HasColumnName("password_hash");
 10485
 10486                    b.Property<Guid>("PublicId")
 10487                        .HasColumnType("uuid")
 10488                        .HasColumnName("public_id");
 10489
 10490                    b.Property<byte[]>("Salt")
 10491                        .IsRequired()
 10492                        .HasColumnType("bytea")
 10493                        .HasColumnName("salt");
 10494
 10495                    b.Property<long>("ScopeId")
 10496                        .HasColumnType("bigint")
 10497                        .HasColumnName("scope_id");
 10498
 10499                    b.Property<string>("TokenHash")
 10500                        .IsRequired()
 10501                        .HasMaxLength(64)
 10502                        .HasColumnType("character varying(64)")
 10503                        .HasColumnName("token_hash");
 10504
 10505                    b.HasKey("Id")
 10506                        .HasName("pk_pending_registration");
 10507
 10508                    b.HasIndex("PublicId")
 10509                        .IsUnique()
 10510                        .HasDatabaseName("ix_pending_registration_public_id");
 10511
 10512                    b.HasIndex("ScopeId")
 10513                        .HasDatabaseName("ix_pending_registration_scope_id");
 10514
 10515                    b.HasIndex("TokenHash")
 10516                        .IsUnique()
 10517                        .HasDatabaseName("ix_pending_registration_token_hash");
 10518
 10519                    b.ToTable("pending_registration", "heimdall");
 20520                });
 521
 10522            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 10523                {
 10524                    b.Property<long>("Id")
 10525                        .ValueGeneratedOnAdd()
 10526                        .HasColumnType("bigint")
 10527                        .HasColumnName("id")
 10528                        .HasColumnOrder(1);
 10529
 10530                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10531
 10532                    b.Property<DateTime?>("AnonymisedAt")
 10533                        .HasColumnType("timestamp with time zone")
 10534                        .HasColumnName("anonymised_at");
 10535
 10536                    b.Property<DateTime?>("BasisRecordedAt")
 10537                        .HasColumnType("timestamp with time zone")
 10538                        .HasColumnName("basis_recorded_at");
 10539
 10540                    b.Property<DateTime>("CreatedAt")
 10541                        .ValueGeneratedOnAdd()
 10542                        .HasColumnType("timestamp with time zone")
 10543                        .HasColumnName("created_at")
 10544                        .HasDefaultValueSql("now()");
 10545
 10546                    b.Property<DateTime?>("DeletedAt")
 10547                        .HasColumnType("timestamp with time zone")
 10548                        .HasColumnName("deleted_at");
 10549
 10550                    b.Property<int?>("DeletionKind")
 10551                        .HasColumnType("integer")
 10552                        .HasColumnName("deletion_kind");
 10553
 10554                    b.Property<string>("Email")
 10555                        .IsRequired()
 10556                        .HasMaxLength(256)
 10557                        .HasColumnType("character varying(256)")
 10558                        .HasColumnName("email");
 10559
 10560                    b.Property<bool>("EmailVerified")
 10561                        .ValueGeneratedOnAdd()
 10562                        .HasColumnType("boolean")
 10563                        .HasDefaultValue(false)
 10564                        .HasColumnName("email_verified");
 10565
 10566                    b.Property<string>("ErasureBlockedReason")
 10567                        .HasMaxLength(500)
 10568                        .HasColumnType("character varying(500)")
 10569                        .HasColumnName("erasure_blocked_reason");
 10570
 10571                    b.Property<DateTime?>("ErasureDueAt")
 10572                        .HasColumnType("timestamp with time zone")
 10573                        .HasColumnName("erasure_due_at");
 10574
 10575                    b.Property<DateTime?>("ErasureRequestedAt")
 10576                        .HasColumnType("timestamp with time zone")
 10577                        .HasColumnName("erasure_requested_at");
 10578
 10579                    b.Property<int>("FailedLoginAttempts")
 10580                        .HasColumnType("integer")
 10581                        .HasColumnName("failed_login_attempts");
 10582
 10583                    b.Property<bool>("IsDeleted")
 10584                        .ValueGeneratedOnAdd()
 10585                        .HasColumnType("boolean")
 10586                        .HasDefaultValue(false)
 10587                        .HasColumnName("is_deleted");
 10588
 10589                    b.Property<int>("LegalBasis")
 10590                        .ValueGeneratedOnAdd()
 10591                        .HasColumnType("integer")
 10592                        .HasDefaultValue(0)
 10593                        .HasColumnName("legal_basis");
 10594
 10595                    b.Property<DateTime?>("LockedOutUntil")
 10596                        .HasColumnType("timestamp with time zone")
 10597                        .HasColumnName("locked_out_until");
 10598
 10599                    b.Property<string>("Name")
 10600                        .IsRequired()
 10601                        .HasMaxLength(200)
 10602                        .HasColumnType("character varying(200)")
 10603                        .HasColumnName("name");
 10604
 10605                    b.Property<byte[]>("PasswordHash")
 10606                        .IsRequired()
 10607                        .HasColumnType("bytea")
 10608                        .HasColumnName("password_hash");
 10609
 10610                    b.Property<string>("PrivacyNoticeVersion")
 10611                        .HasMaxLength(50)
 10612                        .HasColumnType("character varying(50)")
 10613                        .HasColumnName("privacy_notice_version");
 10614
 10615                    b.Property<DateTime?>("ProcessingRestrictedAt")
 10616                        .HasColumnType("timestamp with time zone")
 10617                        .HasColumnName("processing_restricted_at");
 10618
 10619                    b.Property<Guid>("PublicId")
 10620                        .HasColumnType("uuid")
 10621                        .HasColumnName("public_id");
 10622
 10623                    b.Property<int?>("RestrictionGround")
 10624                        .HasColumnType("integer")
 10625                        .HasColumnName("restriction_ground");
 10626
 10627                    b.Property<DateTime?>("RestrictionLiftNotifiedAt")
 10628                        .HasColumnType("timestamp with time zone")
 10629                        .HasColumnName("restriction_lift_notified_at");
 10630
 10631                    b.Property<long>("RoleId")
 10632                        .HasColumnType("bigint")
 10633                        .HasColumnName("role_id");
 10634
 10635                    b.Property<byte[]>("Salt")
 10636                        .IsRequired()
 10637                        .HasColumnType("bytea")
 10638                        .HasColumnName("salt");
 10639
 10640                    b.Property<long?>("ScopeId")
 10641                        .HasColumnType("bigint")
 10642                        .HasColumnName("scope_id");
 10643
 10644                    b.Property<DateTime>("UpdatedAt")
 10645                        .ValueGeneratedOnAdd()
 10646                        .HasColumnType("timestamp with time zone")
 10647                        .HasColumnName("updated_at")
 10648                        .HasDefaultValueSql("now()");
 10649
 10650                    b.HasKey("Id")
 10651                        .HasName("pk_person");
 10652
 10653                    b.HasIndex("DeletedAt")
 10654                        .HasDatabaseName("ix_person_deleted_at")
 10655                        .HasFilter("is_deleted = true AND anonymised_at IS NULL");
 10656
 10657                    b.HasIndex("Email")
 10658                        .HasDatabaseName("ix_person_email");
 10659
 10660                    b.HasIndex("ProcessingRestrictedAt")
 10661                        .HasDatabaseName("ix_person_processing_restricted_at")
 10662                        .HasFilter("processing_restricted_at IS NOT NULL");
 10663
 10664                    b.HasIndex("PublicId")
 10665                        .IsUnique()
 10666                        .HasDatabaseName("ix_person_public_id");
 10667
 10668                    b.HasIndex("RoleId")
 10669                        .HasDatabaseName("ix_person_role_id");
 10670
 10671                    b.ToTable("person", "heimdall");
 20672                });
 673
 10674            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Role", b =>
 10675                {
 10676                    b.Property<long>("Id")
 10677                        .HasColumnType("bigint")
 10678                        .HasColumnName("id")
 10679                        .HasColumnOrder(1);
 10680
 10681                    b.Property<string>("Description")
 10682                        .HasMaxLength(500)
 10683                        .HasColumnType("character varying(500)")
 10684                        .HasColumnName("description");
 10685
 10686                    b.Property<string>("Name")
 10687                        .IsRequired()
 10688                        .HasMaxLength(200)
 10689                        .HasColumnType("character varying(200)")
 10690                        .HasColumnName("name");
 10691
 10692                    b.Property<Guid>("PublicId")
 10693                        .HasColumnType("uuid")
 10694                        .HasColumnName("public_id");
 10695
 10696                    b.HasKey("Id")
 10697                        .HasName("pk_role");
 10698
 10699                    b.HasIndex("Name")
 10700                        .IsUnique()
 10701                        .HasDatabaseName("ix_role_name");
 10702
 10703                    b.HasIndex("PublicId")
 10704                        .IsUnique()
 10705                        .HasDatabaseName("ix_role_public_id");
 10706
 10707                    b.ToTable("role", "heimdall");
 20708                });
 709
 10710            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Scope", b =>
 10711                {
 10712                    b.Property<long>("Id")
 10713                        .ValueGeneratedOnAdd()
 10714                        .HasColumnType("bigint")
 10715                        .HasColumnName("id")
 10716                        .HasColumnOrder(1);
 10717
 10718                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10719
 10720                    b.Property<DateTime>("CreatedAt")
 10721                        .ValueGeneratedOnAdd()
 10722                        .HasColumnType("timestamp with time zone")
 10723                        .HasColumnName("created_at")
 10724                        .HasDefaultValueSql("now()");
 10725
 10726                    b.Property<int?>("DefaultLegalBasis")
 10727                        .HasColumnType("integer")
 10728                        .HasColumnName("default_legal_basis");
 10729
 10730                    b.Property<string>("Description")
 10731                        .HasMaxLength(500)
 10732                        .HasColumnType("character varying(500)")
 10733                        .HasColumnName("description");
 10734
 10735                    b.Property<string>("EmailVerificationUrl")
 10736                        .HasMaxLength(2048)
 10737                        .HasColumnType("character varying(2048)")
 10738                        .HasColumnName("email_verification_url");
 10739
 10740                    b.Property<bool>("GoogleSignInEnabled")
 10741                        .ValueGeneratedOnAdd()
 10742                        .HasColumnType("boolean")
 10743                        .HasDefaultValue(false)
 10744                        .HasColumnName("google_sign_in_enabled");
 10745
 10746                    b.Property<bool>("IsDeleted")
 10747                        .ValueGeneratedOnAdd()
 10748                        .HasColumnType("boolean")
 10749                        .HasDefaultValue(false)
 10750                        .HasColumnName("is_deleted");
 10751
 10752                    b.Property<string>("Name")
 10753                        .IsRequired()
 10754                        .HasMaxLength(200)
 10755                        .HasColumnType("character varying(200)")
 10756                        .HasColumnName("name");
 10757
 10758                    b.Property<string>("PasswordResetUrl")
 10759                        .HasMaxLength(2048)
 10760                        .HasColumnType("character varying(2048)")
 10761                        .HasColumnName("password_reset_url");
 10762
 10763                    b.Property<string>("PrivacyNoticeUri")
 10764                        .HasMaxLength(2048)
 10765                        .HasColumnType("character varying(2048)")
 10766                        .HasColumnName("privacy_notice_uri");
 10767
 10768                    b.Property<Guid>("PublicId")
 10769                        .HasColumnType("uuid")
 10770                        .HasColumnName("public_id");
 10771
 10772                    b.Property<bool>("SelfRegistrationEnabled")
 10773                        .ValueGeneratedOnAdd()
 10774                        .HasColumnType("boolean")
 10775                        .HasDefaultValue(false)
 10776                        .HasColumnName("self_registration_enabled");
 10777
 10778                    b.Property<DateTime>("UpdatedAt")
 10779                        .ValueGeneratedOnAdd()
 10780                        .HasColumnType("timestamp with time zone")
 10781                        .HasColumnName("updated_at")
 10782                        .HasDefaultValueSql("now()");
 10783
 10784                    b.HasKey("Id")
 10785                        .HasName("pk_scope");
 10786
 10787                    b.HasIndex("Name")
 10788                        .IsUnique()
 10789                        .HasDatabaseName("ix_scope_name");
 10790
 10791                    b.HasIndex("PublicId")
 10792                        .IsUnique()
 10793                        .HasDatabaseName("ix_scope_public_id");
 10794
 10795                    b.ToTable("scope", "heimdall");
 20796                });
 797
 10798            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeOwner", b =>
 10799                {
 10800                    b.Property<long>("ScopeId")
 10801                        .HasColumnType("bigint")
 10802                        .HasColumnName("scope_id");
 10803
 10804                    b.Property<long>("PersonId")
 10805                        .HasColumnType("bigint")
 10806                        .HasColumnName("person_id");
 10807
 10808                    b.HasKey("ScopeId", "PersonId")
 10809                        .HasName("pk_scope_owner");
 10810
 10811                    b.HasIndex("PersonId")
 10812                        .HasDatabaseName("ix_scope_owner_person_id");
 10813
 10814                    b.ToTable("scope_owner", "heimdall");
 20815                });
 816
 10817            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopePermission", b =>
 10818                {
 10819                    b.Property<long>("Id")
 10820                        .ValueGeneratedOnAdd()
 10821                        .HasColumnType("bigint")
 10822                        .HasColumnName("id")
 10823                        .HasColumnOrder(1);
 10824
 10825                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10826
 10827                    b.Property<DateTime>("CreatedAt")
 10828                        .ValueGeneratedOnAdd()
 10829                        .HasColumnType("timestamp with time zone")
 10830                        .HasColumnName("created_at")
 10831                        .HasDefaultValueSql("now()");
 10832
 10833                    b.Property<string>("Description")
 10834                        .HasMaxLength(500)
 10835                        .HasColumnType("character varying(500)")
 10836                        .HasColumnName("description");
 10837
 10838                    b.Property<bool>("IncludeAsJwtClaim")
 10839                        .ValueGeneratedOnAdd()
 10840                        .HasColumnType("boolean")
 10841                        .HasDefaultValue(false)
 10842                        .HasColumnName("include_as_jwt_claim");
 10843
 10844                    b.Property<bool>("IsDeleted")
 10845                        .ValueGeneratedOnAdd()
 10846                        .HasColumnType("boolean")
 10847                        .HasDefaultValue(false)
 10848                        .HasColumnName("is_deleted");
 10849
 10850                    b.Property<string>("Name")
 10851                        .IsRequired()
 10852                        .HasMaxLength(200)
 10853                        .HasColumnType("character varying(200)")
 10854                        .HasColumnName("name");
 10855
 10856                    b.Property<Guid>("PublicId")
 10857                        .HasColumnType("uuid")
 10858                        .HasColumnName("public_id");
 10859
 10860                    b.Property<long>("ScopeId")
 10861                        .HasColumnType("bigint")
 10862                        .HasColumnName("scope_id");
 10863
 10864                    b.Property<DateTime>("UpdatedAt")
 10865                        .ValueGeneratedOnAdd()
 10866                        .HasColumnType("timestamp with time zone")
 10867                        .HasColumnName("updated_at")
 10868                        .HasDefaultValueSql("now()");
 10869
 10870                    b.HasKey("Id")
 10871                        .HasName("pk_scope_permission");
 10872
 10873                    b.HasIndex("PublicId")
 10874                        .IsUnique()
 10875                        .HasDatabaseName("ix_scope_permission_public_id");
 10876
 10877                    b.HasIndex("ScopeId")
 10878                        .HasDatabaseName("ix_scope_permission_scope_id");
 10879
 10880                    b.ToTable("scope_permission", "heimdall");
 20881                });
 882
 10883            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeUser", b =>
 10884                {
 10885                    b.Property<long>("ScopeId")
 10886                        .HasColumnType("bigint")
 10887                        .HasColumnName("scope_id");
 10888
 10889                    b.Property<long>("PersonId")
 10890                        .HasColumnType("bigint")
 10891                        .HasColumnName("person_id");
 10892
 10893                    b.HasKey("ScopeId", "PersonId")
 10894                        .HasName("pk_scope_user");
 10895
 10896                    b.HasIndex("PersonId")
 10897                        .IsUnique()
 10898                        .HasDatabaseName("ix_scope_user_person_id");
 10899
 10900                    b.ToTable("scope_user", "heimdall");
 20901                });
 902
 10903            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 10904                {
 10905                    b.Property<long>("Id")
 10906                        .ValueGeneratedOnAdd()
 10907                        .HasColumnType("bigint")
 10908                        .HasColumnName("id")
 10909                        .HasColumnOrder(1);
 10910
 10911                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10912
 10913                    b.Property<bool>("AppEnabled")
 10914                        .ValueGeneratedOnAdd()
 10915                        .HasColumnType("boolean")
 10916                        .HasDefaultValue(false)
 10917                        .HasColumnName("app_enabled");
 10918
 10919                    b.Property<int>("ChallengeAttempts")
 10920                        .ValueGeneratedOnAdd()
 10921                        .HasColumnType("integer")
 10922                        .HasDefaultValue(0)
 10923                        .HasColumnName("challenge_attempts");
 10924
 10925                    b.Property<Guid?>("ChallengeId")
 10926                        .HasColumnType("uuid")
 10927                        .HasColumnName("challenge_id");
 10928
 10929                    b.Property<DateTime>("CreatedAt")
 10930                        .ValueGeneratedOnAdd()
 10931                        .HasColumnType("timestamp with time zone")
 10932                        .HasColumnName("created_at")
 10933                        .HasDefaultValueSql("now()");
 10934
 10935                    b.Property<int>("EmailCodeReissueCount")
 10936                        .ValueGeneratedOnAdd()
 10937                        .HasColumnType("integer")
 10938                        .HasDefaultValue(0)
 10939                        .HasColumnName("email_code_reissue_count");
 10940
 10941                    b.Property<bool>("EmailEnabled")
 10942                        .ValueGeneratedOnAdd()
 10943                        .HasColumnType("boolean")
 10944                        .HasDefaultValue(false)
 10945                        .HasColumnName("email_enabled");
 10946
 10947                    b.Property<bool>("IsActive")
 10948                        .ValueGeneratedOnAdd()
 10949                        .HasColumnType("boolean")
 10950                        .HasDefaultValue(false)
 10951                        .HasColumnName("is_active");
 10952
 10953                    b.Property<long?>("LastTotpTimeStepUsed")
 10954                        .HasColumnType("bigint")
 10955                        .HasColumnName("last_totp_time_step_used");
 10956
 10957                    b.Property<long>("PersonId")
 10958                        .HasColumnType("bigint")
 10959                        .HasColumnName("person_id");
 10960
 10961                    b.Property<byte[]>("TotpSecretEncrypted")
 10962                        .HasColumnType("bytea")
 10963                        .HasColumnName("totp_secret_encrypted");
 10964
 10965                    b.Property<DateTime>("UpdatedAt")
 10966                        .ValueGeneratedOnAdd()
 10967                        .HasColumnType("timestamp with time zone")
 10968                        .HasColumnName("updated_at")
 10969                        .HasDefaultValueSql("now()");
 10970
 10971                    b.HasKey("Id")
 10972                        .HasName("pk_two_factor_auth");
 10973
 10974                    b.HasIndex("PersonId")
 10975                        .IsUnique()
 10976                        .HasDatabaseName("ix_two_factor_auth_person_id");
 10977
 10978                    b.ToTable("two_factor_auth", "heimdall");
 20979                });
 980
 10981            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode", b =>
 10982                {
 10983                    b.Property<long>("Id")
 10984                        .ValueGeneratedOnAdd()
 10985                        .HasColumnType("bigint")
 10986                        .HasColumnName("id")
 10987                        .HasColumnOrder(1);
 10988
 10989                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 10990
 10991                    b.Property<byte[]>("CodeHash")
 10992                        .IsRequired()
 10993                        .HasColumnType("bytea")
 10994                        .HasColumnName("code_hash");
 10995
 10996                    b.Property<DateTime>("CreatedAt")
 10997                        .ValueGeneratedOnAdd()
 10998                        .HasColumnType("timestamp with time zone")
 10999                        .HasColumnName("created_at")
 101000                        .HasDefaultValueSql("now()");
 101001
 101002                    b.Property<DateTime>("ExpiresAt")
 101003                        .HasColumnType("timestamp with time zone")
 101004                        .HasColumnName("expires_at");
 101005
 101006                    b.Property<int>("FailedAttempts")
 101007                        .HasColumnType("integer")
 101008                        .HasColumnName("failed_attempts");
 101009
 101010                    b.Property<byte[]>("Salt")
 101011                        .IsRequired()
 101012                        .HasColumnType("bytea")
 101013                        .HasColumnName("salt");
 101014
 101015                    b.Property<long>("TwoFactorAuthId")
 101016                        .HasColumnType("bigint")
 101017                        .HasColumnName("two_factor_auth_id");
 101018
 101019                    b.Property<bool>("Used")
 101020                        .ValueGeneratedOnAdd()
 101021                        .HasColumnType("boolean")
 101022                        .HasDefaultValue(false)
 101023                        .HasColumnName("used");
 101024
 101025                    b.HasKey("Id")
 101026                        .HasName("pk_two_factor_email_code");
 101027
 101028                    b.HasIndex("TwoFactorAuthId")
 101029                        .HasDatabaseName("ix_two_factor_email_code_two_factor_auth_id");
 101030
 101031                    b.ToTable("two_factor_email_code", "heimdall");
 201032                });
 1033
 101034            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorRecoveryCode", b =>
 101035                {
 101036                    b.Property<long>("Id")
 101037                        .ValueGeneratedOnAdd()
 101038                        .HasColumnType("bigint")
 101039                        .HasColumnName("id")
 101040                        .HasColumnOrder(1);
 101041
 101042                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<long>("Id"));
 101043
 101044                    b.Property<byte[]>("CodeHash")
 101045                        .IsRequired()
 101046                        .HasColumnType("bytea")
 101047                        .HasColumnName("code_hash");
 101048
 101049                    b.Property<DateTime>("CreatedAt")
 101050                        .ValueGeneratedOnAdd()
 101051                        .HasColumnType("timestamp with time zone")
 101052                        .HasColumnName("created_at")
 101053                        .HasDefaultValueSql("now()");
 101054
 101055                    b.Property<long>("TwoFactorAuthId")
 101056                        .HasColumnType("bigint")
 101057                        .HasColumnName("two_factor_auth_id");
 101058
 101059                    b.Property<bool>("Used")
 101060                        .ValueGeneratedOnAdd()
 101061                        .HasColumnType("boolean")
 101062                        .HasDefaultValue(false)
 101063                        .HasColumnName("used");
 101064
 101065                    b.Property<DateTime?>("UsedAt")
 101066                        .HasColumnType("timestamp with time zone")
 101067                        .HasColumnName("used_at");
 101068
 101069                    b.HasKey("Id")
 101070                        .HasName("pk_two_factor_recovery_code");
 101071
 101072                    b.HasIndex("TwoFactorAuthId")
 101073                        .HasDatabaseName("ix_two_factor_recovery_code_two_factor_auth_id");
 101074
 101075                    b.ToTable("two_factor_recovery_code", "heimdall");
 201076                });
 1077
 101078            modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
 101079                {
 101080                    b.Property<int>("Id")
 101081                        .ValueGeneratedOnAdd()
 101082                        .HasColumnType("integer")
 101083                        .HasColumnName("id");
 101084
 101085                    NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
 101086
 101087                    b.Property<string>("FriendlyName")
 101088                        .HasColumnType("text")
 101089                        .HasColumnName("friendly_name");
 101090
 101091                    b.Property<string>("Xml")
 101092                        .HasColumnType("text")
 101093                        .HasColumnName("xml");
 101094
 101095                    b.HasKey("Id")
 101096                        .HasName("pk_data_protection_keys");
 101097
 101098                    b.ToTable("data_protection_keys", "heimdall");
 201099                });
 1100
 101101            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Application", b =>
 101102                {
 101103                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Owner")
 101104                        .WithMany("OwnedApplications")
 101105                        .HasForeignKey("OwnerId")
 101106                        .OnDelete(DeleteBehavior.Cascade)
 101107                        .IsRequired()
 101108                        .HasConstraintName("fk_application_person_owner_id");
 101109
 101110                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 101111                        .WithMany("Applications")
 101112                        .HasForeignKey("ScopeId")
 101113                        .OnDelete(DeleteBehavior.Cascade)
 101114                        .IsRequired()
 101115                        .HasConstraintName("fk_application_scope_scope_id");
 101116
 101117                    b.Navigation("Owner");
 101118
 101119                    b.Navigation("Scope");
 201120                });
 1121
 101122            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ApplicationCredential", b =>
 101123                {
 101124                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Application", "Application")
 101125                        .WithMany("Credentials")
 101126                        .HasForeignKey("ApplicationId")
 101127                        .OnDelete(DeleteBehavior.Cascade)
 101128                        .IsRequired()
 101129                        .HasConstraintName("fk_application_credential_application_application_id");
 101130
 101131                    b.Navigation("Application");
 201132                });
 1133
 101134            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.EmailVerificationToken", b =>
 101135                {
 101136                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 101137                        .WithMany("EmailVerificationTokens")
 101138                        .HasForeignKey("PersonId")
 101139                        .OnDelete(DeleteBehavior.Cascade)
 101140                        .IsRequired()
 101141                        .HasConstraintName("fk_email_verification_token_person_person_id");
 101142
 101143                    b.Navigation("Person");
 201144                });
 1145
 101146            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.GoogleUser", b =>
 101147                {
 101148                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 101149                        .WithMany("GoogleUsers")
 101150                        .HasForeignKey("ScopeId")
 101151                        .OnDelete(DeleteBehavior.Cascade)
 101152                        .IsRequired()
 101153                        .HasConstraintName("fk_google_user_scope_scope_id");
 101154
 101155                    b.Navigation("Scope");
 201156                });
 1157
 101158            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PasswordResetToken", b =>
 101159                {
 101160                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 101161                        .WithMany("PasswordResetTokens")
 101162                        .HasForeignKey("PersonId")
 101163                        .OnDelete(DeleteBehavior.Cascade)
 101164                        .IsRequired()
 101165                        .HasConstraintName("fk_password_reset_token_person_person_id");
 101166
 101167                    b.Navigation("Person");
 201168                });
 1169
 101170            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.PendingRegistration", b =>
 101171                {
 101172                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 101173                        .WithMany()
 101174                        .HasForeignKey("ScopeId")
 101175                        .OnDelete(DeleteBehavior.Cascade)
 101176                        .IsRequired()
 101177                        .HasConstraintName("fk_pending_registration_scope_scope_id");
 101178
 101179                    b.Navigation("Scope");
 201180                });
 1181
 101182            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 101183                {
 101184                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Role", "Role")
 101185                        .WithMany("Persons")
 101186                        .HasForeignKey("RoleId")
 101187                        .OnDelete(DeleteBehavior.Restrict)
 101188                        .IsRequired()
 101189                        .HasConstraintName("fk_person_roles_role_id");
 101190
 101191                    b.Navigation("Role");
 201192                });
 1193
 101194            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeOwner", b =>
 101195                {
 101196                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 101197                        .WithMany("ScopeOwnerships")
 101198                        .HasForeignKey("PersonId")
 101199                        .OnDelete(DeleteBehavior.Cascade)
 101200                        .IsRequired()
 101201                        .HasConstraintName("fk_scope_owner_person_person_id");
 101202
 101203                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 101204                        .WithMany("Owners")
 101205                        .HasForeignKey("ScopeId")
 101206                        .OnDelete(DeleteBehavior.Cascade)
 101207                        .IsRequired()
 101208                        .HasConstraintName("fk_scope_owner_scope_scope_id");
 101209
 101210                    b.Navigation("Person");
 101211
 101212                    b.Navigation("Scope");
 201213                });
 1214
 101215            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopePermission", b =>
 101216                {
 101217                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 101218                        .WithMany("ScopePermissions")
 101219                        .HasForeignKey("ScopeId")
 101220                        .OnDelete(DeleteBehavior.Cascade)
 101221                        .IsRequired()
 101222                        .HasConstraintName("fk_scope_permission_scope_scope_id");
 101223
 101224                    b.Navigation("Scope");
 201225                });
 1226
 101227            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.ScopeUser", b =>
 101228                {
 101229                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 101230                        .WithOne("ScopeMembership")
 101231                        .HasForeignKey("ArturRios.Heimdall.Domain.Entities.ScopeUser", "PersonId")
 101232                        .OnDelete(DeleteBehavior.Cascade)
 101233                        .IsRequired()
 101234                        .HasConstraintName("fk_scope_user_person_person_id");
 101235
 101236                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Scope", "Scope")
 101237                        .WithMany("Users")
 101238                        .HasForeignKey("ScopeId")
 101239                        .OnDelete(DeleteBehavior.Cascade)
 101240                        .IsRequired()
 101241                        .HasConstraintName("fk_scope_user_scope_scope_id");
 101242
 101243                    b.Navigation("Person");
 101244
 101245                    b.Navigation("Scope");
 201246                });
 1247
 101248            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 101249                {
 101250                    b.HasOne("ArturRios.Heimdall.Domain.Entities.Person", "Person")
 101251                        .WithOne("TwoFactorAuth")
 101252                        .HasForeignKey("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "PersonId")
 101253                        .OnDelete(DeleteBehavior.Cascade)
 101254                        .IsRequired()
 101255                        .HasConstraintName("fk_two_factor_auth_person_person_id");
 101256
 101257                    b.Navigation("Person");
 201258                });
 1259
 101260            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorEmailCode", b =>
 101261                {
 101262                    b.HasOne("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "TwoFactorAuth")
 101263                        .WithMany("EmailCodes")
 101264                        .HasForeignKey("TwoFactorAuthId")
 101265                        .OnDelete(DeleteBehavior.Cascade)
 101266                        .IsRequired()
 101267                        .HasConstraintName("fk_two_factor_email_code_two_factor_auth_two_factor_auth_id");
 101268
 101269                    b.Navigation("TwoFactorAuth");
 201270                });
 1271
 101272            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorRecoveryCode", b =>
 101273                {
 101274                    b.HasOne("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", "TwoFactorAuth")
 101275                        .WithMany("RecoveryCodes")
 101276                        .HasForeignKey("TwoFactorAuthId")
 101277                        .OnDelete(DeleteBehavior.Cascade)
 101278                        .IsRequired()
 101279                        .HasConstraintName("fk_two_factor_recovery_code_two_factor_auth_two_factor_auth_id");
 101280
 101281                    b.Navigation("TwoFactorAuth");
 201282                });
 1283
 101284            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Application", b =>
 101285                {
 101286                    b.Navigation("Credentials");
 201287                });
 1288
 101289            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Person", b =>
 101290                {
 101291                    b.Navigation("EmailVerificationTokens");
 101292
 101293                    b.Navigation("OwnedApplications");
 101294
 101295                    b.Navigation("PasswordResetTokens");
 101296
 101297                    b.Navigation("ScopeMembership");
 101298
 101299                    b.Navigation("ScopeOwnerships");
 101300
 101301                    b.Navigation("TwoFactorAuth");
 201302                });
 1303
 101304            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Role", b =>
 101305                {
 101306                    b.Navigation("Persons");
 201307                });
 1308
 101309            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.Scope", b =>
 101310                {
 101311                    b.Navigation("Applications");
 101312
 101313                    b.Navigation("GoogleUsers");
 101314
 101315                    b.Navigation("Owners");
 101316
 101317                    b.Navigation("ScopePermissions");
 101318
 101319                    b.Navigation("Users");
 201320                });
 1321
 101322            modelBuilder.Entity("ArturRios.Heimdall.Domain.Entities.TwoFactorAuth", b =>
 101323                {
 101324                    b.Navigation("EmailCodes");
 101325
 101326                    b.Navigation("RecoveryCodes");
 201327                });
 1328#pragma warning restore 612, 618
 101329        }
 1330    }
 1331}