fix server - agent

This commit is contained in:
2026-05-27 08:37:47 +07:00
parent 13765e58d2
commit b0443d5950
13 changed files with 170 additions and 11 deletions

View File

@@ -9,6 +9,7 @@ const PLACEHOLDER_PASSWORD_HASH = 'ui-placeholder-password-hash';
const EMAIL_CONFIRMATION_EXPIRES_MS = Number(process.env.EMAIL_CONFIRMATION_EXPIRES_MS || 1000 * 60 * 60 * 24);
let emailConfirmationSchemaPromise;
let applicationOpenUrlSchemaPromise;
function toDateInputValue(value) {
const date = value ? new Date(value) : new Date();
@@ -185,6 +186,86 @@ async function ensureEmailConfirmationSchema() {
return emailConfirmationSchemaPromise;
}
async function ensureApplicationOpenUrlSchema() {
if (!applicationOpenUrlSchemaPromise) {
applicationOpenUrlSchemaPromise = getPool().then((pool) => pool.request().query(`
IF COL_LENGTH(N'dbo.Applications', N'OpenUrl') IS NULL
BEGIN
ALTER TABLE dbo.Applications
ADD OpenUrl NVARCHAR(500) NULL;
END;
EXEC(N'
CREATE OR ALTER VIEW dbo.vw_ApplicationList
AS
SELECT
a.Id,
a.AppCode,
a.AppName,
a.AppVersion,
a.Description,
a.Status,
a.Notes,
a.OpenUrl,
a.CreatedAt,
a.UpdatedAt,
a.CreatedByUserId,
u.Username AS CreatedByUsername,
COUNT_BIG(ap.Id) AS PackageCount
FROM dbo.Applications AS a
INNER JOIN dbo.Users AS u
ON u.Id = a.CreatedByUserId
LEFT JOIN dbo.ApplicationPackages AS ap
ON ap.ApplicationId = a.Id
GROUP BY
a.Id,
a.AppCode,
a.AppName,
a.AppVersion,
a.Description,
a.Status,
a.Notes,
a.OpenUrl,
a.CreatedAt,
a.UpdatedAt,
a.CreatedByUserId,
u.Username;
');
EXEC(N'
CREATE OR ALTER VIEW dbo.vw_ApplicationPackageDetails
AS
SELECT
ap.Id,
ap.ApplicationId,
a.AppCode,
a.AppName,
a.AppVersion,
a.OpenUrl AS AppOpenUrl,
ap.PackageId,
p.PackageCode,
p.PackageName,
p.PackageType,
ap.SelectedVersionId,
pv.Version AS SelectedVersion,
pv.FilePath,
pv.DockerImage,
ap.AddedAt,
ap.Notes
FROM dbo.ApplicationPackages AS ap
INNER JOIN dbo.Applications AS a
ON a.Id = ap.ApplicationId
INNER JOIN dbo.Packages AS p
ON p.Id = ap.PackageId
LEFT JOIN dbo.PackageVersions AS pv
ON pv.Id = ap.SelectedVersionId;
');
`));
}
return applicationOpenUrlSchemaPromise;
}
function normalizePackageStatus(isActive) {
return isActive ? 'Active' : 'Archived';
}
@@ -242,6 +323,7 @@ function mapApplicationRow(row) {
createdAt: formatDate(row.CreatedAt),
createdBy: row.CreatedByUsername || '',
notes: row.Notes || row.Description || '',
openUrl: row.OpenUrl || '',
packageCount: Number(row.PackageCount || 0),
packages: []
};
@@ -251,6 +333,7 @@ function mapApplicationPackageRow(row) {
return {
id: String(row.Id),
applicationId: String(row.ApplicationId),
appOpenUrl: row.AppOpenUrl || '',
packageId: String(row.PackageId),
code: row.PackageCode,
name: row.PackageName,
@@ -759,6 +842,7 @@ async function getPackageById(id) {
}
async function listApplications() {
await ensureApplicationOpenUrlSchema();
const pool = await getPool();
const result = await pool.request().query(`
SELECT *
@@ -771,6 +855,7 @@ async function listApplications() {
}
async function listApplicationPackages(applicationId) {
await ensureApplicationOpenUrlSchema();
const pool = await getPool();
const request = pool.request();
let whereClause = '';
@@ -816,6 +901,7 @@ async function attachApplicationPackages(applications) {
}
async function getApplicationById(id) {
await ensureApplicationOpenUrlSchema();
const pool = await getPool();
const appResult = await pool.request()
.input('Id', sql.NVarChar(100), id)
@@ -834,12 +920,13 @@ async function getApplicationById(id) {
}
async function getApplicationManifest(appCode, version, baseUrl) {
await ensureApplicationOpenUrlSchema();
const pool = await getPool();
const appResult = await pool.request()
.input('AppCode', sql.NVarChar(100), String(appCode || '').trim())
.input('AppVersion', sql.NVarChar(50), String(version || '').trim())
.query(`
SELECT TOP (1) Id, AppCode, AppName, AppVersion
SELECT TOP (1) Id, AppCode, AppName, AppVersion, OpenUrl
FROM dbo.Applications
WHERE (CONVERT(NVARCHAR(36), Id) = @AppCode OR AppCode = @AppCode)
AND AppVersion = @AppVersion
@@ -911,6 +998,7 @@ async function getApplicationManifest(appCode, version, baseUrl) {
appId: String(appRow.Id),
appName: appRow.AppName,
version: appRow.AppVersion,
openUrl: appRow.OpenUrl || '',
architecture: 'amd64',
components
};
@@ -1199,6 +1287,7 @@ async function deletePackageVersion(packageVersionId) {
}
async function createApplication(input) {
await ensureApplicationOpenUrlSchema();
const pool = await getPool();
const transaction = new sql.Transaction(pool);
@@ -1210,12 +1299,13 @@ async function createApplication(input) {
.input('AppName', sql.NVarChar(200), input.appName)
.input('AppVersion', sql.NVarChar(50), input.appVersion)
.input('Notes', sql.NVarChar(500), input.notes || null)
.input('OpenUrl', sql.NVarChar(500), input.openUrl || null)
.input('CreatedByUserId', sql.UniqueIdentifier, input.createdByUserId)
.input('Status', sql.NVarChar(50), normalizeApplicationStatus(input.status))
.query(`
INSERT dbo.Applications (AppCode, AppName, AppVersion, Notes, CreatedByUserId, Status)
INSERT dbo.Applications (AppCode, AppName, AppVersion, Notes, OpenUrl, CreatedByUserId, Status)
OUTPUT inserted.Id
VALUES (@AppCode, @AppName, @AppVersion, @Notes, @CreatedByUserId, @Status);
VALUES (@AppCode, @AppName, @AppVersion, @Notes, @OpenUrl, @CreatedByUserId, @Status);
`);
const applicationId = String(appResult.recordset[0].Id);
@@ -1244,6 +1334,7 @@ async function createApplication(input) {
}
async function updateApplication(input) {
await ensureApplicationOpenUrlSchema();
const pool = await getPool();
const transaction = new sql.Transaction(pool);
@@ -1270,6 +1361,7 @@ async function updateApplication(input) {
.input('AppName', sql.NVarChar(200), input.appName)
.input('AppVersion', sql.NVarChar(50), input.appVersion)
.input('Notes', sql.NVarChar(500), input.notes || null)
.input('OpenUrl', sql.NVarChar(500), input.openUrl || null)
.input('Status', sql.NVarChar(50), normalizeApplicationStatus(input.status))
.query(`
UPDATE dbo.Applications
@@ -1277,6 +1369,7 @@ async function updateApplication(input) {
AppName = @AppName,
AppVersion = @AppVersion,
Notes = @Notes,
OpenUrl = @OpenUrl,
Status = @Status,
UpdatedAt = SYSUTCDATETIME()
OUTPUT inserted.Id