feat: build collaboration workspaces
This commit is contained in:
184
modules/alerts/types.ts
Normal file
184
modules/alerts/types.ts
Normal file
@@ -0,0 +1,184 @@
|
||||
import type { IncidentSeverity } from "@/modules/core/types";
|
||||
|
||||
export const ALERT_RULE_TYPE_VALUES = ["health", "care", "device", "incident", "admission", "other"] as const;
|
||||
export type AlertRuleType = (typeof ALERT_RULE_TYPE_VALUES)[number];
|
||||
|
||||
export const ALERT_RULE_STATUS_VALUES = ["enabled", "disabled"] as const;
|
||||
export type AlertRuleStatus = (typeof ALERT_RULE_STATUS_VALUES)[number];
|
||||
|
||||
export const ALERT_TRIGGER_STATUS_VALUES = ["open", "acknowledged", "resolved", "closed"] as const;
|
||||
export type AlertTriggerStatus = (typeof ALERT_TRIGGER_STATUS_VALUES)[number];
|
||||
|
||||
export const ALERT_RULE_TYPE_LABELS: Record<AlertRuleType, string> = {
|
||||
health: "健康",
|
||||
care: "护理",
|
||||
device: "设备",
|
||||
incident: "应急",
|
||||
admission: "入住",
|
||||
other: "其他",
|
||||
};
|
||||
|
||||
export const ALERT_RULE_STATUS_LABELS: Record<AlertRuleStatus, string> = {
|
||||
enabled: "启用",
|
||||
disabled: "停用",
|
||||
};
|
||||
|
||||
export const ALERT_TRIGGER_STATUS_LABELS: Record<AlertTriggerStatus, string> = {
|
||||
open: "待处理",
|
||||
acknowledged: "已确认",
|
||||
resolved: "已解决",
|
||||
closed: "已关闭",
|
||||
};
|
||||
|
||||
export type AlertRule = {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
name: string;
|
||||
ruleType: AlertRuleType;
|
||||
severity: IncidentSeverity;
|
||||
status: AlertRuleStatus;
|
||||
conditionSummary: string;
|
||||
suggestion: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type AlertTrigger = {
|
||||
id: string;
|
||||
organizationId: string;
|
||||
ruleId?: string;
|
||||
ruleName: string;
|
||||
elderId?: string;
|
||||
elderName: string;
|
||||
title: string;
|
||||
description: string;
|
||||
status: AlertTriggerStatus;
|
||||
source: string;
|
||||
handledByAccountId?: string;
|
||||
handledByName?: string;
|
||||
handledAt?: string;
|
||||
handlingNotes: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
|
||||
export type AlertCenterData = {
|
||||
metrics: {
|
||||
enabledRules: number;
|
||||
openTriggers: number;
|
||||
criticalTriggers: number;
|
||||
resolvedTriggers: number;
|
||||
};
|
||||
rules: AlertRule[];
|
||||
triggers: AlertTrigger[];
|
||||
};
|
||||
|
||||
export type AlertRuleInput = {
|
||||
name: string;
|
||||
ruleType: AlertRuleType;
|
||||
severity: IncidentSeverity;
|
||||
status: AlertRuleStatus;
|
||||
conditionSummary: string;
|
||||
suggestion: string;
|
||||
};
|
||||
|
||||
export type AlertTriggerInput = {
|
||||
ruleId?: string;
|
||||
elderId?: string;
|
||||
title: string;
|
||||
description: string;
|
||||
status: AlertTriggerStatus;
|
||||
source: string;
|
||||
handlingNotes: string;
|
||||
};
|
||||
|
||||
type ValidationSuccess<T> = {
|
||||
success: true;
|
||||
data: T;
|
||||
};
|
||||
|
||||
type ValidationFailure = {
|
||||
success: false;
|
||||
reason: string;
|
||||
};
|
||||
|
||||
export type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;
|
||||
|
||||
const INCIDENT_SEVERITY_VALUES = ["info", "warning", "critical"] as const satisfies readonly IncidentSeverity[];
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||||
}
|
||||
|
||||
function readString(source: Record<string, unknown>, key: string): string {
|
||||
const value = source[key];
|
||||
return typeof value === "string" ? value.trim() : "";
|
||||
}
|
||||
|
||||
function readOptionalString(source: Record<string, unknown>, key: string): string | undefined {
|
||||
const value = readString(source, key);
|
||||
return value || undefined;
|
||||
}
|
||||
|
||||
function readEnum<T extends string>(value: unknown, values: readonly T[]): T | null {
|
||||
return typeof value === "string" ? values.find((item) => item === value) ?? null : null;
|
||||
}
|
||||
|
||||
export function validateAlertRuleInput(value: unknown): ValidationResult<AlertRuleInput> {
|
||||
if (!isRecord(value)) {
|
||||
return { success: false, reason: "请求数据格式无效" };
|
||||
}
|
||||
|
||||
const name = readString(value, "name");
|
||||
if (!name) {
|
||||
return { success: false, reason: "规则名称不能为空" };
|
||||
}
|
||||
|
||||
const ruleType = readEnum(value.ruleType, ALERT_RULE_TYPE_VALUES);
|
||||
const severity = readEnum(value.severity, INCIDENT_SEVERITY_VALUES);
|
||||
const status = readEnum(value.status, ALERT_RULE_STATUS_VALUES);
|
||||
if (!ruleType || !severity || !status) {
|
||||
return { success: false, reason: "规则类型、级别或状态无效" };
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
name,
|
||||
ruleType,
|
||||
severity,
|
||||
status,
|
||||
conditionSummary: readString(value, "conditionSummary"),
|
||||
suggestion: readString(value, "suggestion"),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function validateAlertTriggerInput(value: unknown): ValidationResult<AlertTriggerInput> {
|
||||
if (!isRecord(value)) {
|
||||
return { success: false, reason: "请求数据格式无效" };
|
||||
}
|
||||
|
||||
const title = readString(value, "title");
|
||||
if (!title) {
|
||||
return { success: false, reason: "触发记录标题不能为空" };
|
||||
}
|
||||
|
||||
const status = readEnum(value.status, ALERT_TRIGGER_STATUS_VALUES);
|
||||
if (!status) {
|
||||
return { success: false, reason: "触发记录状态无效" };
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
ruleId: readOptionalString(value, "ruleId"),
|
||||
elderId: readOptionalString(value, "elderId"),
|
||||
title,
|
||||
description: readString(value, "description"),
|
||||
status,
|
||||
source: readString(value, "source"),
|
||||
handlingNotes: readString(value, "handlingNotes"),
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user