39 lines
1.5 KiB
TypeScript
39 lines
1.5 KiB
TypeScript
|
|
import { z } from 'zod';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Per-port qualification criterion. Admin-configurable: label / description /
|
||
|
|
* enabled state / display order. The `key` is the stable identifier code
|
||
|
|
* references (templates, derivations) — it can't be changed after creation
|
||
|
|
* because per-interest state rows reference it via composite PK.
|
||
|
|
*/
|
||
|
|
export const createQualificationCriterionSchema = z.object({
|
||
|
|
key: z
|
||
|
|
.string()
|
||
|
|
.min(1)
|
||
|
|
.max(64)
|
||
|
|
.regex(/^[a-z][a-z0-9_]*$/, 'Must be lowercase alphanumeric with underscores'),
|
||
|
|
label: z.string().min(1).max(120),
|
||
|
|
description: z.string().max(500).optional().nullable(),
|
||
|
|
enabled: z.boolean().default(true),
|
||
|
|
displayOrder: z.number().int().min(0).default(0),
|
||
|
|
});
|
||
|
|
|
||
|
|
export const updateQualificationCriterionSchema = createQualificationCriterionSchema
|
||
|
|
.omit({ key: true })
|
||
|
|
.partial();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Per-interest qualification state. Only `confirmed` + optional `notes` are
|
||
|
|
* writable — `confirmedAt` / `confirmedBy` are stamped server-side from
|
||
|
|
* the auth context.
|
||
|
|
*/
|
||
|
|
export const setInterestQualificationSchema = z.object({
|
||
|
|
criterionKey: z.string().min(1),
|
||
|
|
confirmed: z.boolean(),
|
||
|
|
notes: z.string().max(500).optional().nullable(),
|
||
|
|
});
|
||
|
|
|
||
|
|
export type CreateQualificationCriterionInput = z.infer<typeof createQualificationCriterionSchema>;
|
||
|
|
export type UpdateQualificationCriterionInput = z.infer<typeof updateQualificationCriterionSchema>;
|
||
|
|
export type SetInterestQualificationInput = z.infer<typeof setInterestQualificationSchema>;
|