Adds transactional outbox and email verification

Implements outbox pattern for reliable message delivery
Adds email verification flow with Postmark integration
Enhances account registration with secure token generation

Introduces background processing for asynchronous email sending
Implements database-level notification mechanism for message processing
This commit is contained in:
Janus C. H. Knudsen 2026-01-10 11:13:33 +01:00
parent 88812177a9
commit 54b057886c
35 changed files with 1174 additions and 358 deletions

View file

@ -1,60 +1,66 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35013.160
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.Core", "Core\PlanTempus.Core.csproj", "{7B554252-1CE4-44BD-B108-B0BDCCB24742}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.X.TDD", "Tests\PlanTempus.X.TDD.csproj", "{85614050-CFB0-4E39-81D3-7D99946449D9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.Application", "Application\PlanTempus.Application.csproj", "{111CE8AE-E637-4376-A5A3-88D33E77EA88}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.Database", "Database\PlanTempus.Database.csproj", "{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.SetupInfrastructure", "SetupInfrastructure\PlanTempus.SetupInfrastructure.csproj", "{48300227-BCBB-45A3-8359-9064DA85B1F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanTempus.X.BDD", "PlanTempus.X.BDD\PlanTempus.X.BDD.csproj", "{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanTempus.Components", "PlanTempus.Components\PlanTempus.Components.csproj", "{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7B554252-1CE4-44BD-B108-B0BDCCB24742}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B554252-1CE4-44BD-B108-B0BDCCB24742}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B554252-1CE4-44BD-B108-B0BDCCB24742}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B554252-1CE4-44BD-B108-B0BDCCB24742}.Release|Any CPU.Build.0 = Release|Any CPU
{85614050-CFB0-4E39-81D3-7D99946449D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85614050-CFB0-4E39-81D3-7D99946449D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85614050-CFB0-4E39-81D3-7D99946449D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85614050-CFB0-4E39-81D3-7D99946449D9}.Release|Any CPU.Build.0 = Release|Any CPU
{111CE8AE-E637-4376-A5A3-88D33E77EA88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{111CE8AE-E637-4376-A5A3-88D33E77EA88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{111CE8AE-E637-4376-A5A3-88D33E77EA88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{111CE8AE-E637-4376-A5A3-88D33E77EA88}.Release|Any CPU.Build.0 = Release|Any CPU
{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}.Release|Any CPU.Build.0 = Release|Any CPU
{48300227-BCBB-45A3-8359-9064DA85B1F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48300227-BCBB-45A3-8359-9064DA85B1F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48300227-BCBB-45A3-8359-9064DA85B1F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48300227-BCBB-45A3-8359-9064DA85B1F9}.Release|Any CPU.Build.0 = Release|Any CPU
{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}.Release|Any CPU.Build.0 = Release|Any CPU
{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AF20C396-63E0-48AE-A4EA-5D24A20C4845}
EndGlobalSection
EndGlobal
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35013.160
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.Core", "Core\PlanTempus.Core.csproj", "{7B554252-1CE4-44BD-B108-B0BDCCB24742}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.X.TDD", "Tests\PlanTempus.X.TDD.csproj", "{85614050-CFB0-4E39-81D3-7D99946449D9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.Application", "Application\PlanTempus.Application.csproj", "{111CE8AE-E637-4376-A5A3-88D33E77EA88}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.Database", "Database\PlanTempus.Database.csproj", "{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlanTempus.SetupInfrastructure", "SetupInfrastructure\PlanTempus.SetupInfrastructure.csproj", "{48300227-BCBB-45A3-8359-9064DA85B1F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanTempus.X.BDD", "PlanTempus.X.BDD\PlanTempus.X.BDD.csproj", "{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlanTempus.Components", "PlanTempus.Components\PlanTempus.Components.csproj", "{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestPostgresql", "TestPostgresLISTEN\TestPostgresql.csproj", "{67C167C4-8086-0556-39DA-5F9DF6CEE51F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7B554252-1CE4-44BD-B108-B0BDCCB24742}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B554252-1CE4-44BD-B108-B0BDCCB24742}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B554252-1CE4-44BD-B108-B0BDCCB24742}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B554252-1CE4-44BD-B108-B0BDCCB24742}.Release|Any CPU.Build.0 = Release|Any CPU
{85614050-CFB0-4E39-81D3-7D99946449D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85614050-CFB0-4E39-81D3-7D99946449D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85614050-CFB0-4E39-81D3-7D99946449D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85614050-CFB0-4E39-81D3-7D99946449D9}.Release|Any CPU.Build.0 = Release|Any CPU
{111CE8AE-E637-4376-A5A3-88D33E77EA88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{111CE8AE-E637-4376-A5A3-88D33E77EA88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{111CE8AE-E637-4376-A5A3-88D33E77EA88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{111CE8AE-E637-4376-A5A3-88D33E77EA88}.Release|Any CPU.Build.0 = Release|Any CPU
{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5096A7F-E6D4-4C87-874E-2D9A6BEAD57F}.Release|Any CPU.Build.0 = Release|Any CPU
{48300227-BCBB-45A3-8359-9064DA85B1F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48300227-BCBB-45A3-8359-9064DA85B1F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48300227-BCBB-45A3-8359-9064DA85B1F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48300227-BCBB-45A3-8359-9064DA85B1F9}.Release|Any CPU.Build.0 = Release|Any CPU
{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CA2246B-7D8C-40DA-9042-CA17A7A7672B}.Release|Any CPU.Build.0 = Release|Any CPU
{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECC8621A-7B3F-4E26-85A1-926FA263E5D7}.Release|Any CPU.Build.0 = Release|Any CPU
{67C167C4-8086-0556-39DA-5F9DF6CEE51F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67C167C4-8086-0556-39DA-5F9DF6CEE51F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67C167C4-8086-0556-39DA-5F9DF6CEE51F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67C167C4-8086-0556-39DA-5F9DF6CEE51F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AF20C396-63E0-48AE-A4EA-5D24A20C4845}
EndGlobalSection
EndGlobal