diff --git a/ExcelIO/.gitattributes b/ExcelIO/.gitattributes
new file mode 100644
index 0000000000..c941e52669
--- /dev/null
+++ b/ExcelIO/.gitattributes
@@ -0,0 +1 @@
+**/wwwroot/libs/** linguist-vendored
diff --git a/ExcelIO/.gitignore b/ExcelIO/.gitignore
new file mode 100644
index 0000000000..9b3a132b32
--- /dev/null
+++ b/ExcelIO/.gitignore
@@ -0,0 +1,260 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# ExcelIO
+src/ExcelIO.Web/Logs/*
+src/ExcelIO.Web.Host/Logs/*
+src/ExcelIO.IdentityServer/Logs/*
+src/ExcelIO.HttpApi.Host/Logs/*
+src/ExcelIO.HttpApi.HostWithIds/Logs/*
+src/ExcelIO.DbMigrator/Logs/*
diff --git a/ExcelIO/.prettierrc b/ExcelIO/.prettierrc
new file mode 100644
index 0000000000..56af76bd94
--- /dev/null
+++ b/ExcelIO/.prettierrc
@@ -0,0 +1,5 @@
+{
+ "singleQuote": true,
+ "useTabs": false,
+ "tabWidth": 4
+}
diff --git a/ExcelIO/ExcelIO.sln b/ExcelIO/ExcelIO.sln
new file mode 100644
index 0000000000..19a4a4d38a
--- /dev/null
+++ b/ExcelIO/ExcelIO.sln
@@ -0,0 +1,137 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29020.237
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.Domain", "src\ExcelIO.Domain\ExcelIO.Domain.csproj", "{554AD327-6DBA-4F8F-96F8-81CE7A0C863F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.Application", "src\ExcelIO.Application\ExcelIO.Application.csproj", "{1A94A50E-06DC-43C1-80B5-B662820EC3EB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.EntityFrameworkCore", "src\ExcelIO.EntityFrameworkCore\ExcelIO.EntityFrameworkCore.csproj", "{C956DD76-69C8-4A9C-83EA-D17DF83340FD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.Web", "src\ExcelIO.Web\ExcelIO.Web.csproj", "{068855E8-9240-4F1A-910B-CF825794513B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA9AC87F-097E-4F15-8393-4BC07735A5B0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{04DBDB01-70F4-4E06-B468-8F87850B22BE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.Application.Tests", "test\ExcelIO.Application.Tests\ExcelIO.Application.Tests.csproj", "{50B2631D-129C-47B3-A587-029CCD6099BC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.Web.Tests", "test\ExcelIO.Web.Tests\ExcelIO.Web.Tests.csproj", "{5F1B28C6-8D0C-4155-92D0-252F7EA5F674}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.EntityFrameworkCore.DbMigrations", "src\ExcelIO.EntityFrameworkCore.DbMigrations\ExcelIO.EntityFrameworkCore.DbMigrations.csproj", "{0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.Domain.Shared", "src\ExcelIO.Domain.Shared\ExcelIO.Domain.Shared.csproj", "{42F719ED-8413-4895-B5B4-5AB56079BC66}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.Application.Contracts", "src\ExcelIO.Application.Contracts\ExcelIO.Application.Contracts.csproj", "{520659C8-C734-4298-A3DA-B539DB9DFC0B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.HttpApi", "src\ExcelIO.HttpApi\ExcelIO.HttpApi.csproj", "{4164BDF7-F527-4E85-9CE6-E3C2D7426A27}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.HttpApi.Client", "src\ExcelIO.HttpApi.Client\ExcelIO.HttpApi.Client.csproj", "{3B5A0094-670D-4BB1-BFDD-61B88A8773DC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.EntityFrameworkCore.Tests", "test\ExcelIO.EntityFrameworkCore.Tests\ExcelIO.EntityFrameworkCore.Tests.csproj", "{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.TestBase", "test\ExcelIO.TestBase\ExcelIO.TestBase.csproj", "{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.Domain.Tests", "test\ExcelIO.Domain.Tests\ExcelIO.Domain.Tests.csproj", "{E512F4D9-9375-480F-A2F6-A46509F9D824}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.HttpApi.Client.ConsoleTestApp", "test\ExcelIO.HttpApi.Client.ConsoleTestApp\ExcelIO.HttpApi.Client.ConsoleTestApp.csproj", "{EF480016-9127-4916-8735-D2466BDBC582}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExcelIO.DbMigrator", "src\ExcelIO.DbMigrator\ExcelIO.DbMigrator.csproj", "{AA94D832-1CCC-4715-95A9-A483F23A1A5D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {554AD327-6DBA-4F8F-96F8-81CE7A0C863F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1A94A50E-06DC-43C1-80B5-B662820EC3EB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C956DD76-69C8-4A9C-83EA-D17DF83340FD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {068855E8-9240-4F1A-910B-CF825794513B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {068855E8-9240-4F1A-910B-CF825794513B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {068855E8-9240-4F1A-910B-CF825794513B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {068855E8-9240-4F1A-910B-CF825794513B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {50B2631D-129C-47B3-A587-029CCD6099BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {50B2631D-129C-47B3-A587-029CCD6099BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5F1B28C6-8D0C-4155-92D0-252F7EA5F674}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5F1B28C6-8D0C-4155-92D0-252F7EA5F674}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5F1B28C6-8D0C-4155-92D0-252F7EA5F674}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5F1B28C6-8D0C-4155-92D0-252F7EA5F674}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {42F719ED-8413-4895-B5B4-5AB56079BC66}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {42F719ED-8413-4895-B5B4-5AB56079BC66}.Release|Any CPU.Build.0 = Release|Any CPU
+ {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {520659C8-C734-4298-A3DA-B539DB9DFC0B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4164BDF7-F527-4E85-9CE6-E3C2D7426A27}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3B5A0094-670D-4BB1-BFDD-61B88A8773DC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.Build.0 = Release|Any CPU
+ {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E512F4D9-9375-480F-A2F6-A46509F9D824}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E512F4D9-9375-480F-A2F6-A46509F9D824}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EF480016-9127-4916-8735-D2466BDBC582}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EF480016-9127-4916-8735-D2466BDBC582}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AA94D832-1CCC-4715-95A9-A483F23A1A5D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {554AD327-6DBA-4F8F-96F8-81CE7A0C863F} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {1A94A50E-06DC-43C1-80B5-B662820EC3EB} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {C956DD76-69C8-4A9C-83EA-D17DF83340FD} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {068855E8-9240-4F1A-910B-CF825794513B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {50B2631D-129C-47B3-A587-029CCD6099BC} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
+ {5F1B28C6-8D0C-4155-92D0-252F7EA5F674} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
+ {0372FA84-C517-4EB3-9A9F-B9ACAC0CA5E0} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {42F719ED-8413-4895-B5B4-5AB56079BC66} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {520659C8-C734-4298-A3DA-B539DB9DFC0B} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {4164BDF7-F527-4E85-9CE6-E3C2D7426A27} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {3B5A0094-670D-4BB1-BFDD-61B88A8773DC} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
+ {91853F21-9CD9-4132-BC29-A7D5D84FFFE7} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
+ {E512F4D9-9375-480F-A2F6-A46509F9D824} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
+ {EF480016-9127-4916-8735-D2466BDBC582} = {04DBDB01-70F4-4E06-B468-8F87850B22BE}
+ {AA94D832-1CCC-4715-95A9-A483F23A1A5D} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C09128AF-C73F-ED7D-33F5-69BF7D934D50}
+ EndGlobalSection
+EndGlobal
diff --git a/ExcelIO/ExcelIO.sln.DotSettings b/ExcelIO/ExcelIO.sln.DotSettings
new file mode 100644
index 0000000000..cb0b2c919f
--- /dev/null
+++ b/ExcelIO/ExcelIO.sln.DotSettings
@@ -0,0 +1,23 @@
+
+ True
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ Required
+ Required
+ Required
+ Required
+ False
+ True
+ False
+ False
+ True
+ False
+ False
+ SQL
+
\ No newline at end of file
diff --git a/ExcelIO/NuGet.Config b/ExcelIO/NuGet.Config
new file mode 100644
index 0000000000..be8a1ece10
--- /dev/null
+++ b/ExcelIO/NuGet.Config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ExcelIO/common.props b/ExcelIO/common.props
new file mode 100644
index 0000000000..fbef88367b
--- /dev/null
+++ b/ExcelIO/common.props
@@ -0,0 +1,8 @@
+
+
+ latest
+ 1.0.0
+ $(NoWarn);CS1591;CS0436
+ app
+
+
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIO.Application.Contracts.csproj b/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIO.Application.Contracts.csproj
new file mode 100644
index 0000000000..462ca66564
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIO.Application.Contracts.csproj
@@ -0,0 +1,23 @@
+
+
+
+
+
+ netstandard2.0
+ ExcelIO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIOApplicationContractsModule.cs b/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIOApplicationContractsModule.cs
new file mode 100644
index 0000000000..2b8e6739a3
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIOApplicationContractsModule.cs
@@ -0,0 +1,27 @@
+using Volo.Abp.Account;
+using Volo.Abp.FeatureManagement;
+using Volo.Abp.Identity;
+using Volo.Abp.Modularity;
+using Volo.Abp.ObjectExtending;
+using Volo.Abp.PermissionManagement;
+using Volo.Abp.TenantManagement;
+
+namespace ExcelIO
+{
+ [DependsOn(
+ typeof(ExcelIODomainSharedModule),
+ typeof(AbpAccountApplicationContractsModule),
+ typeof(AbpFeatureManagementApplicationContractsModule),
+ typeof(AbpIdentityApplicationContractsModule),
+ typeof(AbpPermissionManagementApplicationContractsModule),
+ typeof(AbpTenantManagementApplicationContractsModule),
+ typeof(AbpObjectExtendingModule)
+ )]
+ public class ExcelIOApplicationContractsModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ ExcelIODtoExtensions.Configure();
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIODtoExtensions.cs b/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIODtoExtensions.cs
new file mode 100644
index 0000000000..5fbd83c9d5
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application.Contracts/ExcelIODtoExtensions.cs
@@ -0,0 +1,29 @@
+using Volo.Abp.Identity;
+using Volo.Abp.ObjectExtending;
+using Volo.Abp.Threading;
+
+namespace ExcelIO
+{
+ public static class ExcelIODtoExtensions
+ {
+ private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
+
+ public static void Configure()
+ {
+ OneTimeRunner.Run(() =>
+ {
+ /* You can add extension properties to DTOs
+ * defined in the depended modules.
+ *
+ * Example:
+ *
+ * ObjectExtensionManager.Instance
+ * .AddOrUpdateProperty("Title");
+ *
+ * See the documentation for more:
+ * https://docs.abp.io/en/abp/latest/Object-Extensions
+ */
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Application.Contracts/Permissions/ExcelIOPermissionDefinitionProvider.cs b/ExcelIO/src/ExcelIO.Application.Contracts/Permissions/ExcelIOPermissionDefinitionProvider.cs
new file mode 100644
index 0000000000..5e45717038
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application.Contracts/Permissions/ExcelIOPermissionDefinitionProvider.cs
@@ -0,0 +1,22 @@
+using ExcelIO.Localization;
+using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Localization;
+
+namespace ExcelIO.Permissions
+{
+ public class ExcelIOPermissionDefinitionProvider : PermissionDefinitionProvider
+ {
+ public override void Define(IPermissionDefinitionContext context)
+ {
+ var myGroup = context.AddGroup(ExcelIOPermissions.GroupName);
+
+ //Define your own permissions here. Example:
+ //myGroup.AddPermission(ExcelIOPermissions.MyPermission1, L("Permission:MyPermission1"));
+ }
+
+ private static LocalizableString L(string name)
+ {
+ return LocalizableString.Create(name);
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Application.Contracts/Permissions/ExcelIOPermissions.cs b/ExcelIO/src/ExcelIO.Application.Contracts/Permissions/ExcelIOPermissions.cs
new file mode 100644
index 0000000000..7ac64a4b73
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application.Contracts/Permissions/ExcelIOPermissions.cs
@@ -0,0 +1,10 @@
+namespace ExcelIO.Permissions
+{
+ public static class ExcelIOPermissions
+ {
+ public const string GroupName = "ExcelIO";
+
+ //Add your own permission names. Example:
+ //public const string MyPermission1 = GroupName + ".MyPermission1";
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Application/ExcelIO.Application.csproj b/ExcelIO/src/ExcelIO.Application/ExcelIO.Application.csproj
new file mode 100644
index 0000000000..c37f51415d
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application/ExcelIO.Application.csproj
@@ -0,0 +1,23 @@
+
+
+
+
+
+ net5.0
+ ExcelIO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ExcelIO/src/ExcelIO.Application/ExcelIOAppService.cs b/ExcelIO/src/ExcelIO.Application/ExcelIOAppService.cs
new file mode 100644
index 0000000000..2ac47f791e
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application/ExcelIOAppService.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ExcelIO.Localization;
+using Volo.Abp.Application.Services;
+
+namespace ExcelIO
+{
+ /* Inherit your application services from this class.
+ */
+ public abstract class ExcelIOAppService : ApplicationService
+ {
+ protected ExcelIOAppService()
+ {
+ LocalizationResource = typeof(ExcelIOResource);
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Application/ExcelIOApplicationAutoMapperProfile.cs b/ExcelIO/src/ExcelIO.Application/ExcelIOApplicationAutoMapperProfile.cs
new file mode 100644
index 0000000000..8fba7ded19
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application/ExcelIOApplicationAutoMapperProfile.cs
@@ -0,0 +1,14 @@
+using AutoMapper;
+
+namespace ExcelIO
+{
+ public class ExcelIOApplicationAutoMapperProfile : Profile
+ {
+ public ExcelIOApplicationAutoMapperProfile()
+ {
+ /* You can configure your AutoMapper mapping configuration here.
+ * Alternatively, you can split your mapping configurations
+ * into multiple profile classes for a better organization. */
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Application/ExcelIOApplicationModule.cs b/ExcelIO/src/ExcelIO.Application/ExcelIOApplicationModule.cs
new file mode 100644
index 0000000000..f8fbf85380
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application/ExcelIOApplicationModule.cs
@@ -0,0 +1,30 @@
+using Volo.Abp.Account;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.FeatureManagement;
+using Volo.Abp.Identity;
+using Volo.Abp.Modularity;
+using Volo.Abp.PermissionManagement;
+using Volo.Abp.TenantManagement;
+
+namespace ExcelIO
+{
+ [DependsOn(
+ typeof(ExcelIODomainModule),
+ typeof(AbpAccountApplicationModule),
+ typeof(ExcelIOApplicationContractsModule),
+ typeof(AbpIdentityApplicationModule),
+ typeof(AbpPermissionManagementApplicationModule),
+ typeof(AbpTenantManagementApplicationModule),
+ typeof(AbpFeatureManagementApplicationModule)
+ )]
+ public class ExcelIOApplicationModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.AddMaps();
+ });
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Application/Properties/AssemblyInfo.cs b/ExcelIO/src/ExcelIO.Application/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..6b9322e216
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Application/Properties/AssemblyInfo.cs
@@ -0,0 +1,2 @@
+using System.Runtime.CompilerServices;
+[assembly:InternalsVisibleToAttribute("ExcelIO.Application.Tests")]
diff --git a/ExcelIO/src/ExcelIO.DbMigrator/DbMigratorHostedService.cs b/ExcelIO/src/ExcelIO.DbMigrator/DbMigratorHostedService.cs
new file mode 100644
index 0000000000..d88198c5f3
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.DbMigrator/DbMigratorHostedService.cs
@@ -0,0 +1,43 @@
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using ExcelIO.Data;
+using Serilog;
+using Volo.Abp;
+
+namespace ExcelIO.DbMigrator
+{
+ public class DbMigratorHostedService : IHostedService
+ {
+ private readonly IHostApplicationLifetime _hostApplicationLifetime;
+
+ public DbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime)
+ {
+ _hostApplicationLifetime = hostApplicationLifetime;
+ }
+
+ public async Task StartAsync(CancellationToken cancellationToken)
+ {
+ using (var application = AbpApplicationFactory.Create(options =>
+ {
+ options.UseAutofac();
+ options.Services.AddLogging(c => c.AddSerilog());
+ }))
+ {
+ application.Initialize();
+
+ await application
+ .ServiceProvider
+ .GetRequiredService()
+ .MigrateAsync();
+
+ application.Shutdown();
+
+ _hostApplicationLifetime.StopApplication();
+ }
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.DbMigrator/ExcelIO.DbMigrator.csproj b/ExcelIO/src/ExcelIO.DbMigrator/ExcelIO.DbMigrator.csproj
new file mode 100644
index 0000000000..acc822b4d6
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.DbMigrator/ExcelIO.DbMigrator.csproj
@@ -0,0 +1,35 @@
+
+
+
+
+
+ Exe
+ net5.0
+
+
+
+
+
+
+
+
+ PreserveNewest
+ Always
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ExcelIO/src/ExcelIO.DbMigrator/ExcelIODbMigratorModule.cs b/ExcelIO/src/ExcelIO.DbMigrator/ExcelIODbMigratorModule.cs
new file mode 100644
index 0000000000..6fd219bb03
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.DbMigrator/ExcelIODbMigratorModule.cs
@@ -0,0 +1,20 @@
+using ExcelIO.EntityFrameworkCore;
+using Volo.Abp.Autofac;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.Modularity;
+
+namespace ExcelIO.DbMigrator
+{
+ [DependsOn(
+ typeof(AbpAutofacModule),
+ typeof(ExcelIOEntityFrameworkCoreDbMigrationsModule),
+ typeof(ExcelIOApplicationContractsModule)
+ )]
+ public class ExcelIODbMigratorModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options => options.IsJobExecutionEnabled = false);
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.DbMigrator/Program.cs b/ExcelIO/src/ExcelIO.DbMigrator/Program.cs
new file mode 100644
index 0000000000..56c86862ad
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.DbMigrator/Program.cs
@@ -0,0 +1,40 @@
+using System.IO;
+using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Serilog;
+using Serilog.Events;
+
+namespace ExcelIO.DbMigrator
+{
+ class Program
+ {
+ static async Task Main(string[] args)
+ {
+ Log.Logger = new LoggerConfiguration()
+ .MinimumLevel.Information()
+ .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
+ .MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning)
+#if DEBUG
+ .MinimumLevel.Override("ExcelIO", LogEventLevel.Debug)
+#else
+ .MinimumLevel.Override("ExcelIO", LogEventLevel.Information)
+#endif
+ .Enrich.FromLogContext()
+ .WriteTo.Async(c => c.File("Logs/logs.txt"))
+ .WriteTo.Async(c => c.Console())
+ .CreateLogger();
+
+ await CreateHostBuilder(args).RunConsoleAsync();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureLogging((context, logging) => logging.ClearProviders())
+ .ConfigureServices((hostContext, services) =>
+ {
+ services.AddHostedService();
+ });
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.DbMigrator/appsettings.json b/ExcelIO/src/ExcelIO.DbMigrator/appsettings.json
new file mode 100644
index 0000000000..79a18c1f2d
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.DbMigrator/appsettings.json
@@ -0,0 +1,24 @@
+{
+ "ConnectionStrings": {
+ "Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=ExcelIO;Trusted_Connection=True;MultipleActiveResultSets=true"
+ },
+ "IdentityServer": {
+ "Clients": {
+ "ExcelIO_Web": {
+ "ClientId": "ExcelIO_Web",
+ "ClientSecret": "1q2w3e*",
+ "RootUrl": "https://localhost:44360"
+ },
+ "ExcelIO_App": {
+ "ClientId": "ExcelIO_App",
+ "ClientSecret": "1q2w3e*",
+ "RootUrl": "http://localhost:4200"
+ },
+ "ExcelIO_Swagger": {
+ "ClientId": "ExcelIO_Swagger",
+ "ClientSecret": "1q2w3e*",
+ "RootUrl": "https://localhost:44358"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.DbMigrator/tempkey.rsa b/ExcelIO/src/ExcelIO.DbMigrator/tempkey.rsa
new file mode 100644
index 0000000000..494c2013e3
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.DbMigrator/tempkey.rsa
@@ -0,0 +1,13 @@
+{
+ "KeyId": "f788zGVUZh9H-HbWL1S-Mg",
+ "Parameters": {
+ "D": "F19hbC5PLO872DszGiJnVoU55ee7XGXmNf0KEKndJ/uGBv5lWklXA0QF80h1ytWXde0jV5isQPB1t7mPhRQlDoDTkywLi1CeOgBPbxzHEfLjZZ5c4olfeX0IJX9BDqgUntY0H1a/+Om/eDu4OZUz3EIJFFZBgz46YZSyTT6ZDvAEdpC/o66sNJmxvJIp+8zVoVDSqBUzxmc+oEamXLg7r2jdymxJMxau1kQFxEGLOrJnNxGsEe8UrYA3qSsm8m/Xg4uOh7RYgnuEEt88+KTvRq+CAMWhN3YNLtOJ3NmXowwE7e1Ma+jih9+UVfxZn14P5+SOJbQ2bYV2sCV+2vBiCQ==",
+ "DP": "oPiGO/qdOQfFEAS9fMInQnsrNylIZVpDYEVoDJ6/jQfE/IpuwxGcmsaGvCob3SKxZiJRLCWpwJYo1hCh/JOSVGWMkVyELky56nbbkkV5ymKLSGZ4JoetdQs+GchnPdR+k2P9Ij1Kjk13ylubN3htzNhcBASJpOfSEv5pPVzGKX0=",
+ "DQ": "z6imxLABHkyftbfUUtpeOlPanEHgpuIjmUdp3T1Ju1jziE63UEhuj0GPAXOF17uYxixwYE8JhOJ7+TyIK9oZeI3zH2OzJqQh8f5PCQ/E+0ULXZDeNV/ShDLCTufu3Fis9Rt64uTp/H/l21oMQ79jc0ysa8DTz1ReJLRc5qjL41U=",
+ "Exponent": "AQAB",
+ "InverseQ": "ieZcvSt5XYukKJKhXpv5Dm/1RD7iH88cZnhLSTEVTMoOUHoYWmApY5pNLGahbfjA9bxnkBWDYex/i7wE9uNNY5CsA6ovUaQLVJDt3kHvR9W+9QtN8D6jjG2TuRbbOdEg4RqhfjUaDfDIgTJX2Wxc8U98FOvOyGw1HzwUPFZKecM=",
+ "Modulus": "vk4z1Bmtmbo+gxITcY+FIlXzcO2wTOGlOXK5GMYj/6PUMFt7lbqkc72AkPsrAo5/JE8LYLhWj7fzSKbjvtowHCz5m2t+FlUYmuiKpvvnJsTqvQrckNlbZ1nm071q5PhP3Dar/OksfBhPtAX+c3+NjDnM/w53ccJJNaBDO/s9JYoN7vH5n6ed1pMSK71hmg4MPsxChcnc1f1PpnG2mqyJ253+GEUbj/kRyeBSmCCr9aadov2ZzxIKVaFNagJEHOzanQmorSLpP25GfOHCuy27Zkef94V/qU9elzjbH4uIKslVGx5T6H99TYh0sUGu11NytYJa5WNAZWow95CzurC2vw==",
+ "P": "4GMCQy+XTNzR5TsgFcdAZv2K6TcQR13fHVvPoxQp/b32V5YUJOBFEUAtqociy5ro4+KzpXP5WPSk1ZtznGKuNZyLq8gTnhpB3rwd0sdo4zxKnQ5nu+n1UhlhWNxg5A9V5TaciUAyPrHWJfLoYTQWygNTgJELQH5zZXi2ihC2uiU=",
+ "Q": "2R36pamnLAJggkPJxiW5qH6HizZ+bkQVg0BBftMLzkAM8Y9CwTW75GRUzGEJFpMckkw0GZSYb1Uwl3DVUpkcQ8LZ91IPYdPpDlYUshhIxl184M55pnO14besKxJtMZ64zhHKVAR2pBMO0n6W4/1iBXkkQqyPViJxdfvXPJMBbhM="
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIO.Domain.Shared.csproj b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIO.Domain.Shared.csproj
new file mode 100644
index 0000000000..71ce5a2b47
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIO.Domain.Shared.csproj
@@ -0,0 +1,31 @@
+
+
+
+
+
+ netstandard2.0
+ ExcelIO
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIODomainErrorCodes.cs b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIODomainErrorCodes.cs
new file mode 100644
index 0000000000..77fc1801cf
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIODomainErrorCodes.cs
@@ -0,0 +1,7 @@
+namespace ExcelIO
+{
+ public static class ExcelIODomainErrorCodes
+ {
+ /* You can add your business exception error codes here, as constants */
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIODomainSharedModule.cs b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIODomainSharedModule.cs
new file mode 100644
index 0000000000..d59dce4197
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIODomainSharedModule.cs
@@ -0,0 +1,59 @@
+using ExcelIO.Localization;
+using Volo.Abp.AuditLogging;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.FeatureManagement;
+using Volo.Abp.Identity;
+using Volo.Abp.IdentityServer;
+using Volo.Abp.Localization;
+using Volo.Abp.Localization.ExceptionHandling;
+using Volo.Abp.Modularity;
+using Volo.Abp.PermissionManagement;
+using Volo.Abp.SettingManagement;
+using Volo.Abp.TenantManagement;
+using Volo.Abp.Validation.Localization;
+using Volo.Abp.VirtualFileSystem;
+
+namespace ExcelIO
+{
+ [DependsOn(
+ typeof(AbpAuditLoggingDomainSharedModule),
+ typeof(AbpBackgroundJobsDomainSharedModule),
+ typeof(AbpFeatureManagementDomainSharedModule),
+ typeof(AbpIdentityDomainSharedModule),
+ typeof(AbpIdentityServerDomainSharedModule),
+ typeof(AbpPermissionManagementDomainSharedModule),
+ typeof(AbpSettingManagementDomainSharedModule),
+ typeof(AbpTenantManagementDomainSharedModule)
+ )]
+ public class ExcelIODomainSharedModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ ExcelIOGlobalFeatureConfigurator.Configure();
+ ExcelIOModuleExtensionConfigurator.Configure();
+ }
+
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Add("en")
+ .AddBaseTypes(typeof(AbpValidationResource))
+ .AddVirtualJson("/Localization/ExcelIO");
+
+ options.DefaultResourceType = typeof(ExcelIOResource);
+ });
+
+ Configure(options =>
+ {
+ options.MapCodeNamespace("ExcelIO", typeof(ExcelIOResource));
+ });
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIOGlobalFeatureConfigurator.cs b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIOGlobalFeatureConfigurator.cs
new file mode 100644
index 0000000000..efc615eaa6
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIOGlobalFeatureConfigurator.cs
@@ -0,0 +1,23 @@
+using Volo.Abp.Threading;
+
+namespace ExcelIO
+{
+ public static class ExcelIOGlobalFeatureConfigurator
+ {
+ private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
+
+ public static void Configure()
+ {
+ OneTimeRunner.Run(() =>
+ {
+ /* You can configure (enable/disable) global features of the used modules here.
+ *
+ * YOU CAN SAFELY DELETE THIS CLASS AND REMOVE ITS USAGES IF YOU DON'T NEED TO IT!
+ *
+ * Please refer to the documentation to lear more about the Global Features System:
+ * https://docs.abp.io/en/abp/latest/Global-Features
+ */
+ });
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIOModuleExtensionConfigurator.cs b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIOModuleExtensionConfigurator.cs
new file mode 100644
index 0000000000..00108c8536
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/ExcelIOModuleExtensionConfigurator.cs
@@ -0,0 +1,72 @@
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Identity;
+using Volo.Abp.ObjectExtending;
+using Volo.Abp.Threading;
+
+namespace ExcelIO
+{
+ public static class ExcelIOModuleExtensionConfigurator
+ {
+ private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
+
+ public static void Configure()
+ {
+ OneTimeRunner.Run(() =>
+ {
+ ConfigureExistingProperties();
+ ConfigureExtraProperties();
+ });
+ }
+
+ private static void ConfigureExistingProperties()
+ {
+ /* You can change max lengths for properties of the
+ * entities defined in the modules used by your application.
+ *
+ * Example: Change user and role name max lengths
+
+ IdentityUserConsts.MaxNameLength = 99;
+ IdentityRoleConsts.MaxNameLength = 99;
+
+ * Notice: It is not suggested to change property lengths
+ * unless you really need it. Go with the standard values wherever possible.
+ *
+ * If you are using EF Core, you will need to run the add-migration command after your changes.
+ */
+ }
+
+ private static void ConfigureExtraProperties()
+ {
+ /* You can configure extra properties for the
+ * entities defined in the modules used by your application.
+ *
+ * This class can be used to define these extra properties
+ * with a high level, easy to use API.
+ *
+ * Example: Add a new property to the user entity of the identity module
+
+ ObjectExtensionManager.Instance.Modules()
+ .ConfigureIdentity(identity =>
+ {
+ identity.ConfigureUser(user =>
+ {
+ user.AddOrUpdateProperty( //property type: string
+ "SocialSecurityNumber", //property name
+ property =>
+ {
+ //validation rules
+ property.Attributes.Add(new RequiredAttribute());
+ property.Attributes.Add(new StringLengthAttribute(64) {MinimumLength = 4});
+
+ //...other configurations for this property
+ }
+ );
+ });
+ });
+
+ * See the documentation for more:
+ * https://docs.abp.io/en/latest/Module-Entity-Extensions
+ */
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/ar.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/ar.json
new file mode 100644
index 0000000000..05cb96a9d6
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/ar.json
@@ -0,0 +1,8 @@
+{
+ "culture": "ar",
+ "texts": {
+ "Menu:Home": "الرئيسية",
+ "Welcome": "مرحبا",
+ "LongWelcomeMessage": "مرحبا بكم في التطبيق. هذا مشروع بدء تشغيل يعتمد على إطار عمل ABP. لمزيد من المعلومات ، يرجى زيارة abp.io."
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/cs.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/cs.json
new file mode 100644
index 0000000000..5a0bbf613e
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/cs.json
@@ -0,0 +1,8 @@
+{
+ "culture": "cs",
+ "texts": {
+ "Menu:Home": "Úvod",
+ "Welcome": "Vítejte",
+ "LongWelcomeMessage": "Vítejte v aplikaci. Toto je startovací projekt založený na ABP frameworku. Pro více informací, navštivte abp.io."
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/de-DE.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/de-DE.json
new file mode 100644
index 0000000000..aca4528c7c
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/de-DE.json
@@ -0,0 +1,8 @@
+{
+ "culture": "de-DE",
+ "texts": {
+ "Menu:Home": "Home",
+ "Welcome": "Willkommen",
+ "LongWelcomeMessage": "Willkommen bei der Anwendung. Dies ist ein Startup-Projekt, das auf dem ABP-Framework basiert. Weitere Informationen finden Sie unter abp.io."
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/en.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/en.json
new file mode 100644
index 0000000000..d2a6a9831e
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/en.json
@@ -0,0 +1,8 @@
+{
+ "culture": "en",
+ "texts": {
+ "Menu:Home": "Home",
+ "Welcome": "Welcome",
+ "LongWelcomeMessage": "Welcome to the application. This is a startup project based on the ABP framework. For more information, visit abp.io."
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/es.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/es.json
new file mode 100644
index 0000000000..31b4b59e25
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/es.json
@@ -0,0 +1,8 @@
+{
+ "culture": "es",
+ "texts": {
+ "Menu:Home": "Inicio",
+ "Welcome": "Bienvenido",
+ "LongWelcomeMessage": "Bienvenido a la aplicación, este es un proyecto base basado en el framework ABP. Para más información, visita abp.io."
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/fr.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/fr.json
new file mode 100644
index 0000000000..e76eac0c71
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/fr.json
@@ -0,0 +1,8 @@
+{
+ "culture": "fr",
+ "texts": {
+ "Menu:Home": "Accueil",
+ "Welcome": "Bienvenue",
+ "LongWelcomeMessage": "Bienvenue dans l'application. Il s'agit d'un projet de démarrage basé sur le framework ABP. Pour plus d'informations, visitez abp.io."
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/hu.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/hu.json
new file mode 100644
index 0000000000..c7b6a33a0f
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/hu.json
@@ -0,0 +1,8 @@
+{
+ "culture": "hu",
+ "texts": {
+ "Menu:Home": "Kezdőlap",
+ "Welcome": "Üdvözlöm",
+ "LongWelcomeMessage": "Üdvözöljük az alkalmazásban. Ez egy ABP keretrendszeren alapuló startup projekt. További információkért látogasson el az abp.io oldalra."
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/pl-PL.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/pl-PL.json
new file mode 100644
index 0000000000..33412f307c
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/pl-PL.json
@@ -0,0 +1,8 @@
+{
+ "culture": "pl-PL",
+ "texts": {
+ "Menu:Home": "Home",
+ "Welcome": "Witaj",
+ "LongWelcomeMessage": "Witaj w aplikacji. To jest inicjalny projekt bazujący na ABP framework. Po więcej informacji odwiedź stronę abp.io."
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/pt-BR.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/pt-BR.json
new file mode 100644
index 0000000000..8c818a07af
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/pt-BR.json
@@ -0,0 +1,8 @@
+{
+ "culture": "pt-BR",
+ "texts": {
+ "Menu:Home": "Principal",
+ "Welcome": "Seja bem-vindo!",
+ "LongWelcomeMessage": "Bem-vindo a esta aplicação. Este é um projeto inicial baseado no ABP framework. Para mais informações, visite abp.io."
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/ru.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/ru.json
new file mode 100644
index 0000000000..8464e44344
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/ru.json
@@ -0,0 +1,8 @@
+{
+ "culture": "ru",
+ "texts": {
+ "Menu:Home": "Главная",
+ "Welcome": "Добро пожаловать",
+ "LongWelcomeMessage": "Добро пожаловать в приложение. Этот запущенный проект основан на фреймворке ABP. Для получения дополнительной информации посетите сайт abp.io."
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/sl.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/sl.json
new file mode 100644
index 0000000000..a066ef26ba
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/sl.json
@@ -0,0 +1,8 @@
+{
+ "culture": "sl",
+ "texts": {
+ "Menu:Home": "Domov",
+ "Welcome": "Dobrodošli",
+ "LongWelcomeMessage": "Dobrodošli v aplikaciji. To je začetni projekt na osnovi okolja ABP. Za več informacij obiščite abp.io."
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/tr.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/tr.json
new file mode 100644
index 0000000000..5bf83ee7a8
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/tr.json
@@ -0,0 +1,8 @@
+{
+ "culture": "tr",
+ "texts": {
+ "Menu:Home": "Ana sayfa",
+ "Welcome": "Hoşgeldiniz",
+ "LongWelcomeMessage": "Uygulamaya hoşgeldiniz. Bu, ABP framework'ü üzerine bina edilmiş bir başlangıç projesidir. Daha fazla bilgi için abp.io adresini ziyaret edebilirsiniz."
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/vi.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/vi.json
new file mode 100644
index 0000000000..c115a35726
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/vi.json
@@ -0,0 +1,8 @@
+{
+ "culture": "vi",
+ "texts": {
+ "Menu:Home": "Trang chủ",
+ "Welcome": "Chào mừng bạn",
+ "LongWelcomeMessage": "Chào mừng bạn đến ứng dụng. Đây là một dự án khởi nghiệp dựa trên khung ABP. Để biết thêm thông tin, hãy truy cập abp.io."
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/zh-Hans.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/zh-Hans.json
new file mode 100644
index 0000000000..23790bde50
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/zh-Hans.json
@@ -0,0 +1,8 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "Menu:Home": "首页",
+ "Welcome": "欢迎",
+ "LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 abp.io."
+ }
+ }
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/zh-Hant.json b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/zh-Hant.json
new file mode 100644
index 0000000000..31e0ab5a47
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIO/zh-Hant.json
@@ -0,0 +1,8 @@
+{
+ "culture": "zh-Hant",
+ "texts": {
+ "Menu:Home": "首頁",
+ "Welcome": "歡迎",
+ "LongWelcomeMessage": "歡迎來到此應用程式. 這是一個基於ABP框架的起始專案. 有關更多訊息, 請瀏覽 abp.io."
+ }
+ }
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIOResource.cs b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIOResource.cs
new file mode 100644
index 0000000000..5f1a247244
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/Localization/ExcelIOResource.cs
@@ -0,0 +1,10 @@
+using Volo.Abp.Localization;
+
+namespace ExcelIO.Localization
+{
+ [LocalizationResourceName("ExcelIO")]
+ public class ExcelIOResource
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs b/ExcelIO/src/ExcelIO.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs
new file mode 100644
index 0000000000..032b2c90b0
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain.Shared/MultiTenancy/MultiTenancyConsts.cs
@@ -0,0 +1,11 @@
+namespace ExcelIO.MultiTenancy
+{
+ public static class MultiTenancyConsts
+ {
+ /* Enable/disable multi-tenancy easily in a single point.
+ * If you will never need to multi-tenancy, you can remove
+ * related modules and code parts, including this file.
+ */
+ public const bool IsEnabled = true;
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain/Data/ExcelIODbMigrationService.cs b/ExcelIO/src/ExcelIO.Domain/Data/ExcelIODbMigrationService.cs
new file mode 100644
index 0000000000..ee579779b6
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/Data/ExcelIODbMigrationService.cs
@@ -0,0 +1,93 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.TenantManagement;
+
+namespace ExcelIO.Data
+{
+ public class ExcelIODbMigrationService : ITransientDependency
+ {
+ public ILogger Logger { get; set; }
+
+ private readonly IDataSeeder _dataSeeder;
+ private readonly IEnumerable _dbSchemaMigrators;
+ private readonly ITenantRepository _tenantRepository;
+ private readonly ICurrentTenant _currentTenant;
+
+ public ExcelIODbMigrationService(
+ IDataSeeder dataSeeder,
+ IEnumerable dbSchemaMigrators,
+ ITenantRepository tenantRepository,
+ ICurrentTenant currentTenant)
+ {
+ _dataSeeder = dataSeeder;
+ _dbSchemaMigrators = dbSchemaMigrators;
+ _tenantRepository = tenantRepository;
+ _currentTenant = currentTenant;
+
+ Logger = NullLogger.Instance;
+ }
+
+ public async Task MigrateAsync()
+ {
+ Logger.LogInformation("Started database migrations...");
+
+ await MigrateDatabaseSchemaAsync();
+ await SeedDataAsync();
+
+ Logger.LogInformation($"Successfully completed host database migrations.");
+
+ var tenants = await _tenantRepository.GetListAsync(includeDetails: true);
+
+ var migratedDatabaseSchemas = new HashSet();
+ foreach (var tenant in tenants)
+ {
+ using (_currentTenant.Change(tenant.Id))
+ {
+ if (tenant.ConnectionStrings.Any())
+ {
+ var tenantConnectionStrings = tenant.ConnectionStrings
+ .Select(x => x.Value)
+ .ToList();
+
+ if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings))
+ {
+ await MigrateDatabaseSchemaAsync(tenant);
+
+ migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings);
+ }
+ }
+
+ await SeedDataAsync(tenant);
+ }
+
+ Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations.");
+ }
+
+ Logger.LogInformation("Successfully completed database migrations.");
+ }
+
+ private async Task MigrateDatabaseSchemaAsync(Tenant tenant = null)
+ {
+ Logger.LogInformation(
+ $"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database...");
+
+ foreach (var migrator in _dbSchemaMigrators)
+ {
+ await migrator.MigrateAsync();
+ }
+ }
+
+ private async Task SeedDataAsync(Tenant tenant = null)
+ {
+ Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed...");
+
+ await _dataSeeder.SeedAsync(tenant?.Id);
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain/Data/IExcelIODbSchemaMigrator.cs b/ExcelIO/src/ExcelIO.Domain/Data/IExcelIODbSchemaMigrator.cs
new file mode 100644
index 0000000000..02a4044355
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/Data/IExcelIODbSchemaMigrator.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace ExcelIO.Data
+{
+ public interface IExcelIODbSchemaMigrator
+ {
+ Task MigrateAsync();
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain/Data/NullExcelIODbSchemaMigrator.cs b/ExcelIO/src/ExcelIO.Domain/Data/NullExcelIODbSchemaMigrator.cs
new file mode 100644
index 0000000000..47d67b7279
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/Data/NullExcelIODbSchemaMigrator.cs
@@ -0,0 +1,16 @@
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace ExcelIO.Data
+{
+ /* This is used if database provider does't define
+ * IExcelIODbSchemaMigrator implementation.
+ */
+ public class NullExcelIODbSchemaMigrator : IExcelIODbSchemaMigrator, ITransientDependency
+ {
+ public Task MigrateAsync()
+ {
+ return Task.CompletedTask;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain/ExcelIO.Domain.csproj b/ExcelIO/src/ExcelIO.Domain/ExcelIO.Domain.csproj
new file mode 100644
index 0000000000..6f63109cbb
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/ExcelIO.Domain.csproj
@@ -0,0 +1,27 @@
+
+
+
+
+
+ net5.0
+ ExcelIO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ExcelIO/src/ExcelIO.Domain/ExcelIOConsts.cs b/ExcelIO/src/ExcelIO.Domain/ExcelIOConsts.cs
new file mode 100644
index 0000000000..3eeec6b47a
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/ExcelIOConsts.cs
@@ -0,0 +1,9 @@
+namespace ExcelIO
+{
+ public static class ExcelIOConsts
+ {
+ public const string DbTablePrefix = "App";
+
+ public const string DbSchema = null;
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain/ExcelIODomainModule.cs b/ExcelIO/src/ExcelIO.Domain/ExcelIODomainModule.cs
new file mode 100644
index 0000000000..adbbda9b89
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/ExcelIODomainModule.cs
@@ -0,0 +1,46 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using ExcelIO.MultiTenancy;
+using Volo.Abp.AuditLogging;
+using Volo.Abp.BackgroundJobs;
+using Volo.Abp.Emailing;
+using Volo.Abp.FeatureManagement;
+using Volo.Abp.Identity;
+using Volo.Abp.IdentityServer;
+using Volo.Abp.Modularity;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.PermissionManagement.Identity;
+using Volo.Abp.PermissionManagement.IdentityServer;
+using Volo.Abp.SettingManagement;
+using Volo.Abp.TenantManagement;
+
+namespace ExcelIO
+{
+ [DependsOn(
+ typeof(ExcelIODomainSharedModule),
+ typeof(AbpAuditLoggingDomainModule),
+ typeof(AbpBackgroundJobsDomainModule),
+ typeof(AbpFeatureManagementDomainModule),
+ typeof(AbpIdentityDomainModule),
+ typeof(AbpPermissionManagementDomainIdentityModule),
+ typeof(AbpIdentityServerDomainModule),
+ typeof(AbpPermissionManagementDomainIdentityServerModule),
+ typeof(AbpSettingManagementDomainModule),
+ typeof(AbpTenantManagementDomainModule),
+ typeof(AbpEmailingModule)
+ )]
+ public class ExcelIODomainModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.IsEnabled = MultiTenancyConsts.IsEnabled;
+ });
+
+#if DEBUG
+ context.Services.Replace(ServiceDescriptor.Singleton());
+#endif
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain/IdentityServer/IdentityServerDataSeedContributor.cs b/ExcelIO/src/ExcelIO.Domain/IdentityServer/IdentityServerDataSeedContributor.cs
new file mode 100644
index 0000000000..b070fba14c
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/IdentityServer/IdentityServerDataSeedContributor.cs
@@ -0,0 +1,324 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using IdentityServer4.Models;
+using Microsoft.Extensions.Configuration;
+using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Data;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Guids;
+using Volo.Abp.IdentityServer.ApiResources;
+using Volo.Abp.IdentityServer.ApiScopes;
+using Volo.Abp.IdentityServer.Clients;
+using Volo.Abp.IdentityServer.IdentityResources;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.PermissionManagement;
+using Volo.Abp.Uow;
+using ApiResource = Volo.Abp.IdentityServer.ApiResources.ApiResource;
+using ApiScope = Volo.Abp.IdentityServer.ApiScopes.ApiScope;
+using Client = Volo.Abp.IdentityServer.Clients.Client;
+
+namespace ExcelIO.IdentityServer
+{
+ public class IdentityServerDataSeedContributor : IDataSeedContributor, ITransientDependency
+ {
+ private readonly IApiResourceRepository _apiResourceRepository;
+ private readonly IApiScopeRepository _apiScopeRepository;
+ private readonly IClientRepository _clientRepository;
+ private readonly IIdentityResourceDataSeeder _identityResourceDataSeeder;
+ private readonly IGuidGenerator _guidGenerator;
+ private readonly IPermissionDataSeeder _permissionDataSeeder;
+ private readonly IConfiguration _configuration;
+ private readonly ICurrentTenant _currentTenant;
+
+ public IdentityServerDataSeedContributor(
+ IClientRepository clientRepository,
+ IApiResourceRepository apiResourceRepository,
+ IApiScopeRepository apiScopeRepository,
+ IIdentityResourceDataSeeder identityResourceDataSeeder,
+ IGuidGenerator guidGenerator,
+ IPermissionDataSeeder permissionDataSeeder,
+ IConfiguration configuration,
+ ICurrentTenant currentTenant)
+ {
+ _clientRepository = clientRepository;
+ _apiResourceRepository = apiResourceRepository;
+ _apiScopeRepository = apiScopeRepository;
+ _identityResourceDataSeeder = identityResourceDataSeeder;
+ _guidGenerator = guidGenerator;
+ _permissionDataSeeder = permissionDataSeeder;
+ _configuration = configuration;
+ _currentTenant = currentTenant;
+ }
+
+ [UnitOfWork]
+ public virtual async Task SeedAsync(DataSeedContext context)
+ {
+ using (_currentTenant.Change(context?.TenantId))
+ {
+ await _identityResourceDataSeeder.CreateStandardResourcesAsync();
+ await CreateApiResourcesAsync();
+ await CreateApiScopesAsync();
+ await CreateClientsAsync();
+ }
+ }
+
+ private async Task CreateApiScopesAsync()
+ {
+ await CreateApiScopeAsync("ExcelIO");
+ }
+
+ private async Task CreateApiResourcesAsync()
+ {
+ var commonApiUserClaims = new[]
+ {
+ "email",
+ "email_verified",
+ "name",
+ "phone_number",
+ "phone_number_verified",
+ "role"
+ };
+
+ await CreateApiResourceAsync("ExcelIO", commonApiUserClaims);
+ }
+
+ private async Task CreateApiResourceAsync(string name, IEnumerable claims)
+ {
+ var apiResource = await _apiResourceRepository.FindByNameAsync(name);
+ if (apiResource == null)
+ {
+ apiResource = await _apiResourceRepository.InsertAsync(
+ new ApiResource(
+ _guidGenerator.Create(),
+ name,
+ name + " API"
+ ),
+ autoSave: true
+ );
+ }
+
+ foreach (var claim in claims)
+ {
+ if (apiResource.FindClaim(claim) == null)
+ {
+ apiResource.AddUserClaim(claim);
+ }
+ }
+
+ return await _apiResourceRepository.UpdateAsync(apiResource);
+ }
+
+ private async Task CreateApiScopeAsync(string name)
+ {
+ var apiScope = await _apiScopeRepository.GetByNameAsync(name);
+ if (apiScope == null)
+ {
+ apiScope = await _apiScopeRepository.InsertAsync(
+ new ApiScope(
+ _guidGenerator.Create(),
+ name,
+ name + " API"
+ ),
+ autoSave: true
+ );
+ }
+
+ return apiScope;
+ }
+
+ private async Task CreateClientsAsync()
+ {
+ var commonScopes = new[]
+ {
+ "email",
+ "openid",
+ "profile",
+ "role",
+ "phone",
+ "address",
+ "ExcelIO"
+ };
+
+ var configurationSection = _configuration.GetSection("IdentityServer:Clients");
+
+ //Web Client
+ var webClientId = configurationSection["ExcelIO_Web:ClientId"];
+ if (!webClientId.IsNullOrWhiteSpace())
+ {
+ var webClientRootUrl = configurationSection["ExcelIO_Web:RootUrl"].EnsureEndsWith('/');
+
+ /* ExcelIO_Web client is only needed if you created a tiered
+ * solution. Otherwise, you can delete this client. */
+
+ await CreateClientAsync(
+ name: webClientId,
+ scopes: commonScopes,
+ grantTypes: new[] { "hybrid" },
+ secret: (configurationSection["ExcelIO_Web:ClientSecret"] ?? "1q2w3e*").Sha256(),
+ redirectUri: $"{webClientRootUrl}signin-oidc",
+ postLogoutRedirectUri: $"{webClientRootUrl}signout-callback-oidc",
+ frontChannelLogoutUri: $"{webClientRootUrl}Account/FrontChannelLogout",
+ corsOrigins: new[] { webClientRootUrl.RemovePostFix("/") }
+ );
+ }
+
+ //Console Test / Angular Client
+ var consoleAndAngularClientId = configurationSection["ExcelIO_App:ClientId"];
+ if (!consoleAndAngularClientId.IsNullOrWhiteSpace())
+ {
+ var webClientRootUrl = configurationSection["ExcelIO_App:RootUrl"]?.TrimEnd('/');
+
+ await CreateClientAsync(
+ name: consoleAndAngularClientId,
+ scopes: commonScopes,
+ grantTypes: new[] { "password", "client_credentials", "authorization_code" },
+ secret: (configurationSection["ExcelIO_App:ClientSecret"] ?? "1q2w3e*").Sha256(),
+ requireClientSecret: false,
+ redirectUri: webClientRootUrl,
+ postLogoutRedirectUri: webClientRootUrl,
+ corsOrigins: new[] { webClientRootUrl.RemovePostFix("/") }
+ );
+ }
+
+ // Blazor Client
+ var blazorClientId = configurationSection["ExcelIO_Blazor:ClientId"];
+ if (!blazorClientId.IsNullOrWhiteSpace())
+ {
+ var blazorRootUrl = configurationSection["ExcelIO_Blazor:RootUrl"].TrimEnd('/');
+
+ await CreateClientAsync(
+ name: blazorClientId,
+ scopes: commonScopes,
+ grantTypes: new[] { "authorization_code" },
+ secret: configurationSection["ExcelIO_Blazor:ClientSecret"]?.Sha256(),
+ requireClientSecret: false,
+ redirectUri: $"{blazorRootUrl}/authentication/login-callback",
+ postLogoutRedirectUri: $"{blazorRootUrl}/authentication/logout-callback",
+ corsOrigins: new[] { blazorRootUrl.RemovePostFix("/") }
+ );
+ }
+
+ // Swagger Client
+ var swaggerClientId = configurationSection["ExcelIO_Swagger:ClientId"];
+ if (!swaggerClientId.IsNullOrWhiteSpace())
+ {
+ var swaggerRootUrl = configurationSection["ExcelIO_Swagger:RootUrl"].TrimEnd('/');
+
+ await CreateClientAsync(
+ name: swaggerClientId,
+ scopes: commonScopes,
+ grantTypes: new[] { "authorization_code" },
+ secret: configurationSection["ExcelIO_Swagger:ClientSecret"]?.Sha256(),
+ requireClientSecret: false,
+ redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html",
+ corsOrigins: new[] { swaggerRootUrl.RemovePostFix("/") }
+ );
+ }
+ }
+
+ private async Task CreateClientAsync(
+ string name,
+ IEnumerable scopes,
+ IEnumerable grantTypes,
+ string secret = null,
+ string redirectUri = null,
+ string postLogoutRedirectUri = null,
+ string frontChannelLogoutUri = null,
+ bool requireClientSecret = true,
+ bool requirePkce = false,
+ IEnumerable permissions = null,
+ IEnumerable corsOrigins = null)
+ {
+ var client = await _clientRepository.FindByClientIdAsync(name);
+ if (client == null)
+ {
+ client = await _clientRepository.InsertAsync(
+ new Client(
+ _guidGenerator.Create(),
+ name
+ )
+ {
+ ClientName = name,
+ ProtocolType = "oidc",
+ Description = name,
+ AlwaysIncludeUserClaimsInIdToken = true,
+ AllowOfflineAccess = true,
+ AbsoluteRefreshTokenLifetime = 31536000, //365 days
+ AccessTokenLifetime = 31536000, //365 days
+ AuthorizationCodeLifetime = 300,
+ IdentityTokenLifetime = 300,
+ RequireConsent = false,
+ FrontChannelLogoutUri = frontChannelLogoutUri,
+ RequireClientSecret = requireClientSecret,
+ RequirePkce = requirePkce
+ },
+ autoSave: true
+ );
+ }
+
+ foreach (var scope in scopes)
+ {
+ if (client.FindScope(scope) == null)
+ {
+ client.AddScope(scope);
+ }
+ }
+
+ foreach (var grantType in grantTypes)
+ {
+ if (client.FindGrantType(grantType) == null)
+ {
+ client.AddGrantType(grantType);
+ }
+ }
+
+ if (!secret.IsNullOrEmpty())
+ {
+ if (client.FindSecret(secret) == null)
+ {
+ client.AddSecret(secret);
+ }
+ }
+
+ if (redirectUri != null)
+ {
+ if (client.FindRedirectUri(redirectUri) == null)
+ {
+ client.AddRedirectUri(redirectUri);
+ }
+ }
+
+ if (postLogoutRedirectUri != null)
+ {
+ if (client.FindPostLogoutRedirectUri(postLogoutRedirectUri) == null)
+ {
+ client.AddPostLogoutRedirectUri(postLogoutRedirectUri);
+ }
+ }
+
+ if (permissions != null)
+ {
+ await _permissionDataSeeder.SeedAsync(
+ ClientPermissionValueProvider.ProviderName,
+ name,
+ permissions,
+ null
+ );
+ }
+
+ if (corsOrigins != null)
+ {
+ foreach (var origin in corsOrigins)
+ {
+ if (!origin.IsNullOrWhiteSpace() && client.FindCorsOrigin(origin) == null)
+ {
+ client.AddCorsOrigin(origin);
+ }
+ }
+ }
+
+ return await _clientRepository.UpdateAsync(client);
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain/Properties/AssemblyInfo.cs b/ExcelIO/src/ExcelIO.Domain/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..882727b6b2
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/Properties/AssemblyInfo.cs
@@ -0,0 +1,3 @@
+using System.Runtime.CompilerServices;
+[assembly:InternalsVisibleToAttribute("ExcelIO.Domain.Tests")]
+[assembly:InternalsVisibleToAttribute("ExcelIO.TestBase")]
diff --git a/ExcelIO/src/ExcelIO.Domain/Settings/ExcelIOSettingDefinitionProvider.cs b/ExcelIO/src/ExcelIO.Domain/Settings/ExcelIOSettingDefinitionProvider.cs
new file mode 100644
index 0000000000..62a921eea6
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/Settings/ExcelIOSettingDefinitionProvider.cs
@@ -0,0 +1,13 @@
+using Volo.Abp.Settings;
+
+namespace ExcelIO.Settings
+{
+ public class ExcelIOSettingDefinitionProvider : SettingDefinitionProvider
+ {
+ public override void Define(ISettingDefinitionContext context)
+ {
+ //Define your own settings here. Example:
+ //context.Add(new SettingDefinition(ExcelIOSettings.MySetting1));
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.Domain/Settings/ExcelIOSettings.cs b/ExcelIO/src/ExcelIO.Domain/Settings/ExcelIOSettings.cs
new file mode 100644
index 0000000000..98afceb34a
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/Settings/ExcelIOSettings.cs
@@ -0,0 +1,10 @@
+namespace ExcelIO.Settings
+{
+ public static class ExcelIOSettings
+ {
+ private const string Prefix = "ExcelIO";
+
+ //Add your own setting names here. Example:
+ //public const string MySetting1 = Prefix + ".MySetting1";
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.Domain/Users/AppUser.cs b/ExcelIO/src/ExcelIO.Domain/Users/AppUser.cs
new file mode 100644
index 0000000000..7eca7f85ba
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.Domain/Users/AppUser.cs
@@ -0,0 +1,63 @@
+using System;
+using Volo.Abp.Domain.Entities.Auditing;
+using Volo.Abp.Users;
+
+namespace ExcelIO.Users
+{
+ /* This entity shares the same table/collection ("AbpUsers" by default) with the
+ * IdentityUser entity of the Identity module.
+ *
+ * - You can define your custom properties into this class.
+ * - You never create or delete this entity, because it is Identity module's job.
+ * - You can query users from database with this entity.
+ * - You can update values of your custom properties.
+ */
+ public class AppUser : FullAuditedAggregateRoot, IUser
+ {
+ #region Base properties
+
+ /* These properties are shared with the IdentityUser entity of the Identity module.
+ * Do not change these properties through this class. Instead, use Identity module
+ * services (like IdentityUserManager) to change them.
+ * So, this properties are designed as read only!
+ */
+
+ public virtual Guid? TenantId { get; private set; }
+
+ public virtual string UserName { get; private set; }
+
+ public virtual string Name { get; private set; }
+
+ public virtual string Surname { get; private set; }
+
+ public virtual string Email { get; private set; }
+
+ public virtual bool EmailConfirmed { get; private set; }
+
+ public virtual string PhoneNumber { get; private set; }
+
+ public virtual bool PhoneNumberConfirmed { get; private set; }
+
+ #endregion
+
+ /* Add your own properties here. Example:
+ *
+ * public string MyProperty { get; set; }
+ *
+ * If you add a property and using the EF Core, remember these;
+ *
+ * 1. Update ExcelIODbContext.OnModelCreating
+ * to configure the mapping for your new property
+ * 2. Update ExcelIOEfCoreEntityExtensionMappings to extend the IdentityUser entity
+ * and add your new property to the migration.
+ * 3. Use the Add-Migration to add a new database migration.
+ * 4. Run the .DbMigrator project (or use the Update-Database command) to apply
+ * schema change to the database.
+ */
+
+ private AppUser()
+ {
+
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/EntityFrameworkCoreExcelIODbSchemaMigrator.cs b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/EntityFrameworkCoreExcelIODbSchemaMigrator.cs
new file mode 100644
index 0000000000..6c0a5f0b69
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/EntityFrameworkCoreExcelIODbSchemaMigrator.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using ExcelIO.Data;
+using Volo.Abp.DependencyInjection;
+
+namespace ExcelIO.EntityFrameworkCore
+{
+ public class EntityFrameworkCoreExcelIODbSchemaMigrator
+ : IExcelIODbSchemaMigrator, ITransientDependency
+ {
+ private readonly IServiceProvider _serviceProvider;
+
+ public EntityFrameworkCoreExcelIODbSchemaMigrator(
+ IServiceProvider serviceProvider)
+ {
+ _serviceProvider = serviceProvider;
+ }
+
+ public async Task MigrateAsync()
+ {
+ /* We intentionally resolving the ExcelIOMigrationsDbContext
+ * from IServiceProvider (instead of directly injecting it)
+ * to properly get the connection string of the current tenant in the
+ * current scope.
+ */
+
+ await _serviceProvider
+ .GetRequiredService()
+ .Database
+ .MigrateAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOEntityFrameworkCoreDbMigrationsModule.cs b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOEntityFrameworkCoreDbMigrationsModule.cs
new file mode 100644
index 0000000000..7f4d1330e5
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOEntityFrameworkCoreDbMigrationsModule.cs
@@ -0,0 +1,16 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Modularity;
+
+namespace ExcelIO.EntityFrameworkCore
+{
+ [DependsOn(
+ typeof(ExcelIOEntityFrameworkCoreModule)
+ )]
+ public class ExcelIOEntityFrameworkCoreDbMigrationsModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddAbpDbContext();
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOMigrationsDbContext.cs b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOMigrationsDbContext.cs
new file mode 100644
index 0000000000..320dadcd40
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOMigrationsDbContext.cs
@@ -0,0 +1,48 @@
+using Microsoft.EntityFrameworkCore;
+using Volo.Abp.AuditLogging.EntityFrameworkCore;
+using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
+using Volo.Abp.EntityFrameworkCore;
+using Volo.Abp.FeatureManagement.EntityFrameworkCore;
+using Volo.Abp.Identity;
+using Volo.Abp.Identity.EntityFrameworkCore;
+using Volo.Abp.IdentityServer.EntityFrameworkCore;
+using Volo.Abp.PermissionManagement.EntityFrameworkCore;
+using Volo.Abp.SettingManagement.EntityFrameworkCore;
+using Volo.Abp.TenantManagement.EntityFrameworkCore;
+
+namespace ExcelIO.EntityFrameworkCore
+{
+ /* This DbContext is only used for database migrations.
+ * It is not used on runtime. See ExcelIODbContext for the runtime DbContext.
+ * It is a unified model that includes configuration for
+ * all used modules and your application.
+ */
+ public class ExcelIOMigrationsDbContext : AbpDbContext
+ {
+ public ExcelIOMigrationsDbContext(DbContextOptions options)
+ : base(options)
+ {
+
+ }
+
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+
+ /* Include modules to your migration db context */
+
+ builder.ConfigurePermissionManagement();
+ builder.ConfigureSettingManagement();
+ builder.ConfigureBackgroundJobs();
+ builder.ConfigureAuditLogging();
+ builder.ConfigureIdentity();
+ builder.ConfigureIdentityServer();
+ builder.ConfigureFeatureManagement();
+ builder.ConfigureTenantManagement();
+
+ /* Configure your own tables/entities inside the ConfigureExcelIO method */
+
+ builder.ConfigureExcelIO();
+ }
+ }
+}
\ No newline at end of file
diff --git a/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOMigrationsDbContextFactory.cs b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOMigrationsDbContextFactory.cs
new file mode 100644
index 0000000000..6abe650807
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/EntityFrameworkCore/ExcelIOMigrationsDbContextFactory.cs
@@ -0,0 +1,33 @@
+using System.IO;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Design;
+using Microsoft.Extensions.Configuration;
+
+namespace ExcelIO.EntityFrameworkCore
+{
+ /* This class is needed for EF Core console commands
+ * (like Add-Migration and Update-Database commands) */
+ public class ExcelIOMigrationsDbContextFactory : IDesignTimeDbContextFactory
+ {
+ public ExcelIOMigrationsDbContext CreateDbContext(string[] args)
+ {
+ ExcelIOEfCoreEntityExtensionMappings.Configure();
+
+ var configuration = BuildConfiguration();
+
+ var builder = new DbContextOptionsBuilder()
+ .UseSqlServer(configuration.GetConnectionString("Default"));
+
+ return new ExcelIOMigrationsDbContext(builder.Options);
+ }
+
+ private static IConfigurationRoot BuildConfiguration()
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), "../ExcelIO.DbMigrator/"))
+ .AddJsonFile("appsettings.json", optional: false);
+
+ return builder.Build();
+ }
+ }
+}
diff --git a/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/ExcelIO.EntityFrameworkCore.DbMigrations.csproj b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/ExcelIO.EntityFrameworkCore.DbMigrations.csproj
new file mode 100644
index 0000000000..ff3e70a4a4
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/ExcelIO.EntityFrameworkCore.DbMigrations.csproj
@@ -0,0 +1,18 @@
+
+
+
+
+
+ net5.0
+ ExcelIO
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/Migrations/20210121064714_init.Designer.cs b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/Migrations/20210121064714_init.Designer.cs
new file mode 100644
index 0000000000..f9e7ef00f5
--- /dev/null
+++ b/ExcelIO/src/ExcelIO.EntityFrameworkCore.DbMigrations/Migrations/20210121064714_init.Designer.cs
@@ -0,0 +1,2307 @@
+//
+using System;
+using ExcelIO.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Volo.Abp.EntityFrameworkCore;
+
+namespace ExcelIO.Migrations
+{
+ [DbContext(typeof(ExcelIOMigrationsDbContext))]
+ [Migration("20210121064714_init")]
+ partial class init
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .UseIdentityColumns()
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer)
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("ProductVersion", "5.0.2");
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)")
+ .HasColumnName("ApplicationName");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)")
+ .HasColumnName("BrowserInfo");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("ClientId");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("ClientIpAddress");
+
+ b.Property("ClientName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("ClientName");
+
+ b.Property("Comments")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("Comments");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("CorrelationId");
+
+ b.Property("Exceptions")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)")
+ .HasColumnName("Exceptions");
+
+ b.Property("ExecutionDuration")
+ .HasColumnType("int")
+ .HasColumnName("ExecutionDuration");
+
+ b.Property("ExecutionTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("HttpMethod")
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)")
+ .HasColumnName("HttpMethod");
+
+ b.Property("HttpStatusCode")
+ .HasColumnType("int")
+ .HasColumnName("HttpStatusCode");
+
+ b.Property("ImpersonatorTenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("ImpersonatorTenantId");
+
+ b.Property("ImpersonatorUserId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("ImpersonatorUserId");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("TenantName")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Url")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("Url");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("UserId");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("UserName");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "ExecutionTime");
+
+ b.HasIndex("TenantId", "UserId", "ExecutionTime");
+
+ b.ToTable("AbpAuditLogs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditLogId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("AuditLogId");
+
+ b.Property("ExecutionDuration")
+ .HasColumnType("int")
+ .HasColumnName("ExecutionDuration");
+
+ b.Property("ExecutionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("ExecutionTime");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("MethodName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("MethodName");
+
+ b.Property("Parameters")
+ .HasMaxLength(2000)
+ .HasColumnType("nvarchar(2000)")
+ .HasColumnName("Parameters");
+
+ b.Property("ServiceName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("ServiceName");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuditLogId");
+
+ b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime");
+
+ b.ToTable("AbpAuditLogActions");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditLogId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("AuditLogId");
+
+ b.Property("ChangeTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("ChangeTime");
+
+ b.Property("ChangeType")
+ .HasColumnType("tinyint")
+ .HasColumnName("ChangeType");
+
+ b.Property("EntityId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("EntityId");
+
+ b.Property("EntityTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("EntityTypeFullName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("EntityTypeFullName");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuditLogId");
+
+ b.HasIndex("TenantId", "EntityTypeFullName", "EntityId");
+
+ b.ToTable("AbpEntityChanges");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("EntityChangeId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("NewValue")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)")
+ .HasColumnName("NewValue");
+
+ b.Property("OriginalValue")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)")
+ .HasColumnName("OriginalValue");
+
+ b.Property("PropertyName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("PropertyName");
+
+ b.Property("PropertyTypeFullName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("PropertyTypeFullName");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("EntityChangeId");
+
+ b.ToTable("AbpEntityPropertyChanges");
+ });
+
+ modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsAbandoned")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false);
+
+ b.Property("JobArgs")
+ .IsRequired()
+ .HasMaxLength(1048576)
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("JobName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastTryTime")
+ .HasColumnType("datetime2");
+
+ b.Property("NextTryTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Priority")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("tinyint")
+ .HasDefaultValue((byte)15);
+
+ b.Property("TryCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("smallint")
+ .HasDefaultValue((short)0);
+
+ b.HasKey("Id");
+
+ b.HasIndex("IsAbandoned", "NextTryTime");
+
+ b.ToTable("AbpBackgroundJobs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderKey")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ProviderName")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name", "ProviderName", "ProviderKey");
+
+ b.ToTable("AbpFeatureValues");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("Description")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsStatic")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("Regex")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("RegexDescription")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("Required")
+ .HasColumnType("bit");
+
+ b.Property("ValueType")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("AbpClaimTypes");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SourceTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SourceUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TargetTenantId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TargetUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId")
+ .IsUnique()
+ .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL");
+
+ b.ToTable("AbpLinkUsers");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDefault")
+ .HasColumnType("bit")
+ .HasColumnName("IsDefault");
+
+ b.Property("IsPublic")
+ .HasColumnType("bit")
+ .HasColumnName("IsPublic");
+
+ b.Property("IsStatic")
+ .HasColumnType("bit")
+ .HasColumnName("IsStatic");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("NormalizedName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName");
+
+ b.ToTable("AbpRoles");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AbpRoleClaims");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Action")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("nvarchar(512)");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Identity")
+ .HasMaxLength(96)
+ .HasColumnType("nvarchar(96)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("TenantName")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TenantId", "Action");
+
+ b.HasIndex("TenantId", "ApplicationName");
+
+ b.HasIndex("TenantId", "Identity");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("AbpSecurityLogs");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AccessFailedCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasDefaultValue(0)
+ .HasColumnName("AccessFailedCount");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("Email");
+
+ b.Property("EmailConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("EmailConfirmed");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("IsExternal")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsExternal");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("LockoutEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("LockoutEnabled");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("Name")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("Name");
+
+ b.Property("NormalizedEmail")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("NormalizedEmail");
+
+ b.Property("NormalizedUserName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("NormalizedUserName");
+
+ b.Property("PasswordHash")
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("PasswordHash");
+
+ b.Property("PhoneNumber")
+ .HasMaxLength(16)
+ .HasColumnType("nvarchar(16)")
+ .HasColumnName("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("PhoneNumberConfirmed");
+
+ b.Property("SecurityStamp")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("SecurityStamp");
+
+ b.Property("Surname")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)")
+ .HasColumnName("Surname");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("TwoFactorEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)")
+ .HasColumnName("UserName");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Email");
+
+ b.HasIndex("NormalizedEmail");
+
+ b.HasIndex("NormalizedUserName");
+
+ b.HasIndex("UserName");
+
+ b.ToTable("AbpUsers");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("nvarchar(1024)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AbpUserClaims");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("ProviderDisplayName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("ProviderKey")
+ .IsRequired()
+ .HasMaxLength(196)
+ .HasColumnType("nvarchar(196)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "LoginProvider");
+
+ b.HasIndex("LoginProvider", "ProviderKey");
+
+ b.ToTable("AbpUserLogins");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b =>
+ {
+ b.Property("OrganizationUnitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("OrganizationUnitId", "UserId");
+
+ b.HasIndex("UserId", "OrganizationUnitId");
+
+ b.ToTable("AbpUserOrganizationUnits");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId", "UserId");
+
+ b.ToTable("AbpUserRoles");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("LoginProvider")
+ .HasMaxLength(64)
+ .HasColumnType("nvarchar(64)");
+
+ b.Property("Name")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.Property("Value")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AbpUserTokens");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(95)
+ .HasColumnType("nvarchar(95)")
+ .HasColumnName("Code");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)")
+ .HasColumnName("DisplayName");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("ParentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Code");
+
+ b.HasIndex("ParentId");
+
+ b.ToTable("AbpOrganizationUnits");
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b =>
+ {
+ b.Property("OrganizationUnitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("RoleId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("TenantId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("TenantId");
+
+ b.HasKey("OrganizationUnitId", "RoleId");
+
+ b.HasIndex("RoleId", "OrganizationUnitId");
+
+ b.ToTable("AbpOrganizationUnitRoles");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AllowedAccessTokenSigningAlgorithms")
+ .HasMaxLength(100)
+ .HasColumnType("nvarchar(100)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Description")
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("DisplayName")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("ShowInDiscoveryDocument")
+ .HasColumnType("bit");
+
+ b.HasKey("Id");
+
+ b.ToTable("IdentityServerApiResources");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b =>
+ {
+ b.Property("ApiResourceId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Type")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.HasKey("ApiResourceId", "Type");
+
+ b.ToTable("IdentityServerApiResourceClaims");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b =>
+ {
+ b.Property("ApiResourceId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Key")
+ .HasMaxLength(250)
+ .HasColumnType("nvarchar(250)");
+
+ b.Property("Value")
+ .HasMaxLength(2000)
+ .HasColumnType("nvarchar(2000)");
+
+ b.HasKey("ApiResourceId", "Key", "Value");
+
+ b.ToTable("IdentityServerApiResourceProperties");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b =>
+ {
+ b.Property("ApiResourceId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Scope")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.HasKey("ApiResourceId", "Scope");
+
+ b.ToTable("IdentityServerApiResourceScopes");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b =>
+ {
+ b.Property("ApiResourceId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Type")
+ .HasMaxLength(250)
+ .HasColumnType("nvarchar(250)");
+
+ b.Property("Value")
+ .HasMaxLength(4000)
+ .HasColumnType("nvarchar(4000)");
+
+ b.Property("Description")
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("Expiration")
+ .HasColumnType("datetime2");
+
+ b.HasKey("ApiResourceId", "Type", "Value");
+
+ b.ToTable("IdentityServerApiResourceSecrets");
+ });
+
+ modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("nvarchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("CreatorId");
+
+ b.Property("DeleterId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("DeleterId");
+
+ b.Property("DeletionTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("DeletionTime");
+
+ b.Property("Description")
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("DisplayName")
+ .HasMaxLength(200)
+ .HasColumnType("nvarchar(200)");
+
+ b.Property("Emphasize")
+ .HasColumnType("bit");
+
+ b.Property("Enabled")
+ .HasColumnType("bit");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("nvarchar(max)")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bit")
+ .HasDefaultValue(false)
+ .HasColumnName("IsDeleted");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime2")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uniqueidentifier")
+ .HasColumnName("LastModifierId");
+
+ b.Property