feat(health-checks): implement health check IP toggling and configuration updates
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 8s
quality / changes (push) Successful in 5s
quality / docker-check (push) Skipped
quality / web (push) Successful in 51s
quality / api (push) Successful in 43s
CD / quality (push) Successful in 1m43s
CD / publish (push) Successful in 1m38s
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 8s
quality / changes (push) Successful in 5s
quality / docker-check (push) Skipped
quality / web (push) Successful in 51s
quality / api (push) Successful in 43s
CD / quality (push) Successful in 1m43s
CD / publish (push) Successful in 1m38s
- Added functionality to toggle individual IPs for services, allowing for dynamic management of IP health status. - Enhanced the health check configuration in the UI, enabling users to set parameters directly from the settings page. - Updated service views to include IP health tracking, improving visibility into the status of each IP associated with a service. - Refactored relevant components to support the new IP toggling feature, ensuring a seamless user experience. This commit significantly enhances the health management capabilities of services, providing users with more control over IP configurations and health monitoring.
This commit is contained in:
1 parent
4224db8eb3
commit
d63c86065c
35 files changed
+1538
-123
No files matched your search
Vendored
+235
-5
@@ -2315,6 +2315,23 @@ declare const serviceIps: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
enabled: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "enabled";
|
||||
tableName: "service_ips";
|
||||
dataType: "boolean";
|
||||
columnType: "SQLiteBoolean";
|
||||
data: boolean;
|
||||
driverParam: number;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
created_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "created_at";
|
||||
tableName: "service_ips";
|
||||
@@ -3147,6 +3164,93 @@ declare const appSettings: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
health_check_cron: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_check_cron";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
health_degraded_failures: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_degraded_failures";
|
||||
tableName: "app_settings";
|
||||
dataType: "number";
|
||||
columnType: "SQLiteInteger";
|
||||
data: number;
|
||||
driverParam: number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
health_down_failures: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_down_failures";
|
||||
tableName: "app_settings";
|
||||
dataType: "number";
|
||||
columnType: "SQLiteInteger";
|
||||
data: number;
|
||||
driverParam: number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
health_latency_warn_ms: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_latency_warn_ms";
|
||||
tableName: "app_settings";
|
||||
dataType: "number";
|
||||
columnType: "SQLiteInteger";
|
||||
data: number;
|
||||
driverParam: number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
health_success_recoveries: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_success_recoveries";
|
||||
tableName: "app_settings";
|
||||
dataType: "number";
|
||||
columnType: "SQLiteInteger";
|
||||
data: number;
|
||||
driverParam: number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
created_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "created_at";
|
||||
tableName: "app_settings";
|
||||
@@ -6346,6 +6450,23 @@ declare const schema: {
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
enabled: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "enabled";
|
||||
tableName: "service_ips";
|
||||
dataType: "boolean";
|
||||
columnType: "SQLiteBoolean";
|
||||
data: boolean;
|
||||
driverParam: number;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
created_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "created_at";
|
||||
tableName: "service_ips";
|
||||
@@ -7178,6 +7299,93 @@ declare const schema: {
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
health_check_cron: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_check_cron";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
health_degraded_failures: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_degraded_failures";
|
||||
tableName: "app_settings";
|
||||
dataType: "number";
|
||||
columnType: "SQLiteInteger";
|
||||
data: number;
|
||||
driverParam: number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
health_down_failures: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_down_failures";
|
||||
tableName: "app_settings";
|
||||
dataType: "number";
|
||||
columnType: "SQLiteInteger";
|
||||
data: number;
|
||||
driverParam: number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
health_latency_warn_ms: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_latency_warn_ms";
|
||||
tableName: "app_settings";
|
||||
dataType: "number";
|
||||
columnType: "SQLiteInteger";
|
||||
data: number;
|
||||
driverParam: number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
health_success_recoveries: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "health_success_recoveries";
|
||||
tableName: "app_settings";
|
||||
dataType: "number";
|
||||
columnType: "SQLiteInteger";
|
||||
data: number;
|
||||
driverParam: number;
|
||||
notNull: false;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
created_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "created_at";
|
||||
tableName: "app_settings";
|
||||
@@ -8112,6 +8320,13 @@ declare function listAudit(db: Db, opts?: {
|
||||
limit?: number;
|
||||
}): AuditLogEntry[];
|
||||
|
||||
type HealthEngineSettings = {
|
||||
healthCheckCron: string;
|
||||
healthDegradedFailures: number;
|
||||
healthDownFailures: number;
|
||||
healthLatencyWarnMs: number;
|
||||
healthSuccessRecoveries: number;
|
||||
};
|
||||
type AppSettingsDto = {
|
||||
id: string;
|
||||
vpsTrackerUrl: string;
|
||||
@@ -8119,20 +8334,26 @@ type AppSettingsDto = {
|
||||
vpsTrackerSyncEnabled: boolean;
|
||||
vpsTrackerLastSyncAt: string | null;
|
||||
showQuickActions: boolean;
|
||||
};
|
||||
} & HealthEngineSettings;
|
||||
type AppSettingsPatch = {
|
||||
vpsTrackerUrl?: string;
|
||||
vpsTrackerIntegrationToken?: string;
|
||||
vpsTrackerSyncEnabled?: boolean;
|
||||
showQuickActions?: boolean;
|
||||
healthCheckCron?: string;
|
||||
healthDegradedFailures?: number;
|
||||
healthDownFailures?: number;
|
||||
healthLatencyWarnMs?: number;
|
||||
healthSuccessRecoveries?: number;
|
||||
};
|
||||
declare function getAppSettings(db: Db): AppSettingsDto;
|
||||
type HealthEngineFallbacks = HealthEngineSettings;
|
||||
declare function getAppSettings(db: Db, fallbacks?: HealthEngineFallbacks): AppSettingsDto;
|
||||
declare function getAppSettingsSecrets(db: Db): {
|
||||
vpsTrackerUrl: string;
|
||||
vpsTrackerIntegrationToken: string;
|
||||
vpsTrackerSyncEnabled: boolean;
|
||||
};
|
||||
declare function updateAppSettings(db: Db, patch: AppSettingsPatch): AppSettingsDto;
|
||||
declare function updateAppSettings(db: Db, patch: AppSettingsPatch, fallbacks?: HealthEngineFallbacks): AppSettingsDto;
|
||||
declare function touchVpsTrackerSync(db: Db): void;
|
||||
|
||||
interface DnsListFilter {
|
||||
@@ -8223,7 +8444,13 @@ declare function createServiceGroup(db: Db, name: string, groupType: string, ico
|
||||
declare function updateServiceGroup(db: Db, id: number, name: string, groupType: string, icon: string | null, domain: string | null, lbPatch?: ServiceGroupLbPatch): ServiceGroup;
|
||||
declare function setServiceGroupEnabled(db: Db, id: number, enabled: boolean): ServiceGroup;
|
||||
declare function deleteServiceGroup(db: Db, id: number): void;
|
||||
type ServiceIpRow = {
|
||||
ip: string;
|
||||
enabled: boolean;
|
||||
};
|
||||
declare function listServiceIpRows(db: Db, serviceId: number): ServiceIpRow[];
|
||||
declare function listServiceIps(db: Db, serviceId: number): string[];
|
||||
declare function setServiceIpEnabled(db: Db, serviceId: number, ip: string, enabled: boolean): void;
|
||||
declare function replaceServiceIps(db: Db, serviceId: number, ips: string[]): void;
|
||||
declare function listNodes(db: Db, serviceId: number): ServiceNode[];
|
||||
declare function getNode(db: Db, id: number): ServiceNode;
|
||||
@@ -8456,6 +8683,7 @@ type repos_DomainMonitorRow = DomainMonitorRow;
|
||||
type repos_HealthAggregate = HealthAggregate;
|
||||
type repos_ServiceGroupLbPatch = ServiceGroupLbPatch;
|
||||
type repos_ServiceIpHealthRow = ServiceIpHealthRow;
|
||||
type repos_ServiceIpRow = ServiceIpRow;
|
||||
type repos_UpdateSubdomainPatch = UpdateSubdomainPatch;
|
||||
declare const repos_addDomainTags: typeof addDomainTags;
|
||||
declare const repos_aggregateGroupScopeHealthByIds: typeof aggregateGroupScopeHealthByIds;
|
||||
@@ -8546,6 +8774,7 @@ declare const repos_listNotificationLog: typeof listNotificationLog;
|
||||
declare const repos_listOriginIpsForFqdn: typeof listOriginIpsForFqdn;
|
||||
declare const repos_listRecordsForBinding: typeof listRecordsForBinding;
|
||||
declare const repos_listServiceGroups: typeof listServiceGroups;
|
||||
declare const repos_listServiceIpRows: typeof listServiceIpRows;
|
||||
declare const repos_listServiceIps: typeof listServiceIps;
|
||||
declare const repos_listServices: typeof listServices;
|
||||
declare const repos_listServicesByGroup: typeof listServicesByGroup;
|
||||
@@ -8567,6 +8796,7 @@ declare const repos_setDomainTags: typeof setDomainTags;
|
||||
declare const repos_setServiceEnabled: typeof setServiceEnabled;
|
||||
declare const repos_setServiceGroup: typeof setServiceGroup;
|
||||
declare const repos_setServiceGroupEnabled: typeof setServiceGroupEnabled;
|
||||
declare const repos_setServiceIpEnabled: typeof setServiceIpEnabled;
|
||||
declare const repos_setServiceLb: typeof setServiceLb;
|
||||
declare const repos_unlinkBindingRecord: typeof unlinkBindingRecord;
|
||||
declare const repos_unlinkGroupDnsRecord: typeof unlinkGroupDnsRecord;
|
||||
@@ -8586,7 +8816,7 @@ declare const repos_upsertCertificateCheck: typeof upsertCertificateCheck;
|
||||
declare const repos_upsertIpHealthStatus: typeof upsertIpHealthStatus;
|
||||
declare const repos_upsertSubdomain: typeof upsertSubdomain;
|
||||
declare namespace repos {
|
||||
export { type repos_BindingIpMeta as BindingIpMeta, type repos_BindingLbPatch as BindingLbPatch, type repos_DnsListFilter as DnsListFilter, type repos_DomainMonitorRow as DomainMonitorRow, type repos_HealthAggregate as HealthAggregate, type repos_ServiceGroupLbPatch as ServiceGroupLbPatch, type repos_ServiceIpHealthRow as ServiceIpHealthRow, type repos_UpdateSubdomainPatch as UpdateSubdomainPatch, repos_addDomainTags as addDomainTags, repos_aggregateGroupScopeHealthByIds as aggregateGroupScopeHealthByIds, repos_aggregateIpHealthByRefs as aggregateIpHealthByRefs, repos_aggregateIpHealthByServiceIds as aggregateIpHealthByServiceIds, repos_bindingsToRemove as bindingsToRemove, repos_bumpBindingVersion as bumpBindingVersion, repos_countCertificatesByStatus as countCertificatesByStatus, repos_createDomain as createDomain, repos_createDomainMonitor as createDomainMonitor, repos_createGroup as createGroup, repos_createHealthCheck as createHealthCheck, repos_createNode as createNode, repos_createService as createService, repos_createServiceGroup as createServiceGroup, repos_createSubdomain as createSubdomain, repos_createSyncJob as createSyncJob, repos_deleteBinding as deleteBinding, repos_deleteBindingsExcept as deleteBindingsExcept, repos_deleteCertificatesNotIn as deleteCertificatesNotIn, repos_deleteDnsRecord as deleteDnsRecord, repos_deleteDomain as deleteDomain, repos_deleteDomainMonitor as deleteDomainMonitor, repos_deleteGroup as deleteGroup, repos_deleteHealthCheck as deleteHealthCheck, repos_deleteIpHealthStatusForIp as deleteIpHealthStatusForIp, repos_deleteIpHealthStatusForRef as deleteIpHealthStatusForRef, repos_deleteNode as deleteNode, repos_deleteService as deleteService, repos_deleteServiceGroup as deleteServiceGroup, repos_deleteSubdomain as deleteSubdomain, repos_ensureNode as ensureNode, repos_findBinding as findBinding, repos_findDnsByCfId as findDnsByCfId, repos_findDomainByZoneName as findDomainByZoneName, repos_findHealthCheckByCfId as findHealthCheckByCfId, repos_findNodeByAddress as findNodeByAddress, repos_findNodeByIp as findNodeByIp, repos_findSubdomainByDomainAndName as findSubdomainByDomainAndName, repos_finishSyncJob as finishSyncJob, repos_getBinding as getBinding, repos_getBindingView as getBindingView, repos_getCertificate as getCertificate, repos_getDnsRecord as getDnsRecord, repos_getDomain as getDomain, repos_getDomainMonitor as getDomainMonitor, repos_getGroup as getGroup, repos_getGroupWithStats as getGroupWithStats, repos_getHealthCheck as getHealthCheck, repos_getIpHealthStatusRow as getIpHealthStatusRow, repos_getNode as getNode, repos_getService as getService, repos_getServiceGroup as getServiceGroup, repos_getSubdomain as getSubdomain, repos_getSyncJob as getSyncJob, repos_insertBinding as insertBinding, repos_insertDnsRecord as insertDnsRecord, repos_insertNotificationLog as insertNotificationLog, repos_linkBindingRecord as linkBindingRecord, repos_linkGroupDnsRecord as linkGroupDnsRecord, repos_listAllBindings as listAllBindings, repos_listAllDomains as listAllDomains, repos_listAllNodes as listAllNodes, repos_listAllSubdomains as listAllSubdomains, repos_listBindingIps as listBindingIps, repos_listBindingIpsWithMeta as listBindingIpsWithMeta, repos_listBindingNodes as listBindingNodes, repos_listBindingsByDomain as listBindingsByDomain, repos_listBindingsByService as listBindingsByService, repos_listCertificates as listCertificates, repos_listDnsByDomain as listDnsByDomain, repos_listDnsRecords as listDnsRecords, repos_listDomainMonitorResults as listDomainMonitorResults, repos_listDomainMonitorResultsForDomain as listDomainMonitorResultsForDomain, repos_listDomainMonitors as listDomainMonitors, repos_listDomainTags as listDomainTags, repos_listDomains as listDomains, repos_listDomainsEnriched as listDomainsEnriched, repos_listEnabledDomainMonitors as listEnabledDomainMonitors, repos_listGroupDnsRecords as listGroupDnsRecords, repos_listGroups as listGroups, repos_listHealthCheckTargets as listHealthCheckTargets, repos_listHealthChecks as listHealthChecks, repos_listIpHealthByServiceIds as listIpHealthByServiceIds, repos_listIpHealthStatus as listIpHealthStatus, repos_listNodes as listNodes, repos_listNotificationLog as listNotificationLog, repos_listOriginIpsForFqdn as listOriginIpsForFqdn, repos_listRecordsForBinding as listRecordsForBinding, repos_listServiceGroups as listServiceGroups, repos_listServiceIps as listServiceIps, repos_listServices as listServices, repos_listServicesByGroup as listServicesByGroup, repos_listSubdomainsByDomain as listSubdomainsByDomain, repos_listUngroupedServices as listUngroupedServices, repos_markDnsPendingDelete as markDnsPendingDelete, repos_mergeHealthAggregates as mergeHealthAggregates, repos_pruneStaleIpHealthStatus as pruneStaleIpHealthStatus, repos_reorderServices as reorderServices, repos_replaceBindingIps as replaceBindingIps, repos_replaceBindingIpsWithMeta as replaceBindingIpsWithMeta, repos_replaceServiceIps as replaceLine truncated
|
||||
export { type repos_BindingIpMeta as BindingIpMeta, type repos_BindingLbPatch as BindingLbPatch, type repos_DnsListFilter as DnsListFilter, type repos_DomainMonitorRow as DomainMonitorRow, type repos_HealthAggregate as HealthAggregate, type repos_ServiceGroupLbPatch as ServiceGroupLbPatch, type repos_ServiceIpHealthRow as ServiceIpHealthRow, type repos_ServiceIpRow as ServiceIpRow, type repos_UpdateSubdomainPatch as UpdateSubdomainPatch, repos_addDomainTags as addDomainTags, repos_aggregateGroupScopeHealthByIds as aggregateGroupScopeHealthByIds, repos_aggregateIpHealthByRefs as aggregateIpHealthByRefs, repos_aggregateIpHealthByServiceIds as aggregateIpHealthByServiceIds, repos_bindingsToRemove as bindingsToRemove, repos_bumpBindingVersion as bumpBindingVersion, repos_countCertificatesByStatus as countCertificatesByStatus, repos_createDomain as createDomain, repos_createDomainMonitor as createDomainMonitor, repos_createGroup as createGroup, repos_createHealthCheck as createHealthCheck, repos_createNode as createNode, repos_createService as createService, repos_createServiceGroup as createServiceGroup, repos_createSubdomain as createSubdomain, repos_createSyncJob as createSyncJob, repos_deleteBinding as deleteBinding, repos_deleteBindingsExcept as deleteBindingsExcept, repos_deleteCertificatesNotIn as deleteCertificatesNotIn, repos_deleteDnsRecord as deleteDnsRecord, repos_deleteDomain as deleteDomain, repos_deleteDomainMonitor as deleteDomainMonitor, repos_deleteGroup as deleteGroup, repos_deleteHealthCheck as deleteHealthCheck, repos_deleteIpHealthStatusForIp as deleteIpHealthStatusForIp, repos_deleteIpHealthStatusForRef as deleteIpHealthStatusForRef, repos_deleteNode as deleteNode, repos_deleteService as deleteService, repos_deleteServiceGroup as deleteServiceGroup, repos_deleteSubdomain as deleteSubdomain, repos_ensureNode as ensureNode, repos_findBinding as findBinding, repos_findDnsByCfId as findDnsByCfId, repos_findDomainByZoneName as findDomainByZoneName, repos_findHealthCheckByCfId as findHealthCheckByCfId, repos_findNodeByAddress as findNodeByAddress, repos_findNodeByIp as findNodeByIp, repos_findSubdomainByDomainAndName as findSubdomainByDomainAndName, repos_finishSyncJob as finishSyncJob, repos_getBinding as getBinding, repos_getBindingView as getBindingView, repos_getCertificate as getCertificate, repos_getDnsRecord as getDnsRecord, repos_getDomain as getDomain, repos_getDomainMonitor as getDomainMonitor, repos_getGroup as getGroup, repos_getGroupWithStats as getGroupWithStats, repos_getHealthCheck as getHealthCheck, repos_getIpHealthStatusRow as getIpHealthStatusRow, repos_getNode as getNode, repos_getService as getService, repos_getServiceGroup as getServiceGroup, repos_getSubdomain as getSubdomain, repos_getSyncJob as getSyncJob, repos_insertBinding as insertBinding, repos_insertDnsRecord as insertDnsRecord, repos_insertNotificationLog as insertNotificationLog, repos_linkBindingRecord as linkBindingRecord, repos_linkGroupDnsRecord as linkGroupDnsRecord, repos_listAllBindings as listAllBindings, repos_listAllDomains as listAllDomains, repos_listAllNodes as listAllNodes, repos_listAllSubdomains as listAllSubdomains, repos_listBindingIps as listBindingIps, repos_listBindingIpsWithMeta as listBindingIpsWithMeta, repos_listBindingNodes as listBindingNodes, repos_listBindingsByDomain as listBindingsByDomain, repos_listBindingsByService as listBindingsByService, repos_listCertificates as listCertificates, repos_listDnsByDomain as listDnsByDomain, repos_listDnsRecords as listDnsRecords, repos_listDomainMonitorResults as listDomainMonitorResults, repos_listDomainMonitorResultsForDomain as listDomainMonitorResultsForDomain, repos_listDomainMonitors as listDomainMonitors, repos_listDomainTags as listDomainTags, repos_listDomains as listDomains, repos_listDomainsEnriched as listDomainsEnriched, repos_listEnabledDomainMonitors as listEnabledDomainMonitors, repos_listGroupDnsRecords as listGroupDnsRecords, repos_listGroups as listGroups, repos_listHealthCheckTargets as listHealthCheckTargets, repos_listHealthChecks as listHealthChecks, repos_listIpHealthByServiceIds as listIpHealthByServiceIds, repos_listIpHealthStatus as listIpHealthStatus, repos_listNodes as listNodes, repos_listNotificationLog as listNotificationLog, repos_listOriginIpsForFqdn as listOriginIpsForFqdn, repos_listRecordsForBinding as listRecordsForBinding, repos_listServiceGroups as listServiceGroups, repos_listServiceIpRows as listServiceIpRows, repos_listServiceIps as listServiceIps, repos_listServices as listServices, repos_listServicesByGroup as listServicesByGroup, repos_listSubdomainsByDomain as listSubdomainsByDomain, repos_listUngroupedServices as listUngroupedServices, repos_markDnsPendingDelete as markDnsPendingDelete, repos_mergeHealthAggregates as mergeHealthAggregates, repos_pruneStaleIpHealthStatus as pruneStaleIpHealthStatus, repos_reorderServices as reorderServices, repos_replaceBindingIps as replaceBindingIps, repos_repLine truncated
|
||||
}
|
||||
|
||||
export { type AppSettingsDto, type AppSettingsPatch, type AppendAuditInput, ConflictError, type Db, type DnsListFilter, NotFoundError, type Sqlite, type UpdateSubdomainPatch, appSettings, appendAudit, auditLog, bindingNodes, certificates, createDb, createMemoryDb, dnsRecords, domainMonitorResults, domainMonitors, domainTags, domains, getAppSettings, getAppSettingsSecrets, groups, healthCheck, healthChecks, ipHealthStatus, listAudit, nodes, notificationLog, repos, resolveDatabasePath, runMigrations, schema, serviceBindingIps, serviceBindingRecords, serviceBindings, serviceGroupDnsRecords, serviceGroups, serviceIps, services, subdomains, syncJobs, touchVpsTrackerSync, updateAppSettings };
|
||||
export { type AppSettingsDto, type AppSettingsPatch, type AppendAuditInput, ConflictError, type Db, type DnsListFilter, type HealthEngineFallbacks, type HealthEngineSettings, NotFoundError, type Sqlite, type UpdateSubdomainPatch, appSettings, appendAudit, auditLog, bindingNodes, certificates, createDb, createMemoryDb, dnsRecords, domainMonitorResults, domainMonitors, domainTags, domains, getAppSettings, getAppSettingsSecrets, groups, healthCheck, healthChecks, ipHealthStatus, listAudit, nodes, notificationLog, repos, resolveDatabasePath, runMigrations, schema, serviceBindingIps, serviceBindingRecords, serviceBindings, serviceGroupDnsRecords, serviceGroups, serviceIps, services, subdomains, syncJobs, touchVpsTrackerSync, updateAppSettings };
|
||||
Vendored
+67
-10
@@ -187,6 +187,7 @@ var serviceIps = sqliteTable("service_ips", {
|
||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||
service_id: integer("service_id").notNull().references(() => services.id, { onDelete: "cascade" }),
|
||||
ip: text("ip").notNull(),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
created_at: text("created_at").notNull().default(sql`datetime('now')`)
|
||||
});
|
||||
var serviceBindingRecords = sqliteTable(
|
||||
@@ -269,6 +270,11 @@ var appSettings = sqliteTable("app_settings", {
|
||||
show_quick_actions: integer("show_quick_actions", {
|
||||
mode: "boolean"
|
||||
}).notNull().default(true),
|
||||
health_check_cron: text("health_check_cron"),
|
||||
health_degraded_failures: integer("health_degraded_failures"),
|
||||
health_down_failures: integer("health_down_failures"),
|
||||
health_latency_warn_ms: integer("health_latency_warn_ms"),
|
||||
health_success_recoveries: integer("health_success_recoveries"),
|
||||
created_at: text("created_at").notNull().default(sql`datetime('now')`),
|
||||
updated_at: text("updated_at").notNull().default(sql`datetime('now')`)
|
||||
});
|
||||
@@ -493,7 +499,17 @@ function listAudit(db, opts = {}) {
|
||||
// src/settings-repo.ts
|
||||
import { eq as eq2 } from "drizzle-orm";
|
||||
var SETTINGS_ID = "settings-main";
|
||||
function toDto(row) {
|
||||
function coalesceInt(value, fallback) {
|
||||
return value == null || Number.isNaN(value) || value < 1 ? fallback : value;
|
||||
}
|
||||
function toDto(row, fallbacks) {
|
||||
const env = fallbacks ?? {
|
||||
healthCheckCron: "0 */2 * * * *",
|
||||
healthDegradedFailures: 1,
|
||||
healthDownFailures: 2,
|
||||
healthLatencyWarnMs: 1e3,
|
||||
healthSuccessRecoveries: 2
|
||||
};
|
||||
return {
|
||||
id: row.id,
|
||||
vpsTrackerUrl: row.vps_tracker_url?.trim() ?? "",
|
||||
@@ -502,18 +518,36 @@ function toDto(row) {
|
||||
),
|
||||
vpsTrackerSyncEnabled: Boolean(row.vps_tracker_sync_enabled),
|
||||
vpsTrackerLastSyncAt: row.vps_tracker_last_sync_at,
|
||||
showQuickActions: row.show_quick_actions == null ? true : Boolean(row.show_quick_actions)
|
||||
showQuickActions: row.show_quick_actions == null ? true : Boolean(row.show_quick_actions),
|
||||
healthCheckCron: row.health_check_cron?.trim() || env.healthCheckCron,
|
||||
healthDegradedFailures: coalesceInt(
|
||||
row.health_degraded_failures,
|
||||
env.healthDegradedFailures
|
||||
),
|
||||
healthDownFailures: coalesceInt(
|
||||
row.health_down_failures,
|
||||
env.healthDownFailures
|
||||
),
|
||||
healthLatencyWarnMs: coalesceInt(
|
||||
row.health_latency_warn_ms,
|
||||
env.healthLatencyWarnMs
|
||||
),
|
||||
healthSuccessRecoveries: coalesceInt(
|
||||
row.health_success_recoveries,
|
||||
env.healthSuccessRecoveries
|
||||
)
|
||||
};
|
||||
}
|
||||
function getAppSettings(db) {
|
||||
function getAppSettings(db, fallbacks) {
|
||||
const row = db.select().from(appSettings).where(eq2(appSettings.id, SETTINGS_ID)).get();
|
||||
if (!row) {
|
||||
db.insert(appSettings).values({ id: SETTINGS_ID }).run();
|
||||
return toDto(
|
||||
db.select().from(appSettings).where(eq2(appSettings.id, SETTINGS_ID)).get()
|
||||
db.select().from(appSettings).where(eq2(appSettings.id, SETTINGS_ID)).get(),
|
||||
fallbacks
|
||||
);
|
||||
}
|
||||
return toDto(row);
|
||||
return toDto(row, fallbacks);
|
||||
}
|
||||
function getAppSettingsSecrets(db) {
|
||||
const row = db.select().from(appSettings).where(eq2(appSettings.id, SETTINGS_ID)).get();
|
||||
@@ -523,7 +557,7 @@ function getAppSettingsSecrets(db) {
|
||||
vpsTrackerSyncEnabled: Boolean(row?.vps_tracker_sync_enabled)
|
||||
};
|
||||
}
|
||||
function updateAppSettings(db, patch) {
|
||||
function updateAppSettings(db, patch, fallbacks) {
|
||||
const existing = db.select().from(appSettings).where(eq2(appSettings.id, SETTINGS_ID)).get();
|
||||
if (!existing) {
|
||||
db.insert(appSettings).values({ id: SETTINGS_ID }).run();
|
||||
@@ -535,9 +569,14 @@ function updateAppSettings(db, patch) {
|
||||
vps_tracker_integration_token: patch.vpsTrackerIntegrationToken !== void 0 && patch.vpsTrackerIntegrationToken.trim() !== "" ? patch.vpsTrackerIntegrationToken : current.vps_tracker_integration_token,
|
||||
vps_tracker_sync_enabled: patch.vpsTrackerSyncEnabled !== void 0 ? patch.vpsTrackerSyncEnabled : current.vps_tracker_sync_enabled,
|
||||
show_quick_actions: patch.showQuickActions !== void 0 ? patch.showQuickActions : current.show_quick_actions,
|
||||
health_check_cron: patch.healthCheckCron !== void 0 ? patch.healthCheckCron.trim() : current.health_check_cron,
|
||||
health_degraded_failures: patch.healthDegradedFailures !== void 0 ? patch.healthDegradedFailures : current.health_degraded_failures,
|
||||
health_down_failures: patch.healthDownFailures !== void 0 ? patch.healthDownFailures : current.health_down_failures,
|
||||
health_latency_warn_ms: patch.healthLatencyWarnMs !== void 0 ? patch.healthLatencyWarnMs : current.health_latency_warn_ms,
|
||||
health_success_recoveries: patch.healthSuccessRecoveries !== void 0 ? patch.healthSuccessRecoveries : current.health_success_recoveries,
|
||||
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
||||
}).where(eq2(appSettings.id, SETTINGS_ID)).run();
|
||||
return getAppSettings(db);
|
||||
return getAppSettings(db, fallbacks);
|
||||
}
|
||||
function touchVpsTrackerSync(db) {
|
||||
db.update(appSettings).set({
|
||||
@@ -638,6 +677,7 @@ __export(repos_exports, {
|
||||
listOriginIpsForFqdn: () => listOriginIpsForFqdn,
|
||||
listRecordsForBinding: () => listRecordsForBinding,
|
||||
listServiceGroups: () => listServiceGroups,
|
||||
listServiceIpRows: () => listServiceIpRows,
|
||||
listServiceIps: () => listServiceIps,
|
||||
listServices: () => listServices,
|
||||
listServicesByGroup: () => listServicesByGroup,
|
||||
@@ -659,6 +699,7 @@ __export(repos_exports, {
|
||||
setServiceEnabled: () => setServiceEnabled,
|
||||
setServiceGroup: () => setServiceGroup,
|
||||
setServiceGroupEnabled: () => setServiceGroupEnabled,
|
||||
setServiceIpEnabled: () => setServiceIpEnabled,
|
||||
setServiceLb: () => setServiceLb,
|
||||
unlinkBindingRecord: () => unlinkBindingRecord,
|
||||
unlinkGroupDnsRecord: () => unlinkGroupDnsRecord,
|
||||
@@ -1155,16 +1196,32 @@ function deleteServiceGroup(db, id) {
|
||||
function insertServiceIpIfMissing(db, serviceId, ip) {
|
||||
const existing = db.select({ ip: serviceIps.ip }).from(serviceIps).where(and2(eq3(serviceIps.service_id, serviceId), eq3(serviceIps.ip, ip))).get();
|
||||
if (!existing) {
|
||||
db.insert(serviceIps).values({ service_id: serviceId, ip }).run();
|
||||
db.insert(serviceIps).values({ service_id: serviceId, ip, enabled: true }).run();
|
||||
}
|
||||
}
|
||||
function listServiceIpRows(db, serviceId) {
|
||||
return db.select({ ip: serviceIps.ip, enabled: serviceIps.enabled }).from(serviceIps).where(eq3(serviceIps.service_id, serviceId)).all().map((row) => ({ ip: row.ip, enabled: Boolean(row.enabled) }));
|
||||
}
|
||||
function listServiceIps(db, serviceId) {
|
||||
return db.select({ ip: serviceIps.ip }).from(serviceIps).where(eq3(serviceIps.service_id, serviceId)).all().map((r) => r.ip);
|
||||
return listServiceIpRows(db, serviceId).map((row) => row.ip);
|
||||
}
|
||||
function setServiceIpEnabled(db, serviceId, ip, enabled) {
|
||||
const result = db.update(serviceIps).set({ enabled }).where(and2(eq3(serviceIps.service_id, serviceId), eq3(serviceIps.ip, ip))).run();
|
||||
if (result.changes === 0) {
|
||||
throw new NotFoundError(`service ip ${ip}`);
|
||||
}
|
||||
}
|
||||
function replaceServiceIps(db, serviceId, ips) {
|
||||
const previous = new Map(
|
||||
listServiceIpRows(db, serviceId).map((row) => [row.ip, row.enabled])
|
||||
);
|
||||
db.delete(serviceIps).where(eq3(serviceIps.service_id, serviceId)).run();
|
||||
for (const ip of ips) {
|
||||
db.insert(serviceIps).values({ service_id: serviceId, ip }).run();
|
||||
db.insert(serviceIps).values({
|
||||
service_id: serviceId,
|
||||
ip,
|
||||
enabled: previous.get(ip) ?? true
|
||||
}).run();
|
||||
ensureNode(db, serviceId, ip);
|
||||
}
|
||||
const keep = new Set(ips);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE service_ips ADD COLUMN enabled INTEGER NOT NULL DEFAULT 1;
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Local health-check engine settings (cron + state-machine thresholds).
|
||||
-- NULL = inherit from process env (HEALTH_CHECK_CRON / HEALTH_*).
|
||||
ALTER TABLE app_settings ADD COLUMN health_check_cron TEXT;
|
||||
ALTER TABLE app_settings ADD COLUMN health_degraded_failures INTEGER;
|
||||
ALTER TABLE app_settings ADD COLUMN health_down_failures INTEGER;
|
||||
ALTER TABLE app_settings ADD COLUMN health_latency_warn_ms INTEGER;
|
||||
ALTER TABLE app_settings ADD COLUMN health_success_recoveries INTEGER;
|
||||
@@ -923,17 +923,42 @@ function insertServiceIpIfMissing(db: Db, serviceId: number, ip: string): void {
|
||||
.where(and(eq(serviceIps.service_id, serviceId), eq(serviceIps.ip, ip)))
|
||||
.get();
|
||||
if (!existing) {
|
||||
db.insert(serviceIps).values({ service_id: serviceId, ip }).run();
|
||||
db.insert(serviceIps).values({ service_id: serviceId, ip, enabled: true }).run();
|
||||
}
|
||||
}
|
||||
|
||||
export function listServiceIps(db: Db, serviceId: number): string[] {
|
||||
export type ServiceIpRow = {
|
||||
ip: string;
|
||||
enabled: boolean;
|
||||
};
|
||||
|
||||
export function listServiceIpRows(db: Db, serviceId: number): ServiceIpRow[] {
|
||||
return db
|
||||
.select({ ip: serviceIps.ip })
|
||||
.select({ ip: serviceIps.ip, enabled: serviceIps.enabled })
|
||||
.from(serviceIps)
|
||||
.where(eq(serviceIps.service_id, serviceId))
|
||||
.all()
|
||||
.map((r) => r.ip);
|
||||
.map((row) => ({ ip: row.ip, enabled: Boolean(row.enabled) }));
|
||||
}
|
||||
|
||||
export function listServiceIps(db: Db, serviceId: number): string[] {
|
||||
return listServiceIpRows(db, serviceId).map((row) => row.ip);
|
||||
}
|
||||
|
||||
export function setServiceIpEnabled(
|
||||
db: Db,
|
||||
serviceId: number,
|
||||
ip: string,
|
||||
enabled: boolean,
|
||||
): void {
|
||||
const result = db
|
||||
.update(serviceIps)
|
||||
.set({ enabled })
|
||||
.where(and(eq(serviceIps.service_id, serviceId), eq(serviceIps.ip, ip)))
|
||||
.run();
|
||||
if (result.changes === 0) {
|
||||
throw new NotFoundError(`service ip ${ip}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function replaceServiceIps(
|
||||
@@ -941,9 +966,18 @@ export function replaceServiceIps(
|
||||
serviceId: number,
|
||||
ips: string[],
|
||||
): void {
|
||||
const previous = new Map(
|
||||
listServiceIpRows(db, serviceId).map((row) => [row.ip, row.enabled]),
|
||||
);
|
||||
db.delete(serviceIps).where(eq(serviceIps.service_id, serviceId)).run();
|
||||
for (const ip of ips) {
|
||||
db.insert(serviceIps).values({ service_id: serviceId, ip }).run();
|
||||
db.insert(serviceIps)
|
||||
.values({
|
||||
service_id: serviceId,
|
||||
ip,
|
||||
enabled: previous.get(ip) ?? true,
|
||||
})
|
||||
.run();
|
||||
ensureNode(db, serviceId, ip);
|
||||
}
|
||||
const keep = new Set(ips);
|
||||
|
||||
@@ -259,6 +259,7 @@ export const serviceIps = sqliteTable("service_ips", {
|
||||
.notNull()
|
||||
.references(() => services.id, { onDelete: "cascade" }),
|
||||
ip: text("ip").notNull(),
|
||||
enabled: integer("enabled", { mode: "boolean" }).notNull().default(true),
|
||||
created_at: text("created_at")
|
||||
.notNull()
|
||||
.default(sql`datetime('now')`),
|
||||
@@ -379,6 +380,11 @@ export const appSettings = sqliteTable("app_settings", {
|
||||
})
|
||||
.notNull()
|
||||
.default(true),
|
||||
health_check_cron: text("health_check_cron"),
|
||||
health_degraded_failures: integer("health_degraded_failures"),
|
||||
health_down_failures: integer("health_down_failures"),
|
||||
health_latency_warn_ms: integer("health_latency_warn_ms"),
|
||||
health_success_recoveries: integer("health_success_recoveries"),
|
||||
created_at: text("created_at")
|
||||
.notNull()
|
||||
.default(sql`datetime('now')`),
|
||||
|
||||
@@ -4,6 +4,14 @@ import { appSettings } from "./schema.js";
|
||||
|
||||
const SETTINGS_ID = "settings-main";
|
||||
|
||||
export type HealthEngineSettings = {
|
||||
healthCheckCron: string;
|
||||
healthDegradedFailures: number;
|
||||
healthDownFailures: number;
|
||||
healthLatencyWarnMs: number;
|
||||
healthSuccessRecoveries: number;
|
||||
};
|
||||
|
||||
export type AppSettingsDto = {
|
||||
id: string;
|
||||
vpsTrackerUrl: string;
|
||||
@@ -11,16 +19,37 @@ export type AppSettingsDto = {
|
||||
vpsTrackerSyncEnabled: boolean;
|
||||
vpsTrackerLastSyncAt: string | null;
|
||||
showQuickActions: boolean;
|
||||
};
|
||||
} & HealthEngineSettings;
|
||||
|
||||
export type AppSettingsPatch = {
|
||||
vpsTrackerUrl?: string;
|
||||
vpsTrackerIntegrationToken?: string;
|
||||
vpsTrackerSyncEnabled?: boolean;
|
||||
showQuickActions?: boolean;
|
||||
healthCheckCron?: string;
|
||||
healthDegradedFailures?: number;
|
||||
healthDownFailures?: number;
|
||||
healthLatencyWarnMs?: number;
|
||||
healthSuccessRecoveries?: number;
|
||||
};
|
||||
|
||||
function toDto(row: typeof appSettings.$inferSelect): AppSettingsDto {
|
||||
export type HealthEngineFallbacks = HealthEngineSettings;
|
||||
|
||||
function coalesceInt(value: number | null | undefined, fallback: number): number {
|
||||
return value == null || Number.isNaN(value) || value < 1 ? fallback : value;
|
||||
}
|
||||
|
||||
function toDto(
|
||||
row: typeof appSettings.$inferSelect,
|
||||
fallbacks?: HealthEngineFallbacks,
|
||||
): AppSettingsDto {
|
||||
const env = fallbacks ?? {
|
||||
healthCheckCron: "0 */2 * * * *",
|
||||
healthDegradedFailures: 1,
|
||||
healthDownFailures: 2,
|
||||
healthLatencyWarnMs: 1000,
|
||||
healthSuccessRecoveries: 2,
|
||||
};
|
||||
return {
|
||||
id: row.id,
|
||||
vpsTrackerUrl: row.vps_tracker_url?.trim() ?? "",
|
||||
@@ -31,10 +60,30 @@ function toDto(row: typeof appSettings.$inferSelect): AppSettingsDto {
|
||||
vpsTrackerLastSyncAt: row.vps_tracker_last_sync_at,
|
||||
showQuickActions:
|
||||
row.show_quick_actions == null ? true : Boolean(row.show_quick_actions),
|
||||
healthCheckCron: row.health_check_cron?.trim() || env.healthCheckCron,
|
||||
healthDegradedFailures: coalesceInt(
|
||||
row.health_degraded_failures,
|
||||
env.healthDegradedFailures,
|
||||
),
|
||||
healthDownFailures: coalesceInt(
|
||||
row.health_down_failures,
|
||||
env.healthDownFailures,
|
||||
),
|
||||
healthLatencyWarnMs: coalesceInt(
|
||||
row.health_latency_warn_ms,
|
||||
env.healthLatencyWarnMs,
|
||||
),
|
||||
healthSuccessRecoveries: coalesceInt(
|
||||
row.health_success_recoveries,
|
||||
env.healthSuccessRecoveries,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export function getAppSettings(db: Db): AppSettingsDto {
|
||||
export function getAppSettings(
|
||||
db: Db,
|
||||
fallbacks?: HealthEngineFallbacks,
|
||||
): AppSettingsDto {
|
||||
const row = db
|
||||
.select()
|
||||
.from(appSettings)
|
||||
@@ -44,9 +93,10 @@ export function getAppSettings(db: Db): AppSettingsDto {
|
||||
db.insert(appSettings).values({ id: SETTINGS_ID }).run();
|
||||
return toDto(
|
||||
db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get()!,
|
||||
fallbacks,
|
||||
);
|
||||
}
|
||||
return toDto(row);
|
||||
return toDto(row, fallbacks);
|
||||
}
|
||||
|
||||
export function getAppSettingsSecrets(db: Db): {
|
||||
@@ -67,7 +117,11 @@ export function getAppSettingsSecrets(db: Db): {
|
||||
};
|
||||
}
|
||||
|
||||
export function updateAppSettings(db: Db, patch: AppSettingsPatch): AppSettingsDto {
|
||||
export function updateAppSettings(
|
||||
db: Db,
|
||||
patch: AppSettingsPatch,
|
||||
fallbacks?: HealthEngineFallbacks,
|
||||
): AppSettingsDto {
|
||||
const existing = db
|
||||
.select()
|
||||
.from(appSettings)
|
||||
@@ -102,12 +156,32 @@ export function updateAppSettings(db: Db, patch: AppSettingsPatch): AppSettingsD
|
||||
patch.showQuickActions !== undefined
|
||||
? patch.showQuickActions
|
||||
: current.show_quick_actions,
|
||||
health_check_cron:
|
||||
patch.healthCheckCron !== undefined
|
||||
? patch.healthCheckCron.trim()
|
||||
: current.health_check_cron,
|
||||
health_degraded_failures:
|
||||
patch.healthDegradedFailures !== undefined
|
||||
? patch.healthDegradedFailures
|
||||
: current.health_degraded_failures,
|
||||
health_down_failures:
|
||||
patch.healthDownFailures !== undefined
|
||||
? patch.healthDownFailures
|
||||
: current.health_down_failures,
|
||||
health_latency_warn_ms:
|
||||
patch.healthLatencyWarnMs !== undefined
|
||||
? patch.healthLatencyWarnMs
|
||||
: current.health_latency_warn_ms,
|
||||
health_success_recoveries:
|
||||
patch.healthSuccessRecoveries !== undefined
|
||||
? patch.healthSuccessRecoveries
|
||||
: current.health_success_recoveries,
|
||||
updated_at: new Date().toISOString(),
|
||||
})
|
||||
.where(eq(appSettings.id, SETTINGS_ID))
|
||||
.run();
|
||||
|
||||
return getAppSettings(db);
|
||||
return getAppSettings(db, fallbacks);
|
||||
}
|
||||
|
||||
export function touchVpsTrackerSync(db: Db): void {
|
||||
|
||||
Reference in new issue
Block a user