Add optional Firma/USt-IdNr. fields to checkout and profile

B2B checkout fields, split out from the e-invoicing migration and
picked back up now that it's shipped. Both fields are independently
optional, format-validated (shared regex in lib/vatId.ts, mirrored
server-side in api/checkout and api/account/profile), persisted in
the checkout draft, and saved as a customer profile default that
pre-fills future checkouts. Order/customer snapshot fields land in a
companion Payload backend commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-07-23 17:53:21 +00:00
parent 2d88fb86a1
commit e48107470a
8 changed files with 119 additions and 1 deletions
+10 -1
View File
@@ -1,5 +1,6 @@
import { NextResponse } from "next/server";
import { getSessionCustomer, updateCustomerProfile } from "../../../lib/customerAuth";
import { normalizeVatId, isValidVatId } from "../../../lib/vatId";
export async function GET() {
const session = await getSessionCustomer();
@@ -12,7 +13,7 @@ export async function PATCH(request: Request) {
if (!session) return NextResponse.json({ ok: false, reason: "Bitte zuerst einloggen." }, { status: 401 });
const body = await request.json().catch(() => null);
const { firstName, lastName, deliveryMethod, street, packstationNumber, postNumber, zip, city, country } = body ?? {};
const { firstName, lastName, deliveryMethod, street, packstationNumber, postNumber, zip, city, country, companyName, vatId } = body ?? {};
if (
typeof firstName !== "string" ||
!firstName ||
@@ -34,6 +35,12 @@ export async function PATCH(request: Request) {
if (deliveryMethod === "packstation" && (!packstationNumber || !postNumber)) {
return NextResponse.json({ ok: false, reason: "Bitte Packstation- und Postnummer angeben." }, { status: 400 });
}
// Both independently optional (see Customers.ts's own comment) — only
// format-checked when actually provided, same as the backend field itself.
const normalizedVatId = typeof vatId === "string" && vatId ? normalizeVatId(vatId) : undefined;
if (normalizedVatId && !isValidVatId(normalizedVatId)) {
return NextResponse.json({ ok: false, reason: "Ungültiges USt-IdNr.-Format (z. B. DE123456789)." }, { status: 400 });
}
const result = await updateCustomerProfile(session.token, session.customer.id, {
firstName,
@@ -45,6 +52,8 @@ export async function PATCH(request: Request) {
zip,
city,
country,
companyName: typeof companyName === "string" && companyName ? companyName : undefined,
vatId: normalizedVatId,
});
return NextResponse.json(result, { status: result.ok ? 200 : 400 });
}