@things-factory/work-shift 10.1.2 → 10.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -108,7 +108,21 @@ async function getWorkDateAndShift(domain, dateTime, options) {
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
/*
|
|
112
|
+
* **교대 시간 밖이다 — 정상이다.**
|
|
113
|
+
*
|
|
114
|
+
* 이 자리는 `logger.error(new Error('shift not found'))` 였고, 던지지 않고 아래에서 정상
|
|
115
|
+
* 반환했다. 「지금은 교대 시간이 아니다」는 밤마다 참이므로, 몇 초마다 스택 트레이스가
|
|
116
|
+
* error 레벨로 쌓였다.
|
|
117
|
+
*
|
|
118
|
+
* plant 레인이 그 로그를 보고 「화면이 터진다」고 사용자님께 잘못 보고했다(2026-09-08).
|
|
119
|
+
* 그쪽 분류(`between-shifts`)와 화면은 처음부터 정상이었다.
|
|
120
|
+
*
|
|
121
|
+
* **정상 상태가 error 로 찍히면 사람이 error 를 안 보게 되고, 잘못 읽게도 된다.** 뒤엣것이
|
|
122
|
+
* 실제로 일어난 쪽이다 — `new Error(...)` 가 스택을 담아 찍으니 던진 것처럼 보인다.
|
|
123
|
+
* 부르는 쪽은 `workShift: ''` 로 그 사실을 이미 받는다 — 로그가 그 위에 더 말할 것이 없다.
|
|
124
|
+
*/
|
|
125
|
+
env_1.logger.debug(`work-shift: ${dateTime} is outside every declared shift — returning an empty shift`);
|
|
112
126
|
}
|
|
113
127
|
/* 3. in case there are no work-shift, just give date and default shift '' */
|
|
114
128
|
return {
|
|
@@ -172,7 +186,21 @@ async function getLatestWorkDateAndShift(domain, dateTime, options) {
|
|
|
172
186
|
}
|
|
173
187
|
}
|
|
174
188
|
}
|
|
175
|
-
|
|
189
|
+
/*
|
|
190
|
+
* **교대 시간 밖이다 — 정상이다.**
|
|
191
|
+
*
|
|
192
|
+
* 이 자리는 `logger.error(new Error('shift not found'))` 였고, 던지지 않고 아래에서 정상
|
|
193
|
+
* 반환했다. 「지금은 교대 시간이 아니다」는 밤마다 참이므로, 몇 초마다 스택 트레이스가
|
|
194
|
+
* error 레벨로 쌓였다.
|
|
195
|
+
*
|
|
196
|
+
* plant 레인이 그 로그를 보고 「화면이 터진다」고 사용자님께 잘못 보고했다(2026-09-08).
|
|
197
|
+
* 그쪽 분류(`between-shifts`)와 화면은 처음부터 정상이었다.
|
|
198
|
+
*
|
|
199
|
+
* **정상 상태가 error 로 찍히면 사람이 error 를 안 보게 되고, 잘못 읽게도 된다.** 뒤엣것이
|
|
200
|
+
* 실제로 일어난 쪽이다 — `new Error(...)` 가 스택을 담아 찍으니 던진 것처럼 보인다.
|
|
201
|
+
* 부르는 쪽은 `workShift: ''` 로 그 사실을 이미 받는다 — 로그가 그 위에 더 말할 것이 없다.
|
|
202
|
+
*/
|
|
203
|
+
env_1.logger.debug(`work-shift: ${dateTime} is outside every declared shift — returning an empty shift`);
|
|
176
204
|
}
|
|
177
205
|
/* 3. in case there are no work-shift, just give date and default shift '' */
|
|
178
206
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"work-shift-range.js","sourceRoot":"","sources":["../../server/controllers/work-shift-range.ts"],"names":[],"mappings":"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","sourcesContent":["import moment from 'moment-timezone'\n\nimport { logger } from '@things-factory/env'\nimport { Domain, getRepository } from '@things-factory/shell'\n\nimport { WorkShift } from '../service/work-shift/work-shift'\nimport { WorkShiftInfo } from '../service/work-shift/work-shift-type'\nimport { shiftsInForceAt } from '../service/work-shift/work-shift-revision-service'\n\n/**\n * 그 시각에 쓰던 교대 — **지금 편성이 아닐 수 있다.**\n *\n * 편성이 바뀌기 전의 시각을 지금 편성으로 읽으면, 그 시각의 사실이 있지도 않았던 교대 이름으로 나온다.\n * 공장이 2교대에서 3교대로 바꾸는 날 지난 석 달의 실적이 통째로 다시 이름 붙는 것이 그것이다.\n *\n * **이력보다 앞선 시각은 빈 목록이다.** 그때 무엇을 쓰고 있었는지 이 시스템은 모른다 — 지금 편성으로\n * 대신하지 않는다.\n */\nasync function shiftsAt(domain: Domain, at: Date): Promise<Pick<WorkShift, 'name' | 'fromDate' | 'fromTime' | 'toDate' | 'toTime'>[]> {\n const found = await shiftsInForceAt(getRepository(WorkShift).manager, domain, at)\n\n return (found?.shifts ?? []) as Pick<WorkShift, 'name' | 'fromDate' | 'fromTime' | 'toDate' | 'toTime'>[]\n}\n\nexport async function getDateRangeForWorkShift(\n domain: Domain,\n workDate: string,\n workShiftName: string,\n options?: { timezone?: string; format?: string }\n): Promise<Date[]> {\n const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }\n const { timezone, format } = dateOptions\n\n /* 그 조업일에 쓰던 편성에서 찾는다 — 지금 편성에는 없는 이름일 수 있다. */\n const asOf = moment.tz(workDate, timezone).toDate()\n const workShift = (await shiftsAt(domain, asOf)).find(shift => shift.name === workShiftName)\n\n if (!workShift) {\n return\n }\n const theDay = moment.tz(workDate, timezone)\n const { name, fromDate, fromTime, toDate, toTime } = workShift\n\n const convertedFromDate = theDay.clone().add(fromDate, 'day')\n const convertedToDate = theDay.clone().add(toDate, 'day')\n const from = moment\n .tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n .toDate()\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone).toDate()\n\n return [from, to]\n}\n\nexport async function getDateRangeForWorkDate(\n domain: Domain,\n workDate: string,\n options?: { timezone?: string; format?: string }\n) {\n const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }\n const { timezone, format } = dateOptions\n\n var beginDate\n var endDate\n\n /* 1. 그 조업일에 쓰던 편성을 가져온다 — 지금 편성이 아닐 수 있다. */\n const workShifts = await shiftsAt(domain, moment.tz(workDate, timezone).toDate())\n\n /* 2. get date-time for every work-shift */\n if (workShifts && workShifts.length > 0) {\n const theDay = moment.tz(workDate, timezone)\n\n for (let j = 0; j < workShifts.length; j++) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]\n\n const convertedFromDate = theDay.clone().add(fromDate, 'day')\n const convertedToDate = theDay.clone().add(toDate, 'day')\n const from = moment\n .tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n .toDate()\n const to = moment\n .tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n .toDate()\n\n if (!beginDate) {\n beginDate = from\n }\n\n endDate = to\n }\n } else {\n return\n }\n\n /* 3. in case there are no work-shift, just give date and default shift '' */\n return [beginDate, endDate]\n}\n\nexport async function getWorkDateAndShift(domain: Domain, dateTime: Date, options?: any): Promise<WorkShiftInfo> {\n const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }\n const { timezone, format } = dateOptions\n\n const givenDate = moment(dateTime).tz(timezone)\n /* 1. 그 시각에 쓰던 편성을 가져온다 — 바뀌기 전의 시각이면 지금 편성이 아니다. */\n const workShifts = await shiftsAt(domain, dateTime)\n\n /* 2. compare given date-time to every work-shift */\n const theDay = givenDate.clone().startOf('day')\n const theDayBefore = theDay.clone().subtract(1, 'day')\n const theDayAfter = theDay.clone().add(1, 'day')\n\n if (workShifts && workShifts.length > 0) {\n const days = [theDayBefore, theDay, theDayAfter]\n let dateBegin, dateEnd\n\n for (let i = 0; i < days.length; i++) {\n const day = days[i]\n dateBegin = null\n\n for (let j = 0; j < workShifts.length; j++) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]\n\n const convertedFromDate = day.clone().add(fromDate, 'day')\n const convertedToDate = day.clone().add(toDate, 'day')\n\n const from = moment.tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n\n dateBegin = dateBegin || from\n dateEnd = from.clone().add(1, 'day')\n\n if (dateTime >= from.toDate() && to.toDate() > dateTime) {\n return {\n workDate: moment(day).format(format),\n workShift: name,\n dateRange: [dateBegin.toDate(), dateEnd.toDate()],\n shiftRange: [from.toDate(), to.toDate()]\n }\n }\n }\n }\n\n logger.error(new Error('shift not found'))\n }\n\n /* 3. in case there are no work-shift, just give date and default shift '' */\n return {\n workDate: givenDate.format(format),\n workShift: '',\n dateRange: [theDay.toDate(), theDayAfter.toDate()]\n }\n}\n\nexport async function getLatestWorkDateAndShift(domain: Domain, dateTime: Date, options?: any): Promise<WorkShiftInfo> {\n const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }\n const { timezone, format } = dateOptions\n\n const givenDate = moment(dateTime).tz(timezone)\n\n /* 1. 그 시각에 쓰던 편성을 가져온다 — 바뀌기 전의 시각이면 지금 편성이 아니다. */\n const workShifts = await shiftsAt(domain, dateTime)\n\n /* 2. compare given date-time to every work-shift */\n const theDay = givenDate.clone().startOf('day')\n const theDayBefore = theDay.clone().subtract(1, 'day')\n const theDayAfter = theDay.clone().add(1, 'day')\n\n if (workShifts && workShifts.length > 0) {\n const days = [theDayBefore, theDay, theDayAfter]\n let dateBegin, dateEnd\n\n for (let i = 0; i < days.length; i++) {\n const day = days[i]\n dateBegin = null\n\n for (let j = 0; j < workShifts.length; j++) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]\n\n const convertedFromDate = day.clone().add(fromDate, 'day')\n const convertedToDate = day.clone().add(toDate, 'day')\n\n const from = moment.tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n\n dateBegin = dateBegin || from\n dateEnd = from.clone().add(1, 'day')\n\n if (dateTime < from.toDate()) {\n if (j > 0) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[j - 1]\n\n const from = moment.tz(\n `${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`,\n 'YYYY-MM-DD HH:mm:ss',\n timezone\n )\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n\n return {\n workDate: moment(day).format(format),\n workShift: name,\n dateRange: [dateBegin.toDate(), dateEnd.toDate()],\n shiftRange: [from.toDate(), to.toDate()]\n }\n } else if (i > 0) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[0]\n\n const convertedFromDate = days[i - 1].clone().add(fromDate, 'day')\n const convertedToDate = days[i - 1].clone().add(toDate, 'day')\n\n const from = moment.tz(\n `${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`,\n 'YYYY-MM-DD HH:mm:ss',\n timezone\n )\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n\n return {\n workDate: moment(day).format(format),\n workShift: name,\n dateRange: [dateBegin.clone().subtract(1, 'day').toDate(), dateBegin.toDate()],\n shiftRange: [from.toDate(), to.toDate()]\n }\n } else {\n return\n }\n }\n }\n }\n\n logger.error(new Error('shift not found'))\n }\n\n /* 3. in case there are no work-shift, just give date and default shift '' */\n return {\n workDate: givenDate.clone().subtract(1, 'day').format(format),\n workShift: '',\n dateRange: [theDayBefore.toDate(), theDay.toDate()]\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"work-shift-range.js","sourceRoot":"","sources":["../../server/controllers/work-shift-range.ts"],"names":[],"mappings":";;AAwBA,4DA2BC;AAED,0DA0CC;AAED,kDAmEC;AAED,8DAoGC;;AA1QD,8EAAoC;AAEpC,6CAA4C;AAC5C,iDAA6D;AAE7D,iEAA4D;AAE5D,mGAAmF;AAEnF;;;;;;;;GAQG;AACH,KAAK,UAAU,QAAQ,CAAC,MAAc,EAAE,EAAQ;IAC9C,MAAM,KAAK,GAAG,MAAM,IAAA,6CAAe,EAAC,IAAA,qBAAa,EAAC,sBAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;IAEjF,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAA8E,CAAA;AAC3G,CAAC;AAEM,KAAK,UAAU,wBAAwB,CAC5C,MAAc,EACd,QAAgB,EAChB,aAAqB,EACrB,OAAgD;IAEhD,MAAM,WAAW,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,CAAA;IAC5F,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAA;IAExC,+CAA+C;IAC/C,MAAM,IAAI,GAAG,yBAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAA;IACnD,MAAM,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,CAAA;IAE5F,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAM;IACR,CAAC;IACD,MAAM,MAAM,GAAG,yBAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC5C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAE9D,MAAM,iBAAiB,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC7D,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IACzD,MAAM,IAAI,GAAG,yBAAM;SAChB,EAAE,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,QAAQ,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC;SAC5F,MAAM,EAAE,CAAA;IACX,MAAM,EAAE,GAAG,yBAAM,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAA;IAEnH,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;AACnB,CAAC;AAEM,KAAK,UAAU,uBAAuB,CAC3C,MAAc,EACd,QAAgB,EAChB,OAAgD;IAEhD,MAAM,WAAW,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,CAAA;IAC5F,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAA;IAExC,IAAI,SAAS,CAAA;IACb,IAAI,OAAO,CAAA;IAEX,6CAA6C;IAC7C,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,yBAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;IAEjF,2CAA2C;IAC3C,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,yBAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;YAElE,MAAM,iBAAiB,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;YAC7D,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YACzD,MAAM,IAAI,GAAG,yBAAM;iBAChB,EAAE,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,QAAQ,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC;iBAC5F,MAAM,EAAE,CAAA;YACX,MAAM,EAAE,GAAG,yBAAM;iBACd,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC;iBACxF,MAAM,EAAE,CAAA;YAEX,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS,GAAG,IAAI,CAAA;YAClB,CAAC;YAED,OAAO,GAAG,EAAE,CAAA;QACd,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAM;IACR,CAAC;IAED,6EAA6E;IAC7E,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;AAC7B,CAAC;AAEM,KAAK,UAAU,mBAAmB,CAAC,MAAc,EAAE,QAAc,EAAE,OAAa;IACrF,MAAM,WAAW,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,CAAA;IAC5F,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAA;IAExC,MAAM,SAAS,GAAG,IAAA,yBAAM,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAA;IAC/C,oDAAoD;IACpD,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAEnD,oDAAoD;IACpD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACtD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IAEhD,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;QAChD,IAAI,SAAS,EAAE,OAAO,CAAA;QAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACnB,SAAS,GAAG,IAAI,CAAA;YAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;gBAElE,MAAM,iBAAiB,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;gBAC1D,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;gBAEtD,MAAM,IAAI,GAAG,yBAAM,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,QAAQ,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAA;gBAChH,MAAM,EAAE,GAAG,yBAAM,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAA;gBAE1G,SAAS,GAAG,SAAS,IAAI,IAAI,CAAA;gBAC7B,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;gBAEpC,IAAI,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;oBACxD,OAAO;wBACL,QAAQ,EAAE,IAAA,yBAAM,EAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;wBACpC,SAAS,EAAE,IAAI;wBACf,SAAS,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;wBACjD,UAAU,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;qBACzC,CAAA;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED;;;;;;;;;;;;;WAaG;QACH,YAAM,CAAC,KAAK,CAAC,eAAe,QAAQ,6DAA6D,CAAC,CAAA;IACpG,CAAC;IAED,6EAA6E;IAC7E,OAAO;QACL,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;QAClC,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;KACnD,CAAA;AACH,CAAC;AAEM,KAAK,UAAU,yBAAyB,CAAC,MAAc,EAAE,QAAc,EAAE,OAAa;IAC3F,MAAM,WAAW,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,CAAA;IAC5F,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,WAAW,CAAA;IAExC,MAAM,SAAS,GAAG,IAAA,yBAAM,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAA;IAE/C,oDAAoD;IACpD,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAEnD,oDAAoD;IACpD,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC/C,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACtD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IAEhD,IAAI,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;QAChD,IAAI,SAAS,EAAE,OAAO,CAAA;QAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACnB,SAAS,GAAG,IAAI,CAAA;YAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;gBAElE,MAAM,iBAAiB,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;gBAC1D,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;gBAEtD,MAAM,IAAI,GAAG,yBAAM,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,QAAQ,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAA;gBAChH,MAAM,EAAE,GAAG,yBAAM,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAA;gBAE1G,SAAS,GAAG,SAAS,IAAI,IAAI,CAAA;gBAC7B,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;gBAEpC,IAAI,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBACV,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;wBAEtE,MAAM,IAAI,GAAG,yBAAM,CAAC,EAAE,CACpB,GAAG,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,QAAQ,EAAE,EACvD,qBAAqB,EACrB,QAAQ,CACT,CAAA;wBACD,MAAM,EAAE,GAAG,yBAAM,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAA;wBAE1G,OAAO;4BACL,QAAQ,EAAE,IAAA,yBAAM,EAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;4BACpC,SAAS,EAAE,IAAI;4BACf,SAAS,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;4BACjD,UAAU,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;yBACzC,CAAA;oBACH,CAAC;yBAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBACjB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;wBAElE,MAAM,iBAAiB,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;wBAClE,MAAM,eAAe,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;wBAE9D,MAAM,IAAI,GAAG,yBAAM,CAAC,EAAE,CACpB,GAAG,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,QAAQ,EAAE,EACvD,qBAAqB,EACrB,QAAQ,CACT,CAAA;wBACD,MAAM,EAAE,GAAG,yBAAM,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,MAAM,EAAE,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAA;wBAE1G,OAAO;4BACL,QAAQ,EAAE,IAAA,yBAAM,EAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;4BACpC,SAAS,EAAE,IAAI;4BACf,SAAS,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;4BAC9E,UAAU,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;yBACzC,CAAA;oBACH,CAAC;yBAAM,CAAC;wBACN,OAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED;;;;;;;;;;;;;WAaG;QACH,YAAM,CAAC,KAAK,CAAC,eAAe,QAAQ,6DAA6D,CAAC,CAAA;IACpG,CAAC;IAED,6EAA6E;IAC7E,OAAO;QACL,QAAQ,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;QAC7D,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;KACpD,CAAA;AACH,CAAC","sourcesContent":["import moment from 'moment-timezone'\n\nimport { logger } from '@things-factory/env'\nimport { Domain, getRepository } from '@things-factory/shell'\n\nimport { WorkShift } from '../service/work-shift/work-shift'\nimport { WorkShiftInfo } from '../service/work-shift/work-shift-type'\nimport { shiftsInForceAt } from '../service/work-shift/work-shift-revision-service'\n\n/**\n * 그 시각에 쓰던 교대 — **지금 편성이 아닐 수 있다.**\n *\n * 편성이 바뀌기 전의 시각을 지금 편성으로 읽으면, 그 시각의 사실이 있지도 않았던 교대 이름으로 나온다.\n * 공장이 2교대에서 3교대로 바꾸는 날 지난 석 달의 실적이 통째로 다시 이름 붙는 것이 그것이다.\n *\n * **이력보다 앞선 시각은 빈 목록이다.** 그때 무엇을 쓰고 있었는지 이 시스템은 모른다 — 지금 편성으로\n * 대신하지 않는다.\n */\nasync function shiftsAt(domain: Domain, at: Date): Promise<Pick<WorkShift, 'name' | 'fromDate' | 'fromTime' | 'toDate' | 'toTime'>[]> {\n const found = await shiftsInForceAt(getRepository(WorkShift).manager, domain, at)\n\n return (found?.shifts ?? []) as Pick<WorkShift, 'name' | 'fromDate' | 'fromTime' | 'toDate' | 'toTime'>[]\n}\n\nexport async function getDateRangeForWorkShift(\n domain: Domain,\n workDate: string,\n workShiftName: string,\n options?: { timezone?: string; format?: string }\n): Promise<Date[]> {\n const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }\n const { timezone, format } = dateOptions\n\n /* 그 조업일에 쓰던 편성에서 찾는다 — 지금 편성에는 없는 이름일 수 있다. */\n const asOf = moment.tz(workDate, timezone).toDate()\n const workShift = (await shiftsAt(domain, asOf)).find(shift => shift.name === workShiftName)\n\n if (!workShift) {\n return\n }\n const theDay = moment.tz(workDate, timezone)\n const { name, fromDate, fromTime, toDate, toTime } = workShift\n\n const convertedFromDate = theDay.clone().add(fromDate, 'day')\n const convertedToDate = theDay.clone().add(toDate, 'day')\n const from = moment\n .tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n .toDate()\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone).toDate()\n\n return [from, to]\n}\n\nexport async function getDateRangeForWorkDate(\n domain: Domain,\n workDate: string,\n options?: { timezone?: string; format?: string }\n) {\n const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }\n const { timezone, format } = dateOptions\n\n var beginDate\n var endDate\n\n /* 1. 그 조업일에 쓰던 편성을 가져온다 — 지금 편성이 아닐 수 있다. */\n const workShifts = await shiftsAt(domain, moment.tz(workDate, timezone).toDate())\n\n /* 2. get date-time for every work-shift */\n if (workShifts && workShifts.length > 0) {\n const theDay = moment.tz(workDate, timezone)\n\n for (let j = 0; j < workShifts.length; j++) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]\n\n const convertedFromDate = theDay.clone().add(fromDate, 'day')\n const convertedToDate = theDay.clone().add(toDate, 'day')\n const from = moment\n .tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n .toDate()\n const to = moment\n .tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n .toDate()\n\n if (!beginDate) {\n beginDate = from\n }\n\n endDate = to\n }\n } else {\n return\n }\n\n /* 3. in case there are no work-shift, just give date and default shift '' */\n return [beginDate, endDate]\n}\n\nexport async function getWorkDateAndShift(domain: Domain, dateTime: Date, options?: any): Promise<WorkShiftInfo> {\n const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }\n const { timezone, format } = dateOptions\n\n const givenDate = moment(dateTime).tz(timezone)\n /* 1. 그 시각에 쓰던 편성을 가져온다 — 바뀌기 전의 시각이면 지금 편성이 아니다. */\n const workShifts = await shiftsAt(domain, dateTime)\n\n /* 2. compare given date-time to every work-shift */\n const theDay = givenDate.clone().startOf('day')\n const theDayBefore = theDay.clone().subtract(1, 'day')\n const theDayAfter = theDay.clone().add(1, 'day')\n\n if (workShifts && workShifts.length > 0) {\n const days = [theDayBefore, theDay, theDayAfter]\n let dateBegin, dateEnd\n\n for (let i = 0; i < days.length; i++) {\n const day = days[i]\n dateBegin = null\n\n for (let j = 0; j < workShifts.length; j++) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]\n\n const convertedFromDate = day.clone().add(fromDate, 'day')\n const convertedToDate = day.clone().add(toDate, 'day')\n\n const from = moment.tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n\n dateBegin = dateBegin || from\n dateEnd = from.clone().add(1, 'day')\n\n if (dateTime >= from.toDate() && to.toDate() > dateTime) {\n return {\n workDate: moment(day).format(format),\n workShift: name,\n dateRange: [dateBegin.toDate(), dateEnd.toDate()],\n shiftRange: [from.toDate(), to.toDate()]\n }\n }\n }\n }\n\n /*\n * **교대 시간 밖이다 — 정상이다.**\n *\n * 이 자리는 `logger.error(new Error('shift not found'))` 였고, 던지지 않고 아래에서 정상\n * 반환했다. 「지금은 교대 시간이 아니다」는 밤마다 참이므로, 몇 초마다 스택 트레이스가\n * error 레벨로 쌓였다.\n *\n * plant 레인이 그 로그를 보고 「화면이 터진다」고 사용자님께 잘못 보고했다(2026-09-08).\n * 그쪽 분류(`between-shifts`)와 화면은 처음부터 정상이었다.\n *\n * **정상 상태가 error 로 찍히면 사람이 error 를 안 보게 되고, 잘못 읽게도 된다.** 뒤엣것이\n * 실제로 일어난 쪽이다 — `new Error(...)` 가 스택을 담아 찍으니 던진 것처럼 보인다.\n * 부르는 쪽은 `workShift: ''` 로 그 사실을 이미 받는다 — 로그가 그 위에 더 말할 것이 없다.\n */\n logger.debug(`work-shift: ${dateTime} is outside every declared shift — returning an empty shift`)\n }\n\n /* 3. in case there are no work-shift, just give date and default shift '' */\n return {\n workDate: givenDate.format(format),\n workShift: '',\n dateRange: [theDay.toDate(), theDayAfter.toDate()]\n }\n}\n\nexport async function getLatestWorkDateAndShift(domain: Domain, dateTime: Date, options?: any): Promise<WorkShiftInfo> {\n const dateOptions = { timezone: domain.timezone || 'UTC', format: 'YYYY-MM-DD', ...options }\n const { timezone, format } = dateOptions\n\n const givenDate = moment(dateTime).tz(timezone)\n\n /* 1. 그 시각에 쓰던 편성을 가져온다 — 바뀌기 전의 시각이면 지금 편성이 아니다. */\n const workShifts = await shiftsAt(domain, dateTime)\n\n /* 2. compare given date-time to every work-shift */\n const theDay = givenDate.clone().startOf('day')\n const theDayBefore = theDay.clone().subtract(1, 'day')\n const theDayAfter = theDay.clone().add(1, 'day')\n\n if (workShifts && workShifts.length > 0) {\n const days = [theDayBefore, theDay, theDayAfter]\n let dateBegin, dateEnd\n\n for (let i = 0; i < days.length; i++) {\n const day = days[i]\n dateBegin = null\n\n for (let j = 0; j < workShifts.length; j++) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[j]\n\n const convertedFromDate = day.clone().add(fromDate, 'day')\n const convertedToDate = day.clone().add(toDate, 'day')\n\n const from = moment.tz(`${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n\n dateBegin = dateBegin || from\n dateEnd = from.clone().add(1, 'day')\n\n if (dateTime < from.toDate()) {\n if (j > 0) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[j - 1]\n\n const from = moment.tz(\n `${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`,\n 'YYYY-MM-DD HH:mm:ss',\n timezone\n )\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n\n return {\n workDate: moment(day).format(format),\n workShift: name,\n dateRange: [dateBegin.toDate(), dateEnd.toDate()],\n shiftRange: [from.toDate(), to.toDate()]\n }\n } else if (i > 0) {\n const { name, fromDate, fromTime, toDate, toTime } = workShifts[0]\n\n const convertedFromDate = days[i - 1].clone().add(fromDate, 'day')\n const convertedToDate = days[i - 1].clone().add(toDate, 'day')\n\n const from = moment.tz(\n `${convertedFromDate.format('YYYY-MM-DD')} ${fromTime}`,\n 'YYYY-MM-DD HH:mm:ss',\n timezone\n )\n const to = moment.tz(`${convertedToDate.format('YYYY-MM-DD')} ${toTime}`, 'YYYY-MM-DD HH:mm:ss', timezone)\n\n return {\n workDate: moment(day).format(format),\n workShift: name,\n dateRange: [dateBegin.clone().subtract(1, 'day').toDate(), dateBegin.toDate()],\n shiftRange: [from.toDate(), to.toDate()]\n }\n } else {\n return\n }\n }\n }\n }\n\n /*\n * **교대 시간 밖이다 — 정상이다.**\n *\n * 이 자리는 `logger.error(new Error('shift not found'))` 였고, 던지지 않고 아래에서 정상\n * 반환했다. 「지금은 교대 시간이 아니다」는 밤마다 참이므로, 몇 초마다 스택 트레이스가\n * error 레벨로 쌓였다.\n *\n * plant 레인이 그 로그를 보고 「화면이 터진다」고 사용자님께 잘못 보고했다(2026-09-08).\n * 그쪽 분류(`between-shifts`)와 화면은 처음부터 정상이었다.\n *\n * **정상 상태가 error 로 찍히면 사람이 error 를 안 보게 되고, 잘못 읽게도 된다.** 뒤엣것이\n * 실제로 일어난 쪽이다 — `new Error(...)` 가 스택을 담아 찍으니 던진 것처럼 보인다.\n * 부르는 쪽은 `workShift: ''` 로 그 사실을 이미 받는다 — 로그가 그 위에 더 말할 것이 없다.\n */\n logger.debug(`work-shift: ${dateTime} is outside every declared shift — returning an empty shift`)\n }\n\n /* 3. in case there are no work-shift, just give date and default shift '' */\n return {\n workDate: givenDate.clone().subtract(1, 'day').format(format),\n workShift: '',\n dateRange: [theDayBefore.toDate(), theDay.toDate()]\n }\n}\n"]}
|