10 Commits

Author SHA1 Message Date
mrcwlnd c77cd7d524 Merge pull request 'fixed' (#13) from testbranch into main
Reviewed-on: #13
2026-06-25 18:59:26 +00:00
mrcwlnd 17c8e5e9ed Merge pull request 'feat: ignore pending model changes warnings and update EF Core version in DbContext configuration' (#12) from testbranch into main
Reviewed-on: #12
2026-06-25 18:49:21 +00:00
mrcwlnd 9bcce06842 Merge pull request 'fixed database' (#11) from testbranch into main
Reviewed-on: #11
2026-06-25 18:41:18 +00:00
mrcwlnd 528eeb13a1 Merge pull request 'Multi tenant integration' (#10) from multi-tenant-integration into main
Reviewed-on: #10
2026-06-25 18:34:05 +00:00
mrcwlnd d5f68ca520 Merge branch 'main' into multi-tenant-integration 2026-06-25 18:34:01 +00:00
mrcwlnd 8a0bf59994 Merge pull request 'feat: add vacation day management to home view and persist changelog version in local storage' (#9) from multi-tenant-integration into main
Reviewed-on: #9
2026-06-24 20:39:48 +00:00
mrcwlnd 147b589d59 Merge pull request 'little bugfix' (#8) from multi-tenant-integration into main
Reviewed-on: #8
2026-06-24 20:33:35 +00:00
mrcwlnd a379088a24 Merge pull request 'Huge updates' (#7) from navbar_styling into main
Reviewed-on: #7
2026-06-24 20:29:47 +00:00
mrcwlnd 9824616323 Merge pull request 'Neue agb seite implementiert' (#6) from navbar_styling into main
Reviewed-on: #6
2026-06-08 22:24:11 +00:00
mrcwlnd 8bd7423209 Merge pull request 'Neue navbar' (#5) from navbar_styling into main
Reviewed-on: #5
2026-06-08 22:06:32 +00:00
4 changed files with 14 additions and 100 deletions
+1 -6
View File
@@ -28,14 +28,9 @@ services:
- DB_PROVIDER=PostgreSQL
- ConnectionStrings__DefaultConnection=Host=db;Database=timetracker;Username=timetracker_user;Password=SecretPassword123;
- EnableHttpsRedirect=false
- TenantSettings__BaseDomain=timetracker.marc-wieland.de
volumes:
- dpkeys:/home/app/.aspnet/DataProtection-Keys
depends_on:
- db
volumes:
pgdata:
name: timetracker_pgdata
dpkeys:
name: timetracker_dpkeys
name: timetracker_pgdata
@@ -1,4 +1,4 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
@@ -13,6 +13,7 @@ namespace timetracker.Data.Migrations
migrationBuilder.AddColumn<bool>(
name: "IsTenantAdmin",
table: "Users",
type: "INTEGER",
nullable: false,
defaultValue: false);
+11 -11
View File
@@ -37,7 +37,7 @@ public class TenantProvider : ITenantProvider
}
// Resolve and cache in HttpContext.Items
ResolveTenant();
ResolveTenantAsync().GetAwaiter().GetResult();
if (httpContext.Items.TryGetValue("TenantId", out cachedId))
{
@@ -48,27 +48,27 @@ public class TenantProvider : ITenantProvider
}
}
public Task<Tenant?> GetCurrentTenantAsync()
public async Task<Tenant?> GetCurrentTenantAsync()
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null) return Task.FromResult<Tenant?>(null);
if (httpContext == null) return null;
if (httpContext.Items.TryGetValue("CurrentTenant", out var cachedTenant))
{
return Task.FromResult((Tenant?)cachedTenant);
return (Tenant?)cachedTenant;
}
ResolveTenant();
await ResolveTenantAsync();
if (httpContext.Items.TryGetValue("CurrentTenant", out cachedTenant))
{
return Task.FromResult((Tenant?)cachedTenant);
return (Tenant?)cachedTenant;
}
return Task.FromResult<Tenant?>(null);
return null;
}
private void ResolveTenant()
private async Task ResolveTenantAsync()
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null) return;
@@ -82,9 +82,9 @@ public class TenantProvider : ITenantProvider
if (!string.IsNullOrEmpty(subdomain))
{
using var db = _dbContextFactory.CreateDbContext();
var tenant = db.Tenants
.FirstOrDefault(t => t.Subdomain.ToLower() == subdomain.ToLower());
await using var db = await _dbContextFactory.CreateDbContextAsync();
var tenant = await db.Tenants
.FirstOrDefaultAsync(t => t.Subdomain.ToLower() == subdomain.ToLower());
if (tenant != null)
{
-82
View File
@@ -195,88 +195,6 @@ using (var scope = app.Services.CreateScope())
}
await db.Database.MigrateAsync();
if (dbProvider.Equals("PostgreSQL", StringComparison.OrdinalIgnoreCase))
{
try
{
var conn = db.Database.GetDbConnection();
if (conn.State != System.Data.ConnectionState.Open)
{
await conn.OpenAsync();
}
// Check if column IsTenantAdmin in Users table is of type integer
using (var cmdCheckType = conn.CreateCommand())
{
cmdCheckType.CommandText = @"
SELECT data_type
FROM information_schema.columns
WHERE table_name = 'Users' AND column_name = 'IsTenantAdmin';";
var dataType = await cmdCheckType.ExecuteScalarAsync() as string;
if (dataType != null && dataType.Equals("integer", StringComparison.OrdinalIgnoreCase))
{
// Alter the column type to boolean
using (var cmdAlterType = conn.CreateCommand())
{
cmdAlterType.CommandText = @"
ALTER TABLE ""Users""
ALTER COLUMN ""IsTenantAdmin"" TYPE boolean
USING (""IsTenantAdmin"" <> 0);";
await cmdAlterType.ExecuteNonQueryAsync();
}
}
}
// Check if column IsApproved in Tenants table is of type integer
using (var cmdCheckApproved = conn.CreateCommand())
{
cmdCheckApproved.CommandText = @"
SELECT data_type
FROM information_schema.columns
WHERE table_name = 'Tenants' AND column_name = 'IsApproved';";
var dataType = await cmdCheckApproved.ExecuteScalarAsync() as string;
if (dataType != null && dataType.Equals("integer", StringComparison.OrdinalIgnoreCase))
{
// Alter the column type to boolean
using (var cmdAlterApproved = conn.CreateCommand())
{
cmdAlterApproved.CommandText = @"
ALTER TABLE ""Tenants""
ALTER COLUMN ""IsApproved"" TYPE boolean
USING (""IsApproved"" <> 0);";
await cmdAlterApproved.ExecuteNonQueryAsync();
}
}
}
// Check if column CreatedAt in Tenants table is of type text or character varying
using (var cmdCheckCreatedAt = conn.CreateCommand())
{
cmdCheckCreatedAt.CommandText = @"
SELECT data_type
FROM information_schema.columns
WHERE table_name = 'Tenants' AND column_name = 'CreatedAt';";
var dataType = await cmdCheckCreatedAt.ExecuteScalarAsync() as string;
if (dataType != null && (dataType.Equals("text", StringComparison.OrdinalIgnoreCase) || dataType.Equals("character varying", StringComparison.OrdinalIgnoreCase)))
{
// Alter the column type to timestamp without time zone
using (var cmdAlterCreatedAt = conn.CreateCommand())
{
cmdAlterCreatedAt.CommandText = @"
ALTER TABLE ""Tenants""
ALTER COLUMN ""CreatedAt"" TYPE timestamp without time zone
USING (""CreatedAt""::timestamp without time zone);";
await cmdAlterCreatedAt.ExecuteNonQueryAsync();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Fehler beim Konvertieren der PostgreSQL-Spaltentypen (IsTenantAdmin/IsApproved/CreatedAt): {ex.Message}");
}
}
}
var forwardedHeadersOptions = new ForwardedHeadersOptions