L10b Betrieb & Aufräumen: Sync – Berichts-Ops, Konflikt-Übernahme, eigene Session im Bundle
- Aufräumpunkt j: report.save_draft und report.submit mit Zod-Schemas (lib/sync/ops.ts) und Registry-Einträgen → services/reports/sync-ops.ts. report.submit reicht baseVersion als expectedWorkOrderVersion und aiReviewed an submitReport durch; Lotse-Entwürfe ohne Bestätigung → rejected invalid. signature.capture bleibt unregistriert (Upload-Art für Unterschriftsbild fehlt). - Aufräumpunkt b: „Übernehmen" in der Konfliktliste delegiert an den Sync-Dispatcher (apply.ts#reapplyOperation, ohne baseVersion) statt des L2-Stubs; unterstützt work_order.transition und report.submit. Hinweistext der Konfliktliste angepasst. - Aufräumpunkt c: getFieldBundle liefert je Auftrag mySession (eigene aktive WorkSession); die Offline-Ansicht leitet den Zeitstatus daraus ab (alte Bundles: Näherung über Auftragsstatus). - scripts/test-betrieb-sync.ts (Bundle, clientId je Mandant, Berichts-Ops, Konflikt-Übernahme, Mandant B, Monteur ohne Zuweisung); test-einsatz-sync.ts prüft „nicht verfügbare Op" jetzt mit signature.capture, weil report.save_draft registriert ist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+22
-3
@@ -2,6 +2,7 @@ import { z } from "zod";
|
||||
import type { SyncOpType } from "./envelope";
|
||||
import { WORK_ORDER_STATUSES } from "@/lib/work-orders/status";
|
||||
import { emergencyCreatePayload } from "@/lib/emergency/schemas";
|
||||
import { reportTextsSchema } from "@/lib/reports/content";
|
||||
|
||||
/**
|
||||
* Payload schemas per sync opType (ARCHITEKTUR §4.6). Client-safe: used by the mobile UI to
|
||||
@@ -113,7 +114,25 @@ export const voiceAttachPayload = z.object({
|
||||
kind: z.enum(NOTE_KINDS).optional(),
|
||||
});
|
||||
|
||||
/** Schemas of ops owned by other lanes are validated there (reports: L5, emergency: L8). */
|
||||
/**
|
||||
* report.save_draft / report.submit (L10b, registered in services/sync/external-ops.ts →
|
||||
* services/reports/sync-ops.ts). `workOrderId` is required: the sync pipeline checks scope and the
|
||||
* conflict version (`baseVersion` = WorkOrder.version seen by the device) on that order.
|
||||
*/
|
||||
export const reportSaveDraftPayload = z.object({
|
||||
workOrderId: id,
|
||||
reportId: id,
|
||||
texts: reportTextsSchema.partial(),
|
||||
});
|
||||
|
||||
export const reportSubmitPayload = z.object({
|
||||
workOrderId: id,
|
||||
reportId: id,
|
||||
/** L9 Freigabeprinzip: "Ich habe den Vorschlag vom Lotsen geprüft" — mandatory for Lotse drafts */
|
||||
aiReviewed: z.boolean().optional(),
|
||||
});
|
||||
|
||||
/** Schemas of ops owned by other lanes are validated there (signature.capture: not offline-capable yet). */
|
||||
const passthrough = z.record(z.string(), z.unknown());
|
||||
|
||||
export const OP_PAYLOAD_SCHEMAS = {
|
||||
@@ -127,8 +146,8 @@ export const OP_PAYLOAD_SCHEMAS = {
|
||||
"material.upsert": materialUpsertPayload,
|
||||
"photo.attach": photoAttachPayload,
|
||||
"voice.attach": voiceAttachPayload,
|
||||
"report.save_draft": passthrough,
|
||||
"report.submit": passthrough,
|
||||
"report.save_draft": reportSaveDraftPayload,
|
||||
"report.submit": reportSubmitPayload,
|
||||
"signature.capture": passthrough,
|
||||
"emergency.create": emergencyCreatePayload,
|
||||
} satisfies Record<SyncOpType, z.ZodType>;
|
||||
|
||||
Reference in New Issue
Block a user