diff --git a/tests/unit/handlers/spare.parts.handlers.test.js b/tests/unit/handlers/spare.parts.handlers.test.js index 15399d3..771830d 100644 --- a/tests/unit/handlers/spare.parts.handlers.test.js +++ b/tests/unit/handlers/spare.parts.handlers.test.js @@ -285,7 +285,7 @@ test('handlers: registerSparePart fires part + Type-1 WO pushActions in parallel const { ctx, pushed } = buildRegisterCtx() const out = await handlers.registerSparePart(ctx, { ...userMeta(), - body: { rackId: PART_RACK, info: { deviceType: 'psu', deviceModel: 'PSU-WM-CB6_V5', serialNum: 'SN-99' } } + body: { rackId: PART_RACK, info: { deviceType: 'psu', deviceModel: 'PSU-WM-CB6_V5', serialNum: 'SN-99', notes: 'NOTES' } } }) t.is(pushed.length, 2, 'one part action, one WO action') @@ -293,7 +293,10 @@ test('handlers: registerSparePart fires part + Type-1 WO pushActions in parallel const woAction = pushed.find(p => p.params[0].rackId === WO_RACK) t.is(partAction.action, 'registerThing') t.is(woAction.action, 'registerThing') + t.alike(partAction.params[0].opts, {}, 'part registration carries empty opts so device racks (miners) accept it') + t.is(woAction.params[0].opts, undefined, 'WO registration carries no opts') t.is(woAction.params[0].info.type, 1, 'Type-1 WO') + t.is(woAction.params[0].info.notes, 'NOTES', 'operator note recorded on the register WO') t.is(woAction.params[0].info.partsMoves[0].fromLocation, null) t.is(woAction.params[0].info.partsMoves[0].toLocation, 'site.warehouse') t.is(woAction.params[0].info.partsMoves[0].partId, out.partId, 'WO partsMoves entry links to the pre-generated partId') @@ -339,11 +342,13 @@ test('handlers: registerSparePartsBatch creates one shared register WO carrying t.is(woInfo.type, 1, 'single Type-1 register WO') t.is(woInfo.deviceCount, 3) t.is(woInfo.partsMoves.length, 3, 'register WO carries every part') - t.is(woInfo.note, 'Pallets 1-3', 'note recorded on the register WO') + t.is(woInfo.notes, 'Pallets 1-3', 'note recorded on the register WO') t.alike(woInfo.partsMoves.map(m => m.partId).sort(), out.parts.map(p => p.partId).sort(), 'WO links every returned part') + t.is(woAction.params[0].opts, undefined, 'WO registration carries no opts') for (const pa of partActions) { - t.is(pa.params[0].info.note, 'Pallets 1-3', 'note attached to each registered part') + t.is(pa.params[0].info.notes, 'Pallets 1-3', 'note attached to each registered part') + t.alike(pa.params[0].opts, {}, 'each part registration carries empty opts so device racks accept it') } t.is(out.parts.length, 3, 'returns a result row per part') t.alike(out.errors, [], 'no errors on happy path') diff --git a/workers/lib/server/handlers/spare.parts.handlers.js b/workers/lib/server/handlers/spare.parts.handlers.js index f94d7e0..5a113b2 100644 --- a/workers/lib/server/handlers/spare.parts.handlers.js +++ b/workers/lib/server/handlers/spare.parts.handlers.js @@ -205,6 +205,7 @@ async function registerSparePart (ctx, req) { deviceIdentifier: info.serialNum, createdBy: voter, createdAt: ts, + ...(info.notes ? { notes: info.notes } : {}), partsMoves: [{ partId, fromLocation: null, @@ -215,10 +216,10 @@ async function registerSparePart (ctx, req) { }] } - const pushSingleAction = (rack, id, info) => ctx.dataProxy.requestData('pushAction', { + const pushSingleAction = (rack, id, info, opts) => ctx.dataProxy.requestData('pushAction', { action: 'registerThing', query: { rack }, - params: [{ rackId: rack, id, info }], + params: [{ rackId: rack, id, info, ...(opts ? { opts } : {}) }], voter, authPerms }, (res, arr) => { @@ -227,7 +228,7 @@ async function registerSparePart (ctx, req) { }) const [partResults, woResults] = await Promise.all([ - pushSingleAction(rackId, partId, partInfo), + pushSingleAction(rackId, partId, partInfo, {}), pushSingleAction(workOrderRackId, woId, woInfo) ]) @@ -275,7 +276,7 @@ async function registerSparePartsBatch (ctx, req) { ...part, location: part.location ?? SPARE_PART_INITIAL_LOCATION } - if (note) partInfo.note = note + if (note) partInfo.notes = note return { partId: randomUUID(), part, partInfo } }) @@ -301,12 +302,12 @@ async function registerSparePartsBatch (ctx, req) { user: voter })) } - if (note) woInfo.note = note + if (note) woInfo.notes = note - const pushSingleAction = (rack, id, info) => ctx.dataProxy.requestData('pushAction', { + const pushSingleAction = (rack, id, info, opts) => ctx.dataProxy.requestData('pushAction', { action: 'registerThing', query: { rack }, - params: [{ rackId: rack, id, info }], + params: [{ rackId: rack, id, info, ...(opts ? { opts } : {}) }], voter, authPerms }, (res, arr) => { @@ -316,7 +317,7 @@ async function registerSparePartsBatch (ctx, req) { const [woResults, ...partResultsList] = await Promise.all([ pushSingleAction(workOrderRackId, woId, woInfo), - ...prepared.map(({ partId, partInfo }) => pushSingleAction(rackId, partId, partInfo)) + ...prepared.map(({ partId, partInfo }) => pushSingleAction(rackId, partId, partInfo, {})) ]) const partsOut = prepared.map(({ partId }, i) => ({ diff --git a/workers/lib/server/routes/work.orders.routes.js b/workers/lib/server/routes/work.orders.routes.js index c80b2f5..2bab74f 100644 --- a/workers/lib/server/routes/work.orders.routes.js +++ b/workers/lib/server/routes/work.orders.routes.js @@ -68,13 +68,7 @@ module.exports = (ctx) => [ method: HTTP_METHODS.GET, url: ENDPOINTS.WORK_ORDER_BY_ID, schema: schemas.byId, - ...createCachedAuthRoute( - ctx, - (req) => ['work-orders', req.params.id], - ENDPOINTS.WORK_ORDER_BY_ID, - getWorkOrder, - [AUTH_PERMISSIONS.WORK_ORDER] - ) + ...createAuthRoute(ctx, getWorkOrder, [AUTH_PERMISSIONS.WORK_ORDER]) }, { method: HTTP_METHODS.GET, diff --git a/workers/lib/server/schemas/work.orders.schemas.js b/workers/lib/server/schemas/work.orders.schemas.js index 63670f0..bd34700 100644 --- a/workers/lib/server/schemas/work.orders.schemas.js +++ b/workers/lib/server/schemas/work.orders.schemas.js @@ -132,6 +132,7 @@ const update = { type: 'object', additionalProperties: false, properties: { + issue: { type: 'string', minLength: 1, maxLength: 2000 }, notes: { type: 'string', maxLength: 4000 }, remarks: { type: 'string', maxLength: 4000 }, site: { type: 'string', maxLength: 200 },