SPB Git

Repository Public

schemas.ts 4.6 KB 122 lines typescript

1import { z } from "zod";23export const localized = z.object({ en: z.string(), fr: z.string() });4export type Localized = z.infer<typeof localized>;56const isoDate = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected YYYY-MM-DD");78export const FAMILIES = ["Mac Studio", "Mac mini", "MacBook Pro", "MacBook Air", "Other"] as const;9export const LIFECYCLES = ["active", "offline", "maintenance", "planned", "retired", "unverified"] as const;10export const ROLES = ["gateway", "services", "research-compute", "data", "monitoring", "worker", "portable"] as const;1112export const nodeSchema = z.object({13  id: z.string().regex(/^node-\d{2}$/),14  number: z.number().int().positive(),15  publicName: z.string().min(1),16  family: z.enum(FAMILIES),17  modelIdentifier: z.string().nullable(),18  chip: z.string().nullable(),19  cpuCores: z.number().int().positive().nullable(),20  cpuCoreLayout: z.string().nullable(),21  gpuCores: z.number().int().positive().nullable(),22  unifiedMemoryGB: z.number().int().positive().nullable(),23  storageGB: z.number().int().positive().nullable(),24  networkInterface: z.string().nullable(),25  role: z.array(z.enum(ROLES)).min(1),26  lifecycle: z.enum(LIFECYCLES),27  rack: z.string().nullable(),28  shelf: z.string().nullable(),29  addedAt: isoDate.nullable(),30  description: localized,31  imageIds: z.array(z.string()),32  verifiedAt: isoDate.nullable(),33  source: z.string().nullable(),34  publicVisibility: z.boolean(),35});36export type NodeRecord = z.infer<typeof nodeSchema>;37export type Family = (typeof FAMILIES)[number];38export type Lifecycle = (typeof LIFECYCLES)[number];39export type Role = (typeof ROLES)[number];4041export const photoSchema = z.object({42  id: z.string(),43  file: z.string(),44  width: z.number().int().positive(),45  height: z.number().int().positive(),46  blur: z.string(),47  takenAt: isoDate.nullable(),48  focus: z.string(),49  title: localized,50  caption: localized,51  alt: localized,52});53export type Photo = z.infer<typeof photoSchema>;5455export const researchSchema = z.object({56  id: z.string(),57  status: z.enum(["completed", "ongoing", "proposed"]),58  kind: z.enum(["working-paper", "experiment", "protocol"]),59  date: z.string().regex(/^\d{4}-\d{2}(-\d{2})?$/),60  title: localized,61  summary: localized,62  clusterUse: localized,63  themes: z.array(z.string()),64  reference: z.object({ label: z.string(), authors: z.string(), series: z.string(), year: z.number().int(), url: z.url() }).nullable(),65});66export type ResearchEntry = z.infer<typeof researchSchema>;6768/** Every published observation must carry its full measurement context. */69export const benchmarkSchema = z.object({70  id: z.string(),71  nodeId: z.string().regex(/^node-\d{2}$/),72  modelId: z.string(),73  modelVersion: z.string(),74  quantization: z.string(),75  runtime: z.string(),76  runtimeVersion: z.string(),77  promptTokens: z.number().int().nonnegative(),78  outputTokens: z.number().int().nonnegative(),79  concurrency: z.number().int().positive(),80  metric: z.enum(["tokens_per_second", "time_to_first_token_ms", "throughput_rps", "peak_memory_gb", "power_w", "wall_time_s"]),81  value: z.number(),82  uncertainty: z.number().nonnegative(),83  repetitions: z.number().int().positive(),84  method: z.string(),85  measuredAt: isoDate,86  rawDataRef: z.string(),87  preview: z.boolean().default(false),88});89export type BenchmarkObservation = z.infer<typeof benchmarkSchema>;9091export const timelineSchema = z.object({ date: isoDate, title: localized, detail: localized });92export type TimelineEvent = z.infer<typeof timelineSchema>;9394export const plannedSchema = z.object({ label: localized, status: z.enum(["planned", "ordered"]), note: localized });95export type PlannedHardware = z.infer<typeof plannedSchema>;9697export const siteSchema = z.object({98  url: z.url(),99  contactEmail: z.email(),100  updatedAt: isoDate,101  inventoryVerifiedAt: isoDate,102  measuredLinkRate: z.string(),103  storageUnits: z.number().int().nonnegative(),104});105export type SiteConfig = z.infer<typeof siteSchema>;106107export const accessRequestSchema = z.object({108  name: z.string().trim().min(2).max(120),109  affiliation: z.string().trim().max(200).optional().default(""),110  email: z.email().max(200),111  projectTitle: z.string().trim().min(3).max(200),112  researchQuestion: z.string().trim().min(20).max(4000),113  compute: z.string().trim().min(5).max(2000),114  dates: z.string().trim().max(200).optional().default(""),115  dataConstraints: z.string().trim().max(2000).optional().default(""),116  expectedOutputs: z.string().trim().max(2000).optional().default(""),117  locale: z.enum(["en", "fr"]).default("en"),118  /** honeypot — must stay empty */119  website: z.string().max(0).optional().default(""),120});121export type AccessRequest = z.infer<typeof accessRequestSchema>;122
Files main
Menu

Theme