Files
portal/src/lib/svelte-admin/schemas.ts
T
NeilClack 93d941569e proclamation-categories: sub-category management inline in parent form
- Registry: Remove 'parent.name' from listFields (all shown records
  are top-level with no parent), remove 'parent: true' from include
  since unused
- +page.server.ts: Custom load filters to parentId=null (top-level
  only); custom upsert syncs children (create/update/delete) and
  handles P2002 duplicate-name errors; custom delete cascades to
  children first to avoid FK constraint violations
- CategoryForm.svelte: Replace parentId select dropdown with dynamic
  list of sub-category inputs. Each row has a name field and Remove
  button. Pre-populates from record.children when editing existing
  categories. Add Sub-category button appends new rows
- +page.svelte: Remove unused relationOptionsData prop from
  CategoryForm; rename submit button label from 'Update' to 'Save'
- prisma: Add ProclamationCategorySubscriptionLevel join table
  migration and regenerate client
- General: Update TipTap mock, Toast, license-keys page, proclamations
  server/route tests, README, AGENTS.md, and other admin forms
2026-07-08 10:31:28 -05:00

75 lines
2.2 KiB
TypeScript

import { z } from 'zod';
const email = z.string().email('Invalid email address');
const phone = z
.string()
.min(10, 'Phone number must be at least 10 digits')
.regex(/^[\d\-\+\(\) ]+$/, 'Invalid phone number format');
const name = z.string().min(1, 'Required').max(100, 'Too long');
export const UserRole = z.object({
name: z.string().min(1, 'Required')
});
export const User = z.object({
name: z.string().min(1, 'Required'),
email,
roleId: z.coerce.number().int().min(1)
});
export const Profile = z.object({
userId: z.string().min(1, 'Required'),
firstName: name,
lastName: name,
phoneNumber: phone
});
export const Address = z.object({
profileId: z.string().min(1),
street: z.string().min(1, 'Street is required'),
city: z.string().min(1, 'City is required'),
state: z.string().min(1, 'State is required'),
postalCode: z.string().min(1, 'Postal code is required'),
country: z.string().min(1, 'Country is required'),
type: z.enum(['Mailing', 'Billing', 'Shipping']).default('Mailing'),
isDefaultMailing: z.coerce.boolean().default(false),
isDefaultBilling: z.coerce.boolean().default(false),
isDefaultShipping: z.coerce.boolean().default(false)
});
export const SolfeggioFrequency = z.object({
name: z.string().min(1, 'Required'),
value: z.coerce.number().int('Must be a whole number')
});
export const SubscriptionLevel = z.object({
name: z.string().min(1, 'Required'),
description: z.string().optional().default('')
});
export const ProclamationCategory = z.object({
name: z.string().min(1, 'Required'),
parentId: z.coerce.number().int().optional()
});
export const Proclamation = z.object({
name: z.string().min(1, 'Required'),
solfeggioFrequencyId: z.coerce.number().int(),
parentCategoryId: z.coerce.number().int(),
categoryId: z.coerce.number().int().optional(),
subscriptionLevelId: z.coerce.number().int(),
content: z.string().optional().default('')
});
export const LicenseKey = z.object({
active: z.coerce.boolean(),
level: z.string().min(1, 'Required'),
userId: z.string().min(1, 'Required')
});
export const UserUpdate = z.object({
id: z.string().min(1),
name: z.string().min(1, 'Required').optional(),
email: z.string().email().optional()
});