131 lines
4.9 KiB
C#
131 lines
4.9 KiB
C#
using System.IO;
|
|
using System.Reflection;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
using QuantEngine.Application.Interfaces;
|
|
using QuantEngine.Core.Interfaces;
|
|
using QuantEngine.Web.Services;
|
|
|
|
namespace QuantEngine.Web.Pages.Admin.Dashboard;
|
|
|
|
[Authorize(AuthenticationSchemes = AdminAuthDefaults.Scheme)]
|
|
public class IndexModel : PageModel
|
|
{
|
|
private readonly IWorkspaceRepository _workspaceRepository;
|
|
private readonly ICollectionReadModelService _collectionReadModelService;
|
|
private readonly IWebHostEnvironment _environment;
|
|
private readonly ILogger<IndexModel> _logger;
|
|
|
|
public int? ActiveUsersCount { get; set; }
|
|
public int? RecentRunsCount { get; set; }
|
|
public bool IsDatabaseConnected { get; set; }
|
|
public string EnvironmentName => _environment.EnvironmentName;
|
|
public string AppVersion
|
|
{
|
|
get
|
|
{
|
|
// 1. Try reading version.txt from application base directory
|
|
try
|
|
{
|
|
var txtPath = Path.Combine(AppContext.BaseDirectory, "version.txt");
|
|
if (System.IO.File.Exists(txtPath))
|
|
{
|
|
var txtVersion = System.IO.File.ReadAllText(txtPath).Trim();
|
|
if (!string.IsNullOrEmpty(txtVersion))
|
|
return txtVersion;
|
|
}
|
|
}
|
|
catch {}
|
|
|
|
// 2. Try reading raw assembly version
|
|
var rawVersion = Assembly.GetEntryAssembly()
|
|
?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
|
|
?.InformationalVersion;
|
|
|
|
if (!string.IsNullOrEmpty(rawVersion) && rawVersion.StartsWith("quant_", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return rawVersion;
|
|
}
|
|
|
|
// 3. Fallback to dynamic local Git parsing if available
|
|
var dateStr = DateTime.UtcNow.AddHours(9).ToString("yyyyMMdd");
|
|
string gitHash = "024122d";
|
|
try
|
|
{
|
|
var baseDir = AppContext.BaseDirectory;
|
|
var current = new DirectoryInfo(baseDir);
|
|
string? repoRoot = null;
|
|
while (current != null)
|
|
{
|
|
if (Directory.Exists(Path.Combine(current.FullName, ".git")))
|
|
{
|
|
repoRoot = current.FullName;
|
|
break;
|
|
}
|
|
current = current.Parent;
|
|
}
|
|
if (repoRoot != null)
|
|
{
|
|
var headPath = Path.Combine(repoRoot, ".git", "HEAD");
|
|
if (System.IO.File.Exists(headPath))
|
|
{
|
|
var headContent = System.IO.File.ReadAllText(headPath).Trim();
|
|
if (headContent.StartsWith("ref:"))
|
|
{
|
|
var refPath = Path.Combine(repoRoot, ".git", headContent.Substring(4).Trim().Replace('/', Path.DirectorySeparatorChar));
|
|
if (System.IO.File.Exists(refPath))
|
|
{
|
|
var fullHash = System.IO.File.ReadAllText(refPath).Trim();
|
|
if (fullHash.Length >= 7)
|
|
gitHash = fullHash.Substring(0, 7);
|
|
}
|
|
}
|
|
else if (headContent.Length >= 7)
|
|
{
|
|
gitHash = headContent.Substring(0, 7);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch {}
|
|
|
|
int runCount = 11;
|
|
return $"quant_{dateStr}.{runCount}.{gitHash}";
|
|
}
|
|
}
|
|
|
|
public IndexModel(
|
|
IWorkspaceRepository workspaceRepository,
|
|
ICollectionReadModelService collectionReadModelService,
|
|
IWebHostEnvironment environment,
|
|
ILogger<IndexModel> logger)
|
|
{
|
|
_workspaceRepository = workspaceRepository;
|
|
_collectionReadModelService = collectionReadModelService;
|
|
_environment = environment;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task OnGetAsync()
|
|
{
|
|
try
|
|
{
|
|
var accounts = await _workspaceRepository.GetAccountsAsync();
|
|
ActiveUsersCount = accounts.Count(a => string.Equals(a.IsActive, "true", StringComparison.OrdinalIgnoreCase));
|
|
|
|
var dashboard = await _collectionReadModelService.GetDashboardStateAsync();
|
|
RecentRunsCount = string.IsNullOrEmpty(dashboard?.LastRunId) ? 0 : 1;
|
|
|
|
// These two queries only complete if the DB round-trip actually
|
|
// succeeded, so reaching this line is the real signal -- do not
|
|
// hardcode a static "정상"/"연결됨" badge independent of it.
|
|
IsDatabaseConnected = true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Dashboard data loading failed");
|
|
IsDatabaseConnected = false;
|
|
}
|
|
}
|
|
}
|