import type { JobResponse, ServerInstanceResponse, ServerMetricsResponse, UserContactProfile, UserStatus, UserThemePreferenceResponse } from "../api/types"; export type WorkspaceRole = "platformAdmin" | "serverOwner" | "serverAdmin"; export type WorkspaceCapability = | "profile.settings.manage" | "platform.overview.read" | "servers.read" | "servers.manage" | "plugins.market.read" | "users.manage" | "aiProviders.manage" | "system.maintenance"; export interface CurrentUserView { id: string; displayName: string; email?: string; status: UserStatus; roles: WorkspaceRole[]; capabilities: WorkspaceCapability[]; profile: UserContactProfile; themePreference?: UserThemePreferenceResponse; source: "api" | "local"; } const roleCapabilities: Record = { platformAdmin: [ "profile.settings.manage", "platform.overview.read", "servers.read", "servers.manage", "plugins.market.read", "users.manage", "aiProviders.manage", "system.maintenance" ], serverOwner: ["profile.settings.manage", "servers.read", "servers.manage"], serverAdmin: ["profile.settings.manage", "servers.read", "servers.manage"] }; export function capabilitiesForRoles(roles: WorkspaceRole[]): WorkspaceCapability[] { const set = new Set(); for (const role of roles) { for (const capability of roleCapabilities[role] ?? []) { set.add(capability); } } return [...set]; } export function isPlatformAdmin(user: CurrentUserView): boolean { return user.roles.includes("platformAdmin"); } export function rolesFromBackendRoles(roles: string[]): WorkspaceRole[] { const mapped = new Set(); for (const role of roles) { const normalized = role.toLowerCase(); if (normalized === "admin" || normalized === "platform-admin" || normalized === "platformadmin") { mapped.add("platformAdmin"); } if (normalized === "server-owner" || normalized === "owner") { mapped.add("serverOwner"); } if (normalized === "server-admin" || normalized === "operator") { mapped.add("serverAdmin"); } } return mapped.size > 0 ? [...mapped] : ["serverAdmin"]; } export type OperationStatus = "pending" | "succeeded" | "failed"; export interface OperationRecord { id: string; intent: string; targetKind: "server" | "plugin" | "config" | "llm" | "platform"; targetId: string; requester: string; status: OperationStatus; jobId?: string; jobState?: JobResponse["state"]; message?: string; errorReason?: string; diagnosticId?: string; createdAt: string; updatedAt: string; } export interface ServerCardView { instance: ServerInstanceResponse; metrics?: ServerMetricsResponse; pendingJobs: number; activeJobs?: number; failedJobs?: number; latestJob?: JobResponse; } export type ServerStatusFilter = "all" | "online" | "offline" | "attention"; export function serverIsOnline(state: ServerInstanceResponse["state"]): boolean { return state === "running"; } export function serverNeedsAttention(state: ServerInstanceResponse["state"]): boolean { return state === "failed" || state === "installing"; } export function filterServerCards(cards: ServerCardView[], keyword: string, status: ServerStatusFilter): ServerCardView[] { const query = keyword.trim().toLowerCase(); return cards.filter((card) => { if (query && !`${card.instance.name} ${card.instance.id} ${card.instance.pluginId}`.toLowerCase().includes(query)) { return false; } if (status === "online") { return serverIsOnline(card.instance.state); } if (status === "offline") { return !serverIsOnline(card.instance.state); } if (status === "attention") { return serverNeedsAttention(card.instance.state); } return true; }); } export interface GameTypeDistributionEntry { serverType: string; label: string; count: number; } export interface PlatformOverviewSignal { id: string; kind: "log" | "fault" | "plugin" | "aiProvider" | "job"; summary: string; detail: string; targetPage: "servers" | "plugins" | "aiProviders" | "maintenance"; targetId?: string; tone: "info" | "warning" | "error"; at: string; } export type ServerDetailSection = "overview" | "logs" | "config" | "plugins" | "llm" | "history"; export const serverDetailSections: Array<{ id: ServerDetailSection; label: string }> = [ { id: "overview", label: "概览" }, { id: "logs", label: "日志" }, { id: "config", label: "配置" }, { id: "plugins", label: "插件控制" }, { id: "llm", label: "AI 助手" }, { id: "history", label: "操作历史" } ]; export interface PluginControlDescriptor { key: string; label: string; description: string; capability: string; lifecycleAction?: "start" | "stop" | "status"; dangerous: boolean; } export interface PluginControlGroupView { pluginId: string; pluginName: string; version: string; status: string; controls: PluginControlDescriptor[]; } export interface DiffLine { kind: "same" | "added" | "removed"; text: string; } export interface ConfigDiffView { serverInstanceId: string; configVersion?: number; checksum?: string; key?: string; source?: string; summary: string; lines: DiffLine[]; nextContent: string; proposedContentInputRef?: string; } export interface LlmSuggestionView { serverInstanceId: string; source: "api"; recommendation: string; diffId?: string; expiresAt?: string; diff?: ConfigDiffView; }