import type { IdentityDatabase } from './db'; export interface EdgeNodeRepositoryOptions { ensureClusterTables?: boolean; } export interface EdgeNodeSummary { nodeId: string; displayName?: string; nodeType: 'center' | 'edge' | 'sp'; podCount: number; createdAt?: string; updatedAt?: string; lastSeen?: string; metadata?: Record | null; } export interface CreateEdgeNodeResult { nodeId: string; token: string; createdAt: string; } export interface EdgeNodeSecret { nodeId: string; displayName?: string; tokenHash: string; nodeType: 'center' | 'edge' | 'sp'; metadata?: Record | null; } export interface CenterNodeInfo { nodeId: string; displayName?: string; internalIp: string; internalPort: number; connectivityStatus: 'unknown' | 'reachable' | 'unreachable'; lastSeen?: Date; } export interface CreateSpNodeResult { nodeId: string; nodeToken: string; serviceToken: string; createdAt: string; } export interface SpNodeInfo { nodeId: string; displayName?: string; publicUrl: string; serviceTokenHash: string; lastSeen?: Date; } export declare class EdgeNodeRepository { private readonly db; private readonly ready; constructor(db: IdentityDatabase, options?: EdgeNodeRepositoryOptions); listNodes(): Promise; createNode(displayName?: string): Promise; getNodeSecret(nodeId: string): Promise; updateNodeHeartbeat(nodeId: string, metadata: Record | null, timestamp: Date): Promise; updateNodeMode(nodeId: string, options: { accessMode: 'direct' | 'proxy'; ipv4?: string; publicPort?: number; subdomain?: string; connectivityStatus?: 'unknown' | 'reachable' | 'unreachable'; capabilities?: Record; }): Promise; getNodeConnectivityInfo(nodeId: string): Promise<{ nodeId: string; accessMode?: string; ipv4?: string; publicPort?: number; publicUrl?: string; subdomain?: string; connectivityStatus?: string; lastConnectivityCheck?: Date; } | undefined>; mergeNodeMetadata(nodeId: string, patch: Record): Promise; getNodeMetadata(nodeId: string): Promise<{ nodeId: string; metadata: Record | null; lastSeen?: Date; } | undefined>; replaceNodePods(nodeId: string, pods: string[]): Promise; assignPodToNode(nodeId: string, baseUrl: string): Promise; findNodeByResourcePath(path: string): Promise<{ nodeId: string; baseUrl: string; accessMode?: string; publicUrl?: string; metadata?: Record | null; } | undefined>; findNodeBySubdomain(hostname: string): Promise<{ nodeId: string; accessMode?: string; publicUrl?: string; metadata?: Record | null; subdomain?: string; } | undefined>; matchesToken(tokenHash: string, token: string): boolean; /** * Get node capabilities and related information for admin queries */ getNodeCapabilities(nodeId: string): Promise<{ nodeId: string; capabilities: Record | null; stringCapabilities: string[] | null; accessMode: string | null; lastSeen: Date | null; connectivityStatus: string | null; } | undefined>; /** * List all nodes with their capability information */ listNodeCapabilities(): Promise | null; stringCapabilities: string[] | null; accessMode: string | null; lastSeen: Date | null; connectivityStatus: string | null; }>>; /** * Register or update a center node in the cluster. * Center nodes use the same table as edge nodes but with nodeType='center'. */ registerCenterNode(options: { nodeId: string; displayName?: string; internalIp: string; internalPort: number; }): Promise<{ nodeId: string; token: string; }>; /** * Update center node heartbeat with internal endpoint info. */ updateCenterNodeHeartbeat(nodeId: string, internalIp: string, internalPort: number, timestamp: Date): Promise; /** * List all center nodes in the cluster. */ listCenterNodes(): Promise; /** * Get a specific center node by ID. */ getCenterNode(nodeId: string): Promise; /** * Find a center node by its internal endpoint (for routing). */ findCenterNodeByEndpoint(internalIp: string, internalPort: number): Promise; /** * Mark a center node as unreachable (for health checks). */ markCenterNodeUnreachable(nodeId: string): Promise; /** * Remove a center node from the cluster. */ removeCenterNode(nodeId: string): Promise; /** * Delete a node */ deleteNode(nodeId: string): Promise; private getNodePodRows; private updateNodePodBaseUrls; private removePodBaseUrlsFromOtherNodes; /** * Register or update an SP node (UPSERT by nodeId). * * SP 本地生成 deviceId 作为 nodeId,注册时带上来。 * 同一 nodeId 重复注册时更新 publicUrl、token 等,保留原记录。 * 不传 nodeId 则 Cloud 随机分配。 */ registerSpNode(options: { publicUrl: string; displayName?: string; /** SP 提供的设备 ID,作为 nodeId(不传则随机生成) */ nodeId?: string; /** SP 已保存的 nodeToken,重复注册时用于保留旧凭证 */ nodeToken?: string; /** SP 提供的 serviceToken,不传则随机生成 */ serviceToken?: string; }): Promise; /** * Get SP node info by nodeId. */ getSpNode(nodeId: string): Promise; }