From 8a20c1744486f698619a47e3e412a4c1df6c1c6f Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 21 Sep 2026 10:42:55 +0200 Subject: [PATCH] Website-Beispiel ohne Demo-Kundennamen, Smoke-Test mit dynamischem Fremdkunden MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der Lotse-Beispielchat nannte „Wohnanlage Elbblick“ aus den Demo-Daten; die Mandantentrennungs-Prüfung für demo2 schlug deshalb an. Dazu Grammatik korrigiert. smoke-auth sucht den für den Monteur fremden Kunden jetzt über die Aufträge statt fest K-D004, weil Aufträge beim Ausprobieren der Plantafel umgeplant werden. Co-Authored-By: Claude Opus 5 --- messages/de/marketing.json | 2 +- messages/en/marketing.json | 2 +- scripts/smoke-auth.ts | 13 ++++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/messages/de/marketing.json b/messages/de/marketing.json index d2b6856..dca89b0 100644 --- a/messages/de/marketing.json +++ b/messages/de/marketing.json @@ -128,7 +128,7 @@ "title": "Sagen, was war — statt Felder suchen", "text": "Der Lotse versteht ganze Sätze, ordnet den Auftrag zu und fragt nach, was fehlt. Er zeigt eine Karte mit dem, was er buchen würde. Erst nach Bestätigung wird etwas geschrieben.", "chatUser": "Auftrag fertig, Speicher eingebaut, 2 Stunden, einen Filter verbraucht", - "chatAssistant": "Ich ordne das Auftrag A-00042 zu, Wohnanlage Elbblick. Zwei Fragen: War die Anfahrt dabei, und soll ich den Auftrag technisch abschließen?", + "chatAssistant": "Ich ordne das dem Auftrag A-00042 zu, Wohnanlage Lindenhof. Zwei Fragen: War die Anfahrt dabei, und soll ich den Auftrag technisch abschließen?", "cardTitle": "Vorschlag", "cardLine1": "2:00 Std. Arbeitszeit buchen", "cardLine2": "1 × Filter als Material erfassen", diff --git a/messages/en/marketing.json b/messages/en/marketing.json index 2f8c740..d73a1a3 100644 --- a/messages/en/marketing.json +++ b/messages/en/marketing.json @@ -128,7 +128,7 @@ "title": "Say what happened — instead of hunting for fields", "text": "Lotse understands whole sentences, maps them to the job and asks for what is missing. It shows a card with what it would book. Nothing is written before you confirm.", "chatUser": "Job done, installed the tank, two hours, used one filter", - "chatAssistant": "I'm mapping this to job A-00042, Elbblick apartments. Two questions: was travel included, and should I mark the job technically complete?", + "chatAssistant": "I'm mapping this to job A-00042, Lindenhof apartments. Two questions: was travel included, and should I mark the job technically complete?", "cardTitle": "Proposal", "cardLine1": "Book 2:00 h of work time", "cardLine2": "Record 1 × filter as material", diff --git a/scripts/smoke-auth.ts b/scripts/smoke-auth.ts index f55b133..b63f9b1 100644 --- a/scripts/smoke-auth.ts +++ b/scripts/smoke-auth.ts @@ -33,7 +33,18 @@ async function ids() { if (!d07 || !d18) throw new Error("Demo-Aufträge fehlen — `npx prisma db seed` (SEED_DEMO) ausführen."); const emergency = await prisma.workOrder.findFirst({ where: { tenantId: demo.id, isEmergency: true, emergencyReason: { startsWith: "Wasserrohrbruch" } }, select: { id: true, number: true } }); const customer = await prisma.customer.findFirstOrThrow({ where: { tenantId: demo.id, customerNumber: "K-D001" } }); - const foreignCustomer = await prisma.customer.findFirstOrThrow({ where: { tenantId: demo.id, customerNumber: "K-D004" } }); + // "Fremder" Kunde für den Monteur: keiner seiner Aufträge (Team oder Einzelzuweisung) gehört dazu. + // Dynamisch statt fest K-D004, weil Aufträge beim Ausprobieren der Plantafel umgeplant werden. + const tech = await prisma.user.findFirstOrThrow({ where: { tenantId: demo.id, email: "monteur@demo.example" }, select: { id: true } }); + const techTeams = (await prisma.teamMember.findMany({ where: { tenantId: demo.id, userId: tech.id }, select: { teamId: true } })).map((m) => m.teamId); + const foreignCustomer = await prisma.customer.findFirstOrThrow({ + where: { + tenantId: demo.id, + deletedAt: null, + workOrders: { none: { OR: [{ assignedTeamId: { in: techTeams } }, { assignees: { some: { userId: tech.id } } }] } }, + }, + orderBy: { customerNumber: "asc" }, + }); const site = await prisma.site.findFirstOrThrow({ where: { tenantId: demo.id, name: "Wohnanlage Elbblick – Haus A" } }); const approved = await prisma.report.findFirstOrThrow({ where: { workOrderId: d18.id, status: "approved" } }); const inReview = d16 ? await prisma.report.findFirst({ where: { workOrderId: d16.id } }) : null;