metis-desk/modules/assets/src/api/domain/asset-definition.ts

53 lines
1.6 KiB
TypeScript

import { z } from "zod/v4";
import { validTemplateSections } from "./template-sections";
const title = z.string().min(1).max(100);
export const FieldTypeSchema = z.enum(["text", "number", "date", "boolean", "choice"]);
export const TemplateFieldSchema = z.strictObject({
fieldId: z.uuid(),
required: z.boolean(),
sectionId: z.uuid().optional(),
});
export const TemplateSectionSchema = z.strictObject({
id: z.uuid(),
name: z.string().trim().min(1).max(100),
description: z.string().trim().max(1000),
});
export const AssetDefinitionSchema = z.discriminatedUnion("kind", [
z.strictObject({
kind: z.literal("field"),
name: title,
description: z.string().max(1000),
type: FieldTypeSchema,
unit: z.string().max(30),
choices: z.array(title).max(100),
}),
z
.strictObject({
kind: z.literal("template"),
name: title,
description: z.string().max(1000),
fields: z.array(TemplateFieldSchema).min(1).max(100),
sections: z.array(TemplateSectionSchema).max(30).optional(),
})
.refine((template) => validTemplateSections(template.sections ?? [], template.fields), {
path: ["sections"],
message: "INVALID_SECTIONS",
}),
z.strictObject({
kind: z.literal("relation"),
name: title,
inverseName: title,
description: z.string().max(1000),
symmetric: z.boolean(),
}),
]);
export type AssetDefinitionSpec = z.infer<typeof AssetDefinitionSchema>;
export type AssetFieldType = z.infer<typeof FieldTypeSchema>;
export class AssetCatalogError extends Error {
constructor(public readonly code: string) {
super(code);
}
}