feat(plan): validate dynamic category keys, resolve audit label from DB
- Replace hardcoded planCategoryEnum z.enum with z.string().trim().min(1) - Add assertActiveCategory() helper that rejects inactive/unknown keys - Add resolveCategoryLabel() helper that resolves the Czech label from plan_categories DB table, falling back to built-in map - Change PlanAuditDescriptionInput.category -> categoryLabel (pre-resolved string) - Update buildPlanAuditDescription to use opts.categoryLabel directly - Update all 6 buildPlanAuditDescription call sites in plan.service.ts to await resolveCategoryLabel(row.category) - Add category validation in createEntry, updateEntry, createOverride, updateOverride - Update planAuditDescription tests to pass categoryLabel instead of category Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,8 +47,8 @@ export function formatPlanDate(iso: string): string {
|
||||
export interface PlanAuditDescriptionInput {
|
||||
/** Employee the plan row belongs to (display name). */
|
||||
userName: string;
|
||||
/** `plan_category` enum value. */
|
||||
category: string;
|
||||
/** Already-resolved Czech category label (resolved from plan_categories). */
|
||||
categoryLabel: string;
|
||||
/** Resolved project name, or null when the row has no project. */
|
||||
projectName?: string | null;
|
||||
/** Range start (YYYY-MM-DD). For overrides, pass the shift date here. */
|
||||
@@ -74,11 +74,7 @@ export function buildPlanAuditDescription(
|
||||
? formatPlanDate(opts.dateFrom)
|
||||
: `${formatPlanDate(opts.dateFrom)} – ${formatPlanDate(opts.dateTo)}`;
|
||||
|
||||
const parts: string[] = [
|
||||
opts.userName,
|
||||
dateLabel,
|
||||
planCategoryLabel(opts.category),
|
||||
];
|
||||
const parts: string[] = [opts.userName, dateLabel, opts.categoryLabel];
|
||||
|
||||
if (opts.projectName && opts.projectName.trim()) {
|
||||
parts.push(opts.projectName.trim());
|
||||
|
||||
Reference in New Issue
Block a user