Files
app/src/schemas/trips.schema.ts
BOHA 1826fc7976 fix: audit fix pass #1 — all 19 verified HIGH findings + critical dep cleanup
Fixes every CRITICAL/HIGH finding from the 2026-06-09 full-codebase audit
(REVIEW_FINDINGS.md); each fix went through independent spec + code-quality
review. Plan and per-task log: docs/superpowers/plans/2026-06-10-audit-high-fix-pass.md

- attendance: schemas accept the combined local datetimes the forms/service
  use (new dateTimeString helpers in schemas/common.ts), breaks persist on
  create, AttendanceCreate submit rebuilt — every submit 400'd since 519edce
- 2fa: backup codes wired to /totp/backup-verify (+ remember-me parity),
  enrollment QR generated locally via qrcode (CSP-blocked external service
  also leaked the secret), dashboard shows per-user enrollment, not policy
- invoices/orders: per-line VAT survives re-saves (numberOr 0-respecting
  coercion in formatters.ts), billing_text persists on update, issued-order
  status transitions update UI gates
- trips: real pagination on all 3 pages, GET /trips/stats server aggregate
  (shared buildTripsWhere + legacy distance coalesce), vehicle_id applies on
  PUT with both-vehicle odometer recompute, print rebuilt (sync window.open,
  escaped template, server totals)
- orders api: attachment_data PDF blob excluded from all non-binary reads
- warehouse: unit field is a Select over UnitEnum, receipt attachments
  downloadable via new authenticated GET route
- downloads: shared RFC 5987 contentDisposition helper — Czech filenames no
  longer 500 (warehouse, received-invoices, orders endpoints)
- misc: block-env hook actually blocks (exit 2 + stderr), project create
  works with empty dates, NaN filter guards on trips endpoints
- deps: remove unused concurrently (clears both critical advisories), pin
  @hono/node-server >=1.19.13 via overrides (clears the 3 moderates without
  the Prisma 6 downgrade), drop deprecated @types stubs

Gates: tsc -b clean - vitest 30 files / 342 tests (31 new) - eslint 0 errors
- build OK

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 09:59:47 +02:00

37 lines
1.3 KiB
TypeScript

import { z } from "zod";
import {
intIdFromForm,
nonNegativeNumberFromForm,
booleanFromForm,
isoDateString,
} from "./common";
export const CreateTripSchema = z.object({
vehicle_id: intIdFromForm,
// user_id is optional here because the route injects it from authData.userId
// when the client doesn't provide it (see POST /trips handler)
user_id: intIdFromForm.optional(),
trip_date: isoDateString,
start_km: nonNegativeNumberFromForm,
end_km: nonNegativeNumberFromForm,
route_from: z.string().min(1, "Vyplňte odkud").max(255),
route_to: z.string().min(1, "Vyplňte kam").max(255),
is_business: booleanFromForm.optional().default(false),
notes: z.string().max(2000).nullish(),
});
export const UpdateTripSchema = z.object({
// trips.vehicle_id is a non-nullable FK — when present it must be a valid id
vehicle_id: intIdFromForm.optional(),
trip_date: isoDateString.optional(),
start_km: nonNegativeNumberFromForm.optional(),
end_km: nonNegativeNumberFromForm.optional(),
route_from: z.string().min(1, "Vyplňte odkud").max(255).optional(),
route_to: z.string().min(1, "Vyplňte kam").max(255).optional(),
is_business: booleanFromForm.optional(),
notes: z.string().max(2000).nullish(),
});
export type CreateTripInput = z.infer<typeof CreateTripSchema>;
export type UpdateTripInput = z.infer<typeof UpdateTripSchema>;