# Task: Add Input Validation for User Data Form ## Objective Add length/format/range validation for the fields listed below, enforced at three layers: frontend (UX), backend (source of truth), and database (last line of defense). Do not change unrelated form behavior, styling, or fields not listed here. ## Scope Only touch the files responsible for these fields: the form component(s), the API endpoint(s) that receive this data, the validation schema/middleware, and the DB migration/schema for these columns. If a field doesn't exist yet in the DB/API, flag it and ask before creating new schema — don't assume the shape. --- ## Field Rules | Field | Type | Rule | |---|---|---| | firstName | string | required, trim, 1–50 chars, Unicode letters/spaces/hyphens/apostrophes allowed | | lastName | string | required, trim, 1–50 chars, same charset as firstName | | email | string | required, trim, max 254 chars, valid email format (use an existing validation library, don't hand-roll regex) | | nationality | enum | required, must be a valid ISO 3166-1 country code (dropdown-backed, not free text) | | phoneNumber | string | required, normalize to E.164 on save (use existing phone validation lib if the project has one; otherwise ask before adding a dependency), max 20 raw input chars | | driverLicense | string | optional unless told otherwise, trim, 5–30 chars, alphanumeric only | | date (generic) | date | must be a valid ISO 8601 date (`YYYY-MM-DD`); reject free text | | address | string | required, trim, 1–255 chars | | idPassport | string | required, trim, 5–30 chars, alphanumeric | | country | enum | required, valid ISO 3166-1 country code (dropdown-backed) | | issuedDate | date | required, ISO 8601, must be ≤ today | | expirationDate | date | required, ISO 8601, must be ≥ issuedDate | | dateTime | datetime | required, store as ISO 8601 with UTC offset — do not store naive local time | | vinNumber | string | required, exactly 17 chars, alphanumeric excluding I/O/Q, uppercase | | city | string | required, trim, 1–85 chars | | amount | number | required, numeric, > 0, max 2 decimal places, reasonable upper bound (ask what "reasonable" means for this use case if not obvious from context — don't guess a business rule) | ## Cross-field rules - `expirationDate` must be after `issuedDate`. - `issuedDate` must not be in the future. - Do not implement any cross-field rule not listed here without asking first. --- ## Implementation steps 1. **Locate existing validation approach.** Check if the project already uses a validation library (Zod, Yup, Joi, class-validator, pydantic, etc.) or a pattern for form validation. Use whatever already exists — do not introduce a new validation library if one is already in use. 2. **Frontend:** add `maxlength`/type-appropriate input constraints and inline error messages matching the rules above. Reuse existing form error-display patterns in the codebase. 3. **Backend:** add/extend the validation schema or middleware for the relevant endpoint(s) to enforce the same rules server-side. This is the authoritative check — assume the frontend check can be bypassed. 4. **Database:** only if column definitions currently allow unbounded/incorrect lengths, add matching length constraints via migration. Do not touch unrelated columns or tables. 5. Normalize country/nationality to ISO codes, phone to E.164, and dates to ISO 8601 at the point of validation/save — not scattered across multiple layers. ## Explicitly out of scope (ask before doing any of this) - Adding a new third-party validation/phone/country-list library if one doesn't already exist in the project. - Changing the DB schema shape (splitting address into multiple columns, etc.) — flag it as a suggestion instead. - Any field not in the list above. - Deep format validation for driverLicense/idPassport beyond length + charset (these vary too much by issuing country to hardcode safely) — ask if stricter per-country validation is actually wanted. ## Validation before reporting done - Confirm each rule above has a corresponding check in frontend AND backend (list them field by field in your report). - Confirm existing tests still pass; add new tests only for the fields touched here. - Report any field where the existing DB column type/length conflicts with the rule above, rather than silently changing it.