This commit is contained in:
@@ -86,6 +86,13 @@ export const billingAddressSchema = z
|
||||
country: z.enum(SUPPORTED_COUNTRIES, {
|
||||
message: "Please choose a country from the list",
|
||||
}),
|
||||
// Bug 35: VAT identifier. Required for company customers (B2B);
|
||||
// omitted entirely for personal customers (B2C — private
|
||||
// individuals don't have a VAT number). The schema marks it
|
||||
// optional because the same schema is used for both flows;
|
||||
// company-vs-personal enforcement happens at the API layer where
|
||||
// `user.isPersonal` is known.
|
||||
vatNumber: z.string().trim().max(50).optional(),
|
||||
})
|
||||
.superRefine((data, ctx) => {
|
||||
const pattern = POSTAL_CODE_PATTERNS[data.country];
|
||||
@@ -123,6 +130,12 @@ export const billingStepSchema = z.object({
|
||||
* Full onboarding payload. Used by the API route and by the wizard's
|
||||
* submit handler. `packageSecrets` is a free-shape map that gets
|
||||
* encrypted by the server before it touches the DB.
|
||||
*
|
||||
* Bug 35: `billingAddress` is now optional at the schema level. The
|
||||
* wizard omits it entirely when the org already has an `org_billing`
|
||||
* record. The API enforces "billing must exist by the end" by either
|
||||
* looking up the existing org_billing row OR validating the supplied
|
||||
* payload — neither path can be skipped without a 400.
|
||||
*/
|
||||
export const onboardingSchema = z.object({
|
||||
instanceName: z
|
||||
@@ -139,7 +152,7 @@ export const onboardingSchema = z.object({
|
||||
packageSecrets: z
|
||||
.record(z.string(), z.record(z.string(), z.string()))
|
||||
.optional(),
|
||||
billingAddress: billingAddressSchema,
|
||||
billingAddress: billingAddressSchema.optional(),
|
||||
billingNotes: z.string().max(2_000).optional(),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user