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:
@@ -301,9 +301,27 @@ export async function getFieldBundle(ctx: ServiceCtx, since?: Date | null) {
|
||||
const histories = Object.fromEntries(
|
||||
await Promise.all(siteIds.map(async (id) => [id, await fieldSiteHistory(ctx, id, 5).catch(() => [])] as const)),
|
||||
);
|
||||
// L10b (L7 offene Punkte 3/4): the caller's own running session per order, so the offline view
|
||||
// shows the correct time actions on team orders with several technicians.
|
||||
const ownSessions = orders.length
|
||||
? await ctx.db.workSession.findMany({
|
||||
where: { workOrderId: { in: orders.map((o) => o.id) }, userId: ctx.userId, status: { in: ACTIVE_SESSION_STATUSES } },
|
||||
orderBy: { startedAt: "desc" },
|
||||
select: { id: true, workOrderId: true, status: true, startedAt: true },
|
||||
})
|
||||
: [];
|
||||
const mySessions = new Map<string, { id: string; status: string; startedAt: string }>();
|
||||
for (const s of ownSessions) {
|
||||
if (!mySessions.has(s.workOrderId)) mySessions.set(s.workOrderId, { id: s.id, status: s.status, startedAt: s.startedAt.toISOString() });
|
||||
}
|
||||
return {
|
||||
serverTime: serverTime.toISOString(),
|
||||
since: since?.toISOString() ?? null,
|
||||
orders: orders.map((o) => ({ ...o, statusGroup: STATUS_GROUP[o.status], siteHistory: o.site ? histories[o.site.id] ?? [] : [] })),
|
||||
orders: orders.map((o) => ({
|
||||
...o,
|
||||
statusGroup: STATUS_GROUP[o.status],
|
||||
siteHistory: o.site ? histories[o.site.id] ?? [] : [],
|
||||
mySession: mySessions.get(o.id) ?? null,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user