Chore/main sync#91
Merged
Merged
Conversation
* chore: package json updates for publishing * update deps
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…etherto#81) - Introduce security dependency review on pull requests - Improve audit reporting (dependency review, npm/pnpm audit, audit-ci on core) - Improve overall CI checks: single install + node_modules cache, lockfile gate, parallel jobs, summary Fleet: core. Suggested PR title matches commit subject.
# Conflicts: # .github/actions/node-restore-cache/action.yml # .github/actions/node-setup-cache/action.yml # .github/workflows/ci.yml # package-lock.json # package.json # tests/unit/routes/ws.routes.test.js # workers/http.node.wrk.js # workers/lib/server/handlers/auth.handlers.js
boris91
approved these changes
Jun 9, 2026
paragmore
approved these changes
Jun 9, 2026
mukama
approved these changes
Jun 9, 2026
paragmore
added a commit
that referenced
this pull request
Jun 9, 2026
* Feature - Site status live api (#4) * feat: add API v2 endpoints (finance, pools, pool-stats, pool-manager) (#11) * feat: add GET /auth/finance/energy-balance endpoint Add energy balance API endpoint that aggregates power consumption, pool transactions, BTC prices, and production costs into a unified time-series response with period-based aggregation (daily/monthly/yearly). Includes shared infrastructure: period.utils, constants for RPC methods, worker types, aggregation fields, and utility functions (getStartOfDay, safeDiv, runParallel). * feat: add GET /auth/pools/:pool/balance-history endpoint Add pool balance history API endpoint that fetches pool balance snapshots via tailLog RPC, groups them into time buckets (1D/1W/1M), and returns time-series data with balance and revenue per bucket. * tiny improvements * feat: add GET /auth/finance/ebitda endpoint Add EBITDA API endpoint that aggregates pool transactions, power/hashrate data, BTC prices, production costs, and block data to calculate selling and HODL EBITDA metrics with period-based aggregation. Includes shared infrastructure: period.utils, constants, and utility functions required for finance endpoints. * feat: add GET /auth/finance/cost-summary endpoint Add cost summary API endpoint that aggregates production costs, BTC prices, and power consumption to calculate energy and operational cost breakdowns with period-based aggregation. * feat: add GET /auth/pools endpoint Add pools API endpoint that aggregates pool device lists and stats from ORK clusters, supports mingo-based filtering, sorting, and field selection, and returns pool summary with totals. * feat: add GET /auth/pool-stats/aggregate endpoint Add pool stats aggregate API endpoint that fetches pool stats history and transactions, processes daily stats and revenue, and aggregates by period (daily/weekly/monthly) with optional pool filtering. * Fix costs bugs * feat: add curtailment, operational issues, and power utilization to energy-balance - Add ELECTRICITY worker type, ENERGY_AGGR/ACTIVE_ENERGY_IN/UTE_ENERGY aggr fields, and GLOBAL_CONFIG RPC method to constants - Add 3 new parallel RPC calls: electricity stats-history (active_energy_in, ute_energy) and getGlobalConfig (nominalPowerAvailability_MW) - Calculate curtailmentMWh, curtailmentRate, operationalIssuesRate, and powerUtilization per log entry - Add avgCurtailmentRate, avgOperationalIssuesRate, avgPowerUtilization to summary - Fix getProductionCosts to use ctx.globalDataLib instead of direct Hyperbee access - Fix processCostsData to return daily costs (energyCostPerDay, operationalCostPerDay) - Update tests to match new cost format and globalDataLib mock * feat: remove block data, fix costs processing, add site param to ebitda - Remove block data RPC call and processBlockData (not in spec) - Remove blockCount, difficulty, ebitdaMarginSelling, ebitdaMarginHodl from log - Fix processCostsData to handle flat objects from globalDataLib with daily costs - Replace direct globalDataLib.getGlobalData range query with getProductionCosts helper - Add site query param to schema, cache key, and handler for site-specific costs * feat: fix costs processing and add site param to cost-summary - Fix processCostsData to handle flat objects from globalDataLib with daily costs - Replace direct globalDataLib range query with getProductionCosts helper - Add site query param to schema, cache key, and handler for site-specific costs - Update tests to match new cost format * feat: add hashrate and remove snapshotCount from balance-history log entries Align pool balance-history endpoint with API v2 spec which requires balance, hashrate, and revenue time-series data. * feat: remove snapshotCount from pool-stats-aggregate log entries Align pool stats aggregate endpoint with API v2 spec which does not include snapshotCount in the response. * fix: use ext-data transactions instead of tail-log for pool stats aggregate tail-log returns empty for type=minerpool. Switch to ext-data with transactions key which has daily revenue and hashrate data. Also fix changed_balance handling (values are BTC, not satoshis). * fix: use ext-data transactions instead of tail-log for balance history tail-log returns empty for type=minerpool. Switch to ext-data with transactions key which provides daily revenue (changed_balance) and hashrate (mining_extra.hash_rate). Also treat 'all' pool param as no filter. * fix: use ext-data stats array instead of list-things for pools endpoint list-things for t-minerpool returns empty; pool data lives in ext-data stats responses. Replaced flattenResults/flattenStatsResults/mergePoolData with flattenPoolStats that parses the actual stats array format. * code cleanup * cleanup * cleanup * Ports pool manager from moria * Removes regions concept to align with site-focused nature of API v2 * chore: remove comments from pool manager files * Remove unncecessaey sute param and add integration tests * removes site * fix: remove site param from ebitda endpoint and add integration test Data is fetched for a single site, so the site parameter is unnecessary. Added security integration test for finance/ebitda endpoint. * fix: remove site param from cost-summary endpoint and add integration test Data is fetched for a single site, so the site parameter is unnecessary. Added security integration test for finance/cost-summary endpoint. * fix: rename filter to query param and use mingo projection for pools Align with list-things pattern by renaming filter→query. Replace manual sort and field filtering with mingo cursor methods for consistency. * fix: move pool filter to RPC payload for balance-history endpoint Pool name filter should be handled by the RPC worker, not filtered client-side. The tx username is the account id. * fix: move pool filter to RPC payload for pool-stats-aggregate endpoint Pool name filter should be handled by the RPC worker, not filtered client-side. The tx username is the account id. * Address PR comments * fix failing tests * Removes tags from projections * Fix integration tests * requestRpcMapAllPages to fetch all pages from orks * fix linting * Fix failing tests * fix: Improves user and roles ux (#12) * return the created user * fix: require users:r permission for GET /auth/roles/permissions * fix: update getRolesPermissions route to require users:w permission * fix: enhance getRolesPermissions to filter roles based on user role * fix: update getRolesPermissions to exclude roleManagement for super admin * Cleanup * feat: add GET /auth/finance/subsidy-fees endpoint (#14) * feat: add GET /auth/finance/subsidy-fees endpoint Port Bitcoin network block data (subsidy rewards + transaction fees) from legacy dashboard to API v2. Fetches HISTORICAL_BLOCKSIZES from mempool worker, aggregates by period (daily/weekly/monthly). * fix: remove unused site parameter from getProductionCosts * Adding CI (#23) * feat: add alerts API v2 endpoints (#24) * resolve conflicts * Feature: Alerts * refactor: use RPC constants and explicit field mapping in alerts handlers * Fix code smells * fix failing tests * Remove metrics * Address comments * feat: add metrics API v2 endpoints (#21) * feat: add finance revenue and revenue-summary endpoints (#22) * feat: add GET /auth/finance/revenue endpoint Port pool transaction revenue data from legacy dashboard to API v2. Separates revenue from pool fees, supporting both F2Pool (changed_balance + tx_fee) and Ocean (satoshis_net_earned + fees_colected_satoshis) formats. Aggregates by period with optional pool filter. * feat: add GET /auth/finance/revenue-summary endpoint Most impactful endpoint — replaces 9 API calls + ~1500 LOC of frontend processing. Merges transaction data, BTC prices, costs, power, hashrate, block data, and electricity data into comprehensive daily rows with EBITDA, production cost, hash revenue, curtailment, and power utilization metrics. * fix: include pool name in worker type for revenue endpoint * refactor: extract shared finance utils and consolidate duplicated logic - Create finance.utils.js with shared utilities: - validateStartEnd: replaces duplicated validation in every handler - normalizeTimestampMs: moved from finance.handlers.js - processTransactions: consolidates processTransactionData and processEbitdaTransactions (fixes missing normalizeTimestampMs and incorrect BTC_SATS division bugs), supports trackFees option - extractCurrentPrice: merges flat and nested EBITDA price formats - processBlockData: extracted for reuse across revenue endpoints - Refactor finance.handlers.js to use shared utils - Add comprehensive unit tests for all utils (24 tests) - Update handler tests to remove tests for deleted functions * Remove spec doc * feat: add device listing API v2 endpoints (#25) * feat: add device listing API v2 endpoints * fix: paginate listThings RPC and add field projections for device endpoints Address PR review: use requestRpcMapAllPages to fetch all items beyond the default 100-item RPC limit, and pass DEVICE_LIST_FIELDS projection to reduce response size when status=1. * fix: use requestRpcMapLimit with limit/offset and remove status - Switch getMiners/getContainers from requestRpcMapAllPages to requestRpcMapLimit, passing limit/offset to RPC instead of fetching all objects - Remove status:1 from all listThings calls as DEVICE_LIST_FIELDS don't have snap properties - Update pagination test to verify RPC payload * Add maximium to limit * Remove /auth/miners * Feat/add get configs route (#26) * Add get configs route * Add tests and lint * Remove old pool manager apis (#29) * feat: add GET /auth/finance/hash-revenue endpoint (#27) * non rpc method calls to ork (#28) * fix: address OWASP security review findings for v2 API endpoints (#30) * ci: enforce coverage (#31) * feat: pool config stats (#32) * feat: pool config stats * var name typo fix * feat: add GET /auth/miners with getThingsCount (#33) * fix: config routes read permissions fix (#34) * ci: improve coverage summary (NYC table) (#35) * feat: containers pool stats (#36) * fix: add schema bounds to prevent negative limit/offset bypass (#37) * ci: move away from pull_request_target (#38) * feat: add groups stats endpoint and racks filter for metrics (#47) * feat: add groups stats endpoint and racks filter for metrics Add GET /auth/groups/stats endpoint for live rack-group aggregation (efficiency, hashrate, power, miner counts). Extend hashrate and consumption metrics with optional racks query parameter for filtering by rack groups via ORK RPC. * feat: add groups stats endpoint and racks filter for metrics Add GET /auth/groups/stats endpoint for live rack-group aggregation (efficiency, hashrate, power, miner counts). Extend hashrate and consumption metrics with optional racks query parameter for filtering by rack groups via ORK RPC. * fix: rename racks filter to containers for metrics endpoints * refactor: deduplicate parseContainers, extractKeyEntry and use AGGR_FIELDS constants * fix: remove non-functional containers filter from hashrate/consumption tailLogCustomRangeAggr RPC method does not support containers param, so remove the dead code from getHashrate/getConsumption handlers, their schemas, route cache keys, and related tests. * fix: handle noAuth mode in capCheck capCheck crashes in noAuth mode when routes pass permissions because ctx.authLib is undefined. Add early return guard matching authCheck. * Revert "fix: handle noAuth mode in capCheck" This reverts commit 2d4d992. * test: improve branch coverage for metrics handlers Add tests for uncovered branches: temperature rolling avg, container history prefix match, non-object guard branches, and groupRange config paths in getPowerMode/getTemperature. * chore: remove unnecessary comment * Add new auth/cooling system api (#51) * Add new auth/cooling system api * Fix review comments, make the tag generic for dcs device and update endpoint path * Fix * remove device name * fix * fix: sanitize queryActions input to prevent injection and DoS (#49) * fix: sanitize queryActions input to prevent injection and DoS (TDEBT-38) Add maxLength constraints to suffix (200) and queries (10000) in route schemas, validate queries array type and cap length at 50 in handler. * fix: tighten queryActions limits and extract to constants Reduce queries string maxLength from 10000 to 1000 and cap the array at 10 items (previously 50). Extract both limits to named constants. * Add energy views endpoint support (#52) * Add energy views endpoint support * move outside to dir with other utils * fix imports * feat: microsoft oauth (#54) * Support site overview endpoints for dcs and miner group wise overview (#55) * Support site overview endpoints for dcs and miner group wise overview * update move to site handlers * Support new dcs device tags update and fix cooling system apis (#56) * Support new dcs device tags update and fix cooling system apis * update the attributes for rack group * Tests * tests * Add hvac circuit 1 and layout api updates (#58) * Add hvac circuit 1 and layout api updates * Update hvac circuit2 api * Add site effciency api (#57) * Add site effciency api * Add site effciency api routes * tests * Add explorer racks api (#59) * (improvement) Explorer handlers, Racks list, Search filtering flow improved (#60) * improv: workers/lib/server/handlers - explorer - 'filterBySearch' flow improved. * improv: workers/lib/server/handlers - explorer - 'filterBySearch' flow & usage improved. * fix: workers/lib/server/handlers - explorer - 'filterBySearch' flow fixed. * test: tests/unit/handlers - explorer - 'filterBySearch' cases coverage extended. * test: tests/unit/handlers - coolingSystem - 'createMockConfig' result generation fixed. * feat: group hashrate by miner and container (#62) * fix: finance v2 handler RPC regressions (#67) * fix: processBlockData parses HISTORICAL_BLOCKSIZES flat-array shape The mempool worker's getWrkExtData returns a flat array of block records [{ts, blockSize, blockReward, blockTotalFees}, ...], but processBlockData only handled nested .data/.blocks wrappers - it iterated entry's own field names, Number('ts') returned NaN, and produced an empty daily map. The SubsidyFee page then rendered "No data available". Detect the flat shape (entry has .ts/.timestamp/.time) and process it directly. Also surface blockSize on getSubsidyFees and getRevenueSummary log entries (and totalBlockSize/avgBlockSize on the summary) - needed for SubsidyFee's "Avg Fees in Sats/vByte" chart to render after this fix. * fix: cost-summary propagates per-day btcPrice Two compounding bugs in getCostSummary caused btcPrice=0 for every log entry, leaving ProductionCostPriceChart's overlay line at 0: 1. Wrong RPC key. The handler queried mempool with key: 'prices', which the worker doesn't recognize and so returns the live snapshot ({currentPrice, blockHeight, ...}). Switched to 'HISTORICAL_PRICES', which returns [{ts, priceUSD}, ...]. 2. processEbitdaPrices couldn't parse the production shape. Same class as the processBlockData fix (Bug C): the mempool worker returns a flat per-ORK array of records, not a wrapper. Detect when entry has .ts/.timestamp/.time and process it as the item directly; also accept priceUSD (the actual upstream field name) alongside price. The processEbitdaPrices fix incidentally makes getRevenueSummary and getHashRevenue use real per-day prices instead of falling back to currentBtcPrice. getEbitda still uses the wrong key: 'prices' (line 344) and is left for a follow-up. * fix: processTailLogData drills into .val for nested TAIL_LOG_RANGE_AGGR The TAIL_LOG_RANGE_AGGR RPC returns per-day items as {ts, val: {site_power_w, hashrate_mhs_5m_sum_aggr}}, but processTailLogData read item[AGGR_FIELDS.SITE_POWER] directly without drilling into .val, so powerW and hashrateMhs were 0 for every entry. RevenueSummary then showed 0 for Avg Power, Avg Hashrate, and Hashrate Capacity Factor; EBITDA's per-day power/hashrate were similarly zeroed. Mirror the .val/.flat fallback pattern that processConsumptionData already uses (workers/lib/server/handlers/finance.handlers.js:172). * fix: hash-revenue hashrate and network-hashrate populate from real RPC Two bugs in getHashRevenue caused hashrateMhs and networkHashrateMhs to be 0 for every log entry, leaving HashBalance entirely zeroed: 1. processHashrateData read item[AGGR_FIELDS.HASHRATE_SUM] directly, but TAIL_LOG_RANGE_AGGR wraps measurements as {ts, val: {hashrate_mhs_5m_sum_aggr}}. Same .val drilling fix as processTailLogData. 2. processNetworkHashrateData expected entries wrapped under .data, but the HISTORICAL_HASHRATE RPC returns a flat per-ORK array of {ts, avgHashrateMHs} records. Same flat-shape detection as processBlockData (Bug C). * Fix memory leak in authCheck by implementing LRU caching and removing in-memory cache (#61) * Support summary for grouped by in hashrate metrics api (#68) * Support summary for grouped by in hashrate metrics api * update groupKey * fix: groups stats accepts rack ids and returns rack objects (#69) * Add groupBy for metrics consumption api (#70) * Update the cooling system handlers to fix flow readings (#71) * fix(finance): correct energy-balance period aggregation (#72) The shared aggregateByPeriod summed every numeric field, which is correct for totals but produced nonsense for rates/means (curtailment rate, btcPrice, sitePowerMW, etc.) on weekly/monthly buckets. - Add an optional `meanKeys` arg to aggregateByPeriod that averages listed fields instead of summing. Default behavior is unchanged for the 6 existing callers. - getEnergyBalance now passes meanKeys for sitePowerMW, btcPrice and the rate fields, then post-processes to recompute energyRevenue*_MW against the (correctly meaned) sitePowerMW denominator. - Add sitePowerMW + energyRevenueBTC_MW/energyRevenueUSD_MW to log entries; add avgPowerConsumption + avgEnergyCostPerMWh + avgOperationalCostPerMWh to summary. - Schema: add 'weekly' to the period enum. * chore: facs version update (#73) * Update the dcs apis to support the new tags (#74) * develop sync (#76) * feat: adopt JWT-based svc-facs-auth (#53) * feat: forecast endpoints (#80) * feat: add rack grouping to metrics/hashrate endpoint (#82) Extend GET /auth/metrics/hashrate with `groupBy=rack` and an optional `racks` CSV filter so charts can render a per-rack hashrate time series for a specific set of racks. - groupBy=rack reads the hashrate_mhs_5m_pdu_rack_group_sum aggregation from stat-1D, the same obj_concat aggregation family already used for type/container group grouping - racks=group-1_rack-1,group-2_rack-1 narrows each log entry's hashrate object and the summary breakdown to the requested racks - racks is cache-keyed and only applied when groupBy=rack * feat: add rack grouping to metrics/consumption endpoint (#83) Extend GET /auth/metrics/consumption with `groupBy=rack` and an optional `racks` CSV filter, mirroring the rack grouping added to metrics/hashrate in #82. - groupBy=rack reads the power_w_pdu_rack_group_sum aggregation from stat-1D, the same obj_concat aggregation family already used for type/container group grouping - racks=group-1_rack-1,group-2_rack-1 narrows each log entry's powerW object (and the derived consumptionMWh) and the summary to those racks - racks is cache-keyed and only applied when groupBy=rack * feat: work order + spare parts HTTP API (#79) * feat: expose Work Order HTTP API + RBAC Adds the Work Order HTTP surface as thin wrappers over the existing things RPC plumbing: POST /auth/work-orders create (registerThing) GET /auth/work-orders list (listThings + type filter) GET /auth/work-orders/:id get (listThings + id+type filter) PATCH /auth/work-orders/:id update (updateThing) POST /auth/work-orders/:id/close close (updateThing status=closed) POST /auth/work-orders/:id/cancel cancel (updateThing status=cancelled) POST /auth/work-orders/:id/assign assign (updateThing assignedTo) GET /auth/work-orders/:id/audit history (getHistoricalLogs) Introduces a new RBAC resource work_order (r/rw) granted to operator/admin/repair_technician roles for write and to viewer roles for read. Strips the duplicated [HRPC_ERR]= prefix and bubbles structured rack errors verbatim. Skips capCheck when the gateway runs with --noauth so local curl-testing works through permissioned routes. * feat: searchable Work Order list with pagination envelope Adds filter shortcuts (q, assignee, creator, partId, status, type, from, to) to GET /auth/work-orders alongside the existing mingo ?query passthrough; q is a case-insensitive regex $or against code and info.issue, the rest map to info.* paths and run on the rack the same way every other list does. Pages now return the {data, totalCount, offset, limit, hasMore} envelope by calling listThings and getThingsCount in parallel, and every shortcut is wired into the cache key so cached pages do not bleed across filter combinations. * feat: spare-part PUT gated by an open Work Order + repair history Adds PUT /auth/spare-parts/:id which validates the supplied workOrderId resolves to an open or in_progress WO, pushes the underlying updateThing on the part rack with workOrderId injected into info, and appends a denormalised entry to the WO's partsMoves[] so the audit trail stays on the Work Order itself. GET /auth/spare-parts/:id/repair-history mingo-queries every WO that ever touched the part and returns each move row hydrated with workOrderCode in the standard {data, totalCount, offset, limit, hasMore} envelope. * feat: Work Order log entries + file upload/download/delete routes Adds POST /auth/work-orders/:id/log which forwards to the existing saveThingComment RPC so the WO comments[] doubles as the work log. Adds POST/GET/DELETE /auth/work-orders/:id/files routes backed by @fastify/multipart on the gateway and the new storeWorkOrderFile/loadWorkOrderFile/removeWorkOrderFile pass- throughs on the ork; uploads validate mime + size, append metadata to WO.info.files via pushAction, and reject mutations on closed or cancelled WOs. * feat: spare-part register flow + Type-1/Type-2 Work Order dispatch POST /auth/spare-parts now creates the part and a paired Type-1 WO in one call, returning {partId, workOrderId, workOrderCode}. POST /auth/work-orders resolves the target part for both flows from deviceIdentifier (id, code, serialNum, or macAddress) and rejects unknown deviceTypes with ERR_INVALID_DEVICE_TYPE / unresolved parts with ERR_PART_NOT_FOUND. * feat: accept warranty payload on Work Order create/update Adds an open `warranty: { vendor, fields }` shape to the create and update body schemas; vendor-specific field validation lives in the inventory worker so app-node stays agnostic of vendor differences. * feat: GET /auth/work-orders/:id/export with PDF + CSV output Export accepts either the WO uuid or its IVI-* code in the path and a required ?format=pdf|csv|docx querystring. CSV flattens one row per parts-movement entry (WO header columns repeated). PDF is server-rendered via PDFKit and includes header, triage, work log, parts movements, file references, and a vendor-specific warranty section. format=docx returns 501 with ERR_EXPORT_FORMAT_NOT_IMPLEMENTED until phase 2. * refactor: ship CSV only; pdf + docx return 501 (deferred to FE/phase 2) Drops the pdfkit dependency and the PDF renderer. The export endpoint now serves CSV directly; pdf and docx both 501 with ERR_EXPORT_FORMAT_NOT_IMPLEMENTED, keeping the route shape stable for when the frontend renders PDF client-side. * feat: align SPARE_PART_INITIAL_LOCATION to canonical 'Site Warehouse' Mirrors the new MINER_LOCATIONS enum from the inventory worker. * refactor: camelCase MINER_LOCATIONS values + SPARE_PART_INITIAL_LOCATION Mirrors the inventory worker constant. * feat: GET /auth/spare-parts with mingo-side location / status / q filters Querystring shortcuts (location, status, q) translate to a mingo query forwarded to the rack via listThings + getThingsCount — no app-node post-filtering. q is a case-insensitive regex against code, info.serialNum, and info.macAddress. WO things are excluded by default via type:{\$ne:...}, overridable by an explicit query.type. Cache key includes every filter shortcut so combinations don't collide. * refactor: extract escapeRegex, listThingsWithCount, stableJsonString to utils Both list handlers (work-orders + spare-parts) hand-rolled the same regex-escape + listThings/getThingsCount/pagination skeleton; collapses to a single utils helper used by both. Cache keys for the two GET list routes now canonicalize their JSON inputs via stableJsonString so semantically-equal queries share a cache slot instead of missing each other on key-order differences. * refactor: drop waitForThing — registerSparePart returns action ids, no polling App-node was polling listThings after each pushAction to surface the rack-assigned thing code in the response — exactly the 'submit-and-poll-in-app-node' anti-pattern the codebase had already rejected. registerSparePart now pre-generates partId/woId, fires both registerThing pushActions in parallel, and returns {partId, workOrderId, partActionId, workOrderActionId, errors}. Clients read the eventually-assigned codes from GET /auth/actions/done/:id like every other write in the app. Removes waitForThing + sleep from utils and the two timeout constants that only existed to tune it. * refactor: address peer-review #3 #6 #8 #10 #12 #20 #3 (atomicity) — updateSparePart now checks the part pushAction's errors[] before firing the WO partsMoves append. If the part write was rejected at push time, throws ERR_PART_UPDATE_PUSH_FAILED:<msg> with a 502 instead of silently enqueueing the WO append. Response shape also gains partActionId / workOrderActionId / workOrderAppendErrors so the FE can detect a post-push WO failure and trigger a manual reconcile. #6 (status casing) — WO status enum normalised to 'inProgress' so every info.* enum value follows the camelCase convention adopted for MINER_LOCATIONS. #8 (registerSparePart field sprawl) — drops the info.model→info.deviceModel→'unknown' fallback chain and the serialNum→macAddress→partId fallback. deviceModel and serialNum are now both required up front with explicit ERR_*_REQUIRED errors. #10 (action latency) — register/update responses include expectedActionLatencyMs sourced from ctx.conf.expectedActionLatencyMs (default 1000) so the FE can pace its /auth/actions/done/:id polling instead of guessing. #12 (export 501) — error message now carries the requested format (ERR_EXPORT_FORMAT_NOT_IMPLEMENTED:pdf / :docx) so the FE can tell which format was rejected without re-reading the request. #20 (pagination) — listThingsWithCount now slices the dedupe'd union down to the requested limit so multi-ork fan-out can't return more rows than the caller asked for. hasMore is now derived from offset + limit rather than offset + data.length. Multi-rack offset-pagination remains best-effort because each rack applies the offset locally; documented inline. * revert: restore 'in_progress' in WO status schema enum Mirrors the inventory rack revert — keeps existing 'in_progress' WO records valid for transitions. * revert: restore human-readable MINER_LOCATIONS values Mirrors the inventory rack revert. * refactor: call generic storeFile / loadFile / removeFile with file type Updates the work-order file handlers to use the renamed generic file RPCs and tags each call with FILE_TYPES.WORK_ORDER so the rack can dispatch on it. * fix: pass workOrderId + fileId to scoped file RPCs, surface blobCleared loadFile / removeFile are now called with { workOrderId, fileId } so the rack resolves the blob descriptor from the work order it belongs to — app-node no longer forwards a raw blobRef. deleteWorkOrderFile surfaces the rack's { cleared } result as blobCleared so the HTTP caller can tell whether the underlying blob was actually removed. * refactor: address PR #79 review feedback - resolve the work_order rack from the ork rack registry via listRacks (getWorkOrderRackId, cached on ctx) and drop the workOrderRackId config key — the rack id is discovered, not deployment config - relocate submitWorkOrderAction out of generic utils into the new server/lib/workOrders module alongside getWorkOrderRackId - add WORK_ORDER_TERMINAL_STATUSES constant, replacing the duplicated ['closed', 'cancelled'] literals across the WO handlers - workOrderExport: derive the CSV header and rows from one [name, extractor] schema instead of two hand-synced lists - rename pushOne -> pushSingleAction in registerSparePart * refactor: derive WO export CSV columns from json keys renderWorkOrderCsv builds the header from the work order's own properties — top-level code plus every info field, then each parts-movement entry's keys — so the CSV tracks the worker response schema with no hand-kept column list. Drops the CSV_HEADERS / WO_COLUMNS / MOVE_COLUMNS definitions. * refactor: remove non-functional comments from WO export and rack helpers * refactor: promote _csvEscape to a generic csvEscape util * refactor: rename WO and spare-parts modules to dot-separated file names Align the work order and spare parts file names with the repo convention (cooling.system.routes.js, energy.system.routes.js, etc.): camelCase basenames become dot-separated — spareParts.handlers.js -> spare.parts.handlers.js, workOrders.js -> work.orders.js, workOrderExport.js -> work.order.export.js. Updates every require() path, route registration in index.js, and test references. * (fix) NPM audit, Dependencies invulnerability fixed (#84) * chore: root - package-lock - dependency tree updated. * fix: root - package-lock - dependency tree packages invulnerability fixed. * feat: list firmwares endpoint (#86) * feat: miner log download via Hypercore P2P streaming (#85) * feat: add miner log download REST endpoints and unit tests * add LogDownloader for P2P miner log streaming Introduces a LogDownloader class that fetches miner log files directly from wrk-miner via Hypercore/Hyperswarm, bypassing the HRPC pipeline. Wired up in the http worker after facilities are ready. * trim verbose comments in log download handlers * Fix LOGS_PEER_NOT_FOUND * feat: forecast history endpoint (#87) * feat: forecast settings (#89) * feat: forecast settings * get forecast settings endpoint * fix: add info params + fix WO auth (#88) * feat: add info params (notes, remarks, site, location) to work order schema Accept optional info object with notes, remarks, site, and location on POST /auth/work-orders and PATCH /auth/work-orders/:id. The handler merges these into the thing info alongside the top-level fields. * fix: auto-qualify bare permission names in tokenHasPerms tokenHasPerms received bare resource names (e.g. 'work_order') from route perms, but _permsMatch expects 'resource:level' format. Splitting a bare name by ':' left `required` as undefined, crashing on spread. * Chore/main sync (#91) * Ci pr trigger change main (#39) * chore: package json updates for publishing (#41) * chore: package json updates for publishing * update deps * ci: package publishing (#40) * ci: adding release pr process and version bump (#42) * Release: v1.0.0 (#44) * ci: release pr local jobs (#46) * ci: persistents credentials to allow tag creation (#48) * Release: v1.0.0 (#50) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * chore: facs version update (#77) * refactor: logs cleanup (#78) * ci: CI Checks — dependency review, audits, and workflow improvements (#81) - Introduce security dependency review on pull requests - Improve audit reporting (dependency review, npm/pnpm audit, audit-ci on core) - Improve overall CI checks: single install + node_modules cache, lockfile gate, parallel jobs, summary Fleet: core. Suggested PR title matches commit subject. * reset ci updates --------- Co-authored-by: andretetherio <andre.mendes@tether.io> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> --------- Co-authored-by: Parag More <34959548+paragmore@users.noreply.github.com> Co-authored-by: Caesar Mukama <mcaesar88@gmail.com> Co-authored-by: andretetherio <andre.mendes@tether.io> Co-authored-by: borik91 <9007515+boris91@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.