Refactor EchoHub solution structure and remove unused components

- Deleted EchoHub.slnx and related project files for EchoHub.Web and EchoHub.Api.
- Removed ServerDirectoryDbContext, ServerDirectoryService, and related extensions and DTOs.
- Updated CommandHandler and Program.cs in EchoHub.Client to handle URL sending instead of file downloading.
- Added SendUrlRequest DTO and corresponding API endpoint in ChannelsController for handling URL uploads.
- Implemented database migration support in EchoHub.Server with initial migration setup.
- Adjusted Program.cs to include HTTP client configuration for image downloading.
- Cleaned up unnecessary files and references to streamline the project.
This commit is contained in:
HueByte
2026-02-19 03:51:38 +01:00
parent 287270b26d
commit ebc8fffec8
22 changed files with 772 additions and 358 deletions
+63 -1
View File
@@ -73,6 +73,11 @@ builder.Services.AddSingleton<JwtTokenService>();
builder.Services.AddSingleton<PresenceTracker>();
builder.Services.AddSingleton<ImageToAsciiService>();
builder.Services.AddSingleton<FileStorageService>();
builder.Services.AddHttpClient("ImageDownload", client =>
{
client.Timeout = TimeSpan.FromSeconds(15);
client.MaxResponseContentBufferSize = 10 * 1024 * 1024; // 10 MB
});
// ── Rate Limiting ────────────────────────────────────────────────────────────
builder.Services.AddRateLimiter(options =>
@@ -125,8 +130,64 @@ var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<EchoHubDbContext>();
await db.Database.EnsureCreatedAsync();
var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
try
{
// If the DB was created by EnsureCreated (no __EFMigrationsHistory table),
// back it up and recreate so MigrateAsync can manage the schema properly.
if (await db.Database.CanConnectAsync())
{
var conn = db.Database.GetDbConnection();
await conn.OpenAsync();
using var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='__EFMigrationsHistory'";
var hasMigrationTable = Convert.ToInt64(await cmd.ExecuteScalarAsync()) > 0;
if (!hasMigrationTable)
{
cmd.CommandText = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='Users'";
var hasLegacyTables = Convert.ToInt64(await cmd.ExecuteScalarAsync()) > 0;
if (hasLegacyTables)
{
var dbPath = conn.DataSource;
await conn.CloseAsync();
// Back up the legacy DB file before deleting
if (!string.IsNullOrEmpty(dbPath) && File.Exists(dbPath))
{
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
var backupPath = $"{dbPath}.legacy_{timestamp}";
File.Copy(dbPath, backupPath, overwrite: false);
logger.LogWarning("Legacy database backed up to '{BackupPath}'.", backupPath);
}
await db.Database.EnsureDeletedAsync();
logger.LogWarning("Legacy database removed. A new database will be created with migration support.");
}
else
{
await conn.CloseAsync();
}
}
else
{
await conn.CloseAsync();
}
}
await db.Database.MigrateAsync();
logger.LogInformation("Database migrated successfully.");
}
catch (Exception ex)
{
logger.LogError(ex, "Database migration failed.");
throw;
}
// Seed the default channel if it doesn't exist
if (!await db.Channels.AnyAsync(c => c.Name == HubConstants.DefaultChannel))
{
db.Channels.Add(new Channel
@@ -138,6 +199,7 @@ using (var scope = app.Services.CreateScope())
});
await db.SaveChangesAsync();
logger.LogInformation("Default channel '{Channel}' created.", HubConstants.DefaultChannel);
}
}