Services board/schedule (L2 assign+update in inTransaction, Versionskonflikt, Audit), recommend (Luftlinie + freie Kolonnenzeit), live (Kolonnen, ohne Geräte-Koordinaten), watch (Verzug ab 80 %, Überschreitung, gefährdete Folgeaufträge, früher fertig mit Vorschlägen), Kolonnenkapazität. Job planning-watch alle 5 min, Events planning.capacity_freed/overrun/followup_at_risk (In-App an Backoffice + Teamleiter, Dedupe im Audit-Log), L12-Adapter für source/approvalStatus/manual. API /api/v1/planning/{board,schedule,recommendations,live} + OpenAPI. Tests core, recommend, live, watch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
31 lines
1.6 KiB
TypeScript
31 lines
1.6 KiB
TypeScript
import { Prisma } from "@prisma/client";
|
|
|
|
/**
|
|
* Adapter to the time tracking model of lane L12 (read-only use in planning).
|
|
*
|
|
* L12 adds `TimeEntry.source` (tracked | manual), `TimeEntry.approvalStatus` (approved | pending |
|
|
* rejected) and `WorkSession.manual`. Planning rules:
|
|
* - live situation / delay evaluation: only `source = tracked` entries of non-manual sessions,
|
|
* - actual duration of completed orders: only `approvalStatus = approved` entries.
|
|
* The filters are enabled automatically as soon as the generated Prisma client knows the fields
|
|
* (after the L12 merge); before that they are no-ops, so this lane compiles against both schemas.
|
|
*/
|
|
|
|
const entryFields = new Set<string>(Object.values(Prisma.TimeEntryScalarFieldEnum));
|
|
const sessionFields = new Set<string>(Object.values(Prisma.WorkSessionScalarFieldEnum));
|
|
|
|
export const TIME_TRACKING_FIELDS = {
|
|
entrySource: entryFields.has("source"),
|
|
entryApproval: entryFields.has("approvalStatus"),
|
|
sessionManual: sessionFields.has("manual"),
|
|
} as const;
|
|
|
|
/** Time entries recorded by the running clock (no manual additions). */
|
|
export const trackedEntryWhere = (TIME_TRACKING_FIELDS.entrySource ? { source: "tracked" } : {}) as unknown as Prisma.TimeEntryWhereInput;
|
|
|
|
/** Approved time entries (actual duration of completed orders). */
|
|
export const approvedEntryWhere = (TIME_TRACKING_FIELDS.entryApproval ? { approvalStatus: "approved" } : {}) as unknown as Prisma.TimeEntryWhereInput;
|
|
|
|
/** Sessions started by the clock (manual after-the-fact sessions excluded). */
|
|
export const trackedSessionWhere = (TIME_TRACKING_FIELDS.sessionManual ? { manual: false } : {}) as unknown as Prisma.WorkSessionWhereInput;
|