From 7c3ef367cdbc3c99ac0d3560357f69f35e2ac633 Mon Sep 17 00:00:00 2001 From: bo Date: Thu, 30 Apr 2026 13:37:01 +0200 Subject: [PATCH 1/7] feat: add DataSource entity and EF migration (#138) - Add ProviderType enum replacing RemoteDataSourceTypeEnum - Add DataSource entity (flat table, inherits BaseEntity) - Doi replaces GbifDataSetId (nullable in DB, enforced at app layer) - Cleaned-up property names: RemoteAddress, ArchiveName, NonValidOccurrenceIds, WebServiceVersion - GbifApiQuery/HarvestPropertyOverrides/ImportPropertyOverrides stored as nvarchar(max) for large JSON payloads - Add DataSourceConfiguration with column constraints and indexes - Wire up OnModelCreatingPartial call in ArtskartDbContext - Add EF migration AddDataSource --- Artskart3.Core/Domain/Entities/DataSource.cs | 86 + Artskart3.Core/Domain/Enums/ProviderType.cs | 9 + .../Data/DbContext/ArtskartDbContext.cs | 5 + .../DataSourceConfiguration.cs | 50 + .../20260430112855_AddDataSource.Designer.cs | 3003 +++++++++++++++++ .../20260430112855_AddDataSource.cs | 91 + .../ArtskartDbContextModelSnapshot.cs | 124 + 7 files changed, 3368 insertions(+) create mode 100644 Artskart3.Core/Domain/Entities/DataSource.cs create mode 100644 Artskart3.Core/Domain/Enums/ProviderType.cs create mode 100644 Artskart3.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs create mode 100644 Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.Designer.cs create mode 100644 Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.cs diff --git a/Artskart3.Core/Domain/Entities/DataSource.cs b/Artskart3.Core/Domain/Entities/DataSource.cs new file mode 100644 index 00000000..75add71d --- /dev/null +++ b/Artskart3.Core/Domain/Entities/DataSource.cs @@ -0,0 +1,86 @@ +using Artskart3.Core.Domain.Entities.Base; +using Artskart3.Core.Domain.Enums; + +namespace Artskart3.Core.Domain.Entities; + +/// +/// Provider configuration for a remote data source (formerly SourceDataBase in RavenDB). +/// One flat table; use typed views or application-layer filtering to work with specific provider types. +/// +public class DataSource : BaseEntity +{ + public string Name { get; set; } = string.Empty; + + /// + /// Discriminates the provider type and drives import pipeline branching. + /// + public ProviderType ProviderType { get; set; } + + /// + /// How many records to fetch per batch during harvest. + /// + public int RecordsBatchSize { get; set; } + + /// + /// Web service API version (ArtskartDataDeliveryWebServiceV1 providers). + /// + public int WebServiceVersion { get; set; } + + /// + /// URL of the remote endpoint (web service or IPT archive base URL). + /// + public string? RemoteAddress { get; set; } + + /// + /// IPT archive filename, or local cache filename for GbifApi providers. + /// + public string? ArchiveName { get; set; } + + /// + /// Internal notes for operators. + /// + public string? Notes { get; set; } + + public bool IsEditedNameOrNotes { get; set; } + + /// + /// Flags records from this source as having non-valid occurrence IDs. + /// + public bool NonValidOccurrenceIds { get; set; } + + /// + /// JSON predicate string used by GbifApi providers to query the GBIF occurrence API. + /// + public string? GbifApiQuery { get; set; } + + /// + /// JSON overrides applied during the harvest phase (field mapping / transformations). + /// + public string? HarvestPropertyOverrides { get; set; } + + /// + /// JSON overrides applied during the import/processing phase. + /// + public string? ImportPropertyOverrides { get; set; } + + /// + /// How often (in days) the source should be re-harvested. + /// + public int UpdateFrequencyInDays { get; set; } + + /// + /// Digital Object Identifier — replaces GbifDataSetId from the old solution. + /// Required for active GbifIpt and GbifApi providers; enforced at the application layer. + /// + public string? Doi { get; set; } + + /// + /// GBIF publisher UUID. Used for API-based providers and publisher-scoped queries. + /// + public Guid? GbifPublisherId { get; set; } + + /// + /// Marks observations from this source as sensitive (restricted coordinates etc.). + /// + public bool IsSensitive { get; set; } +} diff --git a/Artskart3.Core/Domain/Enums/ProviderType.cs b/Artskart3.Core/Domain/Enums/ProviderType.cs new file mode 100644 index 00000000..6f3caecf --- /dev/null +++ b/Artskart3.Core/Domain/Enums/ProviderType.cs @@ -0,0 +1,9 @@ +namespace Artskart3.Core.Domain.Enums; + +public enum ProviderType +{ + ArtskartDataDeliveryWebServiceV1 = 0, + GbifIpt = 1, + Artsobservasjoner20Api = 2, + GbifApi = 3 +} diff --git a/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs b/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs index 9543b7af..e9019e3c 100644 --- a/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs +++ b/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs @@ -29,6 +29,8 @@ public ArtskartDbContext(DbContextOptions options) public virtual DbSet CommandLogs { get; set; } + public virtual DbSet DataSources { get; set; } + public virtual DbSet DeletedItems { get; set; } public virtual DbSet ExportStatuses { get; set; } @@ -1041,6 +1043,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.LastEventProcessedTimeStamp).HasColumnType("datetime"); }); + + OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); @@ -1048,6 +1052,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) partial void OnModelCreatingPartial(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new ObservationSearchIndexConfiguration()); + modelBuilder.ApplyConfiguration(new DataSourceConfiguration()); } } } diff --git a/Artskart3.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs b/Artskart3.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs new file mode 100644 index 00000000..f98f2bda --- /dev/null +++ b/Artskart3.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs @@ -0,0 +1,50 @@ +using Artskart3.Core.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Artskart3.Infrastructure.Data.EntityConfigurations; + +public class DataSourceConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("DataSource"); + + builder.HasKey(e => e.Id); + + builder.Property(e => e.Name) + .IsRequired() + .HasMaxLength(500); + + builder.Property(e => e.ProviderType) + .IsRequired(); + + builder.Property(e => e.RemoteAddress) + .HasMaxLength(1000); + + builder.Property(e => e.ArchiveName) + .HasMaxLength(500); + + builder.Property(e => e.Notes) + .HasMaxLength(2000); + + // Large JSON columns — no length limit + builder.Property(e => e.GbifApiQuery) + .HasColumnType("nvarchar(max)"); + + builder.Property(e => e.HarvestPropertyOverrides) + .HasColumnType("nvarchar(max)"); + + builder.Property(e => e.ImportPropertyOverrides) + .HasColumnType("nvarchar(max)"); + + builder.Property(e => e.Doi) + .HasMaxLength(200); + + builder.HasIndex(e => e.ProviderType) + .HasDatabaseName("IX_DataSource_ProviderType"); + + builder.HasIndex(e => e.IsDeleted) + .HasDatabaseName("IX_DataSource_IsDeleted"); + } +} diff --git a/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.Designer.cs b/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.Designer.cs new file mode 100644 index 00000000..b6afb862 --- /dev/null +++ b/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.Designer.cs @@ -0,0 +1,3003 @@ +// +using System; +using Artskart3.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Artskart3.Infrastructure.Migrations +{ + [DbContext(typeof(ArtskartDbContext))] + [Migration("20260430112855_AddDataSource")] + partial class AddDataSource + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Area", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AreaTypeId") + .HasColumnType("int") + .HasColumnName("AreaTypeID"); + + b.Property("Bbox") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DocumentId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Fid") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("GmBbox") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("IsCurrent") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ObservationCount") + .HasColumnType("int"); + + b.Property("ParentFid") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("SyncDateTime") + .HasColumnType("datetime"); + + b.Property("TimeStamp") + .ValueGeneratedOnAdd() + .HasColumnType("datetime") + .HasDefaultValue(new DateTime(1900, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.Area"); + + b.HasIndex(new[] { "AreaTypeId", "Id", "Fid" }, "IX_AreaTypeID"); + + b.HasIndex(new[] { "Fid" }, "IX_Fid"); + + b.HasIndex(new[] { "ParentFid" }, "IX_ParentFid"); + + b.HasIndex(new[] { "Name" }, "NonClusteredIndex-20180305-111522"); + + b.ToTable("Area", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.AreaType", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CategoryName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsRequired") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.AreaType"); + + b.ToTable("AreaType", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.BasisOfRecord", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.Property("ObservationCount") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("Variants") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("nvarchar(300)"); + + b.HasKey("Id") + .HasName("PK_dbo.BasisOfRecord"); + + b.ToTable("BasisOfRecord", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Behavior", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Deleted") + .HasColumnType("bit"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.Property("ObservationCount") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("Variants") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("nvarchar(300)"); + + b.HasKey("Id") + .HasName("PK_dbo.Behavior"); + + b.ToTable("Behavior", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Category", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CategoryTypeId") + .HasColumnType("int"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("nvarchar(2)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ObservationCount") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.Category"); + + b.HasIndex(new[] { "CategoryTypeId" }, "IX_CategoryTypeId"); + + b.ToTable("Category", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.CategoryType", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.CategoryType"); + + b.ToTable("CategoryType", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.CommandLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasColumnName("ID"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Command") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CommandType") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DatabaseName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("EndTime") + .HasColumnType("datetime2"); + + b.Property("ErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrorNumber") + .HasColumnType("int"); + + b.Property("ExtendedInfo") + .HasColumnType("xml"); + + b.Property("IndexName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("IndexType") + .HasColumnType("tinyint"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ObjectName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ObjectType") + .HasMaxLength(2) + .IsUnicode(false) + .HasColumnType("char(2)") + .IsFixedLength(); + + b.Property("PartitionNumber") + .HasColumnType("int"); + + b.Property("SchemaName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("StartTime") + .HasColumnType("datetime2"); + + b.Property("StatisticsName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("CommandLog", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.DataSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchiveName") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("GbifApiQuery") + .HasColumnType("nvarchar(max)"); + + b.Property("GbifPublisherId") + .HasColumnType("uniqueidentifier"); + + b.Property("HarvestPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("ImportPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsEditedNameOrNotes") + .HasColumnType("bit"); + + b.Property("IsSensitive") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("NonValidOccurrenceIds") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ProviderType") + .HasColumnType("int"); + + b.Property("RecordsBatchSize") + .HasColumnType("int"); + + b.Property("RemoteAddress") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("UpdateFrequencyInDays") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("WebServiceVersion") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IsDeleted") + .HasDatabaseName("IX_DataSource_IsDeleted"); + + b.HasIndex("ProviderType") + .HasDatabaseName("IX_DataSource_ProviderType"); + + b.ToTable("DataSource", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.DeletedItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("RecordId") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("ReplicationId") + .HasColumnType("int"); + + b.Property("TimeStamp") + .HasColumnType("datetime"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.DeletedItem"); + + b.HasIndex(new[] { "RecordId" }, "Ix_RecordId"); + + b.HasIndex(new[] { "TimeStamp" }, "Ix_TimeStamp"); + + b.HasIndex(new[] { "TimeStamp" }, "Ix_TimeStampWithRecordId"); + + b.ToTable("DeletedItem", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ExportStatus", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasColumnType("nvarchar(max)"); + + b.Property("ExportCreated") + .HasColumnType("datetime2"); + + b.Property("ExportFinished") + .HasColumnType("datetime2"); + + b.Property("ExportInfo") + .HasColumnType("nvarchar(max)"); + + b.Property("ExportJobId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ExportStarted") + .HasColumnType("datetime2"); + + b.Property("FileSize") + .HasColumnType("bigint"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("StatusCode") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.ExportStatus"); + + b.ToTable("ExportStatus", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Fab4exclude", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.FAB4Exclude"); + + b.ToTable("FAB4Exclude", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Filter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValueSql("(newsequentialid())"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("SerializedFilter") + .IsRequired() + .HasMaxLength(3700) + .HasColumnType("nvarchar(3700)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.Filter"); + + b.ToTable("Filter", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.GeometryColumn", b => + { + b.Property("FTableCatalog") + .HasMaxLength(128) + .IsUnicode(false) + .HasColumnType("varchar(128)") + .HasColumnName("f_table_catalog"); + + b.Property("FTableSchema") + .HasMaxLength(128) + .IsUnicode(false) + .HasColumnType("varchar(128)") + .HasColumnName("f_table_schema"); + + b.Property("FTableName") + .HasMaxLength(256) + .IsUnicode(false) + .HasColumnType("varchar(256)") + .HasColumnName("f_table_name"); + + b.Property("FGeometryColumn") + .HasMaxLength(256) + .IsUnicode(false) + .HasColumnType("varchar(256)") + .HasColumnName("f_geometry_column"); + + b.Property("CoordDimension") + .HasColumnType("int") + .HasColumnName("coord_dimension"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("GeometryType") + .IsRequired() + .HasMaxLength(30) + .IsUnicode(false) + .HasColumnType("varchar(30)") + .HasColumnName("geometry_type"); + + b.Property("Id") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Srid") + .HasColumnType("int") + .HasColumnName("srid"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("FTableCatalog", "FTableSchema", "FTableName", "FGeometryColumn") + .HasName("geometry_columns_pk"); + + b.ToTable("geometry_columns", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModeCommand") + .HasColumnType("int") + .HasColumnName("Mode_Command"); + + b.Property("ModeDataset") + .HasColumnType("nvarchar(max)") + .HasColumnName("Mode_Dataset"); + + b.Property("ModeFilePath") + .HasColumnType("nvarchar(max)") + .HasColumnName("Mode_FilePath"); + + b.Property("ModePartitionYear") + .HasColumnType("int") + .HasColumnName("Mode_PartitionYear"); + + b.Property("ModeProcessMode") + .HasColumnType("int") + .HasColumnName("Mode_ProcessMode"); + + b.Property("ModeSensitiveRecords") + .HasColumnType("bit") + .HasColumnName("Mode_SensitiveRecords"); + + b.Property("Runtime") + .HasColumnType("float"); + + b.Property("SerializedObject") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SumNewRecordsImported") + .HasColumnType("int"); + + b.Property("SumRecordsDeleted") + .HasColumnType("int"); + + b.Property("SumRecordsProcessed") + .HasColumnType("int"); + + b.Property("SumRecordsRejected") + .HasColumnType("int"); + + b.Property("SumUpdatedRecords") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("TimestampFinished") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.ImportLog"); + + b.HasIndex(new[] { "Timestamp" }, "Ix_Time"); + + b.ToTable("ImportLog", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Message") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Severity") + .HasColumnType("int"); + + b.Property("SeverityDescription") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Subject") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.ImportNotification"); + + b.HasIndex(new[] { "Timestamp" }, "IX_TimeStamp"); + + b.ToTable("ImportNotification", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportState", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DateLastProcessed") + .HasColumnType("datetime2"); + + b.Property("DateLastProcessedFinished") + .HasColumnType("datetime2"); + + b.Property("DateLastProcessedWithChangeInRecords") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("FailCount") + .HasColumnType("int"); + + b.Property("GbifDataSetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ImportedNumberOfRecords") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastProcessResult") + .HasColumnType("nvarchar(max)"); + + b.Property("LastRecordDateLastModified") + .HasColumnType("datetime2"); + + b.Property("LastRecordImportedCatalogNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("RejectedNumberOfRecords") + .HasColumnType("int"); + + b.Property("ReportedLastTrackDateInCache") + .HasColumnType("datetime2"); + + b.Property("ReportedTotalNumberOfRecordsInCache") + .HasColumnType("int"); + + b.Property("TrackDateOfLastRecordProcessed") + .HasColumnType("datetime2"); + + b.Property("UpdateMode") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.ImportState"); + + b.ToTable("ImportState", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Location", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CoordinatePrecision") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("East") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Latitude") + .HasColumnType("float"); + + b.Property("Locality") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("LocationId") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Longitude") + .HasColumnType("float"); + + b.Property("LookupId") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("NodeId") + .HasColumnType("int"); + + b.Property("North") + .HasColumnType("int"); + + b.Property("TimeStamp") + .HasColumnType("datetime"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.Location"); + + b.HasIndex(new[] { "CoordinatePrecision" }, "IX_CoordinatePrecision"); + + b.HasIndex(new[] { "East", "North" }, "IX_EastNorth"); + + b.HasIndex(new[] { "East" }, "IX_EastNorthGeom"); + + b.HasIndex(new[] { "LookupId" }, "IX_LookupId"); + + b.ToTable("Location", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter16x16km", b => + { + b.Property("Objectid") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasColumnName("OBJECTID"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid")); + + b.Property("KriteriumMaskeringsrute") + .HasColumnType("int") + .HasColumnName("KRITERIUM_MASKERINGSRUTE"); + + b.Property("Ruteid") + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("char(50)") + .HasColumnName("RUTEID") + .IsFixedLength(); + + b.HasKey("Objectid"); + + b.ToTable("Maskeringsruter_16x16km", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter4x4km", b => + { + b.Property("Objectid") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasColumnName("OBJECTID"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid")); + + b.Property("KriteriumMaskeringsrute") + .HasColumnType("int") + .HasColumnName("KRITERIUM_MASKERINGSRUTE"); + + b.Property("Ruteid") + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("char(50)") + .HasColumnName("RUTEID") + .IsFixedLength(); + + b.HasKey("Objectid"); + + b.ToTable("Maskeringsruter_4x4km", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter8x8km", b => + { + b.Property("Objectid") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasColumnName("OBJECTID"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid")); + + b.Property("KriteriumMaskeringsrute") + .HasColumnType("int") + .HasColumnName("KRITERIUM_MASKERINGSRUTE"); + + b.Property("Ruteid") + .HasMaxLength(50) + .IsUnicode(false) + .HasColumnType("char(50)") + .HasColumnName("RUTEID") + .IsFixedLength(); + + b.HasKey("Objectid"); + + b.ToTable("Maskeringsruter_8x8km", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("DownloadRetryCount") + .HasColumnType("int"); + + b.Property("Downloaded") + .HasColumnType("bit"); + + b.Property("Image") + .HasColumnType("varbinary(max)"); + + b.Property("InDownloadqueue") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("License") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("MediaFileTypeId") + .HasColumnType("int"); + + b.Property("ObservationId") + .HasColumnType("int") + .HasColumnName("Observation_Id"); + + b.Property("Origin") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("RightsHolder") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Size") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.MediaFile"); + + b.HasIndex("MediaFileTypeId"); + + b.HasIndex(new[] { "Downloaded", "MediaFileTypeId", "DownloadRetryCount" }, "IX_DownLoaded"); + + b.HasIndex(new[] { "ObservationId" }, "IX_Observation_Id"); + + b.ToTable("MediaFile", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFileType", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MediaTypeName") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("MimeType") + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.MediaFileType"); + + b.ToTable("MediaFileType", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.MigrationHistory", b => + { + b.Property("MigrationId") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.Property("ContextKey") + .HasMaxLength(300) + .HasColumnType("nvarchar(300)"); + + b.Property("Model") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("ProductVersion") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.HasKey("MigrationId", "ContextKey") + .HasName("PK_dbo.__MigrationHistory"); + + b.ToTable("__MigrationHistory", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Observation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("BasisOfRecordId") + .HasColumnType("int"); + + b.Property("CatalogNumber") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CategoryId") + .HasColumnType("int"); + + b.Property("CollectionCode") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CoordinatePrecisionInMeters") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DateLastModified") + .HasColumnType("datetime2"); + + b.Property("DateTimeCollected") + .HasColumnType("datetime2"); + + b.Property("DateTimeRecordImported") + .HasColumnType("datetime2"); + + b.Property("DateTimeRecordProcessed") + .HasColumnType("datetime") + .HasColumnName("DateTimeRecordProsessed"); + + b.Property("DatetimeIdentified") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("East") + .HasColumnType("int"); + + b.Property("HasAnnotations") + .HasColumnType("bit"); + + b.Property("HasErrors") + .HasColumnType("bit"); + + b.Property("HashCode") + .HasColumnType("int"); + + b.Property("InstitutionCode") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("InstitutionId") + .HasMaxLength(25) + .HasColumnType("nvarchar(25)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Latitude") + .HasColumnType("float"); + + b.Property("LocationId") + .HasColumnType("int"); + + b.Property("Longitude") + .HasColumnType("float"); + + b.Property("MatchedScientificNameId") + .HasColumnType("int"); + + b.Property("MonthCollected") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("int") + .HasComputedColumnSql("(datepart(month,[DateTimeCollected]))", false); + + b.Property("NodeId") + .HasColumnType("int"); + + b.Property("North") + .HasColumnType("int"); + + b.Property("ObservationQualityTypeId") + .HasColumnType("int"); + + b.Property("OccurrenceId") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)") + .HasColumnName("OccurenceId"); + + b.Property("ProcessEngineId") + .HasColumnType("int"); + + b.Property("ProxyId") + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("TaxonGroupId") + .HasColumnType("int"); + + b.Property("TaxonId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("YearCollected") + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("int") + .HasComputedColumnSql("(datepart(year,[DateTimeCollected]))", false); + + b.HasKey("Id") + .HasName("PK_dbo.Observation"); + + b.HasIndex("BasisOfRecordId") + .HasDatabaseName("IX_Observation_BasisOfRecordId"); + + b.HasIndex("CategoryId") + .HasDatabaseName("IX_Observation_CategoryId"); + + b.HasIndex("CoordinatePrecisionInMeters") + .HasDatabaseName("IX_Observation_CoordinatePrecisionInMeters"); + + b.HasIndex("DateLastModified") + .HasDatabaseName("IX_Observation_DateLastModified"); + + b.HasIndex("InstitutionCode") + .HasDatabaseName("IX_Observation_InstitutionCode"); + + b.HasIndex("InstitutionId") + .HasDatabaseName("IX_Observation_InstitutionId"); + + b.HasIndex("LocationId") + .HasDatabaseName("IX_Observation_LocationId"); + + b.HasIndex("MonthCollected") + .HasDatabaseName("IX_Observation_MonthCollected"); + + b.HasIndex("TaxonGroupId") + .HasDatabaseName("IX_Observation_TaxonGroupId"); + + b.HasIndex("YearCollected") + .HasDatabaseName("IX_Observation_YearCollected"); + + b.HasIndex("TaxonGroupId", "LocationId") + .HasDatabaseName("IX_Observation_TaxonGroupId_LocationId"); + + b.HasIndex("YearCollected", "LocationId") + .HasDatabaseName("IX_Observation_YearCollected_LocationId"); + + b.HasIndex("LocationId", "HasErrors", "HasAnnotations") + .HasDatabaseName("IX_Observation_LocationId_HasErrors_HasAnnotations"); + + b.HasIndex(new[] { "BasisOfRecordId" }, "IX_BasisOfRecordId"); + + b.HasIndex(new[] { "CatalogNumber" }, "IX_CatalogNumber"); + + b.HasIndex(new[] { "CategoryId", "DateTimeRecordImported" }, "IX_CategoryId"); + + b.HasIndex(new[] { "DateTimeCollected" }, "IX_DateTimeCollected") + .IsDescending(); + + b.HasIndex(new[] { "DateTimeRecordImported" }, "IX_DateTimeRecordImported"); + + b.HasIndex(new[] { "DatetimeIdentified" }, "IX_DatetimeIdentified"); + + b.HasIndex(new[] { "LocationId", "Id" }, "IX_LocationCatProxy"); + + b.HasIndex(new[] { "LocationId", "CategoryId" }, "IX_LocationId"); + + b.HasIndex(new[] { "MatchedScientificNameId" }, "IX_MatchedScientificName"); + + b.HasIndex(new[] { "MonthCollected" }, "IX_MonthCollected"); + + b.HasIndex(new[] { "NodeId" }, "IX_NodeId"); + + b.HasIndex(new[] { "ObservationQualityTypeId" }, "IX_ObservationQualityTypeId"); + + b.HasIndex(new[] { "CategoryId" }, "IX_Observation_CategoryId"); + + b.HasIndex(new[] { "DateLastModified" }, "IX_Observation_DateLastModified"); + + b.HasIndex(new[] { "InstitutionCode" }, "IX_Observation_InstitutionCode"); + + b.HasIndex(new[] { "InstitutionId" }, "IX_Observation_InstitutionId"); + + b.HasIndex(new[] { "LocationId" }, "IX_Observation_LocationId"); + + b.HasIndex(new[] { "LocationId", "HasErrors", "HasAnnotations" }, "IX_Observation_LocationId_HasErrors_HasAnnotations"); + + b.HasIndex(new[] { "MonthCollected" }, "IX_Observation_MonthCollected"); + + b.HasIndex(new[] { "TaxonGroupId" }, "IX_Observation_TaxonGroupId"); + + b.HasIndex(new[] { "YearCollected" }, "IX_Observation_YearCollected"); + + b.HasIndex(new[] { "YearCollected", "LocationId" }, "IX_Observation_YearCollected_LocationId"); + + b.HasIndex(new[] { "OccurrenceId" }, "IX_OccurenceId"); + + b.HasIndex(new[] { "ProxyId" }, "IX_ProxyId"); + + b.HasIndex(new[] { "TaxonId", "Id", "CoordinatePrecisionInMeters", "YearCollected" }, "IX_Rodliste"); + + b.HasIndex(new[] { "TaxonGroupId", "CategoryId" }, "IX_TaxonGroupId"); + + b.HasIndex(new[] { "TaxonGroupId", "LocationId" }, "IX_TaxonGroupIdLocationId"); + + b.HasIndex(new[] { "TaxonId", "MatchedScientificNameId" }, "IX_TaxonId"); + + b.HasIndex(new[] { "YearCollected", "MonthCollected" }, "IX_YearCollected"); + + b.HasIndex(new[] { "CoordinatePrecisionInMeters" }, "Ix_CoordPrec"); + + b.HasIndex(new[] { "TaxonGroupId" }, "TaxonGroupId"); + + b.ToTable("Observation", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationDetail", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AssociatedReferences") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CollectingMethod") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Collector") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DatasetId") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("DatasetName") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DateTimeCollectedStr") + .HasMaxLength(15) + .HasColumnType("nvarchar(15)"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DynamicProperties") + .HasColumnType("nvarchar(max)"); + + b.Property("EventTime") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("FieldNumber") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("GeoreferenceRemarks") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Habitat") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("IdentifiedBy") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IndividualCount") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Locality") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("MaximumElevationInMeters") + .HasColumnType("int"); + + b.Property("MeasurementMethod") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("MinimumElevationInMeters") + .HasColumnType("int"); + + b.Property("Notes") + .HasMaxLength(3500) + .HasColumnType("nvarchar(3500)"); + + b.Property("OtherCatalogNumbers") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Preparations") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("RecordNumber") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RelatedResourceId") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("RelationshipOfResource") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Sex") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TypeStatus") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("VerbatimDepth") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id") + .HasName("PK_dbo.ObservationDetails"); + + b.HasIndex(new[] { "Id" }, "IX_Id"); + + b.ToTable("ObservationDetails"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AnnotationId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DateTimeModified") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("ErrorContext") + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ObservationId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("ValidationCode") + .HasColumnType("int"); + + b.HasKey("Id") + .HasName("PK_dbo.ObservationError"); + + b.HasIndex(new[] { "AnnotationId" }, "IX_AnnotationId"); + + b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); + + b.ToTable("ObservationError", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationLink", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LinkedObservationId") + .HasColumnType("int"); + + b.Property("ObservationId") + .HasColumnType("int"); + + b.Property("Remarks") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.ObservationLink"); + + b.HasIndex(new[] { "LinkedObservationId" }, "IX_LinkedObservationId"); + + b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); + + b.ToTable("ObservationLink", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationQualityType", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id") + .HasName("PK_dbo.ObservationQualityType"); + + b.ToTable("ObservationQualityType", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Code") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DateCreated") + .HasColumnType("datetime"); + + b.Property("DateModified") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ExternalId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("ObservationCount") + .HasColumnType("int"); + + b.Property("OrganizationTypeId") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.Organization"); + + b.HasIndex(new[] { "ExternalId" }, "IX_ExternalId"); + + b.HasIndex(new[] { "OrganizationTypeId" }, "IX_OrganizationTypeId"); + + b.HasIndex(new[] { "ParentId" }, "IX_ParentId"); + + b.ToTable("Organization", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationRelation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ObservationId") + .HasColumnType("int"); + + b.Property("OrganizationId") + .HasColumnType("int"); + + b.Property("RelationTypeId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.OrganizationRelation"); + + b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); + + b.HasIndex(new[] { "OrganizationId" }, "IX_OrganizationId"); + + b.HasIndex(new[] { "RelationTypeId" }, "IX_RelationTypeId"); + + b.ToTable("OrganizationRelation", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationRelationType", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.OrganizationRelationType"); + + b.ToTable("OrganizationRelationType", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationType", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.OrganizationType"); + + b.ToTable("OrganizationType", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ProcessRecordResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("ErrorContext") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("NotificationCode") + .HasColumnType("int"); + + b.Property("RejectedRecordId") + .HasColumnType("int") + .HasColumnName("RejectedRecord_Id"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("ValidationCode") + .HasColumnType("int"); + + b.HasKey("Id") + .HasName("PK_dbo.ProcessRecordResult"); + + b.HasIndex(new[] { "RejectedRecordId" }, "IX_RejectedRecord_Id"); + + b.HasIndex(new[] { "NotificationCode" }, "IxNotificationCode"); + + b.HasIndex(new[] { "ValidationCode" }, "IxValidationCode"); + + b.ToTable("ProcessRecordResult", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ProcessSourceDataResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedRecordsCount") + .HasColumnType("int"); + + b.Property("ErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("NewImportedRecordsCount") + .HasColumnType("int"); + + b.Property("ProcessedRecordsCount") + .HasColumnType("int"); + + b.Property("RejectedRecordsCount") + .HasColumnType("int"); + + b.Property("SerializedObject") + .HasColumnType("nvarchar(max)"); + + b.Property("SingleDatabaseResult") + .HasColumnType("int"); + + b.Property("SourceDataId") + .HasColumnType("int"); + + b.Property("TimeStampFinished") + .HasColumnType("datetime2"); + + b.Property("TimeStampStarted") + .HasColumnType("datetime2"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("WarningRecordsCount") + .HasColumnType("int"); + + b.HasKey("Id") + .HasName("PK_dbo.ProcessSourceDataResult"); + + b.ToTable("ProcessSourceDataResult", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ProsessEngineHistory", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("PublishDate") + .HasColumnType("datetime"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.ProsessEngineHistory"); + + b.ToTable("ProsessEngineHistory", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.RecordNotificationType", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Deleted") + .HasColumnType("bit"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id") + .HasName("PK_dbo.RecordNotificationType"); + + b.ToTable("RecordNotificationType", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.RecordValidationType", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Deleted") + .HasColumnType("bit"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id") + .HasName("PK_dbo.RecordValidationType"); + + b.ToTable("RecordValidationType", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.RejectedRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CollectionCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DatetimeRecordProsessed") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Gid") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("InstitutionCode") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("RecordId") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("SourceDataId") + .HasColumnType("int"); + + b.Property("TentativId") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.RejectedRecord"); + + b.HasIndex(new[] { "RecordId" }, "IX_RecordId"); + + b.HasIndex(new[] { "Gid" }, "Ix_Gid"); + + b.HasIndex(new[] { "InstitutionCode", "CollectionCode" }, "Ix_InstitutionCode"); + + b.HasIndex(new[] { "SourceDataId", "DatetimeRecordProsessed" }, "Ix_SourceDataId") + .IsDescending(false, true); + + b.HasIndex(new[] { "RecordId" }, "NonClusteredIndex-20171028-195228"); + + b.ToTable("RejectedRecord", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.SensitiveObservationDatum", b => + { + b.Property("ObservationId") + .HasColumnType("int"); + + b.Property("CoordinatePrecisionInMeters") + .HasColumnType("int"); + + b.Property("DateTimeCollected") + .HasColumnType("datetime2"); + + b.Property("East") + .HasColumnType("int"); + + b.Property("Latitude") + .HasColumnType("float"); + + b.Property("Locality") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Longitude") + .HasColumnType("float"); + + b.Property("North") + .HasColumnType("int"); + + b.Property("Notes") + .HasMaxLength(3500) + .HasColumnType("nvarchar(3500)"); + + b.HasKey("ObservationId") + .HasName("PK_dbo.SensitiveObservationData"); + + b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); + + b.ToTable("SensitiveObservationData"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.SpatialRefSy", b => + { + b.Property("Srid") + .HasColumnType("int") + .HasColumnName("srid"); + + b.Property("AuthName") + .HasMaxLength(256) + .IsUnicode(false) + .HasColumnType("varchar(256)") + .HasColumnName("auth_name"); + + b.Property("AuthSrid") + .HasColumnType("int") + .HasColumnName("auth_srid"); + + b.Property("Proj4text") + .HasMaxLength(2048) + .IsUnicode(false) + .HasColumnType("varchar(2048)") + .HasColumnName("proj4text"); + + b.Property("Srtext") + .HasMaxLength(2048) + .IsUnicode(false) + .HasColumnType("varchar(2048)") + .HasColumnName("srtext"); + + b.HasKey("Srid") + .HasName("PK__spatial___36B11BD5A2397CD6"); + + b.ToTable("spatial_ref_sys", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Tag", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ObservationCount") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.Tag"); + + b.ToTable("Tag", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Taxon", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CumulativeObservationCount") + .HasColumnType("int"); + + b.Property("DailyCumulativeObservationCount") + .HasColumnType("int"); + + b.Property("DailyObservationCount") + .HasColumnType("int"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("ExistsInCountry") + .HasColumnType("bit"); + + b.Property("ExternalTaxonId") + .HasColumnType("int") + .HasColumnName("TaxonId"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ObservationCount") + .HasColumnType("int"); + + b.Property("ParentTaxonId") + .HasColumnType("int"); + + b.Property("PreferredPopularName") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)") + .HasColumnName("PrefferedPopularname"); + + b.Property("ScientificNameIdHiarchy") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("TaxonGroupId") + .HasColumnType("int"); + + b.Property("TaxonIdHiarchy") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("TaxonRankId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime") + .HasColumnName("DateTimeUpdated"); + + b.Property("ValidScientificName") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ValidScientificNameAuthorship") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ValidScientificNameId") + .HasColumnType("int"); + + b.Property("WeeklyCumulativeObservationCount") + .HasColumnType("int"); + + b.Property("WeeklyObservationCount") + .HasColumnType("int"); + + b.HasKey("Id") + .HasName("PK_dbo.Taxon"); + + b.HasIndex(new[] { "PreferredPopularName" }, "IX_PrefferedPopularname"); + + b.HasIndex(new[] { "TaxonGroupId" }, "IX_TaxonGroupId"); + + b.HasIndex(new[] { "TaxonRankId" }, "IX_TaxonRankId"); + + b.HasIndex(new[] { "TaxonRankId", "TaxonIdHiarchy" }, "IX_TaxonRank_TaxonHirachy"); + + b.HasIndex(new[] { "ValidScientificName" }, "IX_ValidScientificName"); + + b.HasIndex(new[] { "ParentTaxonId" }, "IxParentTaxonId"); + + b.HasIndex(new[] { "ParentTaxonId" }, "IxParentTaxonId_Id_ObsCount"); + + b.HasIndex(new[] { "PreferredPopularName" }, "NonClusteredIndex-20190129-153041"); + + b.ToTable("Taxon", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonGroup", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit") + .HasColumnName("Deleted"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(75) + .HasColumnType("nvarchar(75)"); + + b.Property("ObservationCount") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.TaxonGroup"); + + b.ToTable("TaxonGroup", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonName", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("Accepted") + .HasColumnType("bit"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ScientificName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ScientificNameAuthorship") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("TaxonId") + .HasColumnType("int") + .HasColumnName("Taxon_Id"); + + b.Property("UpdatedAt") + .HasColumnType("datetime") + .HasColumnName("DateTimeUpdated"); + + b.HasKey("Id") + .HasName("PK_dbo.TaxonName"); + + b.HasIndex(new[] { "ScientificName" }, "IX_ScientificName"); + + b.HasIndex(new[] { "TaxonId" }, "IX_Taxon_Id"); + + b.ToTable("TaxonName", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonPopularName", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Language") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Preferred") + .HasColumnType("bit") + .HasColumnName("Preffered"); + + b.Property("SourceId") + .HasColumnType("int"); + + b.Property("TaxonId") + .HasColumnType("int") + .HasColumnName("Taxon_Id"); + + b.Property("UpdatedAt") + .HasColumnType("datetime") + .HasColumnName("DateTimeUpdated"); + + b.HasKey("Id") + .HasName("PK_dbo.TaxonPopularName"); + + b.HasIndex(new[] { "TaxonId" }, "IX_Taxon_Id"); + + b.ToTable("TaxonPopularName", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Context") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Prefix") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ScientificName") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Tag") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TagGroup") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("TaxonId") + .HasColumnType("int") + .HasColumnName("Taxon_Id"); + + b.Property("UpdatedAt") + .HasColumnType("datetime") + .HasColumnName("DateTimeUpdated"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.HasKey("Id") + .HasName("PK_dbo.TaxonProperty"); + + b.HasIndex(new[] { "TaxonId" }, "IX_Taxon_Id"); + + b.ToTable("TaxonProperty", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonRank", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(25) + .HasColumnType("nvarchar(25)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.TaxonRank"); + + b.ToTable("TaxonRank", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonomyState", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastEventProcessedTimeStamp") + .HasColumnType("datetime"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id") + .HasName("PK_dbo.TaxonomyState"); + + b.ToTable("TaxonomyState", (string)null); + }); + + modelBuilder.Entity("LocationArea", b => + { + b.Property("LocationId") + .HasColumnType("int"); + + b.Property("AreaId") + .HasColumnType("int"); + + b.HasKey("LocationId", "AreaId") + .HasName("PK_dbo.LocationAreas"); + + b.HasIndex(new[] { "AreaId" }, "IX_AreaId"); + + b.HasIndex(new[] { "LocationId" }, "IX_LocationId"); + + b.HasIndex(new[] { "LocationId", "AreaId" }, "IX_LocationIdArea"); + + b.ToTable("LocationAreas", (string)null); + }); + + modelBuilder.Entity("ObservationBehavior", b => + { + b.Property("ObservationId") + .HasColumnType("int"); + + b.Property("BehaviorId") + .HasColumnType("int"); + + b.HasKey("ObservationId", "BehaviorId") + .HasName("PK_dbo.ObservationBehaviors"); + + b.HasIndex(new[] { "BehaviorId" }, "IX_BehaviorId"); + + b.ToTable("ObservationBehaviors", (string)null); + }); + + modelBuilder.Entity("ObservationTag", b => + { + b.Property("ObservationId") + .HasColumnType("int"); + + b.Property("TagId") + .HasColumnType("int"); + + b.HasKey("ObservationId", "TagId") + .HasName("PK_dbo.ObservationTags"); + + b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); + + b.HasIndex(new[] { "TagId" }, "IX_TagId"); + + b.HasIndex(new[] { "TagId", "ObservationId" }, "IX_TagIdObsId"); + + b.ToTable("ObservationTags", (string)null); + }); + + modelBuilder.Entity("ObservationTaxon", b => + { + b.Property("ObservationId") + .HasColumnType("int"); + + b.Property("TaxonId") + .HasColumnType("int"); + + b.HasKey("ObservationId", "TaxonId") + .HasName("PK_dbo.ObservationTaxons"); + + b.HasIndex(new[] { "TaxonId", "ObservationId" }, "IX_TaxonId"); + + b.ToTable("ObservationTaxons", (string)null); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Area", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.AreaType", "AreaType") + .WithMany("Areas") + .HasForeignKey("AreaTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.Area_dbo.AreaType_AreaTypeID"); + + b.Navigation("AreaType"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Category", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.CategoryType", "CategoryType") + .WithMany("Categories") + .HasForeignKey("CategoryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.Category_dbo.CategoryType_CategoryTypeId"); + + b.Navigation("CategoryType"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFile", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.MediaFileType", "MediaFileType") + .WithMany("MediaFiles") + .HasForeignKey("MediaFileTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.MediaFile_dbo.MediaFileType_MediaFileTypeId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") + .WithMany("MediaFiles") + .HasForeignKey("ObservationId") + .HasConstraintName("FK_dbo.MediaFile_dbo.Observation_Observation_Id"); + + b.Navigation("MediaFileType"); + + b.Navigation("Observation"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Observation", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.BasisOfRecord", "BasisOfRecord") + .WithMany("Observations") + .HasForeignKey("BasisOfRecordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.Observation_dbo.BasisOfRecord_BasisOfRecordId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Category", "Category") + .WithMany("Observations") + .HasForeignKey("CategoryId") + .HasConstraintName("FK_dbo.Observation_dbo.Category_CategoryId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Location", "Location") + .WithMany("Observations") + .HasForeignKey("LocationId") + .HasConstraintName("FK_dbo.Observation_dbo.Location_LocationId"); + + b.HasOne("Artskart3.Core.Domain.Entities.TaxonName", "MatchedScientificName") + .WithMany("Observations") + .HasForeignKey("MatchedScientificNameId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.Observation_dbo.TaxonName_MatchedScientificNameId"); + + b.HasOne("Artskart3.Core.Domain.Entities.ObservationQualityType", "ObservationQualityType") + .WithMany("Observations") + .HasForeignKey("ObservationQualityTypeId") + .HasConstraintName("FK_dbo.Observation_dbo.ObservationQualityType_ObservationQualityTypeId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Taxon", "Taxon") + .WithMany("Observations") + .HasForeignKey("TaxonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.Observation_dbo.Taxon_TaxonId"); + + b.Navigation("BasisOfRecord"); + + b.Navigation("Category"); + + b.Navigation("Location"); + + b.Navigation("MatchedScientificName"); + + b.Navigation("ObservationQualityType"); + + b.Navigation("Taxon"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationDetail", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Observation", "IdNavigation") + .WithOne("ObservationDetail") + .HasForeignKey("Artskart3.Core.Domain.Entities.ObservationDetail", "Id") + .IsRequired() + .HasConstraintName("FK_dbo.ObservationDetails_dbo.Observation_Id"); + + b.Navigation("IdNavigation"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationError", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") + .WithMany("ObservationErrors") + .HasForeignKey("ObservationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.ObservationError_dbo.Observation_ObservationId"); + + b.Navigation("Observation"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationLink", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Observation", "LinkedObservation") + .WithMany("ObservationLinkLinkedObservations") + .HasForeignKey("LinkedObservationId") + .HasConstraintName("FK_dbo.ObservationLink_dbo.Observation_LinkedObservationId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") + .WithMany("ObservationLinkObservations") + .HasForeignKey("ObservationId") + .IsRequired() + .HasConstraintName("FK_dbo.ObservationLink_dbo.Observation_ObservationId"); + + b.Navigation("LinkedObservation"); + + b.Navigation("Observation"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Organization", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.OrganizationType", "OrganizationType") + .WithMany("Organizations") + .HasForeignKey("OrganizationTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.Organization_dbo.OrganizationType_OrganizationTypeId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Organization", "Parent") + .WithMany("InverseParent") + .HasForeignKey("ParentId") + .HasConstraintName("FK_dbo.Organization_dbo.Organization_ParentId"); + + b.Navigation("OrganizationType"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationRelation", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") + .WithMany("OrganizationRelations") + .HasForeignKey("ObservationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.OrganizationRelation_dbo.Observation_ObservationId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Organization", "Organization") + .WithMany("OrganizationRelations") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.OrganizationRelation_dbo.Organization_OrganizationId"); + + b.HasOne("Artskart3.Core.Domain.Entities.OrganizationRelationType", "RelationType") + .WithMany("OrganizationRelations") + .HasForeignKey("RelationTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.OrganizationRelation_dbo.OrganizationRelationType_RelationTypeId"); + + b.Navigation("Observation"); + + b.Navigation("Organization"); + + b.Navigation("RelationType"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ProcessRecordResult", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.RejectedRecord", "RejectedRecord") + .WithMany("ProcessRecordResults") + .HasForeignKey("RejectedRecordId") + .HasConstraintName("FK_dbo.ProcessRecordResult_dbo.RejectedRecord_RejectedRecord_Id"); + + b.Navigation("RejectedRecord"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.SensitiveObservationDatum", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") + .WithOne("SensitiveObservationDatum") + .HasForeignKey("Artskart3.Core.Domain.Entities.SensitiveObservationDatum", "ObservationId") + .IsRequired() + .HasConstraintName("FK_dbo.SensitiveObservationData_dbo.Observation_ObservationId"); + + b.Navigation("Observation"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Taxon", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.TaxonGroup", "TaxonGroup") + .WithMany("Taxons") + .HasForeignKey("TaxonGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.Taxon_dbo.TaxonGroup_TaxonGroupId"); + + b.HasOne("Artskart3.Core.Domain.Entities.TaxonRank", "TaxonRank") + .WithMany("Taxons") + .HasForeignKey("TaxonRankId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.Taxon_dbo.TaxonRank_TaxonRankId"); + + b.Navigation("TaxonGroup"); + + b.Navigation("TaxonRank"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonName", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Taxon", "Taxon") + .WithMany("TaxonNames") + .HasForeignKey("TaxonId") + .HasConstraintName("FK_dbo.TaxonName_dbo.Taxon_Taxon_Id"); + + b.Navigation("Taxon"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonPopularName", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Taxon", "Taxon") + .WithMany("TaxonPopularNames") + .HasForeignKey("TaxonId") + .HasConstraintName("FK_dbo.TaxonPopularName_dbo.Taxon_Taxon_Id"); + + b.Navigation("Taxon"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonProperty", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Taxon", "Taxon") + .WithMany("TaxonProperties") + .HasForeignKey("TaxonId") + .HasConstraintName("FK_dbo.TaxonProperty_dbo.Taxon_Taxon_Id"); + + b.Navigation("Taxon"); + }); + + modelBuilder.Entity("LocationArea", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Area", null) + .WithMany() + .HasForeignKey("AreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.LocationAreas_dbo.Area_AreaId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Location", null) + .WithMany() + .HasForeignKey("LocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.LocationAreas_dbo.Location_LocationId"); + }); + + modelBuilder.Entity("ObservationBehavior", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Behavior", null) + .WithMany() + .HasForeignKey("BehaviorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.ObservationBehaviors_dbo.Behavior_BehaviorId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Observation", null) + .WithMany() + .HasForeignKey("ObservationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.ObservationBehaviors_dbo.Observation_ObservationId"); + }); + + modelBuilder.Entity("ObservationTag", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Observation", null) + .WithMany() + .HasForeignKey("ObservationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.ObservationTags_dbo.Observation_ObservationId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Tag", null) + .WithMany() + .HasForeignKey("TagId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.ObservationTags_dbo.Tag_TagId"); + }); + + modelBuilder.Entity("ObservationTaxon", b => + { + b.HasOne("Artskart3.Core.Domain.Entities.Observation", null) + .WithMany() + .HasForeignKey("ObservationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("FK_dbo.ObservationTaxons_dbo.Observation_ObservationId"); + + b.HasOne("Artskart3.Core.Domain.Entities.Taxon", null) + .WithMany() + .HasForeignKey("TaxonId") + .IsRequired() + .HasConstraintName("FK_dbo.ObservationTaxons_dbo.Taxon_TaxonId"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.AreaType", b => + { + b.Navigation("Areas"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.BasisOfRecord", b => + { + b.Navigation("Observations"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Category", b => + { + b.Navigation("Observations"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.CategoryType", b => + { + b.Navigation("Categories"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Location", b => + { + b.Navigation("Observations"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFileType", b => + { + b.Navigation("MediaFiles"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Observation", b => + { + b.Navigation("MediaFiles"); + + b.Navigation("ObservationDetail"); + + b.Navigation("ObservationErrors"); + + b.Navigation("ObservationLinkLinkedObservations"); + + b.Navigation("ObservationLinkObservations"); + + b.Navigation("OrganizationRelations"); + + b.Navigation("SensitiveObservationDatum"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationQualityType", b => + { + b.Navigation("Observations"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Organization", b => + { + b.Navigation("InverseParent"); + + b.Navigation("OrganizationRelations"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationRelationType", b => + { + b.Navigation("OrganizationRelations"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationType", b => + { + b.Navigation("Organizations"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.RejectedRecord", b => + { + b.Navigation("ProcessRecordResults"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.Taxon", b => + { + b.Navigation("Observations"); + + b.Navigation("TaxonNames"); + + b.Navigation("TaxonPopularNames"); + + b.Navigation("TaxonProperties"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonGroup", b => + { + b.Navigation("Taxons"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonName", b => + { + b.Navigation("Observations"); + }); + + modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonRank", b => + { + b.Navigation("Taxons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.cs b/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.cs new file mode 100644 index 00000000..9d513765 --- /dev/null +++ b/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.cs @@ -0,0 +1,91 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Artskart3.Infrastructure.Migrations +{ + /// + public partial class AddDataSource : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DataSource", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + ProviderType = table.Column(type: "int", nullable: false), + RecordsBatchSize = table.Column(type: "int", nullable: false), + WebServiceVersion = table.Column(type: "int", nullable: false), + RemoteAddress = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + ArchiveName = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), + Notes = table.Column(type: "nvarchar(2000)", maxLength: 2000, nullable: true), + IsEditedNameOrNotes = table.Column(type: "bit", nullable: false), + NonValidOccurrenceIds = table.Column(type: "bit", nullable: false), + GbifApiQuery = table.Column(type: "nvarchar(max)", nullable: true), + HarvestPropertyOverrides = table.Column(type: "nvarchar(max)", nullable: true), + ImportPropertyOverrides = table.Column(type: "nvarchar(max)", nullable: true), + UpdateFrequencyInDays = table.Column(type: "int", nullable: false), + Doi = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: true), + GbifPublisherId = table.Column(type: "uniqueidentifier", nullable: true), + IsSensitive = table.Column(type: "bit", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false), + IsDeleted = table.Column(type: "bit", nullable: false), + DeletedAt = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DataSource", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Observation_BasisOfRecordId", + table: "Observation", + column: "BasisOfRecordId"); + + migrationBuilder.CreateIndex( + name: "IX_Observation_CoordinatePrecisionInMeters", + table: "Observation", + column: "CoordinatePrecisionInMeters"); + + migrationBuilder.CreateIndex( + name: "IX_Observation_TaxonGroupId_LocationId", + table: "Observation", + columns: new[] { "TaxonGroupId", "LocationId" }); + + migrationBuilder.CreateIndex( + name: "IX_DataSource_IsDeleted", + table: "DataSource", + column: "IsDeleted"); + + migrationBuilder.CreateIndex( + name: "IX_DataSource_ProviderType", + table: "DataSource", + column: "ProviderType"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DataSource"); + + migrationBuilder.DropIndex( + name: "IX_Observation_BasisOfRecordId", + table: "Observation"); + + migrationBuilder.DropIndex( + name: "IX_Observation_CoordinatePrecisionInMeters", + table: "Observation"); + + migrationBuilder.DropIndex( + name: "IX_Observation_TaxonGroupId_LocationId", + table: "Observation"); + } + } +} diff --git a/Artskart3.Infrastructure/Migrations/ArtskartDbContextModelSnapshot.cs b/Artskart3.Infrastructure/Migrations/ArtskartDbContextModelSnapshot.cs index 202381f8..4fd97dd6 100644 --- a/Artskart3.Infrastructure/Migrations/ArtskartDbContextModelSnapshot.cs +++ b/Artskart3.Infrastructure/Migrations/ArtskartDbContextModelSnapshot.cs @@ -374,6 +374,91 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("CommandLog", (string)null); }); + modelBuilder.Entity("Artskart3.Core.Domain.Entities.DataSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchiveName") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("GbifApiQuery") + .HasColumnType("nvarchar(max)"); + + b.Property("GbifPublisherId") + .HasColumnType("uniqueidentifier"); + + b.Property("HarvestPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("ImportPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsEditedNameOrNotes") + .HasColumnType("bit"); + + b.Property("IsSensitive") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("NonValidOccurrenceIds") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ProviderType") + .HasColumnType("int"); + + b.Property("RecordsBatchSize") + .HasColumnType("int"); + + b.Property("RemoteAddress") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("UpdateFrequencyInDays") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("WebServiceVersion") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IsDeleted") + .HasDatabaseName("IX_DataSource_IsDeleted"); + + b.HasIndex("ProviderType") + .HasDatabaseName("IX_DataSource_ProviderType"); + + b.ToTable("DataSource", (string)null); + }); + modelBuilder.Entity("Artskart3.Core.Domain.Entities.DeletedItem", b => { b.Property("Id") @@ -1179,6 +1264,45 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id") .HasName("PK_dbo.Observation"); + b.HasIndex("BasisOfRecordId") + .HasDatabaseName("IX_Observation_BasisOfRecordId"); + + b.HasIndex("CategoryId") + .HasDatabaseName("IX_Observation_CategoryId"); + + b.HasIndex("CoordinatePrecisionInMeters") + .HasDatabaseName("IX_Observation_CoordinatePrecisionInMeters"); + + b.HasIndex("DateLastModified") + .HasDatabaseName("IX_Observation_DateLastModified"); + + b.HasIndex("InstitutionCode") + .HasDatabaseName("IX_Observation_InstitutionCode"); + + b.HasIndex("InstitutionId") + .HasDatabaseName("IX_Observation_InstitutionId"); + + b.HasIndex("LocationId") + .HasDatabaseName("IX_Observation_LocationId"); + + b.HasIndex("MonthCollected") + .HasDatabaseName("IX_Observation_MonthCollected"); + + b.HasIndex("TaxonGroupId") + .HasDatabaseName("IX_Observation_TaxonGroupId"); + + b.HasIndex("YearCollected") + .HasDatabaseName("IX_Observation_YearCollected"); + + b.HasIndex("TaxonGroupId", "LocationId") + .HasDatabaseName("IX_Observation_TaxonGroupId_LocationId"); + + b.HasIndex("YearCollected", "LocationId") + .HasDatabaseName("IX_Observation_YearCollected_LocationId"); + + b.HasIndex("LocationId", "HasErrors", "HasAnnotations") + .HasDatabaseName("IX_Observation_LocationId_HasErrors_HasAnnotations"); + b.HasIndex(new[] { "BasisOfRecordId" }, "IX_BasisOfRecordId"); b.HasIndex(new[] { "CatalogNumber" }, "IX_CatalogNumber"); From a429ba5b8e62033ae1df51481f0f306ce352bb76 Mon Sep 17 00:00:00 2001 From: bo Date: Thu, 30 Apr 2026 14:32:41 +0200 Subject: [PATCH 2/7] refactor: move DataSource to new Artskart3.Import project (#138) 3-database architecture: DB1 Artskart3Import - raw import data (this project) DB2 Artskart3Core - processed/standardised observations (Artskart3.Infrastructure) DB3 Artskart3Index - search-optimised index (future index3core) Changes: - Remove DataSource entity and ProviderType enum from Artskart3.Core - Revert Artskart3.Infrastructure to pre-DataSource state (migration, DbSet, EntityConfiguration and OnModelCreatingPartial call removed, model snapshot restored) - Create Artskart3.Import class library (net10.0, EF Core 10.0.5) - Add DataSource entity, ProviderType enum, DataSourceConfiguration, ArtskartImportDbContext and ArtskartImportDbContextFactory - Add InitialImportBaseline EF migration for Artskart3Import database - Add Artskart3.Import to solution and as reference in Artskart3.Api - Add ArtskartImportDb connection string to appsettings.json --- Artskart3.Api/Artskart3.Api.csproj | 1 + Artskart3.Api/appsettings.json | 3 +- Artskart3.Import/Artskart3.Import.csproj | 24 + .../Data/ArtskartImportDbContext.cs | 26 + .../Data/ArtskartImportDbContextFactory.cs | 29 + .../DataSourceConfiguration.cs | 4 +- .../Domain/Entities/DataSource.cs | 15 +- .../Domain/Enums/ProviderType.cs | 2 +- ...30123211_InitialImportBaseline.Designer.cs | 115 + .../20260430123211_InitialImportBaseline.cs | 33 +- .../ArtskartImportDbContextModelSnapshot.cs | 112 + .../Data/DbContext/ArtskartDbContext.cs | 5 - .../20260430112855_AddDataSource.Designer.cs | 3003 ----------------- .../ArtskartDbContextModelSnapshot.cs | 124 - Artskart3.slnx | 1 + 15 files changed, 327 insertions(+), 3170 deletions(-) create mode 100644 Artskart3.Import/Artskart3.Import.csproj create mode 100644 Artskart3.Import/Data/ArtskartImportDbContext.cs create mode 100644 Artskart3.Import/Data/ArtskartImportDbContextFactory.cs rename {Artskart3.Infrastructure => Artskart3.Import}/Data/EntityConfigurations/DataSourceConfiguration.cs (93%) rename {Artskart3.Core => Artskart3.Import}/Domain/Entities/DataSource.cs (88%) rename {Artskart3.Core => Artskart3.Import}/Domain/Enums/ProviderType.cs (76%) create mode 100644 Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.Designer.cs rename Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.cs => Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.cs (73%) create mode 100644 Artskart3.Import/Migrations/ArtskartImportDbContextModelSnapshot.cs delete mode 100644 Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.Designer.cs diff --git a/Artskart3.Api/Artskart3.Api.csproj b/Artskart3.Api/Artskart3.Api.csproj index e0106c7d..e98afc16 100644 --- a/Artskart3.Api/Artskart3.Api.csproj +++ b/Artskart3.Api/Artskart3.Api.csproj @@ -30,6 +30,7 @@ + diff --git a/Artskart3.Api/appsettings.json b/Artskart3.Api/appsettings.json index c1ed4915..48f5c0ce 100644 --- a/Artskart3.Api/appsettings.json +++ b/Artskart3.Api/appsettings.json @@ -19,7 +19,8 @@ "ConnectionStrings": { "Redis": "", "AzureServiceBus": "", - "ArtskartDb": "data source=localhost;initial catalog=Artskart3Index;Integrated Security=true;MultipleActiveResultSets=True;App=EntityFramework;TrustServerCertificate=True" + "ArtskartDb": "data source=localhost;initial catalog=Artskart3Index;Integrated Security=true;MultipleActiveResultSets=True;App=EntityFramework;TrustServerCertificate=True", + "ArtskartImportDb": "data source=localhost;initial catalog=Artskart3Import;Integrated Security=true;MultipleActiveResultSets=True;App=EntityFramework;TrustServerCertificate=True" }, "KeyVault": { "Url": "" diff --git a/Artskart3.Import/Artskart3.Import.csproj b/Artskart3.Import/Artskart3.Import.csproj new file mode 100644 index 00000000..f04c3b52 --- /dev/null +++ b/Artskart3.Import/Artskart3.Import.csproj @@ -0,0 +1,24 @@ + + + + net10.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + diff --git a/Artskart3.Import/Data/ArtskartImportDbContext.cs b/Artskart3.Import/Data/ArtskartImportDbContext.cs new file mode 100644 index 00000000..b8e11574 --- /dev/null +++ b/Artskart3.Import/Data/ArtskartImportDbContext.cs @@ -0,0 +1,26 @@ +using Artskart3.Import.Data.EntityConfigurations; +using Artskart3.Import.Domain.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Artskart3.Import.Data; + +public class ArtskartImportDbContext : DbContext +{ + public ArtskartImportDbContext() + { + } + + public ArtskartImportDbContext(DbContextOptions options) + : base(options) + { + } + + public virtual DbSet DataSources { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.ApplyConfiguration(new DataSourceConfiguration()); + + base.OnModelCreating(modelBuilder); + } +} diff --git a/Artskart3.Import/Data/ArtskartImportDbContextFactory.cs b/Artskart3.Import/Data/ArtskartImportDbContextFactory.cs new file mode 100644 index 00000000..302ec9c5 --- /dev/null +++ b/Artskart3.Import/Data/ArtskartImportDbContextFactory.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; + +namespace Artskart3.Import.Data; + +/// +/// Used by EF Core tooling (dotnet ef migrations add, dotnet ef database update) at design time. +/// Reads the connection string from appsettings.json in the API project. +/// +public class ArtskartImportDbContextFactory : IDesignTimeDbContextFactory +{ + public ArtskartImportDbContext CreateDbContext(string[] args) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "..", "Artskart3.Api")) + .AddJsonFile("appsettings.json", optional: false) + .AddJsonFile("appsettings.Development.json", optional: true) + .Build(); + + var connectionString = configuration.GetConnectionString("ArtskartImportDb") + ?? throw new InvalidOperationException("Connection string 'ArtskartImportDb' not found in appsettings.json."); + + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer(connectionString); + + return new ArtskartImportDbContext(optionsBuilder.Options); + } +} diff --git a/Artskart3.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs b/Artskart3.Import/Data/EntityConfigurations/DataSourceConfiguration.cs similarity index 93% rename from Artskart3.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs rename to Artskart3.Import/Data/EntityConfigurations/DataSourceConfiguration.cs index f98f2bda..9439a011 100644 --- a/Artskart3.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs +++ b/Artskart3.Import/Data/EntityConfigurations/DataSourceConfiguration.cs @@ -1,8 +1,8 @@ -using Artskart3.Core.Domain.Entities; +using Artskart3.Import.Domain.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -namespace Artskart3.Infrastructure.Data.EntityConfigurations; +namespace Artskart3.Import.Data.EntityConfigurations; public class DataSourceConfiguration : IEntityTypeConfiguration { diff --git a/Artskart3.Core/Domain/Entities/DataSource.cs b/Artskart3.Import/Domain/Entities/DataSource.cs similarity index 88% rename from Artskart3.Core/Domain/Entities/DataSource.cs rename to Artskart3.Import/Domain/Entities/DataSource.cs index 75add71d..487244c6 100644 --- a/Artskart3.Core/Domain/Entities/DataSource.cs +++ b/Artskart3.Import/Domain/Entities/DataSource.cs @@ -1,14 +1,15 @@ -using Artskart3.Core.Domain.Entities.Base; -using Artskart3.Core.Domain.Enums; +using Artskart3.Import.Domain.Enums; -namespace Artskart3.Core.Domain.Entities; +namespace Artskart3.Import.Domain.Entities; /// /// Provider configuration for a remote data source (formerly SourceDataBase in RavenDB). /// One flat table; use typed views or application-layer filtering to work with specific provider types. /// -public class DataSource : BaseEntity +public class DataSource { + public int Id { get; set; } + public string Name { get; set; } = string.Empty; /// @@ -41,6 +42,8 @@ public class DataSource : BaseEntity /// public string? Notes { get; set; } + public bool IsDeleted { get; set; } + public bool IsEditedNameOrNotes { get; set; } /// @@ -83,4 +86,8 @@ public class DataSource : BaseEntity /// Marks observations from this source as sensitive (restricted coordinates etc.). /// public bool IsSensitive { get; set; } + + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; + public DateTime? DeletedAt { get; set; } } diff --git a/Artskart3.Core/Domain/Enums/ProviderType.cs b/Artskart3.Import/Domain/Enums/ProviderType.cs similarity index 76% rename from Artskart3.Core/Domain/Enums/ProviderType.cs rename to Artskart3.Import/Domain/Enums/ProviderType.cs index 6f3caecf..9f45f118 100644 --- a/Artskart3.Core/Domain/Enums/ProviderType.cs +++ b/Artskart3.Import/Domain/Enums/ProviderType.cs @@ -1,4 +1,4 @@ -namespace Artskart3.Core.Domain.Enums; +namespace Artskart3.Import.Domain.Enums; public enum ProviderType { diff --git a/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.Designer.cs b/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.Designer.cs new file mode 100644 index 00000000..5aec8b47 --- /dev/null +++ b/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.Designer.cs @@ -0,0 +1,115 @@ +// +using System; +using Artskart3.Import.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Artskart3.Import.Migrations +{ + [DbContext(typeof(ArtskartImportDbContext))] + [Migration("20260430123211_InitialImportBaseline")] + partial class InitialImportBaseline + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Artskart3.Import.Domain.Entities.DataSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchiveName") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("GbifApiQuery") + .HasColumnType("nvarchar(max)"); + + b.Property("GbifPublisherId") + .HasColumnType("uniqueidentifier"); + + b.Property("HarvestPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("ImportPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsEditedNameOrNotes") + .HasColumnType("bit"); + + b.Property("IsSensitive") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("NonValidOccurrenceIds") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ProviderType") + .HasColumnType("int"); + + b.Property("RecordsBatchSize") + .HasColumnType("int"); + + b.Property("RemoteAddress") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("UpdateFrequencyInDays") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("WebServiceVersion") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IsDeleted") + .HasDatabaseName("IX_DataSource_IsDeleted"); + + b.HasIndex("ProviderType") + .HasDatabaseName("IX_DataSource_ProviderType"); + + b.ToTable("DataSource", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.cs b/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.cs similarity index 73% rename from Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.cs rename to Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.cs index 9d513765..6ea9285c 100644 --- a/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.cs +++ b/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.cs @@ -3,10 +3,10 @@ #nullable disable -namespace Artskart3.Infrastructure.Migrations +namespace Artskart3.Import.Migrations { /// - public partial class AddDataSource : Migration + public partial class InitialImportBaseline : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) @@ -24,6 +24,7 @@ protected override void Up(MigrationBuilder migrationBuilder) RemoteAddress = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), ArchiveName = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: true), Notes = table.Column(type: "nvarchar(2000)", maxLength: 2000, nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false), IsEditedNameOrNotes = table.Column(type: "bit", nullable: false), NonValidOccurrenceIds = table.Column(type: "bit", nullable: false), GbifApiQuery = table.Column(type: "nvarchar(max)", nullable: true), @@ -35,7 +36,6 @@ protected override void Up(MigrationBuilder migrationBuilder) IsSensitive = table.Column(type: "bit", nullable: false), CreatedAt = table.Column(type: "datetime2", nullable: false), UpdatedAt = table.Column(type: "datetime2", nullable: false), - IsDeleted = table.Column(type: "bit", nullable: false), DeletedAt = table.Column(type: "datetime2", nullable: true) }, constraints: table => @@ -43,21 +43,6 @@ protected override void Up(MigrationBuilder migrationBuilder) table.PrimaryKey("PK_DataSource", x => x.Id); }); - migrationBuilder.CreateIndex( - name: "IX_Observation_BasisOfRecordId", - table: "Observation", - column: "BasisOfRecordId"); - - migrationBuilder.CreateIndex( - name: "IX_Observation_CoordinatePrecisionInMeters", - table: "Observation", - column: "CoordinatePrecisionInMeters"); - - migrationBuilder.CreateIndex( - name: "IX_Observation_TaxonGroupId_LocationId", - table: "Observation", - columns: new[] { "TaxonGroupId", "LocationId" }); - migrationBuilder.CreateIndex( name: "IX_DataSource_IsDeleted", table: "DataSource", @@ -74,18 +59,6 @@ protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "DataSource"); - - migrationBuilder.DropIndex( - name: "IX_Observation_BasisOfRecordId", - table: "Observation"); - - migrationBuilder.DropIndex( - name: "IX_Observation_CoordinatePrecisionInMeters", - table: "Observation"); - - migrationBuilder.DropIndex( - name: "IX_Observation_TaxonGroupId_LocationId", - table: "Observation"); } } } diff --git a/Artskart3.Import/Migrations/ArtskartImportDbContextModelSnapshot.cs b/Artskart3.Import/Migrations/ArtskartImportDbContextModelSnapshot.cs new file mode 100644 index 00000000..81e67999 --- /dev/null +++ b/Artskart3.Import/Migrations/ArtskartImportDbContextModelSnapshot.cs @@ -0,0 +1,112 @@ +// +using System; +using Artskart3.Import.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Artskart3.Import.Migrations +{ + [DbContext(typeof(ArtskartImportDbContext))] + partial class ArtskartImportDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Artskart3.Import.Domain.Entities.DataSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchiveName") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("GbifApiQuery") + .HasColumnType("nvarchar(max)"); + + b.Property("GbifPublisherId") + .HasColumnType("uniqueidentifier"); + + b.Property("HarvestPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("ImportPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsEditedNameOrNotes") + .HasColumnType("bit"); + + b.Property("IsSensitive") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("NonValidOccurrenceIds") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ProviderType") + .HasColumnType("int"); + + b.Property("RecordsBatchSize") + .HasColumnType("int"); + + b.Property("RemoteAddress") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("UpdateFrequencyInDays") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("WebServiceVersion") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IsDeleted") + .HasDatabaseName("IX_DataSource_IsDeleted"); + + b.HasIndex("ProviderType") + .HasDatabaseName("IX_DataSource_ProviderType"); + + b.ToTable("DataSource", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs b/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs index e9019e3c..9543b7af 100644 --- a/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs +++ b/Artskart3.Infrastructure/Data/DbContext/ArtskartDbContext.cs @@ -29,8 +29,6 @@ public ArtskartDbContext(DbContextOptions options) public virtual DbSet CommandLogs { get; set; } - public virtual DbSet DataSources { get; set; } - public virtual DbSet DeletedItems { get; set; } public virtual DbSet ExportStatuses { get; set; } @@ -1043,8 +1041,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.LastEventProcessedTimeStamp).HasColumnType("datetime"); }); - - OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); @@ -1052,7 +1048,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) partial void OnModelCreatingPartial(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new ObservationSearchIndexConfiguration()); - modelBuilder.ApplyConfiguration(new DataSourceConfiguration()); } } } diff --git a/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.Designer.cs b/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.Designer.cs deleted file mode 100644 index b6afb862..00000000 --- a/Artskart3.Infrastructure/Migrations/20260430112855_AddDataSource.Designer.cs +++ /dev/null @@ -1,3003 +0,0 @@ -// -using System; -using Artskart3.Infrastructure.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Artskart3.Infrastructure.Migrations -{ - [DbContext(typeof(ArtskartDbContext))] - [Migration("20260430112855_AddDataSource")] - partial class AddDataSource - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.5") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Area", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("AreaTypeId") - .HasColumnType("int") - .HasColumnName("AreaTypeID"); - - b.Property("Bbox") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("DocumentId") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("Fid") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("GmBbox") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("IsCurrent") - .HasColumnType("bit"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("ObservationCount") - .HasColumnType("int"); - - b.Property("ParentFid") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("SyncDateTime") - .HasColumnType("datetime"); - - b.Property("TimeStamp") - .ValueGeneratedOnAdd() - .HasColumnType("datetime") - .HasDefaultValue(new DateTime(1900, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.Area"); - - b.HasIndex(new[] { "AreaTypeId", "Id", "Fid" }, "IX_AreaTypeID"); - - b.HasIndex(new[] { "Fid" }, "IX_Fid"); - - b.HasIndex(new[] { "ParentFid" }, "IX_ParentFid"); - - b.HasIndex(new[] { "Name" }, "NonClusteredIndex-20180305-111522"); - - b.ToTable("Area", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.AreaType", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CategoryName") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("IsRequired") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.AreaType"); - - b.ToTable("AreaType", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.BasisOfRecord", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .HasMaxLength(30) - .HasColumnType("nvarchar(30)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(60) - .HasColumnType("nvarchar(60)"); - - b.Property("ObservationCount") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("Variants") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("nvarchar(300)"); - - b.HasKey("Id") - .HasName("PK_dbo.BasisOfRecord"); - - b.ToTable("BasisOfRecord", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Behavior", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("Deleted") - .HasColumnType("bit"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(60) - .HasColumnType("nvarchar(60)"); - - b.Property("ObservationCount") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("Variants") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("nvarchar(300)"); - - b.HasKey("Id") - .HasName("PK_dbo.Behavior"); - - b.ToTable("Behavior", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Category", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CategoryTypeId") - .HasColumnType("int"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(2) - .HasColumnType("nvarchar(2)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("ObservationCount") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.Category"); - - b.HasIndex(new[] { "CategoryTypeId" }, "IX_CategoryTypeId"); - - b.ToTable("Category", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.CategoryType", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(60) - .HasColumnType("nvarchar(60)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.CategoryType"); - - b.ToTable("CategoryType", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.CommandLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasColumnName("ID"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Command") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("CommandType") - .IsRequired() - .HasMaxLength(60) - .HasColumnType("nvarchar(60)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DatabaseName") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("EndTime") - .HasColumnType("datetime2"); - - b.Property("ErrorMessage") - .HasColumnType("nvarchar(max)"); - - b.Property("ErrorNumber") - .HasColumnType("int"); - - b.Property("ExtendedInfo") - .HasColumnType("xml"); - - b.Property("IndexName") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("IndexType") - .HasColumnType("tinyint"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("ObjectName") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("ObjectType") - .HasMaxLength(2) - .IsUnicode(false) - .HasColumnType("char(2)") - .IsFixedLength(); - - b.Property("PartitionNumber") - .HasColumnType("int"); - - b.Property("SchemaName") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("StartTime") - .HasColumnType("datetime2"); - - b.Property("StatisticsName") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id"); - - b.ToTable("CommandLog", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.DataSource", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ArchiveName") - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Doi") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("GbifApiQuery") - .HasColumnType("nvarchar(max)"); - - b.Property("GbifPublisherId") - .HasColumnType("uniqueidentifier"); - - b.Property("HarvestPropertyOverrides") - .HasColumnType("nvarchar(max)"); - - b.Property("ImportPropertyOverrides") - .HasColumnType("nvarchar(max)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("IsEditedNameOrNotes") - .HasColumnType("bit"); - - b.Property("IsSensitive") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("NonValidOccurrenceIds") - .HasColumnType("bit"); - - b.Property("Notes") - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("ProviderType") - .HasColumnType("int"); - - b.Property("RecordsBatchSize") - .HasColumnType("int"); - - b.Property("RemoteAddress") - .HasMaxLength(1000) - .HasColumnType("nvarchar(1000)"); - - b.Property("UpdateFrequencyInDays") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("WebServiceVersion") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("IsDeleted") - .HasDatabaseName("IX_DataSource_IsDeleted"); - - b.HasIndex("ProviderType") - .HasDatabaseName("IX_DataSource_ProviderType"); - - b.ToTable("DataSource", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.DeletedItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("RecordId") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("ReplicationId") - .HasColumnType("int"); - - b.Property("TimeStamp") - .HasColumnType("datetime"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.DeletedItem"); - - b.HasIndex(new[] { "RecordId" }, "Ix_RecordId"); - - b.HasIndex(new[] { "TimeStamp" }, "Ix_TimeStamp"); - - b.HasIndex(new[] { "TimeStamp" }, "Ix_TimeStampWithRecordId"); - - b.ToTable("DeletedItem", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ExportStatus", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Doi") - .HasColumnType("nvarchar(max)"); - - b.Property("ExportCreated") - .HasColumnType("datetime2"); - - b.Property("ExportFinished") - .HasColumnType("datetime2"); - - b.Property("ExportInfo") - .HasColumnType("nvarchar(max)"); - - b.Property("ExportJobId") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("ExportStarted") - .HasColumnType("datetime2"); - - b.Property("FileSize") - .HasColumnType("bigint"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("StatusCode") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.ExportStatus"); - - b.ToTable("ExportStatus", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Fab4exclude", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.FAB4Exclude"); - - b.ToTable("FAB4Exclude", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Filter", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasDefaultValueSql("(newsequentialid())"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("SerializedFilter") - .IsRequired() - .HasMaxLength(3700) - .HasColumnType("nvarchar(3700)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.Filter"); - - b.ToTable("Filter", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.GeometryColumn", b => - { - b.Property("FTableCatalog") - .HasMaxLength(128) - .IsUnicode(false) - .HasColumnType("varchar(128)") - .HasColumnName("f_table_catalog"); - - b.Property("FTableSchema") - .HasMaxLength(128) - .IsUnicode(false) - .HasColumnType("varchar(128)") - .HasColumnName("f_table_schema"); - - b.Property("FTableName") - .HasMaxLength(256) - .IsUnicode(false) - .HasColumnType("varchar(256)") - .HasColumnName("f_table_name"); - - b.Property("FGeometryColumn") - .HasMaxLength(256) - .IsUnicode(false) - .HasColumnType("varchar(256)") - .HasColumnName("f_geometry_column"); - - b.Property("CoordDimension") - .HasColumnType("int") - .HasColumnName("coord_dimension"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("GeometryType") - .IsRequired() - .HasMaxLength(30) - .IsUnicode(false) - .HasColumnType("varchar(30)") - .HasColumnName("geometry_type"); - - b.Property("Id") - .HasColumnType("int"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Srid") - .HasColumnType("int") - .HasColumnName("srid"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("FTableCatalog", "FTableSchema", "FTableName", "FGeometryColumn") - .HasName("geometry_columns_pk"); - - b.ToTable("geometry_columns", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("ModeCommand") - .HasColumnType("int") - .HasColumnName("Mode_Command"); - - b.Property("ModeDataset") - .HasColumnType("nvarchar(max)") - .HasColumnName("Mode_Dataset"); - - b.Property("ModeFilePath") - .HasColumnType("nvarchar(max)") - .HasColumnName("Mode_FilePath"); - - b.Property("ModePartitionYear") - .HasColumnType("int") - .HasColumnName("Mode_PartitionYear"); - - b.Property("ModeProcessMode") - .HasColumnType("int") - .HasColumnName("Mode_ProcessMode"); - - b.Property("ModeSensitiveRecords") - .HasColumnType("bit") - .HasColumnName("Mode_SensitiveRecords"); - - b.Property("Runtime") - .HasColumnType("float"); - - b.Property("SerializedObject") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("SumNewRecordsImported") - .HasColumnType("int"); - - b.Property("SumRecordsDeleted") - .HasColumnType("int"); - - b.Property("SumRecordsProcessed") - .HasColumnType("int"); - - b.Property("SumRecordsRejected") - .HasColumnType("int"); - - b.Property("SumUpdatedRecords") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("datetime2"); - - b.Property("TimestampFinished") - .HasColumnType("datetime2"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.ImportLog"); - - b.HasIndex(new[] { "Timestamp" }, "Ix_Time"); - - b.ToTable("ImportLog", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportNotification", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Message") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("Severity") - .HasColumnType("int"); - - b.Property("SeverityDescription") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Subject") - .IsRequired() - .HasMaxLength(250) - .HasColumnType("nvarchar(250)"); - - b.Property("Timestamp") - .HasColumnType("datetime2"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.ImportNotification"); - - b.HasIndex(new[] { "Timestamp" }, "IX_TimeStamp"); - - b.ToTable("ImportNotification", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ImportState", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DateLastProcessed") - .HasColumnType("datetime2"); - - b.Property("DateLastProcessedFinished") - .HasColumnType("datetime2"); - - b.Property("DateLastProcessedWithChangeInRecords") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Doi") - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("FailCount") - .HasColumnType("int"); - - b.Property("GbifDataSetId") - .HasColumnType("uniqueidentifier"); - - b.Property("ImportedNumberOfRecords") - .HasColumnType("int"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("LastProcessResult") - .HasColumnType("nvarchar(max)"); - - b.Property("LastRecordDateLastModified") - .HasColumnType("datetime2"); - - b.Property("LastRecordImportedCatalogNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasColumnType("nvarchar(max)"); - - b.Property("RejectedNumberOfRecords") - .HasColumnType("int"); - - b.Property("ReportedLastTrackDateInCache") - .HasColumnType("datetime2"); - - b.Property("ReportedTotalNumberOfRecordsInCache") - .HasColumnType("int"); - - b.Property("TrackDateOfLastRecordProcessed") - .HasColumnType("datetime2"); - - b.Property("UpdateMode") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.ImportState"); - - b.ToTable("ImportState", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Location", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CoordinatePrecision") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("East") - .HasColumnType("int"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Latitude") - .HasColumnType("float"); - - b.Property("Locality") - .HasMaxLength(1000) - .HasColumnType("nvarchar(1000)"); - - b.Property("LocationId") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("Longitude") - .HasColumnType("float"); - - b.Property("LookupId") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("NodeId") - .HasColumnType("int"); - - b.Property("North") - .HasColumnType("int"); - - b.Property("TimeStamp") - .HasColumnType("datetime"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.Location"); - - b.HasIndex(new[] { "CoordinatePrecision" }, "IX_CoordinatePrecision"); - - b.HasIndex(new[] { "East", "North" }, "IX_EastNorth"); - - b.HasIndex(new[] { "East" }, "IX_EastNorthGeom"); - - b.HasIndex(new[] { "LookupId" }, "IX_LookupId"); - - b.ToTable("Location", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter16x16km", b => - { - b.Property("Objectid") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasColumnName("OBJECTID"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid")); - - b.Property("KriteriumMaskeringsrute") - .HasColumnType("int") - .HasColumnName("KRITERIUM_MASKERINGSRUTE"); - - b.Property("Ruteid") - .HasMaxLength(50) - .IsUnicode(false) - .HasColumnType("char(50)") - .HasColumnName("RUTEID") - .IsFixedLength(); - - b.HasKey("Objectid"); - - b.ToTable("Maskeringsruter_16x16km", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter4x4km", b => - { - b.Property("Objectid") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasColumnName("OBJECTID"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid")); - - b.Property("KriteriumMaskeringsrute") - .HasColumnType("int") - .HasColumnName("KRITERIUM_MASKERINGSRUTE"); - - b.Property("Ruteid") - .HasMaxLength(50) - .IsUnicode(false) - .HasColumnType("char(50)") - .HasColumnName("RUTEID") - .IsFixedLength(); - - b.HasKey("Objectid"); - - b.ToTable("Maskeringsruter_4x4km", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Maskeringsruter8x8km", b => - { - b.Property("Objectid") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasColumnName("OBJECTID"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Objectid")); - - b.Property("KriteriumMaskeringsrute") - .HasColumnType("int") - .HasColumnName("KRITERIUM_MASKERINGSRUTE"); - - b.Property("Ruteid") - .HasMaxLength(50) - .IsUnicode(false) - .HasColumnType("char(50)") - .HasColumnName("RUTEID") - .IsFixedLength(); - - b.HasKey("Objectid"); - - b.ToTable("Maskeringsruter_8x8km", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFile", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("DownloadRetryCount") - .HasColumnType("int"); - - b.Property("Downloaded") - .HasColumnType("bit"); - - b.Property("Image") - .HasColumnType("varbinary(max)"); - - b.Property("InDownloadqueue") - .HasColumnType("bit"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("License") - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("MediaFileTypeId") - .HasColumnType("int"); - - b.Property("ObservationId") - .HasColumnType("int") - .HasColumnName("Observation_Id"); - - b.Property("Origin") - .IsRequired() - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("RightsHolder") - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("Size") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.MediaFile"); - - b.HasIndex("MediaFileTypeId"); - - b.HasIndex(new[] { "Downloaded", "MediaFileTypeId", "DownloadRetryCount" }, "IX_DownLoaded"); - - b.HasIndex(new[] { "ObservationId" }, "IX_Observation_Id"); - - b.ToTable("MediaFile", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFileType", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("MediaTypeName") - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("MimeType") - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.MediaFileType"); - - b.ToTable("MediaFileType", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.MigrationHistory", b => - { - b.Property("MigrationId") - .HasMaxLength(150) - .HasColumnType("nvarchar(150)"); - - b.Property("ContextKey") - .HasMaxLength(300) - .HasColumnType("nvarchar(300)"); - - b.Property("Model") - .IsRequired() - .HasColumnType("varbinary(max)"); - - b.Property("ProductVersion") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.HasKey("MigrationId", "ContextKey") - .HasName("PK_dbo.__MigrationHistory"); - - b.ToTable("__MigrationHistory", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Observation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("BasisOfRecordId") - .HasColumnType("int"); - - b.Property("CatalogNumber") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("CategoryId") - .HasColumnType("int"); - - b.Property("CollectionCode") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("CoordinatePrecisionInMeters") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DateLastModified") - .HasColumnType("datetime2"); - - b.Property("DateTimeCollected") - .HasColumnType("datetime2"); - - b.Property("DateTimeRecordImported") - .HasColumnType("datetime2"); - - b.Property("DateTimeRecordProcessed") - .HasColumnType("datetime") - .HasColumnName("DateTimeRecordProsessed"); - - b.Property("DatetimeIdentified") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("East") - .HasColumnType("int"); - - b.Property("HasAnnotations") - .HasColumnType("bit"); - - b.Property("HasErrors") - .HasColumnType("bit"); - - b.Property("HashCode") - .HasColumnType("int"); - - b.Property("InstitutionCode") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("InstitutionId") - .HasMaxLength(25) - .HasColumnType("nvarchar(25)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Latitude") - .HasColumnType("float"); - - b.Property("LocationId") - .HasColumnType("int"); - - b.Property("Longitude") - .HasColumnType("float"); - - b.Property("MatchedScientificNameId") - .HasColumnType("int"); - - b.Property("MonthCollected") - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("int") - .HasComputedColumnSql("(datepart(month,[DateTimeCollected]))", false); - - b.Property("NodeId") - .HasColumnType("int"); - - b.Property("North") - .HasColumnType("int"); - - b.Property("ObservationQualityTypeId") - .HasColumnType("int"); - - b.Property("OccurrenceId") - .HasMaxLength(255) - .HasColumnType("nvarchar(255)") - .HasColumnName("OccurenceId"); - - b.Property("ProcessEngineId") - .HasColumnType("int"); - - b.Property("ProxyId") - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("TaxonGroupId") - .HasColumnType("int"); - - b.Property("TaxonId") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("YearCollected") - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("int") - .HasComputedColumnSql("(datepart(year,[DateTimeCollected]))", false); - - b.HasKey("Id") - .HasName("PK_dbo.Observation"); - - b.HasIndex("BasisOfRecordId") - .HasDatabaseName("IX_Observation_BasisOfRecordId"); - - b.HasIndex("CategoryId") - .HasDatabaseName("IX_Observation_CategoryId"); - - b.HasIndex("CoordinatePrecisionInMeters") - .HasDatabaseName("IX_Observation_CoordinatePrecisionInMeters"); - - b.HasIndex("DateLastModified") - .HasDatabaseName("IX_Observation_DateLastModified"); - - b.HasIndex("InstitutionCode") - .HasDatabaseName("IX_Observation_InstitutionCode"); - - b.HasIndex("InstitutionId") - .HasDatabaseName("IX_Observation_InstitutionId"); - - b.HasIndex("LocationId") - .HasDatabaseName("IX_Observation_LocationId"); - - b.HasIndex("MonthCollected") - .HasDatabaseName("IX_Observation_MonthCollected"); - - b.HasIndex("TaxonGroupId") - .HasDatabaseName("IX_Observation_TaxonGroupId"); - - b.HasIndex("YearCollected") - .HasDatabaseName("IX_Observation_YearCollected"); - - b.HasIndex("TaxonGroupId", "LocationId") - .HasDatabaseName("IX_Observation_TaxonGroupId_LocationId"); - - b.HasIndex("YearCollected", "LocationId") - .HasDatabaseName("IX_Observation_YearCollected_LocationId"); - - b.HasIndex("LocationId", "HasErrors", "HasAnnotations") - .HasDatabaseName("IX_Observation_LocationId_HasErrors_HasAnnotations"); - - b.HasIndex(new[] { "BasisOfRecordId" }, "IX_BasisOfRecordId"); - - b.HasIndex(new[] { "CatalogNumber" }, "IX_CatalogNumber"); - - b.HasIndex(new[] { "CategoryId", "DateTimeRecordImported" }, "IX_CategoryId"); - - b.HasIndex(new[] { "DateTimeCollected" }, "IX_DateTimeCollected") - .IsDescending(); - - b.HasIndex(new[] { "DateTimeRecordImported" }, "IX_DateTimeRecordImported"); - - b.HasIndex(new[] { "DatetimeIdentified" }, "IX_DatetimeIdentified"); - - b.HasIndex(new[] { "LocationId", "Id" }, "IX_LocationCatProxy"); - - b.HasIndex(new[] { "LocationId", "CategoryId" }, "IX_LocationId"); - - b.HasIndex(new[] { "MatchedScientificNameId" }, "IX_MatchedScientificName"); - - b.HasIndex(new[] { "MonthCollected" }, "IX_MonthCollected"); - - b.HasIndex(new[] { "NodeId" }, "IX_NodeId"); - - b.HasIndex(new[] { "ObservationQualityTypeId" }, "IX_ObservationQualityTypeId"); - - b.HasIndex(new[] { "CategoryId" }, "IX_Observation_CategoryId"); - - b.HasIndex(new[] { "DateLastModified" }, "IX_Observation_DateLastModified"); - - b.HasIndex(new[] { "InstitutionCode" }, "IX_Observation_InstitutionCode"); - - b.HasIndex(new[] { "InstitutionId" }, "IX_Observation_InstitutionId"); - - b.HasIndex(new[] { "LocationId" }, "IX_Observation_LocationId"); - - b.HasIndex(new[] { "LocationId", "HasErrors", "HasAnnotations" }, "IX_Observation_LocationId_HasErrors_HasAnnotations"); - - b.HasIndex(new[] { "MonthCollected" }, "IX_Observation_MonthCollected"); - - b.HasIndex(new[] { "TaxonGroupId" }, "IX_Observation_TaxonGroupId"); - - b.HasIndex(new[] { "YearCollected" }, "IX_Observation_YearCollected"); - - b.HasIndex(new[] { "YearCollected", "LocationId" }, "IX_Observation_YearCollected_LocationId"); - - b.HasIndex(new[] { "OccurrenceId" }, "IX_OccurenceId"); - - b.HasIndex(new[] { "ProxyId" }, "IX_ProxyId"); - - b.HasIndex(new[] { "TaxonId", "Id", "CoordinatePrecisionInMeters", "YearCollected" }, "IX_Rodliste"); - - b.HasIndex(new[] { "TaxonGroupId", "CategoryId" }, "IX_TaxonGroupId"); - - b.HasIndex(new[] { "TaxonGroupId", "LocationId" }, "IX_TaxonGroupIdLocationId"); - - b.HasIndex(new[] { "TaxonId", "MatchedScientificNameId" }, "IX_TaxonId"); - - b.HasIndex(new[] { "YearCollected", "MonthCollected" }, "IX_YearCollected"); - - b.HasIndex(new[] { "CoordinatePrecisionInMeters" }, "Ix_CoordPrec"); - - b.HasIndex(new[] { "TaxonGroupId" }, "TaxonGroupId"); - - b.ToTable("Observation", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationDetail", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("AssociatedReferences") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("CollectingMethod") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Collector") - .HasMaxLength(250) - .HasColumnType("nvarchar(250)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DatasetId") - .HasMaxLength(250) - .HasColumnType("nvarchar(250)"); - - b.Property("DatasetName") - .HasMaxLength(1000) - .HasColumnType("nvarchar(1000)"); - - b.Property("DateTimeCollectedStr") - .HasMaxLength(15) - .HasColumnType("nvarchar(15)"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("DynamicProperties") - .HasColumnType("nvarchar(max)"); - - b.Property("EventTime") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("FieldNumber") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("GeoreferenceRemarks") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("Habitat") - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("IdentifiedBy") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("IndividualCount") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Locality") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("MaximumElevationInMeters") - .HasColumnType("int"); - - b.Property("MeasurementMethod") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("MinimumElevationInMeters") - .HasColumnType("int"); - - b.Property("Notes") - .HasMaxLength(3500) - .HasColumnType("nvarchar(3500)"); - - b.Property("OtherCatalogNumbers") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("Preparations") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("RecordNumber") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("RelatedResourceId") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("RelationshipOfResource") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("Sex") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("TypeStatus") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("VerbatimDepth") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.HasKey("Id") - .HasName("PK_dbo.ObservationDetails"); - - b.HasIndex(new[] { "Id" }, "IX_Id"); - - b.ToTable("ObservationDetails"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationError", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("AnnotationId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DateTimeModified") - .HasColumnType("datetime"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("ErrorContext") - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("ObservationId") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("ValidationCode") - .HasColumnType("int"); - - b.HasKey("Id") - .HasName("PK_dbo.ObservationError"); - - b.HasIndex(new[] { "AnnotationId" }, "IX_AnnotationId"); - - b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); - - b.ToTable("ObservationError", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationLink", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("LinkedObservationId") - .HasColumnType("int"); - - b.Property("ObservationId") - .HasColumnType("int"); - - b.Property("Remarks") - .HasColumnType("nvarchar(max)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.ObservationLink"); - - b.HasIndex(new[] { "LinkedObservationId" }, "IX_LinkedObservationId"); - - b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); - - b.ToTable("ObservationLink", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationQualityType", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("Value") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id") - .HasName("PK_dbo.ObservationQualityType"); - - b.ToTable("ObservationQualityType", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Organization", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Code") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DateCreated") - .HasColumnType("datetime"); - - b.Property("DateModified") - .HasColumnType("datetime"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("ExternalId") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("ObservationCount") - .HasColumnType("int"); - - b.Property("OrganizationTypeId") - .HasColumnType("int"); - - b.Property("ParentId") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.Organization"); - - b.HasIndex(new[] { "ExternalId" }, "IX_ExternalId"); - - b.HasIndex(new[] { "OrganizationTypeId" }, "IX_OrganizationTypeId"); - - b.HasIndex(new[] { "ParentId" }, "IX_ParentId"); - - b.ToTable("Organization", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationRelation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("ObservationId") - .HasColumnType("int"); - - b.Property("OrganizationId") - .HasColumnType("int"); - - b.Property("RelationTypeId") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.OrganizationRelation"); - - b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); - - b.HasIndex(new[] { "OrganizationId" }, "IX_OrganizationId"); - - b.HasIndex(new[] { "RelationTypeId" }, "IX_RelationTypeId"); - - b.ToTable("OrganizationRelation", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationRelationType", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.OrganizationRelationType"); - - b.ToTable("OrganizationRelationType", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationType", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.OrganizationType"); - - b.ToTable("OrganizationType", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ProcessRecordResult", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("ErrorContext") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("NotificationCode") - .HasColumnType("int"); - - b.Property("RejectedRecordId") - .HasColumnType("int") - .HasColumnName("RejectedRecord_Id"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("ValidationCode") - .HasColumnType("int"); - - b.HasKey("Id") - .HasName("PK_dbo.ProcessRecordResult"); - - b.HasIndex(new[] { "RejectedRecordId" }, "IX_RejectedRecord_Id"); - - b.HasIndex(new[] { "NotificationCode" }, "IxNotificationCode"); - - b.HasIndex(new[] { "ValidationCode" }, "IxValidationCode"); - - b.ToTable("ProcessRecordResult", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ProcessSourceDataResult", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedRecordsCount") - .HasColumnType("int"); - - b.Property("ErrorMessage") - .HasColumnType("nvarchar(max)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("NewImportedRecordsCount") - .HasColumnType("int"); - - b.Property("ProcessedRecordsCount") - .HasColumnType("int"); - - b.Property("RejectedRecordsCount") - .HasColumnType("int"); - - b.Property("SerializedObject") - .HasColumnType("nvarchar(max)"); - - b.Property("SingleDatabaseResult") - .HasColumnType("int"); - - b.Property("SourceDataId") - .HasColumnType("int"); - - b.Property("TimeStampFinished") - .HasColumnType("datetime2"); - - b.Property("TimeStampStarted") - .HasColumnType("datetime2"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("WarningRecordsCount") - .HasColumnType("int"); - - b.HasKey("Id") - .HasName("PK_dbo.ProcessSourceDataResult"); - - b.ToTable("ProcessSourceDataResult", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ProsessEngineHistory", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("PublishDate") - .HasColumnType("datetime"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.ProsessEngineHistory"); - - b.ToTable("ProsessEngineHistory", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.RecordNotificationType", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("Deleted") - .HasColumnType("bit"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("Value") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id") - .HasName("PK_dbo.RecordNotificationType"); - - b.ToTable("RecordNotificationType", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.RecordValidationType", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("Deleted") - .HasColumnType("bit"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("Value") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.HasKey("Id") - .HasName("PK_dbo.RecordValidationType"); - - b.ToTable("RecordValidationType", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.RejectedRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CollectionCode") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DatetimeRecordProsessed") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Gid") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("InstitutionCode") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("RecordId") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("SourceDataId") - .HasColumnType("int"); - - b.Property("TentativId") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.RejectedRecord"); - - b.HasIndex(new[] { "RecordId" }, "IX_RecordId"); - - b.HasIndex(new[] { "Gid" }, "Ix_Gid"); - - b.HasIndex(new[] { "InstitutionCode", "CollectionCode" }, "Ix_InstitutionCode"); - - b.HasIndex(new[] { "SourceDataId", "DatetimeRecordProsessed" }, "Ix_SourceDataId") - .IsDescending(false, true); - - b.HasIndex(new[] { "RecordId" }, "NonClusteredIndex-20171028-195228"); - - b.ToTable("RejectedRecord", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.SensitiveObservationDatum", b => - { - b.Property("ObservationId") - .HasColumnType("int"); - - b.Property("CoordinatePrecisionInMeters") - .HasColumnType("int"); - - b.Property("DateTimeCollected") - .HasColumnType("datetime2"); - - b.Property("East") - .HasColumnType("int"); - - b.Property("Latitude") - .HasColumnType("float"); - - b.Property("Locality") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Longitude") - .HasColumnType("float"); - - b.Property("North") - .HasColumnType("int"); - - b.Property("Notes") - .HasMaxLength(3500) - .HasColumnType("nvarchar(3500)"); - - b.HasKey("ObservationId") - .HasName("PK_dbo.SensitiveObservationData"); - - b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); - - b.ToTable("SensitiveObservationData"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.SpatialRefSy", b => - { - b.Property("Srid") - .HasColumnType("int") - .HasColumnName("srid"); - - b.Property("AuthName") - .HasMaxLength(256) - .IsUnicode(false) - .HasColumnType("varchar(256)") - .HasColumnName("auth_name"); - - b.Property("AuthSrid") - .HasColumnType("int") - .HasColumnName("auth_srid"); - - b.Property("Proj4text") - .HasMaxLength(2048) - .IsUnicode(false) - .HasColumnType("varchar(2048)") - .HasColumnName("proj4text"); - - b.Property("Srtext") - .HasMaxLength(2048) - .IsUnicode(false) - .HasColumnType("varchar(2048)") - .HasColumnName("srtext"); - - b.HasKey("Srid") - .HasName("PK__spatial___36B11BD5A2397CD6"); - - b.ToTable("spatial_ref_sys", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Tag", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("ObservationCount") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.Tag"); - - b.ToTable("Tag", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Taxon", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CumulativeObservationCount") - .HasColumnType("int"); - - b.Property("DailyCumulativeObservationCount") - .HasColumnType("int"); - - b.Property("DailyObservationCount") - .HasColumnType("int"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("ExistsInCountry") - .HasColumnType("bit"); - - b.Property("ExternalTaxonId") - .HasColumnType("int") - .HasColumnName("TaxonId"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("ObservationCount") - .HasColumnType("int"); - - b.Property("ParentTaxonId") - .HasColumnType("int"); - - b.Property("PreferredPopularName") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)") - .HasColumnName("PrefferedPopularname"); - - b.Property("ScientificNameIdHiarchy") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("TaxonGroupId") - .HasColumnType("int"); - - b.Property("TaxonIdHiarchy") - .IsRequired() - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("TaxonRankId") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime") - .HasColumnName("DateTimeUpdated"); - - b.Property("ValidScientificName") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("ValidScientificNameAuthorship") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("ValidScientificNameId") - .HasColumnType("int"); - - b.Property("WeeklyCumulativeObservationCount") - .HasColumnType("int"); - - b.Property("WeeklyObservationCount") - .HasColumnType("int"); - - b.HasKey("Id") - .HasName("PK_dbo.Taxon"); - - b.HasIndex(new[] { "PreferredPopularName" }, "IX_PrefferedPopularname"); - - b.HasIndex(new[] { "TaxonGroupId" }, "IX_TaxonGroupId"); - - b.HasIndex(new[] { "TaxonRankId" }, "IX_TaxonRankId"); - - b.HasIndex(new[] { "TaxonRankId", "TaxonIdHiarchy" }, "IX_TaxonRank_TaxonHirachy"); - - b.HasIndex(new[] { "ValidScientificName" }, "IX_ValidScientificName"); - - b.HasIndex(new[] { "ParentTaxonId" }, "IxParentTaxonId"); - - b.HasIndex(new[] { "ParentTaxonId" }, "IxParentTaxonId_Id_ObsCount"); - - b.HasIndex(new[] { "PreferredPopularName" }, "NonClusteredIndex-20190129-153041"); - - b.ToTable("Taxon", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonGroup", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit") - .HasColumnName("Deleted"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(75) - .HasColumnType("nvarchar(75)"); - - b.Property("ObservationCount") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.TaxonGroup"); - - b.ToTable("TaxonGroup", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonName", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("Accepted") - .HasColumnType("bit"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("ScientificName") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("ScientificNameAuthorship") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("TaxonId") - .HasColumnType("int") - .HasColumnName("Taxon_Id"); - - b.Property("UpdatedAt") - .HasColumnType("datetime") - .HasColumnName("DateTimeUpdated"); - - b.HasKey("Id") - .HasName("PK_dbo.TaxonName"); - - b.HasIndex(new[] { "ScientificName" }, "IX_ScientificName"); - - b.HasIndex(new[] { "TaxonId" }, "IX_Taxon_Id"); - - b.ToTable("TaxonName", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonPopularName", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Language") - .IsRequired() - .HasMaxLength(10) - .HasColumnType("nvarchar(10)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Preferred") - .HasColumnType("bit") - .HasColumnName("Preffered"); - - b.Property("SourceId") - .HasColumnType("int"); - - b.Property("TaxonId") - .HasColumnType("int") - .HasColumnName("Taxon_Id"); - - b.Property("UpdatedAt") - .HasColumnType("datetime") - .HasColumnName("DateTimeUpdated"); - - b.HasKey("Id") - .HasName("PK_dbo.TaxonPopularName"); - - b.HasIndex(new[] { "TaxonId" }, "IX_Taxon_Id"); - - b.ToTable("TaxonPopularName", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonProperty", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Context") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Prefix") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("ScientificName") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Tag") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("TagGroup") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("TaxonId") - .HasColumnType("int") - .HasColumnName("Taxon_Id"); - - b.Property("UpdatedAt") - .HasColumnType("datetime") - .HasColumnName("DateTimeUpdated"); - - b.Property("Url") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.HasKey("Id") - .HasName("PK_dbo.TaxonProperty"); - - b.HasIndex(new[] { "TaxonId" }, "IX_Taxon_Id"); - - b.ToTable("TaxonProperty", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonRank", b => - { - b.Property("Id") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(25) - .HasColumnType("nvarchar(25)"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.TaxonRank"); - - b.ToTable("TaxonRank", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonomyState", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("LastEventProcessedTimeStamp") - .HasColumnType("datetime"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("Id") - .HasName("PK_dbo.TaxonomyState"); - - b.ToTable("TaxonomyState", (string)null); - }); - - modelBuilder.Entity("LocationArea", b => - { - b.Property("LocationId") - .HasColumnType("int"); - - b.Property("AreaId") - .HasColumnType("int"); - - b.HasKey("LocationId", "AreaId") - .HasName("PK_dbo.LocationAreas"); - - b.HasIndex(new[] { "AreaId" }, "IX_AreaId"); - - b.HasIndex(new[] { "LocationId" }, "IX_LocationId"); - - b.HasIndex(new[] { "LocationId", "AreaId" }, "IX_LocationIdArea"); - - b.ToTable("LocationAreas", (string)null); - }); - - modelBuilder.Entity("ObservationBehavior", b => - { - b.Property("ObservationId") - .HasColumnType("int"); - - b.Property("BehaviorId") - .HasColumnType("int"); - - b.HasKey("ObservationId", "BehaviorId") - .HasName("PK_dbo.ObservationBehaviors"); - - b.HasIndex(new[] { "BehaviorId" }, "IX_BehaviorId"); - - b.ToTable("ObservationBehaviors", (string)null); - }); - - modelBuilder.Entity("ObservationTag", b => - { - b.Property("ObservationId") - .HasColumnType("int"); - - b.Property("TagId") - .HasColumnType("int"); - - b.HasKey("ObservationId", "TagId") - .HasName("PK_dbo.ObservationTags"); - - b.HasIndex(new[] { "ObservationId" }, "IX_ObservationId"); - - b.HasIndex(new[] { "TagId" }, "IX_TagId"); - - b.HasIndex(new[] { "TagId", "ObservationId" }, "IX_TagIdObsId"); - - b.ToTable("ObservationTags", (string)null); - }); - - modelBuilder.Entity("ObservationTaxon", b => - { - b.Property("ObservationId") - .HasColumnType("int"); - - b.Property("TaxonId") - .HasColumnType("int"); - - b.HasKey("ObservationId", "TaxonId") - .HasName("PK_dbo.ObservationTaxons"); - - b.HasIndex(new[] { "TaxonId", "ObservationId" }, "IX_TaxonId"); - - b.ToTable("ObservationTaxons", (string)null); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Area", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.AreaType", "AreaType") - .WithMany("Areas") - .HasForeignKey("AreaTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.Area_dbo.AreaType_AreaTypeID"); - - b.Navigation("AreaType"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Category", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.CategoryType", "CategoryType") - .WithMany("Categories") - .HasForeignKey("CategoryTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.Category_dbo.CategoryType_CategoryTypeId"); - - b.Navigation("CategoryType"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFile", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.MediaFileType", "MediaFileType") - .WithMany("MediaFiles") - .HasForeignKey("MediaFileTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.MediaFile_dbo.MediaFileType_MediaFileTypeId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") - .WithMany("MediaFiles") - .HasForeignKey("ObservationId") - .HasConstraintName("FK_dbo.MediaFile_dbo.Observation_Observation_Id"); - - b.Navigation("MediaFileType"); - - b.Navigation("Observation"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Observation", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.BasisOfRecord", "BasisOfRecord") - .WithMany("Observations") - .HasForeignKey("BasisOfRecordId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.Observation_dbo.BasisOfRecord_BasisOfRecordId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Category", "Category") - .WithMany("Observations") - .HasForeignKey("CategoryId") - .HasConstraintName("FK_dbo.Observation_dbo.Category_CategoryId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Location", "Location") - .WithMany("Observations") - .HasForeignKey("LocationId") - .HasConstraintName("FK_dbo.Observation_dbo.Location_LocationId"); - - b.HasOne("Artskart3.Core.Domain.Entities.TaxonName", "MatchedScientificName") - .WithMany("Observations") - .HasForeignKey("MatchedScientificNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.Observation_dbo.TaxonName_MatchedScientificNameId"); - - b.HasOne("Artskart3.Core.Domain.Entities.ObservationQualityType", "ObservationQualityType") - .WithMany("Observations") - .HasForeignKey("ObservationQualityTypeId") - .HasConstraintName("FK_dbo.Observation_dbo.ObservationQualityType_ObservationQualityTypeId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Taxon", "Taxon") - .WithMany("Observations") - .HasForeignKey("TaxonId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.Observation_dbo.Taxon_TaxonId"); - - b.Navigation("BasisOfRecord"); - - b.Navigation("Category"); - - b.Navigation("Location"); - - b.Navigation("MatchedScientificName"); - - b.Navigation("ObservationQualityType"); - - b.Navigation("Taxon"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationDetail", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Observation", "IdNavigation") - .WithOne("ObservationDetail") - .HasForeignKey("Artskart3.Core.Domain.Entities.ObservationDetail", "Id") - .IsRequired() - .HasConstraintName("FK_dbo.ObservationDetails_dbo.Observation_Id"); - - b.Navigation("IdNavigation"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationError", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") - .WithMany("ObservationErrors") - .HasForeignKey("ObservationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.ObservationError_dbo.Observation_ObservationId"); - - b.Navigation("Observation"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationLink", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Observation", "LinkedObservation") - .WithMany("ObservationLinkLinkedObservations") - .HasForeignKey("LinkedObservationId") - .HasConstraintName("FK_dbo.ObservationLink_dbo.Observation_LinkedObservationId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") - .WithMany("ObservationLinkObservations") - .HasForeignKey("ObservationId") - .IsRequired() - .HasConstraintName("FK_dbo.ObservationLink_dbo.Observation_ObservationId"); - - b.Navigation("LinkedObservation"); - - b.Navigation("Observation"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Organization", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.OrganizationType", "OrganizationType") - .WithMany("Organizations") - .HasForeignKey("OrganizationTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.Organization_dbo.OrganizationType_OrganizationTypeId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Organization", "Parent") - .WithMany("InverseParent") - .HasForeignKey("ParentId") - .HasConstraintName("FK_dbo.Organization_dbo.Organization_ParentId"); - - b.Navigation("OrganizationType"); - - b.Navigation("Parent"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationRelation", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") - .WithMany("OrganizationRelations") - .HasForeignKey("ObservationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.OrganizationRelation_dbo.Observation_ObservationId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Organization", "Organization") - .WithMany("OrganizationRelations") - .HasForeignKey("OrganizationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.OrganizationRelation_dbo.Organization_OrganizationId"); - - b.HasOne("Artskart3.Core.Domain.Entities.OrganizationRelationType", "RelationType") - .WithMany("OrganizationRelations") - .HasForeignKey("RelationTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.OrganizationRelation_dbo.OrganizationRelationType_RelationTypeId"); - - b.Navigation("Observation"); - - b.Navigation("Organization"); - - b.Navigation("RelationType"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ProcessRecordResult", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.RejectedRecord", "RejectedRecord") - .WithMany("ProcessRecordResults") - .HasForeignKey("RejectedRecordId") - .HasConstraintName("FK_dbo.ProcessRecordResult_dbo.RejectedRecord_RejectedRecord_Id"); - - b.Navigation("RejectedRecord"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.SensitiveObservationDatum", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Observation", "Observation") - .WithOne("SensitiveObservationDatum") - .HasForeignKey("Artskart3.Core.Domain.Entities.SensitiveObservationDatum", "ObservationId") - .IsRequired() - .HasConstraintName("FK_dbo.SensitiveObservationData_dbo.Observation_ObservationId"); - - b.Navigation("Observation"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Taxon", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.TaxonGroup", "TaxonGroup") - .WithMany("Taxons") - .HasForeignKey("TaxonGroupId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.Taxon_dbo.TaxonGroup_TaxonGroupId"); - - b.HasOne("Artskart3.Core.Domain.Entities.TaxonRank", "TaxonRank") - .WithMany("Taxons") - .HasForeignKey("TaxonRankId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.Taxon_dbo.TaxonRank_TaxonRankId"); - - b.Navigation("TaxonGroup"); - - b.Navigation("TaxonRank"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonName", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Taxon", "Taxon") - .WithMany("TaxonNames") - .HasForeignKey("TaxonId") - .HasConstraintName("FK_dbo.TaxonName_dbo.Taxon_Taxon_Id"); - - b.Navigation("Taxon"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonPopularName", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Taxon", "Taxon") - .WithMany("TaxonPopularNames") - .HasForeignKey("TaxonId") - .HasConstraintName("FK_dbo.TaxonPopularName_dbo.Taxon_Taxon_Id"); - - b.Navigation("Taxon"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonProperty", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Taxon", "Taxon") - .WithMany("TaxonProperties") - .HasForeignKey("TaxonId") - .HasConstraintName("FK_dbo.TaxonProperty_dbo.Taxon_Taxon_Id"); - - b.Navigation("Taxon"); - }); - - modelBuilder.Entity("LocationArea", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Area", null) - .WithMany() - .HasForeignKey("AreaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.LocationAreas_dbo.Area_AreaId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Location", null) - .WithMany() - .HasForeignKey("LocationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.LocationAreas_dbo.Location_LocationId"); - }); - - modelBuilder.Entity("ObservationBehavior", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Behavior", null) - .WithMany() - .HasForeignKey("BehaviorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.ObservationBehaviors_dbo.Behavior_BehaviorId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Observation", null) - .WithMany() - .HasForeignKey("ObservationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.ObservationBehaviors_dbo.Observation_ObservationId"); - }); - - modelBuilder.Entity("ObservationTag", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Observation", null) - .WithMany() - .HasForeignKey("ObservationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.ObservationTags_dbo.Observation_ObservationId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Tag", null) - .WithMany() - .HasForeignKey("TagId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.ObservationTags_dbo.Tag_TagId"); - }); - - modelBuilder.Entity("ObservationTaxon", b => - { - b.HasOne("Artskart3.Core.Domain.Entities.Observation", null) - .WithMany() - .HasForeignKey("ObservationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired() - .HasConstraintName("FK_dbo.ObservationTaxons_dbo.Observation_ObservationId"); - - b.HasOne("Artskart3.Core.Domain.Entities.Taxon", null) - .WithMany() - .HasForeignKey("TaxonId") - .IsRequired() - .HasConstraintName("FK_dbo.ObservationTaxons_dbo.Taxon_TaxonId"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.AreaType", b => - { - b.Navigation("Areas"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.BasisOfRecord", b => - { - b.Navigation("Observations"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Category", b => - { - b.Navigation("Observations"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.CategoryType", b => - { - b.Navigation("Categories"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Location", b => - { - b.Navigation("Observations"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.MediaFileType", b => - { - b.Navigation("MediaFiles"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Observation", b => - { - b.Navigation("MediaFiles"); - - b.Navigation("ObservationDetail"); - - b.Navigation("ObservationErrors"); - - b.Navigation("ObservationLinkLinkedObservations"); - - b.Navigation("ObservationLinkObservations"); - - b.Navigation("OrganizationRelations"); - - b.Navigation("SensitiveObservationDatum"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.ObservationQualityType", b => - { - b.Navigation("Observations"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Organization", b => - { - b.Navigation("InverseParent"); - - b.Navigation("OrganizationRelations"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationRelationType", b => - { - b.Navigation("OrganizationRelations"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.OrganizationType", b => - { - b.Navigation("Organizations"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.RejectedRecord", b => - { - b.Navigation("ProcessRecordResults"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.Taxon", b => - { - b.Navigation("Observations"); - - b.Navigation("TaxonNames"); - - b.Navigation("TaxonPopularNames"); - - b.Navigation("TaxonProperties"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonGroup", b => - { - b.Navigation("Taxons"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonName", b => - { - b.Navigation("Observations"); - }); - - modelBuilder.Entity("Artskart3.Core.Domain.Entities.TaxonRank", b => - { - b.Navigation("Taxons"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Artskart3.Infrastructure/Migrations/ArtskartDbContextModelSnapshot.cs b/Artskart3.Infrastructure/Migrations/ArtskartDbContextModelSnapshot.cs index 4fd97dd6..202381f8 100644 --- a/Artskart3.Infrastructure/Migrations/ArtskartDbContextModelSnapshot.cs +++ b/Artskart3.Infrastructure/Migrations/ArtskartDbContextModelSnapshot.cs @@ -374,91 +374,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("CommandLog", (string)null); }); - modelBuilder.Entity("Artskart3.Core.Domain.Entities.DataSource", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ArchiveName") - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("Doi") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("GbifApiQuery") - .HasColumnType("nvarchar(max)"); - - b.Property("GbifPublisherId") - .HasColumnType("uniqueidentifier"); - - b.Property("HarvestPropertyOverrides") - .HasColumnType("nvarchar(max)"); - - b.Property("ImportPropertyOverrides") - .HasColumnType("nvarchar(max)"); - - b.Property("IsDeleted") - .HasColumnType("bit"); - - b.Property("IsEditedNameOrNotes") - .HasColumnType("bit"); - - b.Property("IsSensitive") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("NonValidOccurrenceIds") - .HasColumnType("bit"); - - b.Property("Notes") - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("ProviderType") - .HasColumnType("int"); - - b.Property("RecordsBatchSize") - .HasColumnType("int"); - - b.Property("RemoteAddress") - .HasMaxLength(1000) - .HasColumnType("nvarchar(1000)"); - - b.Property("UpdateFrequencyInDays") - .HasColumnType("int"); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.Property("WebServiceVersion") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("IsDeleted") - .HasDatabaseName("IX_DataSource_IsDeleted"); - - b.HasIndex("ProviderType") - .HasDatabaseName("IX_DataSource_ProviderType"); - - b.ToTable("DataSource", (string)null); - }); - modelBuilder.Entity("Artskart3.Core.Domain.Entities.DeletedItem", b => { b.Property("Id") @@ -1264,45 +1179,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id") .HasName("PK_dbo.Observation"); - b.HasIndex("BasisOfRecordId") - .HasDatabaseName("IX_Observation_BasisOfRecordId"); - - b.HasIndex("CategoryId") - .HasDatabaseName("IX_Observation_CategoryId"); - - b.HasIndex("CoordinatePrecisionInMeters") - .HasDatabaseName("IX_Observation_CoordinatePrecisionInMeters"); - - b.HasIndex("DateLastModified") - .HasDatabaseName("IX_Observation_DateLastModified"); - - b.HasIndex("InstitutionCode") - .HasDatabaseName("IX_Observation_InstitutionCode"); - - b.HasIndex("InstitutionId") - .HasDatabaseName("IX_Observation_InstitutionId"); - - b.HasIndex("LocationId") - .HasDatabaseName("IX_Observation_LocationId"); - - b.HasIndex("MonthCollected") - .HasDatabaseName("IX_Observation_MonthCollected"); - - b.HasIndex("TaxonGroupId") - .HasDatabaseName("IX_Observation_TaxonGroupId"); - - b.HasIndex("YearCollected") - .HasDatabaseName("IX_Observation_YearCollected"); - - b.HasIndex("TaxonGroupId", "LocationId") - .HasDatabaseName("IX_Observation_TaxonGroupId_LocationId"); - - b.HasIndex("YearCollected", "LocationId") - .HasDatabaseName("IX_Observation_YearCollected_LocationId"); - - b.HasIndex("LocationId", "HasErrors", "HasAnnotations") - .HasDatabaseName("IX_Observation_LocationId_HasErrors_HasAnnotations"); - b.HasIndex(new[] { "BasisOfRecordId" }, "IX_BasisOfRecordId"); b.HasIndex(new[] { "CatalogNumber" }, "IX_CatalogNumber"); diff --git a/Artskart3.slnx b/Artskart3.slnx index 863b3919..f495a190 100644 --- a/Artskart3.slnx +++ b/Artskart3.slnx @@ -6,4 +6,5 @@ + From 82b233135fe4dd8b489c4d94bf3d42ad1fa3c0ec Mon Sep 17 00:00:00 2001 From: bo Date: Thu, 30 Apr 2026 14:48:51 +0200 Subject: [PATCH 3/7] Refactor import layer into Clean Architecture split (Import.Core + Import.Infrastructure) --- Artskart3.Api/Artskart3.Api.csproj | 2 +- .../Artskart3.Import.Core.csproj | 9 +++ .../Domain/Entities/DataSource.cs | 4 +- .../Domain/Enums/ProviderType.cs | 2 +- .../IDataSourceRepository.cs | 12 ++++ .../Artskart3.Import.Infrastructure.csproj | 5 ++ .../Data/ArtskartImportDbContext.cs | 6 +- .../Data/ArtskartImportDbContextFactory.cs | 2 +- .../DataSourceConfiguration.cs | 4 +- .../ImportServiceCollectionExtensions.cs | 22 +++++++ ...30124749_InitialImportBaseline.Designer.cs | 8 +-- .../20260430124749_InitialImportBaseline.cs | 2 +- .../ArtskartImportDbContextModelSnapshot.cs | 6 +- .../Repositories/DataSourceRepository.cs | 57 +++++++++++++++++++ Artskart3.slnx | 3 +- 15 files changed, 125 insertions(+), 19 deletions(-) create mode 100644 Artskart3.Import.Core/Artskart3.Import.Core.csproj rename {Artskart3.Import => Artskart3.Import.Core}/Domain/Entities/DataSource.cs (97%) rename {Artskart3.Import => Artskart3.Import.Core}/Domain/Enums/ProviderType.cs (74%) create mode 100644 Artskart3.Import.Core/Domain/RepositoryInterfaces/IDataSourceRepository.cs rename Artskart3.Import/Artskart3.Import.csproj => Artskart3.Import.Infrastructure/Artskart3.Import.Infrastructure.csproj (82%) rename {Artskart3.Import => Artskart3.Import.Infrastructure}/Data/ArtskartImportDbContext.cs (77%) rename {Artskart3.Import => Artskart3.Import.Infrastructure}/Data/ArtskartImportDbContextFactory.cs (96%) rename {Artskart3.Import => Artskart3.Import.Infrastructure}/Data/EntityConfigurations/DataSourceConfiguration.cs (92%) create mode 100644 Artskart3.Import.Infrastructure/DependencyInjection/ImportServiceCollectionExtensions.cs rename Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.Designer.cs => Artskart3.Import.Infrastructure/Migrations/20260430124749_InitialImportBaseline.Designer.cs (94%) rename Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.cs => Artskart3.Import.Infrastructure/Migrations/20260430124749_InitialImportBaseline.cs (98%) rename {Artskart3.Import => Artskart3.Import.Infrastructure}/Migrations/ArtskartImportDbContextModelSnapshot.cs (95%) create mode 100644 Artskart3.Import.Infrastructure/Persistence/Repositories/DataSourceRepository.cs diff --git a/Artskart3.Api/Artskart3.Api.csproj b/Artskart3.Api/Artskart3.Api.csproj index e98afc16..87e574e5 100644 --- a/Artskart3.Api/Artskart3.Api.csproj +++ b/Artskart3.Api/Artskart3.Api.csproj @@ -30,7 +30,7 @@ - + diff --git a/Artskart3.Import.Core/Artskart3.Import.Core.csproj b/Artskart3.Import.Core/Artskart3.Import.Core.csproj new file mode 100644 index 00000000..9ed914b5 --- /dev/null +++ b/Artskart3.Import.Core/Artskart3.Import.Core.csproj @@ -0,0 +1,9 @@ + + + + net10.0 + enable + enable + + + diff --git a/Artskart3.Import/Domain/Entities/DataSource.cs b/Artskart3.Import.Core/Domain/Entities/DataSource.cs similarity index 97% rename from Artskart3.Import/Domain/Entities/DataSource.cs rename to Artskart3.Import.Core/Domain/Entities/DataSource.cs index 487244c6..ec7be23b 100644 --- a/Artskart3.Import/Domain/Entities/DataSource.cs +++ b/Artskart3.Import.Core/Domain/Entities/DataSource.cs @@ -1,6 +1,6 @@ -using Artskart3.Import.Domain.Enums; +using Artskart3.Import.Core.Domain.Enums; -namespace Artskart3.Import.Domain.Entities; +namespace Artskart3.Import.Core.Domain.Entities; /// /// Provider configuration for a remote data source (formerly SourceDataBase in RavenDB). diff --git a/Artskart3.Import/Domain/Enums/ProviderType.cs b/Artskart3.Import.Core/Domain/Enums/ProviderType.cs similarity index 74% rename from Artskart3.Import/Domain/Enums/ProviderType.cs rename to Artskart3.Import.Core/Domain/Enums/ProviderType.cs index 9f45f118..ad1516b0 100644 --- a/Artskart3.Import/Domain/Enums/ProviderType.cs +++ b/Artskart3.Import.Core/Domain/Enums/ProviderType.cs @@ -1,4 +1,4 @@ -namespace Artskart3.Import.Domain.Enums; +namespace Artskart3.Import.Core.Domain.Enums; public enum ProviderType { diff --git a/Artskart3.Import.Core/Domain/RepositoryInterfaces/IDataSourceRepository.cs b/Artskart3.Import.Core/Domain/RepositoryInterfaces/IDataSourceRepository.cs new file mode 100644 index 00000000..82e0be80 --- /dev/null +++ b/Artskart3.Import.Core/Domain/RepositoryInterfaces/IDataSourceRepository.cs @@ -0,0 +1,12 @@ +using Artskart3.Import.Core.Domain.Entities; + +namespace Artskart3.Import.Core.Domain.RepositoryInterfaces; + +public interface IDataSourceRepository +{ + Task> GetAllAsync(CancellationToken cancellationToken = default); + Task GetByIdAsync(int id, CancellationToken cancellationToken = default); + Task AddAsync(DataSource dataSource, CancellationToken cancellationToken = default); + Task UpdateAsync(DataSource dataSource, CancellationToken cancellationToken = default); + Task DeleteAsync(int id, CancellationToken cancellationToken = default); +} diff --git a/Artskart3.Import/Artskart3.Import.csproj b/Artskart3.Import.Infrastructure/Artskart3.Import.Infrastructure.csproj similarity index 82% rename from Artskart3.Import/Artskart3.Import.csproj rename to Artskart3.Import.Infrastructure/Artskart3.Import.Infrastructure.csproj index f04c3b52..31beb36e 100644 --- a/Artskart3.Import/Artskart3.Import.csproj +++ b/Artskart3.Import.Infrastructure/Artskart3.Import.Infrastructure.csproj @@ -6,6 +6,10 @@ enable + + + + @@ -19,6 +23,7 @@ + diff --git a/Artskart3.Import/Data/ArtskartImportDbContext.cs b/Artskart3.Import.Infrastructure/Data/ArtskartImportDbContext.cs similarity index 77% rename from Artskart3.Import/Data/ArtskartImportDbContext.cs rename to Artskart3.Import.Infrastructure/Data/ArtskartImportDbContext.cs index b8e11574..d809b88e 100644 --- a/Artskart3.Import/Data/ArtskartImportDbContext.cs +++ b/Artskart3.Import.Infrastructure/Data/ArtskartImportDbContext.cs @@ -1,8 +1,8 @@ -using Artskart3.Import.Data.EntityConfigurations; -using Artskart3.Import.Domain.Entities; +using Artskart3.Import.Core.Domain.Entities; +using Artskart3.Import.Infrastructure.Data.EntityConfigurations; using Microsoft.EntityFrameworkCore; -namespace Artskart3.Import.Data; +namespace Artskart3.Import.Infrastructure.Data; public class ArtskartImportDbContext : DbContext { diff --git a/Artskart3.Import/Data/ArtskartImportDbContextFactory.cs b/Artskart3.Import.Infrastructure/Data/ArtskartImportDbContextFactory.cs similarity index 96% rename from Artskart3.Import/Data/ArtskartImportDbContextFactory.cs rename to Artskart3.Import.Infrastructure/Data/ArtskartImportDbContextFactory.cs index 302ec9c5..caa622b4 100644 --- a/Artskart3.Import/Data/ArtskartImportDbContextFactory.cs +++ b/Artskart3.Import.Infrastructure/Data/ArtskartImportDbContextFactory.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Design; using Microsoft.Extensions.Configuration; -namespace Artskart3.Import.Data; +namespace Artskart3.Import.Infrastructure.Data; /// /// Used by EF Core tooling (dotnet ef migrations add, dotnet ef database update) at design time. diff --git a/Artskart3.Import/Data/EntityConfigurations/DataSourceConfiguration.cs b/Artskart3.Import.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs similarity index 92% rename from Artskart3.Import/Data/EntityConfigurations/DataSourceConfiguration.cs rename to Artskart3.Import.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs index 9439a011..f61298df 100644 --- a/Artskart3.Import/Data/EntityConfigurations/DataSourceConfiguration.cs +++ b/Artskart3.Import.Infrastructure/Data/EntityConfigurations/DataSourceConfiguration.cs @@ -1,8 +1,8 @@ -using Artskart3.Import.Domain.Entities; +using Artskart3.Import.Core.Domain.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -namespace Artskart3.Import.Data.EntityConfigurations; +namespace Artskart3.Import.Infrastructure.Data.EntityConfigurations; public class DataSourceConfiguration : IEntityTypeConfiguration { diff --git a/Artskart3.Import.Infrastructure/DependencyInjection/ImportServiceCollectionExtensions.cs b/Artskart3.Import.Infrastructure/DependencyInjection/ImportServiceCollectionExtensions.cs new file mode 100644 index 00000000..6d18a8aa --- /dev/null +++ b/Artskart3.Import.Infrastructure/DependencyInjection/ImportServiceCollectionExtensions.cs @@ -0,0 +1,22 @@ +using Artskart3.Import.Core.Domain.RepositoryInterfaces; +using Artskart3.Import.Infrastructure.Data; +using Artskart3.Import.Infrastructure.Persistence.Repositories; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; + +namespace Artskart3.Import.Infrastructure.DependencyInjection; + +public static class ImportServiceCollectionExtensions +{ + public static IServiceCollection AddImportInfrastructure( + this IServiceCollection services, + string connectionString) + { + services.AddDbContext(options => + options.UseSqlServer(connectionString)); + + services.AddScoped(); + + return services; + } +} diff --git a/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.Designer.cs b/Artskart3.Import.Infrastructure/Migrations/20260430124749_InitialImportBaseline.Designer.cs similarity index 94% rename from Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.Designer.cs rename to Artskart3.Import.Infrastructure/Migrations/20260430124749_InitialImportBaseline.Designer.cs index 5aec8b47..971a921d 100644 --- a/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.Designer.cs +++ b/Artskart3.Import.Infrastructure/Migrations/20260430124749_InitialImportBaseline.Designer.cs @@ -1,6 +1,6 @@ // using System; -using Artskart3.Import.Data; +using Artskart3.Import.Infrastructure.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; @@ -9,10 +9,10 @@ #nullable disable -namespace Artskart3.Import.Migrations +namespace Artskart3.Import.Infrastructure.Migrations { [DbContext(typeof(ArtskartImportDbContext))] - [Migration("20260430123211_InitialImportBaseline")] + [Migration("20260430124749_InitialImportBaseline")] partial class InitialImportBaseline { /// @@ -25,7 +25,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - modelBuilder.Entity("Artskart3.Import.Domain.Entities.DataSource", b => + modelBuilder.Entity("Artskart3.Import.Core.Domain.Entities.DataSource", b => { b.Property("Id") .ValueGeneratedOnAdd() diff --git a/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.cs b/Artskart3.Import.Infrastructure/Migrations/20260430124749_InitialImportBaseline.cs similarity index 98% rename from Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.cs rename to Artskart3.Import.Infrastructure/Migrations/20260430124749_InitialImportBaseline.cs index 6ea9285c..2c019ee3 100644 --- a/Artskart3.Import/Migrations/20260430123211_InitialImportBaseline.cs +++ b/Artskart3.Import.Infrastructure/Migrations/20260430124749_InitialImportBaseline.cs @@ -3,7 +3,7 @@ #nullable disable -namespace Artskart3.Import.Migrations +namespace Artskart3.Import.Infrastructure.Migrations { /// public partial class InitialImportBaseline : Migration diff --git a/Artskart3.Import/Migrations/ArtskartImportDbContextModelSnapshot.cs b/Artskart3.Import.Infrastructure/Migrations/ArtskartImportDbContextModelSnapshot.cs similarity index 95% rename from Artskart3.Import/Migrations/ArtskartImportDbContextModelSnapshot.cs rename to Artskart3.Import.Infrastructure/Migrations/ArtskartImportDbContextModelSnapshot.cs index 81e67999..ad072080 100644 --- a/Artskart3.Import/Migrations/ArtskartImportDbContextModelSnapshot.cs +++ b/Artskart3.Import.Infrastructure/Migrations/ArtskartImportDbContextModelSnapshot.cs @@ -1,6 +1,6 @@ // using System; -using Artskart3.Import.Data; +using Artskart3.Import.Infrastructure.Data; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; @@ -8,7 +8,7 @@ #nullable disable -namespace Artskart3.Import.Migrations +namespace Artskart3.Import.Infrastructure.Migrations { [DbContext(typeof(ArtskartImportDbContext))] partial class ArtskartImportDbContextModelSnapshot : ModelSnapshot @@ -22,7 +22,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - modelBuilder.Entity("Artskart3.Import.Domain.Entities.DataSource", b => + modelBuilder.Entity("Artskart3.Import.Core.Domain.Entities.DataSource", b => { b.Property("Id") .ValueGeneratedOnAdd() diff --git a/Artskart3.Import.Infrastructure/Persistence/Repositories/DataSourceRepository.cs b/Artskart3.Import.Infrastructure/Persistence/Repositories/DataSourceRepository.cs new file mode 100644 index 00000000..ecdb0900 --- /dev/null +++ b/Artskart3.Import.Infrastructure/Persistence/Repositories/DataSourceRepository.cs @@ -0,0 +1,57 @@ +using Artskart3.Import.Core.Domain.Entities; +using Artskart3.Import.Core.Domain.RepositoryInterfaces; +using Artskart3.Import.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; + +namespace Artskart3.Import.Infrastructure.Persistence.Repositories; + +public class DataSourceRepository : IDataSourceRepository +{ + private readonly ArtskartImportDbContext _context; + + public DataSourceRepository(ArtskartImportDbContext context) + { + _context = context; + } + + public async Task> GetAllAsync(CancellationToken cancellationToken = default) + { + return await _context.DataSources + .Where(d => !d.IsDeleted) + .OrderBy(d => d.Name) + .ToListAsync(cancellationToken); + } + + public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default) + { + return await _context.DataSources + .FirstOrDefaultAsync(d => d.Id == id, cancellationToken); + } + + public async Task AddAsync(DataSource dataSource, CancellationToken cancellationToken = default) + { + dataSource.CreatedAt = DateTime.UtcNow; + dataSource.UpdatedAt = DateTime.UtcNow; + _context.DataSources.Add(dataSource); + await _context.SaveChangesAsync(cancellationToken); + return dataSource; + } + + public async Task UpdateAsync(DataSource dataSource, CancellationToken cancellationToken = default) + { + dataSource.UpdatedAt = DateTime.UtcNow; + _context.DataSources.Update(dataSource); + await _context.SaveChangesAsync(cancellationToken); + } + + public async Task DeleteAsync(int id, CancellationToken cancellationToken = default) + { + var dataSource = await GetByIdAsync(id, cancellationToken); + if (dataSource is null) return; + + dataSource.IsDeleted = true; + dataSource.DeletedAt = DateTime.UtcNow; + dataSource.UpdatedAt = DateTime.UtcNow; + await _context.SaveChangesAsync(cancellationToken); + } +} diff --git a/Artskart3.slnx b/Artskart3.slnx index f495a190..b211c69d 100644 --- a/Artskart3.slnx +++ b/Artskart3.slnx @@ -6,5 +6,6 @@ - + + From eb2165a531b5cece20dc09072a6d34250c0d0488 Mon Sep 17 00:00:00 2001 From: bo Date: Thu, 30 Apr 2026 15:42:22 +0200 Subject: [PATCH 4/7] docs: update README with Import database setup and three-database architecture overview --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/README.md b/README.md index f82b479f..96e1558b 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,50 @@ dotnet ef migrations remove --startup-project ..\Artskart3.Api > Migrasjonsfilene ligger i `Artskart3.Infrastructure/Migrations/`. Ikke rediger disse manuelt etter at de er kjørt mot en delt database. +### Import-databasen (Artskart3Import) + +Import-laget følger Clean Architecture og er delt i to prosjekter: +- `Artskart3.Import.Core` — domeneentiteter og repository-grensesnitt (ingen EF-avhengigheter) +- `Artskart3.Import.Infrastructure` — EF DbContext, migrasjoner og repository-implementasjoner + +**Opprett/oppdater lokal import-database:** +```powershell +dotnet ef database update ` + --project Artskart3.Import.Infrastructure ` + --startup-project Artskart3.Api ` + --context ArtskartImportDbContext +``` + +**Legge til en ny migrasjon for import-konteksten:** +```powershell +dotnet ef migrations add ` + --project Artskart3.Import.Infrastructure ` + --startup-project Artskart3.Api ` + --context ArtskartImportDbContext +``` + +**Angre siste import-migrasjon:** +```powershell +dotnet ef migrations remove ` + --project Artskart3.Import.Infrastructure ` + --startup-project Artskart3.Api ` + --context ArtskartImportDbContext +``` + +> Migrasjonsfilene ligger i `Artskart3.Import.Infrastructure/Migrations/`. + +### Databaseoversikt + +Løsningen bruker tre separate databaser: + +| Database | Prosjekt | Formål | +|---|---|---| +| `Artskart3Search` | `Artskart3.Infrastructure` | Søkeoptimalisert leseindeks | +| `Artskart3Import` | `Artskart3.Import.Infrastructure` | Rå leverandørdata fra eksterne kilder (DwC-A, GBIF API m.m.) | +| `Artskart3Operational` | Kommer | Validerte og prosesserte forekomstdata (kilde til sannhet) | + +Taxonomidata hentes fra [Nortaxa](https://nortaxa.artsdatabanken.no) via API og caches lokalt i `Artskart3Search`. + ## Navngiving av branches Standariserer navngiving av branches er `prosjektnavn-sak#-navn_på_oppgave` som for eksempel: `artskart3-sak42-project-setup-and-commits` From 32043cbc898c1f934ea98874b2845e737b543895 Mon Sep 17 00:00:00 2001 From: bo Date: Tue, 5 May 2026 13:59:48 +0200 Subject: [PATCH 5/7] feat: add GbifDatasetDiscovery entity to Import bounded context (#138) --- .../Domain/Entities/GbifDatasetDiscovery.cs | 57 ++++++ .../Domain/Enums/DiscoveryStatus.cs | 19 ++ .../IGbifDatasetDiscoveryRepository.cs | 14 ++ .../Data/ArtskartImportDbContext.cs | 2 + .../GbifDatasetDiscoveryConfiguration.cs | 53 +++++ .../ImportServiceCollectionExtensions.cs | 1 + ...115624_AddGbifDatasetDiscovery.Designer.cs | 184 ++++++++++++++++++ .../20260505115624_AddGbifDatasetDiscovery.cs | 58 ++++++ .../ArtskartImportDbContextModelSnapshot.cs | 69 +++++++ .../GbifDatasetDiscoveryRepository.cs | 44 +++++ 10 files changed, 501 insertions(+) create mode 100644 Artskart3.Import.Core/Domain/Entities/GbifDatasetDiscovery.cs create mode 100644 Artskart3.Import.Core/Domain/Enums/DiscoveryStatus.cs create mode 100644 Artskart3.Import.Core/Domain/RepositoryInterfaces/IGbifDatasetDiscoveryRepository.cs create mode 100644 Artskart3.Import.Infrastructure/Data/EntityConfigurations/GbifDatasetDiscoveryConfiguration.cs create mode 100644 Artskart3.Import.Infrastructure/Migrations/20260505115624_AddGbifDatasetDiscovery.Designer.cs create mode 100644 Artskart3.Import.Infrastructure/Migrations/20260505115624_AddGbifDatasetDiscovery.cs create mode 100644 Artskart3.Import.Infrastructure/Persistence/Repositories/GbifDatasetDiscoveryRepository.cs diff --git a/Artskart3.Import.Core/Domain/Entities/GbifDatasetDiscovery.cs b/Artskart3.Import.Core/Domain/Entities/GbifDatasetDiscovery.cs new file mode 100644 index 00000000..ebfb2157 --- /dev/null +++ b/Artskart3.Import.Core/Domain/Entities/GbifDatasetDiscovery.cs @@ -0,0 +1,57 @@ +using Artskart3.Import.Core.Domain.Enums; + +namespace Artskart3.Import.Core.Domain.Entities; + +public class GbifDatasetDiscovery +{ + public int Id { get; set; } + + /// + /// The GBIF dataset key (UUID). + /// + public string GbifId { get; set; } = string.Empty; + + /// + /// The GBIF publisher/organisation UUID. + /// + public Guid GbifPublisherId { get; set; } + + /// + /// The GBIF publishing organisation key string. + /// + public string PublishingOrganizationKey { get; set; } = string.Empty; + + public string Title { get; set; } = string.Empty; + + public string? Description { get; set; } + + /// + /// The dataset homepage URL on GBIF. + /// + public string? HomepageUrl { get; set; } + + /// + /// The Darwin Core Archive download URL. + /// + public string? DwcArchiveUrl { get; set; } + + public string? Doi { get; set; } + + /// + /// Additional identifiers for the dataset (stored as JSON array). + /// + public List Identifiers { get; set; } = []; + + /// + /// Review status of this discovered dataset. + /// + public DiscoveryStatus Status { get; set; } = DiscoveryStatus.Pending; + + /// + /// When this dataset was first discovered via the GBIF API. + /// + public DateTime DiscoveredAt { get; set; } + + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } +} diff --git a/Artskart3.Import.Core/Domain/Enums/DiscoveryStatus.cs b/Artskart3.Import.Core/Domain/Enums/DiscoveryStatus.cs new file mode 100644 index 00000000..d0197ec8 --- /dev/null +++ b/Artskart3.Import.Core/Domain/Enums/DiscoveryStatus.cs @@ -0,0 +1,19 @@ +namespace Artskart3.Import.Core.Domain.Enums; + +public enum DiscoveryStatus +{ + /// + /// Discovered via the GBIF API but not yet reviewed. + /// + Pending, + + /// + /// Reviewed and approved for import as a DataSource. + /// + Approved, + + /// + /// Reviewed and determined to be not relevant for import. + /// + Rejected +} diff --git a/Artskart3.Import.Core/Domain/RepositoryInterfaces/IGbifDatasetDiscoveryRepository.cs b/Artskart3.Import.Core/Domain/RepositoryInterfaces/IGbifDatasetDiscoveryRepository.cs new file mode 100644 index 00000000..64919bf8 --- /dev/null +++ b/Artskart3.Import.Core/Domain/RepositoryInterfaces/IGbifDatasetDiscoveryRepository.cs @@ -0,0 +1,14 @@ +using Artskart3.Import.Core.Domain.Entities; +using Artskart3.Import.Core.Domain.Enums; + +namespace Artskart3.Import.Core.Domain.RepositoryInterfaces; + +public interface IGbifDatasetDiscoveryRepository +{ + Task> GetAllAsync(); + Task> GetByStatusAsync(DiscoveryStatus status); + Task GetByIdAsync(int id); + Task GetByGbifIdAsync(string gbifId); + Task AddAsync(GbifDatasetDiscovery discovery); + Task UpdateAsync(GbifDatasetDiscovery discovery); +} diff --git a/Artskart3.Import.Infrastructure/Data/ArtskartImportDbContext.cs b/Artskart3.Import.Infrastructure/Data/ArtskartImportDbContext.cs index d809b88e..6e815f7a 100644 --- a/Artskart3.Import.Infrastructure/Data/ArtskartImportDbContext.cs +++ b/Artskart3.Import.Infrastructure/Data/ArtskartImportDbContext.cs @@ -16,10 +16,12 @@ public ArtskartImportDbContext(DbContextOptions options } public virtual DbSet DataSources { get; set; } + public virtual DbSet GbifDatasetDiscoveries { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new DataSourceConfiguration()); + modelBuilder.ApplyConfiguration(new GbifDatasetDiscoveryConfiguration()); base.OnModelCreating(modelBuilder); } diff --git a/Artskart3.Import.Infrastructure/Data/EntityConfigurations/GbifDatasetDiscoveryConfiguration.cs b/Artskart3.Import.Infrastructure/Data/EntityConfigurations/GbifDatasetDiscoveryConfiguration.cs new file mode 100644 index 00000000..a6ef2df1 --- /dev/null +++ b/Artskart3.Import.Infrastructure/Data/EntityConfigurations/GbifDatasetDiscoveryConfiguration.cs @@ -0,0 +1,53 @@ +using Artskart3.Import.Core.Domain.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Artskart3.Import.Infrastructure.Data.EntityConfigurations; + +public class GbifDatasetDiscoveryConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("GbifDatasetDiscovery"); + + builder.HasKey(e => e.Id); + + builder.Property(e => e.GbifId) + .IsRequired() + .HasMaxLength(200); + + builder.Property(e => e.PublishingOrganizationKey) + .IsRequired() + .HasMaxLength(200); + + builder.Property(e => e.Title) + .IsRequired() + .HasMaxLength(1000); + + builder.Property(e => e.Description) + .HasColumnType("nvarchar(max)"); + + builder.Property(e => e.HomepageUrl) + .HasMaxLength(1000); + + builder.Property(e => e.DwcArchiveUrl) + .HasMaxLength(1000); + + builder.Property(e => e.Doi) + .HasMaxLength(200); + + // Stored as a JSON array + builder.Property(e => e.Identifiers) + .HasColumnType("nvarchar(max)"); + + builder.Property(e => e.Status) + .IsRequired(); + + builder.HasIndex(e => e.GbifId) + .IsUnique() + .HasDatabaseName("IX_GbifDatasetDiscovery_GbifId"); + + builder.HasIndex(e => e.Status) + .HasDatabaseName("IX_GbifDatasetDiscovery_Status"); + } +} diff --git a/Artskart3.Import.Infrastructure/DependencyInjection/ImportServiceCollectionExtensions.cs b/Artskart3.Import.Infrastructure/DependencyInjection/ImportServiceCollectionExtensions.cs index 6d18a8aa..a8ab1002 100644 --- a/Artskart3.Import.Infrastructure/DependencyInjection/ImportServiceCollectionExtensions.cs +++ b/Artskart3.Import.Infrastructure/DependencyInjection/ImportServiceCollectionExtensions.cs @@ -16,6 +16,7 @@ public static IServiceCollection AddImportInfrastructure( options.UseSqlServer(connectionString)); services.AddScoped(); + services.AddScoped(); return services; } diff --git a/Artskart3.Import.Infrastructure/Migrations/20260505115624_AddGbifDatasetDiscovery.Designer.cs b/Artskart3.Import.Infrastructure/Migrations/20260505115624_AddGbifDatasetDiscovery.Designer.cs new file mode 100644 index 00000000..f99217db --- /dev/null +++ b/Artskart3.Import.Infrastructure/Migrations/20260505115624_AddGbifDatasetDiscovery.Designer.cs @@ -0,0 +1,184 @@ +// +using System; +using Artskart3.Import.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Artskart3.Import.Infrastructure.Migrations +{ + [DbContext(typeof(ArtskartImportDbContext))] + [Migration("20260505115624_AddGbifDatasetDiscovery")] + partial class AddGbifDatasetDiscovery + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Artskart3.Import.Core.Domain.Entities.DataSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchiveName") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("GbifApiQuery") + .HasColumnType("nvarchar(max)"); + + b.Property("GbifPublisherId") + .HasColumnType("uniqueidentifier"); + + b.Property("HarvestPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("ImportPropertyOverrides") + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsEditedNameOrNotes") + .HasColumnType("bit"); + + b.Property("IsSensitive") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("NonValidOccurrenceIds") + .HasColumnType("bit"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ProviderType") + .HasColumnType("int"); + + b.Property("RecordsBatchSize") + .HasColumnType("int"); + + b.Property("RemoteAddress") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("UpdateFrequencyInDays") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.Property("WebServiceVersion") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IsDeleted") + .HasDatabaseName("IX_DataSource_IsDeleted"); + + b.HasIndex("ProviderType") + .HasDatabaseName("IX_DataSource_ProviderType"); + + b.ToTable("DataSource", (string)null); + }); + + modelBuilder.Entity("Artskart3.Import.Core.Domain.Entities.GbifDatasetDiscovery", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DiscoveredAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("DwcArchiveUrl") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("GbifId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("GbifPublisherId") + .HasColumnType("uniqueidentifier"); + + b.Property("HomepageUrl") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.PrimitiveCollection("Identifiers") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PublishingOrganizationKey") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("GbifId") + .IsUnique() + .HasDatabaseName("IX_GbifDatasetDiscovery_GbifId"); + + b.HasIndex("Status") + .HasDatabaseName("IX_GbifDatasetDiscovery_Status"); + + b.ToTable("GbifDatasetDiscovery", (string)null); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Artskart3.Import.Infrastructure/Migrations/20260505115624_AddGbifDatasetDiscovery.cs b/Artskart3.Import.Infrastructure/Migrations/20260505115624_AddGbifDatasetDiscovery.cs new file mode 100644 index 00000000..c004028f --- /dev/null +++ b/Artskart3.Import.Infrastructure/Migrations/20260505115624_AddGbifDatasetDiscovery.cs @@ -0,0 +1,58 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Artskart3.Import.Infrastructure.Migrations +{ + /// + public partial class AddGbifDatasetDiscovery : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "GbifDatasetDiscovery", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + GbifId = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + GbifPublisherId = table.Column(type: "uniqueidentifier", nullable: false), + PublishingOrganizationKey = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: false), + Title = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: false), + Description = table.Column(type: "nvarchar(max)", nullable: true), + HomepageUrl = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + DwcArchiveUrl = table.Column(type: "nvarchar(1000)", maxLength: 1000, nullable: true), + Doi = table.Column(type: "nvarchar(200)", maxLength: 200, nullable: true), + Identifiers = table.Column(type: "nvarchar(max)", nullable: false), + Status = table.Column(type: "int", nullable: false), + DiscoveredAt = table.Column(type: "datetime2", nullable: false), + CreatedAt = table.Column(type: "datetime2", nullable: false), + UpdatedAt = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GbifDatasetDiscovery", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_GbifDatasetDiscovery_GbifId", + table: "GbifDatasetDiscovery", + column: "GbifId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_GbifDatasetDiscovery_Status", + table: "GbifDatasetDiscovery", + column: "Status"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "GbifDatasetDiscovery"); + } + } +} diff --git a/Artskart3.Import.Infrastructure/Migrations/ArtskartImportDbContextModelSnapshot.cs b/Artskart3.Import.Infrastructure/Migrations/ArtskartImportDbContextModelSnapshot.cs index ad072080..40a07710 100644 --- a/Artskart3.Import.Infrastructure/Migrations/ArtskartImportDbContextModelSnapshot.cs +++ b/Artskart3.Import.Infrastructure/Migrations/ArtskartImportDbContextModelSnapshot.cs @@ -106,6 +106,75 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("DataSource", (string)null); }); + + modelBuilder.Entity("Artskart3.Import.Core.Domain.Entities.GbifDatasetDiscovery", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DiscoveredAt") + .HasColumnType("datetime2"); + + b.Property("Doi") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("DwcArchiveUrl") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("GbifId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("GbifPublisherId") + .HasColumnType("uniqueidentifier"); + + b.Property("HomepageUrl") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.PrimitiveCollection("Identifiers") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PublishingOrganizationKey") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("GbifId") + .IsUnique() + .HasDatabaseName("IX_GbifDatasetDiscovery_GbifId"); + + b.HasIndex("Status") + .HasDatabaseName("IX_GbifDatasetDiscovery_Status"); + + b.ToTable("GbifDatasetDiscovery", (string)null); + }); #pragma warning restore 612, 618 } } diff --git a/Artskart3.Import.Infrastructure/Persistence/Repositories/GbifDatasetDiscoveryRepository.cs b/Artskart3.Import.Infrastructure/Persistence/Repositories/GbifDatasetDiscoveryRepository.cs new file mode 100644 index 00000000..51581f95 --- /dev/null +++ b/Artskart3.Import.Infrastructure/Persistence/Repositories/GbifDatasetDiscoveryRepository.cs @@ -0,0 +1,44 @@ +using Artskart3.Import.Core.Domain.Entities; +using Artskart3.Import.Core.Domain.Enums; +using Artskart3.Import.Core.Domain.RepositoryInterfaces; +using Artskart3.Import.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; + +namespace Artskart3.Import.Infrastructure.Persistence.Repositories; + +public class GbifDatasetDiscoveryRepository : IGbifDatasetDiscoveryRepository +{ + private readonly ArtskartImportDbContext _context; + + public GbifDatasetDiscoveryRepository(ArtskartImportDbContext context) + { + _context = context; + } + + public async Task> GetAllAsync() + => await _context.GbifDatasetDiscoveries.ToListAsync(); + + public async Task> GetByStatusAsync(DiscoveryStatus status) + => await _context.GbifDatasetDiscoveries.Where(d => d.Status == status).ToListAsync(); + + public async Task GetByIdAsync(int id) + => await _context.GbifDatasetDiscoveries.FindAsync(id); + + public async Task GetByGbifIdAsync(string gbifId) + => await _context.GbifDatasetDiscoveries.FirstOrDefaultAsync(d => d.GbifId == gbifId); + + public async Task AddAsync(GbifDatasetDiscovery discovery) + { + discovery.CreatedAt = DateTime.UtcNow; + discovery.UpdatedAt = DateTime.UtcNow; + await _context.GbifDatasetDiscoveries.AddAsync(discovery); + await _context.SaveChangesAsync(); + } + + public async Task UpdateAsync(GbifDatasetDiscovery discovery) + { + discovery.UpdatedAt = DateTime.UtcNow; + _context.GbifDatasetDiscoveries.Update(discovery); + await _context.SaveChangesAsync(); + } +} From e68002dc5ac73e9e0d6baf2022dc2299916cb2aa Mon Sep 17 00:00:00 2001 From: bo Date: Wed, 13 May 2026 12:13:27 +0200 Subject: [PATCH 6/7] #138 Added merge conflict aritifacts to gitignore file --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 8dfac7d0..42a1d5ae 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,12 @@ msbuild.wrn # Environment files /.env +# Merge conflict artifacts +*.BASE +*.LOCAL +*.REMOTE +*.bak + # Angular CLI and build artefacts /.angular-cli.json /.ng/ From a149fa8386b102c04a7b50f8bb130af79e1d4799 Mon Sep 17 00:00:00 2001 From: bolsson <6236608+bolsson@users.noreply.github.com> Date: Wed, 20 May 2026 10:11:18 +0200 Subject: [PATCH 7/7] Refine summary comment in DataSource class Updated summary comment for DataSource class to remove reference to SourceDataBase in RavenDB. Signed-off-by: bolsson <6236608+bolsson@users.noreply.github.com> --- Artskart3.Import.Core/Domain/Entities/DataSource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Artskart3.Import.Core/Domain/Entities/DataSource.cs b/Artskart3.Import.Core/Domain/Entities/DataSource.cs index ec7be23b..4647915f 100644 --- a/Artskart3.Import.Core/Domain/Entities/DataSource.cs +++ b/Artskart3.Import.Core/Domain/Entities/DataSource.cs @@ -3,7 +3,7 @@ namespace Artskart3.Import.Core.Domain.Entities; /// -/// Provider configuration for a remote data source (formerly SourceDataBase in RavenDB). +/// Provider configuration for a remote data source. /// One flat table; use typed views or application-layer filtering to work with specific provider types. /// public class DataSource