fix(freight-portal): stop owner details vanishing between wizard steps

SourcedField rendered read-only whenever a value existed, so the input a
customer had just typed into turned into a badge as soon as the step saved and
they navigated back — and dropped out of requiredKeys at the same time. It now
locks on ownership instead: a Fayda verification owns what its claims filled,
everything else stays an editable, prefilled input.

The representation step follows the same rule and asks in the right order:

- The power-of-attorney question collapses to its answer once given, with a
  button back to it (none for a freight forwarder, whose answer is forced).
- A foreign company picks how to prove the person outright — Fayda or a
  passport — rather than being shown both at once.
- The representative's own fields appear only once the person is established,
  and only for what the verification did not supply; what it did supply is
  already on the panel above and is no longer repeated beneath it.
- Dropped the freight-forwarder lecture and the DARS blurb; the badge and the
  upload field's own help text already say both.

VAT numbers accept any non-blank value. A foreign tax authority's carries
letters and dashes and a co-operative's follows neither pattern, so the 10-11
digit rule only ever rejected numbers we had no business judging.
This commit is contained in:
Nathnael
2026-08-11 12:54:38 +00:00
parent 02d9debe1d
commit 72164b0b8e
6 changed files with 363 additions and 230 deletions

View File

@@ -5,7 +5,6 @@ import {
MaxLength,
IsEnum,
IsIn,
Matches,
} from "class-validator";
import { ETHIOPIAN_REGIONS, type EthiopianRegion } from "@edr/types";
import { CompanyNationality } from "../entities/company.entity";
@@ -36,13 +35,14 @@ export class UpdateProfileDto {
@IsTin({ message: "TIN must be exactly 10 digits" })
tin?: string;
// Ethiopian VAT registration numbers are 10 digits (the same shape as the
// TIN), but some are issued with an 11th. Both portal forms enforce the same
// range; without it here the API happily stored whatever a stale client sent,
// and the two layers disagreed about what the column may hold.
// No shape check. Ethiopian VAT numbers are usually 10 or 11 digits, but a
// foreign company's is whatever its own tax authority issues — letters,
// dashes and any length — and a co-operative's registration numbering does
// not follow the trade-licence pattern either. The field is required (the
// portal enforces non-blank) but its content is not ours to police.
@IsOptional()
@IsString()
@Matches(/^\d{10,11}$/, { message: "VAT number must be 10 or 11 digits" })
@MaxLength(64)
vatNumber?: string;
// `fanNumber` is deliberately absent: the FAN is a Fayda number, so it would