Files
multi-simadmin/packages/contracts/src/instances.ts
T
chick f11877f13e feat(contracts): share notification, organization and device capability models
Move the Hub channel table, organization tags and device capability definitions
into the workspace packages so the control plane and the console validate the
same contract, and refresh the frozen upstream evidence for the new paths.
2026-09-05 18:52:54 +08:00

86 lines
2.6 KiB
TypeScript

export const API_V1_PREFIX = '/api/v1' as const;
export const MAX_PAGE_SIZE = 100 as const;
export const SORT_DIRECTIONS = ['asc', 'desc'] as const;
export const CAPABILITY_STATUSES = [
'supported',
'unsupported',
'auth-required',
'degraded',
'unknown',
] as const;
export const FRESHNESS_STATUSES = ['fresh', 'stale', 'expired', 'unknown'] as const;
export type SortDirection = (typeof SORT_DIRECTIONS)[number];
export type CapabilityStatus = (typeof CAPABILITY_STATUSES)[number];
export type SnapshotFreshness = (typeof FRESHNESS_STATUSES)[number];
export type Revision = number;
/** Page ordering is stable: the resource id is always the final ascending tie-breaker. */
export interface PageQuery<SortField extends string> {
readonly page?: number;
readonly pageSize?: number;
readonly sort?: SortField;
readonly direction?: SortDirection;
}
export interface PageMeta {
readonly page: number;
readonly pageSize: number;
readonly total: number;
}
export interface PageEnvelope<T> {
readonly items: readonly T[];
readonly page: PageMeta;
}
export type PasswordUpdate =
| { readonly action: 'preserve' }
| { readonly action: 'set'; readonly password: string }
| { readonly action: 'clear' };
export interface InstanceInput {
readonly name: string;
readonly origin: string;
readonly tags?: readonly string[];
readonly groupId?: string | null;
readonly password?: PasswordUpdate;
}
export interface InstancePatch {
readonly name?: string;
readonly origin?: string;
readonly tags?: readonly string[];
readonly groupId?: string | null;
readonly password?: PasswordUpdate;
}
export interface LoginInput {
/** One-shot input; omit to resolve the saved credential reference server-side. */
readonly password?: string;
}
export interface Instance {
readonly id: string;
readonly name: string;
readonly origin: string;
readonly tags: readonly string[];
readonly groupId: string | null;
readonly revision: Revision;
readonly capabilityStatus: CapabilityStatus;
readonly freshness: SnapshotFreshness;
readonly credentialConfigured: boolean;
}
export interface InstanceFilters {
readonly search?: string;
readonly capabilityStatus?: CapabilityStatus;
readonly freshness?: SnapshotFreshness;
readonly tag?: string;
readonly groupId?: string;
readonly credentialConfigured?: boolean;
}
export type InstancePageQuery = PageQuery<'name' | 'status' | 'freshness' | 'updatedAt'> &
InstanceFilters;
export type InstancePage = PageEnvelope<Instance>;
export interface SessionMetadata {
readonly instanceId: string;
readonly authenticated: boolean;
readonly checkedAt: string;
}