import { z } from "zod/v4"; const id = z.uuid(); const optionalId = id.nullable(); const name = z.string().trim().min(1).max(100); const note = z.string().trim().max(4000).nullable(); const optionalText = z.string().trim().min(1).max(255).nullable(); export const ConfigurationSchema = z.enum([ "pending", "configured", "removal_pending", "removed", "never_configured", ]); const period = { startDate: z.iso.date(), endDate: z.iso.date().nullable() }; const scope = { systemId: id, environmentId: optionalId }; const named = { name, active: z.boolean() }; const definitions = [ z.strictObject({ kind: z.literal("system"), ...named }), z.strictObject({ kind: z.literal("resource_type"), ...named }), z.strictObject({ kind: z.literal("permission"), ...named, resourceTypeId: id, description: note, }), z.strictObject({ kind: z.literal("template"), ...named, description: note, systemId: optionalId, }), z.strictObject({ kind: z.literal("environment"), ...named, systemId: id }), z.strictObject({ kind: z.literal("account"), ...scope, login: z.string().trim().min(1).max(255), usage: z.enum(["personal", "shared", "technical"]), active: z.boolean(), expiresOn: z.iso.date().nullable(), notes: note, }), z.strictObject({ kind: z.literal("account_person"), accountId: id, personId: id, ...period, configuration: ConfigurationSchema.nullable(), }), z.strictObject({ kind: z.literal("group"), ...scope, ...named, identifier: z.string().trim().min(1).max(255), description: note, templateId: optionalId, }), z.strictObject({ kind: z.literal("membership"), accountId: id, groupId: id, ...period, configuration: ConfigurationSchema, }), z.strictObject({ kind: z.literal("resource"), ...named, resourceTypeId: id, systemId: optionalId, environmentId: optionalId, reference: optionalText, notes: note, }), z.strictObject({ kind: z.literal("grant"), resourceId: id, permissionId: id, accountId: optionalId, groupId: optionalId, ...period, configuration: ConfigurationSchema, }), z.strictObject({ kind: z.literal("need"), personId: id, resourceId: id, permissionIds: z.array(id).min(1).max(50), ...period, notes: note, }), z.strictObject({ kind: z.literal("coverage"), needId: id, grantId: id, accountPersonId: id, membershipId: optionalId, ...period, }), ] as const; export const AccessDefinitionSchema = z.discriminatedUnion("kind", definitions); export type AccessDefinition = z.infer; export type AccessKind = AccessDefinition["kind"]; export const AccessKindSchema = z.enum([ "system", "resource_type", "permission", "template", "environment", "account", "account_person", "group", "membership", "resource", "grant", "need", "coverage", ]);