feat: canonical custom field types, validation, and type-aware querying

- Unify field types across all layers: Text, Textarea, SelectOne, SelectMultiple, Date, DateTime, Number
- Add CustomFieldValidationConfig with type-specific Zod schemas
- Add validateCustomFieldValue() dispatching per-type validation
- Add validation_config (JSONB) and default_value columns to custom_fields
- Replace ad-hoc date/datetime/pattern checks with centralized validator
- Type-aware cf.* query operators: gt:, gte:, lt:, lte:, before:, after:, contains:
- Type-aware admin builder UI with inline option editor, min/max, date ranges, constraints
- Type-aware ticket detail rendering: Number inputs, Textarea, SelectMultiple checkbox groups
- Backward compatible: legacy type names mapped to canonical; old pattern field still checked
- Update seed data to canonical PascalCase types
- Migration 0018: add validation_config and default_value to custom_fields

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Gjermund Høsøien Wiggen
2026-06-15 21:29:28 +02:00
parent 70f0924d4b
commit 9679734e3f
15 changed files with 4501 additions and 125 deletions

View File

@@ -340,6 +340,8 @@ export async function createCustomField(data: {
values?: unknown | null;
max_values?: number;
pattern?: string | null;
validation_config?: Record<string, unknown> | null;
default_value?: string | null;
}): Promise<{ data: CustomField | null; error: string | null }> {
return request<CustomField>("/custom-fields", { method: "POST", body: JSON.stringify(data) });
}
@@ -351,6 +353,8 @@ export async function updateCustomField(id: string, data: {
values?: unknown | null;
max_values?: number;
pattern?: string | null;
validation_config?: Record<string, unknown> | null;
default_value?: string | null;
}): Promise<{ data: CustomField | null; error: string | null }> {
return request<CustomField>(`/custom-fields/${id}`, { method: "PATCH", body: JSON.stringify(data) });
}