fix(plan): allow empty notes, use local time for past-date gate

Three related fixes from manual smoke testing:
- Zod schema: drop min(1) on note field across all four schemas — note is
  optional in real usage, and the modal initialized it to empty.
- assertNotPastDate: replace toISOString() (UTC) with local-time getters
  to match the rest of the codebase. Fixes off-by-one near day boundaries.
- createEntry / updateEntry: also check the date_to endpoint for past
  dates, so a range can't extend backwards into the past even when its
  start is today or future. Defense in depth.

Modal: drop `required` attribute and asterisk from the note field. Tests:
add 5 new cases covering empty note, past date HTTP rejection, and the
new to-endpoint check in updateEntry.
This commit is contained in:
BOHA
2026-06-05 13:42:21 +02:00
parent 9c110abf46
commit f31797fb5b
4 changed files with 109 additions and 23 deletions

View File

@@ -29,10 +29,7 @@ export const CreatePlanEntrySchema = z
.transform((v) => Number(v))
.nullish(),
category: planCategoryEnum.default("work"),
note: z
.string()
.min(1, "Text poznámky je povinný")
.max(500, "Maximálně 500 znaků"),
note: z.string().max(500, "Maximálně 500 znaků"),
})
.refine((v) => v.date_to >= v.date_from, {
message: "Datum do musí být stejné nebo po datumu od",
@@ -48,7 +45,7 @@ export const UpdatePlanEntrySchema = z
.transform((v) => (v === null ? null : Number(v)))
.nullish(),
category: planCategoryEnum.optional(),
note: z.string().min(1).max(500).optional(),
note: z.string().max(500).optional(),
})
.refine(
(v) =>
@@ -69,10 +66,7 @@ export const CreatePlanOverrideSchema = z.object({
.transform((v) => Number(v))
.nullish(),
category: planCategoryEnum,
note: z
.string()
.min(1, "Text poznámky je povinný")
.max(500, "Maximálně 500 znaků"),
note: z.string().max(500, "Maximálně 500 znaků"),
});
export const UpdatePlanOverrideSchema = z.object({
@@ -81,7 +75,7 @@ export const UpdatePlanOverrideSchema = z.object({
.transform((v) => (v === null ? null : Number(v)))
.nullish(),
category: planCategoryEnum.optional(),
note: z.string().min(1).max(500).optional(),
note: z.string().max(500).optional(),
});
export const PlanRangeQuerySchema = z.object({